... | ... |
@@ -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); |