... | ... |
@@ -26,7 +26,20 @@ |
26 | 26 |
#define BUFSIZE 8192 |
27 | 27 |
#define BUFBLOCK 128 |
28 | 28 |
#define BUFBLOCKBLOCK 256 |
29 |
+#define POSTBLOCK 16 |
|
29 | 30 |
|
31 |
+typedef struct wk_post { |
|
32 |
+ char *name; |
|
33 |
+ char *value; |
|
34 |
+ int isfile; |
|
35 |
+ int filewritten; |
|
36 |
+} wk_post; |
|
37 |
+ |
|
38 |
+typedef enum wkc_status { |
|
39 |
+ wkc_header=0, |
|
40 |
+ wkc_post, |
|
41 |
+ wkc_none, |
|
42 |
+} wkc_status; |
|
30 | 43 |
|
31 | 44 |
typedef struct wk_client { |
32 | 45 |
wk *web; |
... | ... |
@@ -36,12 +49,16 @@ typedef struct wk_client { |
36 | 49 |
int sizeoutbufids; |
37 | 50 |
int usedoutbufids; |
38 | 51 |
int outbufids[MAXOUTBUF]; |
52 |
+ wkc_status status; |
|
39 | 53 |
int serviced; |
40 | 54 |
int continuationactive; |
41 | 55 |
int fdtoserve; |
42 | 56 |
wk_uri uri; |
43 | 57 |
int headerbufid; |
44 | 58 |
int keepalive; |
59 |
+ int sizepost; |
|
60 |
+ int usedpost; |
|
61 |
+ wk_post *post; |
|
45 | 62 |
} wk_client; |
46 | 63 |
|
47 | 64 |
typedef struct wk_clientblock { |
... | ... |
@@ -75,6 +92,7 @@ typedef struct _wk { |
75 | 92 |
wk_bufblock *bufblocks; |
76 | 93 |
void (*callback_event)(/*wk *web,int connid, wk_event event, void *userptr*/); |
77 | 94 |
wk_action (*callback_http)(/*wk *web,int connid, wk_uri *uri, void *userptr*/); |
95 |
+ wk_action (*callback_post)(/*wk *web,int connid, wk_uri *uri, void *userptr*/); |
|
78 | 96 |
wk_action (*callback_continuation)(/*wk *web,int connid, wk_uri *uri, void *userptr*/); |
79 | 97 |
void *userptr; |
80 | 98 |
} _wk; |
... | ... |
@@ -83,10 +101,14 @@ static wk_client *wk_accept(_wk *web); |
83 | 101 |
static wk_client *wk_clientacquire(_wk *web); |
84 | 102 |
static int wk_clientrelease(_wk *web, int connid); |
85 | 103 |
static wk_client *wk_clientget(_wk *web, int connid); |
86 |
-static int wk_clientserviceread(_wk *web, wk_client *client); |
|
104 |
+static int wk_clientservicereadheader(_wk *web, wk_client *client); |
|
105 |
+static int wk_postadd(_wk *web, wk_client *client,char *varname, char *tofile); |
|
106 |
+static int wk_postset(_wk *web, wk_client *client,char *varname, char *value); |
|
107 |
+static char *wk_postget(_wk *web, wk_client *client,char *varname, int *isfile); |
|
108 |
+static int wk_postfree(_wk *web, wk_client *client); |
|
87 | 109 |
|
88 | 110 |
wk * |
89 |
-wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *web,int connid, wk_event event, void *userptr*/), wk_action (*callback_http)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), wk_action (*callback_continuation)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), void *userptr) |
|
111 |
+wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *web,int connid, wk_event event, void *userptr*/), wk_action (*callback_http)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), wk_action (*callback_post)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), wk_action (*callback_continuation)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), void *userptr) |
|
90 | 112 |
{ |
91 | 113 |
_wk *web; |
92 | 114 |
if(ssel==NULL || callback_http==NULL) |
... | ... |
@@ -97,6 +119,7 @@ wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *web,int connid, wk |
97 | 119 |
web->serverfd=-1; |
98 | 120 |
web->callback_event=callback_event; |
99 | 121 |
web->callback_http=callback_http; |
122 |
+ web->callback_post=callback_post; |
|
100 | 123 |
web->callback_continuation=callback_continuation; |
101 | 124 |
web->userptr=userptr; |
102 | 125 |
web->ssel=ssel; |
... | ... |
@@ -151,6 +174,7 @@ wk_free(wk *paramweb) |
151 | 174 |
} |
152 | 175 |
if(client->fdtoserve!=-1) |
153 | 176 |
close(client->fdtoserve),client->fdtoserve=-1; |
177 |
+ wk_postfree(web,client); |
|
154 | 178 |
} |
155 | 179 |
} |
156 | 180 |
cb->usedclients=0; |
... | ... |
@@ -231,10 +255,14 @@ wk_service(wk *paramweb) |
231 | 255 |
wk_close((wk *) web, client->connid); |
232 | 256 |
continue; |
233 | 257 |
} |
234 |
- if(wk_clientserviceread(web,client)==-1) { |
|
235 |
- /* internal error, protocol error or no enough memory */ |
|
236 |
- wk_close((wk *) web, client->connid); |
|
237 |
- continue; |
|
258 |
+ if(client->status==wkc_header) { |
|
259 |
+ if(wk_clientservicereadheader(web,client)==-1) { |
|
260 |
+ /* internal error, protocol error or no enough memory */ |
|
261 |
+ wk_close((wk *) web, client->connid); |
|
262 |
+ continue; |
|
263 |
+ } |
|
264 |
+ } else if(client->status==wkc_post) { |
|
265 |
+#warning TODO |
|
238 | 266 |
} |
239 | 267 |
} |
240 | 268 |
} |
... | ... |
@@ -482,6 +510,57 @@ wk_uri_getheaderbynum(wk_uri *uri, int num) |
482 | 510 |
return(NULL); |
483 | 511 |
} |
484 | 512 |
|
513 |
+char * |
|
514 |
+wk_uri_getvar(wk_uri *uri, char *varname, int *len) |
|
515 |
+{ |
|
516 |
+ char *ptr,*end; |
|
517 |
+ int varlen; |
|
518 |
+ if(uri==NULL || uri->path==NULL || (ptr=strchr(uri->path,'?'))==NULL) |
|
519 |
+ return(NULL); |
|
520 |
+ varlen=strlen(varname); |
|
521 |
+ ptr++; |
|
522 |
+ while(*ptr!='\0' && ptr!=NULL) { |
|
523 |
+ if(memcmp(ptr,varname,varlen)==0 && ptr[varlen]=='=') { |
|
524 |
+ ptr+=varlen+1; |
|
525 |
+ if((end=strchr(ptr,'&'))==NULL) |
|
526 |
+ end=ptr+strlen(ptr); |
|
527 |
+ if(len!=NULL) |
|
528 |
+ *len=end-ptr; |
|
529 |
+ return(ptr); |
|
530 |
+ } |
|
531 |
+ if((end=strchr(ptr,'&'))==NULL) |
|
532 |
+ break; |
|
533 |
+ ptr=end+1; |
|
534 |
+ } |
|
535 |
+ return(NULL); |
|
536 |
+} |
|
537 |
+ |
|
538 |
+ |
|
539 |
+int |
|
540 |
+wk_post_addvalid(wk *paramweb, int connid, char *varname, char *tofile) |
|
541 |
+{ |
|
542 |
+ _wk *web=(_wk *)paramweb; |
|
543 |
+ wk_client *client; |
|
544 |
+ if(web==NULL || varname==NULL) |
|
545 |
+ return(-1); |
|
546 |
+ if((client=wk_clientget(web,connid))==NULL) |
|
547 |
+ return(-1); |
|
548 |
+ return(wk_postadd(web,client,varname,tofile)); |
|
549 |
+} |
|
550 |
+ |
|
551 |
+char * |
|
552 |
+wk_post_get(wk *paramweb, int connid, char *varname, int *isfile) |
|
553 |
+{ |
|
554 |
+ _wk *web=(_wk *)paramweb; |
|
555 |
+ wk_client *client; |
|
556 |
+ if(web==NULL || varname==NULL) |
|
557 |
+ return(NULL); |
|
558 |
+ if((client=wk_clientget(web,connid))==NULL) |
|
559 |
+ return(NULL); |
|
560 |
+ return(wk_postget(web,client,varname,isfile)); |
|
561 |
+} |
|
562 |
+ |
|
563 |
+ |
|
485 | 564 |
const char * |
486 | 565 |
mime_getdefault(const char *filename, const char *defaultmime) |
487 | 566 |
{ |
... | ... |
@@ -739,6 +818,7 @@ wk_clientrelease(_wk *web, int connid) |
739 | 818 |
wk_sbufrelease((wk *)web,client->outbufids[w]),client->outbufids[w]=-1; |
740 | 819 |
if(client->headerbufid!=-1) |
741 | 820 |
wk_sbufrelease((wk *)web,client->headerbufid),client->headerbufid=-1; |
821 |
+ wk_postfree(web,client); |
|
742 | 822 |
memset(client,0,sizeof(wk_client)); |
743 | 823 |
return(0); |
744 | 824 |
} |
... | ... |
@@ -771,7 +851,7 @@ str_findfirstempty(char *ptr, int size) |
771 | 851 |
} |
772 | 852 |
|
773 | 853 |
static int |
774 |
-wk_clientserviceread(_wk *web, wk_client *client) |
|
854 |
+wk_clientservicereadheader(_wk *web, wk_client *client) |
|
775 | 855 |
{ |
776 | 856 |
sbuf *in,*hbuf; |
777 | 857 |
char *end; |
... | ... |
@@ -850,7 +930,109 @@ wk_clientserviceread(_wk *web, wk_client *client) |
850 | 930 |
/* call the http method */ |
851 | 931 |
client->serviced=1; |
852 | 932 |
client->continuationactive=0; |
933 |
+#warning TODO: wkc_post |
|
853 | 934 |
client->continuationactive=web->callback_http((wk *)web, client->connid, uri, web->userptr); |
854 | 935 |
return(0); |
855 | 936 |
} |
856 | 937 |
|
938 |
+static int |
|
939 |
+wk_postadd(_wk *web, wk_client *client,char *varname, char *tofile) |
|
940 |
+{ |
|
941 |
+ wk_post *post; |
|
942 |
+ if(client->post==NULL || client->sizepost==client->usedpost) { |
|
943 |
+ wk_post *newpost; |
|
944 |
+ if((newpost=(wk_post *)realloc(client->post,(client->sizepost+POSTBLOCK)*sizeof(wk_post)))==NULL) |
|
945 |
+ return(-1); /* insufficient memory */ |
|
946 |
+ client->post=newpost; |
|
947 |
+ memset(client->post+client->sizepost,0,POSTBLOCK*sizeof(wk_post)); |
|
948 |
+ client->sizepost+=POSTBLOCK; |
|
949 |
+ } |
|
950 |
+ post=client->post+client->usedpost; |
|
951 |
+ if((post->name=strdup(varname))==NULL) |
|
952 |
+ return(-1); /* insufficient memory */ |
|
953 |
+ if(tofile!=NULL) { |
|
954 |
+ if((post->value=strdup(tofile))==NULL) { |
|
955 |
+ free(post->name),post->name=NULL; |
|
956 |
+ return(-1); /* insufficient memory */ |
|
957 |
+ } |
|
958 |
+ } else |
|
959 |
+ post->isfile=0; |
|
960 |
+ return(0); |
|
961 |
+} |
|
962 |
+ |
|
963 |
+static int |
|
964 |
+wk_postset(_wk *web, wk_client *client,char *varname, char *value) |
|
965 |
+{ |
|
966 |
+ int i; |
|
967 |
+ wk_post *post; |
|
968 |
+ int fd; |
|
969 |
+ int len; |
|
970 |
+ if(varname==NULL || value==NULL) |
|
971 |
+ return(-1); |
|
972 |
+ for(i=0;i<client->usedpost;i++) { |
|
973 |
+ if(strcmp(client->post[i].name,varname)==0) |
|
974 |
+ break; |
|
975 |
+ } |
|
976 |
+ if(i>=client->usedpost) |
|
977 |
+ return(-1); /* var not found */ |
|
978 |
+ post=client->post+i; |
|
979 |
+ if(post->isfile) { |
|
980 |
+ if((fd=open(post->value,O_CREAT|O_APPEND,0600))==-1) |
|
981 |
+ return(-1); /* couldn't open file */ |
|
982 |
+ len=strlen(value); |
|
983 |
+ if(write(fd,value,len)!=len) { |
|
984 |
+ close(fd),fd=-1; |
|
985 |
+ return(-1); /* couldn't open file */ |
|
986 |
+ } |
|
987 |
+ close(fd),fd=-1; |
|
988 |
+ post->filewritten=1; |
|
989 |
+ } else { |
|
990 |
+ if(post->value!=NULL) |
|
991 |
+ free(post->value),post->value=NULL; |
|
992 |
+ if((post->value=strdup(value))==NULL) |
|
993 |
+ return(-1); |
|
994 |
+ } |
|
995 |
+ return(0); |
|
996 |
+} |
|
997 |
+ |
|
998 |
+static char * |
|
999 |
+wk_postget(_wk *web, wk_client *client,char *varname, int *isfile) |
|
1000 |
+{ |
|
1001 |
+ int i; |
|
1002 |
+ wk_post *post; |
|
1003 |
+ if(varname==NULL) |
|
1004 |
+ return(NULL); |
|
1005 |
+ for(i=0;i<client->usedpost;i++) { |
|
1006 |
+ if(strcmp(client->post[i].name,varname)==0) |
|
1007 |
+ break; |
|
1008 |
+ } |
|
1009 |
+ if(i>=client->usedpost) |
|
1010 |
+ return(NULL); /* var not found */ |
|
1011 |
+ post=client->post+i; |
|
1012 |
+ if(isfile!=NULL) |
|
1013 |
+ *isfile=post->isfile; |
|
1014 |
+ if(post->isfile && !post->filewritten) |
|
1015 |
+ return(NULL); |
|
1016 |
+ return(post->value); |
|
1017 |
+} |
|
1018 |
+ |
|
1019 |
+static int |
|
1020 |
+wk_postfree(_wk *web, wk_client *client) |
|
1021 |
+{ |
|
1022 |
+ int i; |
|
1023 |
+ for(i=0;i<client->usedpost;i++) { |
|
1024 |
+ if(client->post[i].name!=NULL) |
|
1025 |
+ free(client->post[i].name),client->post[i].name=NULL; |
|
1026 |
+ if(client->post[i].value!=NULL) |
|
1027 |
+ free(client->post[i].value),client->post[i].value=NULL; |
|
1028 |
+ client->post[i].isfile=0; |
|
1029 |
+ } |
|
1030 |
+ if(client->post!=NULL) { |
|
1031 |
+ client->usedpost=0; |
|
1032 |
+ client->sizepost=0; |
|
1033 |
+ free(client->post),client->post=NULL; |
|
1034 |
+ } |
|
1035 |
+ return(0); |
|
1036 |
+} |
|
1037 |
+ |
|
1038 |
+ |
... | ... |
@@ -40,10 +40,11 @@ typedef enum wk_error { |
40 | 40 |
|
41 | 41 |
typedef enum wk_action { |
42 | 42 |
wkact_finished=0, |
43 |
+ wkact_post, |
|
43 | 44 |
wkact_continuation, |
44 | 45 |
} wk_action; |
45 | 46 |
|
46 |
-wk *wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *web,int connid, wk_event event, void *userptr*/), wk_action (*callback_http)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), wk_action (*callback_continuation)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), void *userptr); |
|
47 |
+wk *wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *web,int connid, wk_event event, void *userptr*/), wk_action (*callback_http)(/*wk *web,int connid, wk_uri *uri, void *userptr*/),wk_action (*callback_post)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), wk_action (*callback_continuation)(/*wk *web,int connid, wk_uri *uri, void *userptr*/), void *userptr); |
|
47 | 48 |
void wk_free(wk *web); |
48 | 49 |
|
49 | 50 |
wk_uri *wk_geturi(wk *web, int connid); /* for use in callback_event() when wke_closed */ |
... | ... |
@@ -60,6 +61,11 @@ int wk_close(wk *web, int connid); |
60 | 61 |
char *wk_uri_getheader(wk_uri *wkuri, char *header, char *defaultvalue); |
61 | 62 |
char *wk_uri_getheaderbynum(wk_uri *wkuri, int num); |
62 | 63 |
|
64 |
+char *wk_uri_getvar(wk_uri *wkuri, char *varname, int *len); |
|
65 |
+ |
|
66 |
+int wk_post_addvalid(wk *web, int connid, char *varname, char *tofile); |
|
67 |
+char *wk_post_get(wk *web, int connid, char *varname, int *isfile); |
|
68 |
+ |
|
63 | 69 |
const char *mime_getdefault(const char *filename, const char *defaultmime); |
64 | 70 |
|
65 | 71 |
|
... | ... |
@@ -388,7 +388,8 @@ webkernel_basic(test_action action) |
388 | 388 |
long hostsize; |
389 | 389 |
int timeout; |
390 | 390 |
int fds[2]; |
391 |
- char buf; |
|
391 |
+ char buf[128]; |
|
392 |
+ int usedbuf; |
|
392 | 393 |
char test_request[]={"\ |
393 | 394 |
GET /test.cgi HTTP/1.0\r\n\ |
394 | 395 |
Host: localhost\r\n\ |
... | ... |
@@ -407,7 +408,7 @@ Connection: keep-alive\r\n\ |
407 | 408 |
check=0; |
408 | 409 |
if((ssel=sselect_init())==NULL) |
409 | 410 |
return(STRING_FAIL ": couln't alloc a sselect structure"); |
410 |
- for(port=19747,off=0,check=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,&check))==NULL;off++,port++) |
|
411 |
+ for(port=19747,off=0,check=0;(web=wk_init(port,ssel,NULL,webkernel_basichttp,NULL,NULL,&check))==NULL;off++,port++) |
|
411 | 412 |
; |
412 | 413 |
if(web==NULL) { |
413 | 414 |
webkernel_basicclose(&client,&ssel,&host,&web); |
... | ... |
@@ -466,7 +467,12 @@ Connection: keep-alive\r\n\ |
466 | 467 |
return(STRING_FAIL ": client read not detected\n"); |
467 | 468 |
} |
468 | 469 |
/* read data */ |
469 |
- if(read(client,buf,2)!=2 || memcmp(buf,"Ok",2)!=0) { |
|
470 |
+ if((usedbuf=read(client,buf,sizeof(buf)-1))<0) { |
|
471 |
+ webkernel_basicclose(&client,&ssel,&host,&web); |
|
472 |
+ return(STRING_FAIL ": couldn't read reply\n"); |
|
473 |
+ } |
|
474 |
+ buf[usedbuf]='\0'; |
|
475 |
+ if(usedbuf<2 || memcmp(buf+usedbuf-2,"Ok",2)!=0) { |
|
470 | 476 |
webkernel_basicclose(&client,&ssel,&host,&web); |
471 | 477 |
return(STRING_FAIL ": corrupted data in read on client\n"); |
472 | 478 |
} |