Browse code

webkernel: get vars from GET request, partial implementation of vars for POST request.

Dario Rodriguez authored on 23/06/2014 20:31:46
Showing 4 changed files
... ...
@@ -1,3 +1,4 @@
1 1
 src/*.o
2 2
 src/webkernel_test
3 3
 src/*~
4
+src/*.workingnote
... ...
@@ -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
         }