Browse code

webkernel: init, free, start of service and structures of clients

Dario Rodriguez authored on 13/06/2014 11:16:28
Showing 3 changed files
... ...
@@ -17,6 +17,7 @@
17 17
 
18 18
 #ifndef SOCKLIB_H
19 19
 #define SOCKLIB_H
20
+#include <sys/select.h> /* fd_set */
20 21
 
21 22
 typedef void sselect;
22 23
 
... ...
@@ -12,19 +12,58 @@
12 12
 #include <stdlib.h>
13 13
 #include <unistd.h>
14 14
 #include <string.h>
15
+#include "socklib.h"
15 16
 #include "webkernel.h"
16 17
 
18
+#define FDBLOCK 256
19
+#define CLIENTBLOCK 1024
20
+#define CLIENTBLOCKBLOCK 256
21
+
22
+
23
+typedef struct wk_client {
24
+        wk *web;
25
+        int connid; /* it is numblock*CLIENTBLOCK+offset_in_block */
26
+        int fd;
27
+} wk_client;
28
+
29
+typedef struct wk_clientblock {
30
+        int sizeclients;
31
+        int usedclients;
32
+        wk_client *clients;
33
+} wk_clientblock;
34
+
17 35
 typedef struct _wk {
18
-        int dummy;
36
+        int serverfd;
37
+        fd_set fdset;
38
+        sselect *ssel;
39
+        int sizeclientblocks;
40
+        int usedclientblocks;
41
+        wk_clientblock *clientblocks;
19 42
 } _wk;
20 43
 
44
+static int wk_accept(_wk *web);
45
+static wk_client *wk_clientacquire(_wk *web);
46
+static int wk_clientrelease(_wk *web, int connid);
47
+wk_client *wk_clientget(_wk *web, int connid);
48
+
21 49
 wk *
22 50
 wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *paramweb,int connid, wk_event event, void *userptr*/), void (*callback_http)(/*wk *paramweb,int connid, wk_uri *uri, void *userptr*/), void (*callback_continuation)(/*wk *paramweb,int connid, wk_uri *uri, void *userptr*/), void *userptr)
23 51
 {
24 52
         _wk *web;
53
+        if(ssel==NULL || callback_http==NULL)
54
+                return(NULL);
25 55
         if((web=malloc(sizeof(_wk)))==NULL)
26 56
                 return(NULL);
27 57
         memset(web,0,sizeof(_wk));
58
+        web->serverfd=-1;
59
+        web->ssel=ssel;
60
+        FD_ZERO(&(web->fdset));
61
+        if((web->serverfd=ipv4_server(port))==-1) {
62
+                wk_free((wk *)web),web=NULL;
63
+                return(NULL);
64
+        }
65
+        FD_SET(web->serverfd,&(web->fdset));
66
+        sselect_addread(ssel,web->serverfd,NULL);
28 67
         return((wk *)web);
29 68
 }
30 69
 
... ...
@@ -34,6 +73,11 @@ wk_free(wk *paramweb)
34 73
         _wk *web=(_wk *)paramweb;
35 74
         if(web==NULL)
36 75
                 return;
76
+        if(web->serverfd!=-1) {
77
+                sselect_delread(web->ssel,web->serverfd);
78
+                FD_CLR(web->serverfd,&(web->fdset));
79
+                close(web->serverfd),web->serverfd=-1;
80
+        }
37 81
         free(web),web=NULL;
38 82
 }
39 83
 
... ...
@@ -46,7 +90,23 @@ wk_geturi(wk *paramweb, int connid)
46 90
 int
47 91
 wk_service(wk *paramweb)
48 92
 {
49
-
93
+        int fds[FDBLOCK];
94
+        int fd;
95
+        int n;
96
+        int i;
97
+        _wk *web=(_wk *)paramweb;
98
+        if(web==NULL)
99
+                return(-1);
100
+        while((n=sselect_getreadfiltered(web,&(web->fdset),fds,sizeof(fds)/sizeof(fds[0])))>0) {
101
+                for(i=0;i<n;i++) {
102
+                        fd=fds[i];
103
+                        if(fd==web->serverfd) {
104
+                                /* accept new connection */
105
+                                wk_accept(web);
106
+                                continue;
107
+                        }
108
+                }
109
+        }
50 110
 }
51 111
 
52 112
 int
... ...
@@ -98,12 +158,14 @@ wk_uri_getheaderbynum(wk_uri *wkuri, int num)
98 158
 }
99 159
 
100 160
 const char *
101
-mime_getdefault(char *filename)
161
+mime_getdefault(const char *filename, const char *defaultmime)
102 162
 {
163
+        const char *dotptr,*dotdotptr;
164
+        int i;
103 165
         struct {
104
-                char *ext;
105
-                char *mime;
106
-        } dotdot[]={{".tar.gz","application/x-tgz"}},
166
+                const char *ext;
167
+                const char *mime;
168
+        } dotdot[]={{"tar.gz","application/x-tgz"}},
107 169
           dot[]={
108 170
                 {"html","text/html"},
109 171
                 {"htm","text/html"},
... ...
@@ -130,7 +192,23 @@ mime_getdefault(char *filename)
130 192
                 {"mp4","video/mp4"},
131 193
                 {"webm","video/webm"},
132 194
                 {"avi","video/x-msvideo"}};
133
-#warning TODO
195
+        if(filename==NULL || (dotptr=strrchr(filename,'.'))==NULL)
196
+                return(defaultmime);
197
+        if(dotptr>filename) {
198
+                for(dotdotptr=(dotptr-1);dotdotptr>filename && *dotdotptr!='.';dotdotptr--)
199
+                        ;
200
+                if(*dotdotptr=='.') {
201
+                        for(i=0;i<(sizeof(dotdot)/sizeof(dotdot[0]));i++) {
202
+                                if(strcmp(dotdotptr+1,dotdot[i].ext)==0)
203
+                                        return(dotdot[i].mime);
204
+                        }
205
+                }
206
+        }
207
+        for(i=0;i<(sizeof(dot)/sizeof(dot[0]));i++) {
208
+                if(strcmp(dotptr+1,dot[i].ext)==0)
209
+                        return(dot[i].mime);
210
+        }
211
+        return(defaultmime);
134 212
 }
135 213
 
136 214
 siobuf *
... ...
@@ -145,3 +223,45 @@ wk_iobuffree(wk *paramweb, int iobufnum)
145 223
 
146 224
 }
147 225
 
226
+/* local functions */
227
+static int
228
+wk_accept(_wk *web)
229
+{
230
+        int newfd;
231
+        wk_client *client;
232
+        if((newfd=sock_accept(web->serverfd))==-1)
233
+                return(-1);
234
+        if((client=wk_clientacquire(web))==NULL) {
235
+                close(newfd),newfd=-1;
236
+                return(-1);
237
+        }
238
+        client->fd=newfd;
239
+        FD_SET(client->fd,&(web->fdset));
240
+        sselect_addread(web->ssel,client->fd,(void *)client);
241
+        return(0);
242
+}
243
+
244
+static wk_client *
245
+wk_clientacquire(_wk *web)
246
+{
247
+#warning TODO
248
+}
249
+
250
+static int
251
+wk_clientrelease(_wk *web, int connid)
252
+{
253
+}
254
+
255
+wk_client *
256
+wk_clientget(_wk *web, int connid)
257
+{
258
+        int numblock;
259
+        numblock=connid/CLIENTBLOCK;
260
+        if(web==NULL ||
261
+          web->clientblocks==NULL ||
262
+          web->sizeclientblocks<=numblock ||
263
+          web->clientblocks[numblock].clients==NULL)
264
+                return(NULL);
265
+        return(web->clientblocks[numblock].clients+(connid%CLIENTBLOCK));
266
+}
267
+
... ...
@@ -55,7 +55,7 @@ int wk_close(wk *web, int connid);
55 55
 char *wk_uri_getheader(wk_uri *wkuri, char *header, char *defaultvalue);
56 56
 char *wk_uri_getheaderbynum(wk_uri *wkuri, int num);
57 57
 
58
-const char *mime_getdefault(char *filename);
58
+const char *mime_getdefault(const char *filename, const char *defaultmime);
59 59
 
60 60
 siobuf *wk_iobufget(wk *web);
61 61
 void wk_iobuffree(wk *web, int iobufnum);