2 /* -}{----------------------------------------------------------------------- */
7 /* -}{----------------------------------------------------------------------- */
9 extern void ensure_self_sub(ni_event* evq);
11 /* -}{----------------------------------------------------------------------- */
13 #define TMPBUFSIZE 4096
14 static char tmpbuf[TMPBUFSIZE];
16 /* -}{----------------------------------------------------------------------- */
18 static void cache_read(char*, char*, char*, int, k_stat, void*);
19 static void entity_written(char*, char*, char*, int, k_stat, void*);
20 static void write_headers(char* path, ni_resource* res);
21 static void headers_written(char*, char*, char*, int, k_stat, void*);
24 /* -}{----------------------------------------------------------------------- */
26 char* make_cache_path(char* uri)
30 if(l>100){ k_log_out("URI too long to save: %s", uri); return 0; }
35 path=k_malloc(l+1+10);
36 sprintf(path, "%sindex.html", uri);
41 void look_in_file_cache(ni_event* evq)
43 k_hashtable* sub=evq->ent_head;
44 char* uri=k_hashtable_get(sub, "Sub-To:");
47 if(l>100){ ensure_self_sub(evq); return; }
50 if(*(uri+l-1)!='/') sprintf(hdr, "%s.hdr", uri);
51 else sprintf(hdr, "%sindex.html.hdr", uri);
53 if(strstr(hdr, "..")){ ensure_self_sub(evq); return; }
54 if(strchr(hdr, '?' )){ ensure_self_sub(evq); return; }
56 char* c=strchr(hdr, ':');
57 char* e=strchr(hdr, '/');
60 k_file_read(".", k_strdup(hdr), USE_MALL, 0, cache_read, evq);
63 void save_in_file_cache(ni_resource* res)
66 char* path =make_cache_path(uri); if(!path) return;
67 k_hashtable* ent_head=res->ent_head;
68 void* data =res->entity;
69 int partial =k_hashtable_is( ent_head, "Status:", "206");
70 size_t size =k_hashtable_get_int(ent_head, "Content-Length:");
71 char* conrange=k_hashtable_get( ent_head, "Content-Range:");
72 int constant=k_hashtable_is( ent_head, "CUX:", "C");
75 write_headers(path, res);
79 int ok=k_file_sync(data, size);
81 k_log_err("Failed to write (sync mmap): %s", uri);
85 write_headers(path, res);
89 k_log_out("save_in_file_cache partial %s", conrange);
90 if(!conrange || strncmp(conrange, "0-", 2)){
91 k_log_err("not saving partial");
95 size=atoi(conrange+2);
97 k_log_out("save_in_file_cache updateable: %d bytes", size);
98 k_file_write(".", path, data, size, entity_written, res);
102 /* -}{----------------------------------------------------------------------- */
104 void entity_written(char* basedir,
111 if(data) k_log_out("File cache entity written: %s", path);
113 k_log_err("Failed to write entity: %s", path);
117 ni_resource* res=context;
118 write_headers(path, res);
121 void write_headers(char* path, ni_resource* res)
123 snprintf(tmpbuf, TMPBUFSIZE, "%s.hdr", path);
124 k_free(path); path=k_strdup(tmpbuf);
125 k_hashtable_snprintf(res->ent_head, tmpbuf, TMPBUFSIZE);
126 k_file_write(".", path, tmpbuf, strlen(tmpbuf), headers_written, 0);
129 void headers_written(char* basedir,
136 if(data) k_log_out("File cache headers written: %s", path);
137 else k_log_err("Failed to write headers: %s", path);
141 void cache_read(char* basedir,
148 if(!data) k_log_out("no cache of %s", path);
149 else k_log_out("file cache read: %d %s", kstat.size, path);
150 char* e=strstr(path, ".hdr");
152 ni_event* evq=context;
153 if(!data){ k_free(path); ensure_self_sub(evq); return; }
156 *(header+kstat.size-2)=0;
157 k_hashtable* ent_head=k_hashtable_new("nHeaders/cache_read", 1);
158 k_hashtable_put(ent_head, "", header);
159 if(!ni_get_headers(header, 0, ent_head)){
160 k_hashtable_delete(ent_head);
162 ensure_self_sub(evq);
165 ni_event_delete(evq);
167 ni_event* evt=ni_event_new(0, 0, ent_head, 0);
168 int constant=k_hashtable_is(ent_head, "CUX:", "C");
169 size_t m=constant? USE_MMAP: USE_MALL;
170 k_file_read(".", path, m, 0, cache_read, evt);
173 ni_event* evt=context;
176 ni_event_show(evt, "File Cache Found:");
177 k_event_post("ni", evt);
180 /* -}{----------------------------------------------------------------------- */