...
|
...
|
@@ -15,6 +15,7 @@
|
15
|
15
|
#include <sys/types.h>
|
16
|
16
|
#include <sys/stat.h>
|
17
|
17
|
#include <unistd.h>
|
|
18
|
+#include <mhash.h>
|
18
|
19
|
#include "gen_res.h"
|
19
|
20
|
#include "socklib.h"
|
20
|
21
|
#include "loglib.h"
|
...
|
...
|
@@ -32,12 +33,15 @@
|
32
|
33
|
#define CFBANNERPATH "default.png"
|
33
|
34
|
#define CFSSLPROXY 0
|
34
|
35
|
|
|
36
|
+#define DEBUG_HEADERS
|
|
37
|
+
|
35
|
38
|
static int signal_init(int signum, void (*fn)(int));
|
36
|
39
|
static void sigint(int signum);
|
37
|
40
|
volatile int sigint_flag=0;
|
38
|
41
|
|
39
|
42
|
int kakumei_inviteexists(kakumei *ka, char *invite);
|
40
|
43
|
int kakumei_invitedel(kakumei *ka, char *invite);
|
|
44
|
+int kakumei_etag(kakumei *ka, char *filename, char *etag, int etagsize);
|
41
|
45
|
|
42
|
46
|
wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr);
|
43
|
47
|
wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr);
|
...
|
...
|
@@ -177,6 +181,38 @@ kakumei_invitedel(kakumei *ka, char *invite)
|
177
|
181
|
return(0);
|
178
|
182
|
}
|
179
|
183
|
|
|
184
|
+int
|
|
185
|
+kakumei_etag(kakumei *ka, char *filename, char *etag, int etagsize)
|
|
186
|
+{
|
|
187
|
+ struct stat st;
|
|
188
|
+ MHASH td;
|
|
189
|
+ char binhash[20];
|
|
190
|
+ char hash[40];
|
|
191
|
+ int i;
|
|
192
|
+ char c;
|
|
193
|
+ if(filename==NULL || etag==NULL || etagsize<1)
|
|
194
|
+ return(-1);
|
|
195
|
+ if(stat(filename,&st)!=0 || !S_ISREG(st.st_mode))
|
|
196
|
+ return(-1);
|
|
197
|
+ if((td=mhash_init(MHASH_SHA1))==MHASH_FAILED)
|
|
198
|
+ return(-1);
|
|
199
|
+ mhash(td,&(st.st_mtime),sizeof(st.st_mtime));
|
|
200
|
+ mhash(td,&(st.st_size),sizeof(st.st_size));
|
|
201
|
+ mhash_deinit(td,&binhash);
|
|
202
|
+ for(i=0;i<sizeof(binhash);i++) {
|
|
203
|
+ c=(((unsigned char *)binhash)[i]>>4);
|
|
204
|
+ c=(c>=10)?(c-10+'a'):c+'0';
|
|
205
|
+ hash[i<<1]=c;
|
|
206
|
+ c=(((unsigned char *)binhash)[i]&0xf);
|
|
207
|
+ c=(c>=10)?(c-10+'a'):c+'0';
|
|
208
|
+ hash[(i<<1)+1]=c;
|
|
209
|
+ }
|
|
210
|
+ memcpy(etag,hash,(etagsize>sizeof(hash))?sizeof(hash):(etagsize-1));
|
|
211
|
+ etag[(etagsize>sizeof(hash))?sizeof(hash):(etagsize-1)]='\0';
|
|
212
|
+ return(0);
|
|
213
|
+}
|
|
214
|
+
|
|
215
|
+
|
180
|
216
|
|
181
|
217
|
wk_action
|
182
|
218
|
callback_http(wk *web, int connid, wk_uri *uri, void *userptr)
|
...
|
...
|
@@ -185,6 +221,7 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr)
|
185
|
221
|
resindex *res;
|
186
|
222
|
char partialpath[1024];
|
187
|
223
|
char *ptr;
|
|
224
|
+ char etag[ETAGSIZE+1];
|
188
|
225
|
struct {
|
189
|
226
|
char *name;
|
190
|
227
|
} whitelist[]={{"/index.html"},
|
...
|
...
|
@@ -207,6 +244,14 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr)
|
207
|
244
|
log_write("HTTP","Request: /newuser?...");
|
208
|
245
|
else
|
209
|
246
|
log_write("HTTP","Request: %s",uri->path);
|
|
247
|
+#ifdef DEBUG_HEADERS
|
|
248
|
+ {
|
|
249
|
+ int j;
|
|
250
|
+ char *h;
|
|
251
|
+ for(j=0;(h=wk_uri_getheaderbynum(uri,j))!=NULL;j++)
|
|
252
|
+ log_write("HDR","%s",h);
|
|
253
|
+ }
|
|
254
|
+#endif
|
210
|
255
|
/* extract the name */
|
211
|
256
|
strncpy(partialpath,uri->path,sizeof(partialpath)-1);
|
212
|
257
|
partialpath[sizeof(partialpath)-1]='\0';
|
...
|
...
|
@@ -238,6 +283,7 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr)
|
238
|
283
|
if(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL) {
|
239
|
284
|
if(whitelisted || validsession) {
|
240
|
285
|
log_write("HTTP","Serving in-memory file %s",partialpath+1);
|
|
286
|
+ wk_serve_etagset(web,connid,res->etag);
|
241
|
287
|
wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream"));
|
242
|
288
|
return(wkact_finished);
|
243
|
289
|
} else if((res=res_find(resindexdata,"index.html"))!=NULL) {
|
...
|
...
|
@@ -251,6 +297,8 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr)
|
251
|
297
|
}
|
252
|
298
|
} else if(strcmp(uri->path,"/banner.png")==0) {
|
253
|
299
|
log_write("HTTP","Serving banner from disk, file %s",partialpath);
|
|
300
|
+ if(kakumei_etag(ka,partialpath,etag,sizeof(etag))==0)
|
|
301
|
+ wk_serve_etagset(web,connid,etag);
|
254
|
302
|
if(wk_serve_file(web,connid,partialpath,mime_getdefault(partialpath,"image/png"))!=0) {
|
255
|
303
|
log_write("HTTP","File not found, file %s",partialpath);
|
256
|
304
|
wk_serve_error(web,connid,wkerr_notfound);
|