+++ /dev/null
-
-/* -}{----------------------------------------------------------------------- */
-
-#include <kernelapi.h>
-#include <ni.h>
-
-/* -}{----------------------------------------------------------------------- */
-
-extern void ensure_self_sub(ni_event* evq);
-
-/* -}{----------------------------------------------------------------------- */
-
-#define TMPBUFSIZE 4096
-static char tmpbuf[TMPBUFSIZE];
-
-/* -}{----------------------------------------------------------------------- */
-
-static void cache_read(char*, char*, char*, int, k_stat, void*);
-static void entity_written(char*, char*, char*, int, k_stat, void*);
-static void write_headers(char* path, ni_resource* res);
-static void headers_written(char*, char*, char*, int, k_stat, void*);
-
-
-/* -}{----------------------------------------------------------------------- */
-
-char* make_cache_path(char* uri)
-{
- char* path;
- size_t l=strlen(uri);
- if(l>100){ k_log_out("URI too long to save: %s", uri); return 0; }
- if(*(uri+l-1)!='/'){
- path=k_strdup(uri);
- }
- else{
- path=k_malloc(l+1+10);
- sprintf(path, "%sindex.html", uri);
- }
- return path;
-}
-
-void look_in_file_cache(ni_event* evq)
-{
- k_hashtable* sub=evq->ent_head;
- char* uri=k_hashtable_get(sub, "Sub-To:");
- size_t l=strlen(uri);
-
- if(l>100){ ensure_self_sub(evq); return; }
-
- char hdr[128];
- if(*(uri+l-1)!='/') sprintf(hdr, "%s.hdr", uri);
- else sprintf(hdr, "%sindex.html.hdr", uri);
-
- if(strstr(hdr, "..")){ ensure_self_sub(evq); return; }
- if(strchr(hdr, '?' )){ ensure_self_sub(evq); return; }
-
- char* c=strchr(hdr, ':');
- char* e=strchr(hdr, '/');
- if(c && c< e) *c='-';
-
- k_file_read(".", k_strdup(hdr), USE_MALL, 0, cache_read, evq);
-}
-
-void save_in_file_cache(ni_resource* res)
-{
- char* uri =res->uri;
- char* path =make_cache_path(uri); if(!path) return;
- k_hashtable* ent_head=res->ent_head;
- void* data =res->entity;
- int partial =k_hashtable_is( ent_head, "Status:", "206");
- size_t size =k_hashtable_get_int(ent_head, "Content-Length:");
- char* conrange=k_hashtable_get( ent_head, "Content-Range:");
- int constant=k_hashtable_is( ent_head, "CUX:", "C");
-
- if(!data){
- write_headers(path, res);
- }
- else
- if(constant){
- int ok=k_file_sync(data, size);
- if(!ok){
- k_log_err("Failed to write (sync mmap): %s", uri);
- k_free(path);
- return;
- }
- write_headers(path, res);
- }
- else{
- if(partial){
- k_log_out("save_in_file_cache partial %s", conrange);
- if(!conrange || strncmp(conrange, "0-", 2)){
- k_log_err("not saving partial");
- k_free(path);
- return;
- }
- size=atoi(conrange+2);
- }
- k_log_out("save_in_file_cache updateable: %d bytes", size);
- k_file_write(".", path, data, size, entity_written, res);
- }
-}
-
-/* -}{----------------------------------------------------------------------- */
-
-void entity_written(char* basedir,
- char* path,
- char* data,
- int usedmmap,
- k_stat kstat,
- void* context)
-{
- if(data) k_log_out("File cache entity written: %s", path);
- else{
- k_log_err("Failed to write entity: %s", path);
- k_free(path);
- return;
- }
- ni_resource* res=context;
- write_headers(path, res);
-}
-
-void write_headers(char* path, ni_resource* res)
-{
- snprintf(tmpbuf, TMPBUFSIZE, "%s.hdr", path);
- k_free(path); path=k_strdup(tmpbuf);
- k_hashtable_snprintf(res->ent_head, tmpbuf, TMPBUFSIZE);
- k_file_write(".", path, tmpbuf, strlen(tmpbuf), headers_written, 0);
-}
-
-void headers_written(char* basedir,
- char* path,
- char* data,
- int usedmmap,
- k_stat kstat,
- void* context)
-{
- if(data) k_log_out("File cache headers written: %s", path);
- else k_log_err("Failed to write headers: %s", path);
- k_free(path);
-}
-
-void cache_read(char* basedir,
- char* path,
- char* data,
- int usedmmap,
- k_stat kstat,
- void* context)
-{
- if(!data) k_log_out("no cache of %s", path);
- else k_log_out("file cache read: %d %s", kstat.size, path);
- char* e=strstr(path, ".hdr");
- if(e){
- ni_event* evq=context;
- if(!data){ k_free(path); ensure_self_sub(evq); return; }
-
- char* header=data;
- *(header+kstat.size-2)=0;
- k_hashtable* ent_head=k_hashtable_new("nHeaders/cache_read", 1);
- k_hashtable_put(ent_head, "", header);
- if(!ni_get_headers(header, 0, ent_head)){
- k_hashtable_delete(ent_head);
- k_free(path);
- ensure_self_sub(evq);
- return;
- }
- ni_event_delete(evq);
- *e=0;
- ni_event* evt=ni_event_new(0, 0, ent_head, 0);
- int constant=k_hashtable_is(ent_head, "CUX:", "C");
- size_t m=constant? USE_MMAP: USE_MALL;
- k_file_read(".", path, m, 0, cache_read, evt);
- return;
- }
- ni_event* evt=context;
- k_free(path);
- evt->entity=data;
- ni_event_show(evt, "File Cache Found:");
- k_event_post("ni", evt);
-}
-
-/* -}{----------------------------------------------------------------------- */
-
-