... | ... |
@@ -196,21 +196,21 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
196 | 196 |
return(wkact_finished); |
197 | 197 |
} |
198 | 198 |
#warning TODO: do something with the email |
199 |
- { |
|
200 |
- FILE *f; |
|
201 |
- if((f=fopen("emails.txt","a"))==NULL) { |
|
202 |
- wk_serve_error(web,connid,wkerr_internal); |
|
203 |
- return(wkact_finished); |
|
204 |
- } |
|
205 |
- fprintf(f,"%s %s\n",language,email); |
|
206 |
- fclose(f); |
|
207 |
- } |
|
208 |
- if((res=res_find(resindexdata,"success.html"))!=NULL) { |
|
209 |
- wk_serve_buffer_as_file(web,connid,(char *) res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
210 |
- } else { |
|
211 |
- char success[]={"The email has been saved.\n"}; |
|
212 |
- wk_serve_buffer_as_file(web,connid,success,strlen(success),"text/plain"); |
|
213 |
- } |
|
199 |
+ { |
|
200 |
+ FILE *f; |
|
201 |
+ if((f=fopen("emails.txt","a"))==NULL) { |
|
202 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
203 |
+ return(wkact_finished); |
|
204 |
+ } |
|
205 |
+ fprintf(f,"%s %s\n",language,email); |
|
206 |
+ fclose(f); |
|
207 |
+ } |
|
208 |
+ if((res=res_find(resindexdata,"success.html"))!=NULL) { |
|
209 |
+ wk_serve_buffer_as_file(web,connid,(char *) res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
210 |
+ } else { |
|
211 |
+ char success[]={"The email has been saved.\n"}; |
|
212 |
+ wk_serve_buffer_as_file(web,connid,success,strlen(success),"text/plain"); |
|
213 |
+ } |
|
214 | 214 |
return(wkact_finished); |
215 | 215 |
} |
216 | 216 |
wk_serve_error(web,connid,wkerr_notfound); |
... | ... |
@@ -144,6 +144,7 @@ callback_post(wk *web, int connid, wk_uri *uri, void *userptr) |
144 | 144 |
/* to be able to retrieve them in callback_http */ |
145 | 145 |
if(strcmp(partialpath,"/addemail")==0) { |
146 | 146 |
wk_post_addvalid(web,connid,"email",NULL); |
147 |
+ wk_post_addvalid(web,connid,"language",NULL); |
|
147 | 148 |
} |
148 | 149 |
return(wkact_finished); |
149 | 150 |
} |
... | ... |
@@ -189,13 +190,27 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
189 | 190 |
newsl_serve_buffer_with_rootdir(newsl,web,connid,(char *) res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
190 | 191 |
return(wkact_finished); |
191 | 192 |
} else if(strcmp(partialpath,"/addemail")==0) { |
192 |
- char *email; |
|
193 |
- if((email=wk_post_get(web,connid,"email",NULL))==NULL) { |
|
193 |
+ char *email,*language; |
|
194 |
+ if((email=wk_post_get(web,connid,"email",NULL))==NULL || (language=wk_post_get(web,connid,"language",NULL))==NULL) { |
|
194 | 195 |
wk_serve_error(web,connid,wkerr_internal); |
195 | 196 |
return(wkact_finished); |
196 | 197 |
} |
197 | 198 |
#warning TODO: do something with the email |
198 |
- wk_serve_buffer_as_file(web,connid,email,strlen(email),"text/plain"); |
|
199 |
+ { |
|
200 |
+ FILE *f; |
|
201 |
+ if((f=fopen("emails.txt","a"))==NULL) { |
|
202 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
203 |
+ return(wkact_finished); |
|
204 |
+ } |
|
205 |
+ fprintf(f,"%s %s\n",language,email); |
|
206 |
+ fclose(f); |
|
207 |
+ } |
|
208 |
+ if((res=res_find(resindexdata,"success.html"))!=NULL) { |
|
209 |
+ wk_serve_buffer_as_file(web,connid,(char *) res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
210 |
+ } else { |
|
211 |
+ char success[]={"The email has been saved.\n"}; |
|
212 |
+ wk_serve_buffer_as_file(web,connid,success,strlen(success),"text/plain"); |
|
213 |
+ } |
|
199 | 214 |
return(wkact_finished); |
200 | 215 |
} |
201 | 216 |
wk_serve_error(web,connid,wkerr_notfound); |
... | ... |
@@ -202,35 +202,54 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
202 | 202 |
return(wkact_finished); |
203 | 203 |
} |
204 | 204 |
|
205 |
+ |
|
206 |
+/* newsl_serve_buffer_with_rootdir() substitutes /~/ with /$rootdir/ */ |
|
207 |
+/* NOTE: it is limited to webkernel's MAXOUTBUF * BUFSIZE; normally MAXOUTBUF is 128 and BUFSIZE is 8192 (that is, 1MB) */ |
|
205 | 208 |
int |
206 | 209 |
newsl_serve_buffer_with_rootdir(newslettersan *newsl, wk *web, int connid, char *data, int datalen, const char *mime) |
207 | 210 |
{ |
208 | 211 |
int res; |
209 |
- sbuf *buf; |
|
210 |
- int sbufid; |
|
212 |
+ int newdatalen; |
|
213 |
+ int newstrlen; |
|
211 | 214 |
char *last,*next,*end; |
215 |
+ int etagnotmodified; |
|
212 | 216 |
if(newsl==NULL || web==NULL || data==NULL || datalen<0) |
213 | 217 |
return(-1); /* sanity check failed */ |
214 |
- if((sbufid=wk_sbufacquire(web))==-1 || (buf=wk_sbufget(web,sbufid))==NULL) |
|
215 |
- return(-1); |
|
216 |
- /* we copy the buffer substituting /~/ for /$rootdir/ */ |
|
218 |
+ /* we calculate the new datalen */ |
|
217 | 219 |
end=data+datalen; |
220 |
+ newstrlen=1+strlen(newsl->config->rootdir)+1; |
|
218 | 221 |
for(last=data,next=((last+3)<=end)?memchr(last,'/',end-last-3):NULL;next!=NULL;next=((last+3)<=end)?memchr(last,'/',end-last-3):NULL) { |
219 | 222 |
if(memcmp(next,"/~/",3)==0) { |
220 |
- sbuf_add(buf,last,next-last); |
|
221 |
- sbuf_add(buf,"/",1); |
|
222 |
- sbuf_addstr(buf,newsl->config->rootdir); |
|
223 |
- sbuf_add(buf,"/",1); |
|
223 |
+ newdatalen+=next-last+newstrlen; |
|
224 | 224 |
last=next+3; |
225 | 225 |
} else { |
226 |
- sbuf_add(buf,last,next-last+1); |
|
226 |
+ newdatalen+=next-last+1; |
|
227 | 227 |
last=next+1; |
228 | 228 |
} |
229 | 229 |
} |
230 |
- sbuf_add(buf,last,end-last); |
|
231 |
- /* send the constructed buffer */ |
|
232 |
- res=wk_serve_buffer_as_file(web,connid,sbuf_ptr(buf),sbuf_count(buf),mime); |
|
233 |
- wk_sbufrelease(web,sbufid),sbufid=-1,buf=NULL; |
|
234 |
- return(res); |
|
235 |
- |
|
230 |
+ newdatalen+=end-last; |
|
231 |
+ /* serve the headers */ |
|
232 |
+ res=wk_serve_generic_headers(web,connid,newdatalen,mime,&etagnotmodified); |
|
233 |
+ if(res!=0) |
|
234 |
+ return(res); /* error in headers */ |
|
235 |
+ /* serve the contents */ |
|
236 |
+ if(!etagnotmodified) { |
|
237 |
+ /* we copy the buffer substituting /~/ for /$rootdir/ */ |
|
238 |
+ end=data+datalen; |
|
239 |
+ for(last=data,next=((last+3)<=end)?memchr(last,'/',end-last-3):NULL;next!=NULL;next=((last+3)<=end)?memchr(last,'/',end-last-3):NULL) { |
|
240 |
+ if(memcmp(next,"/~/",3)==0) { |
|
241 |
+ wk_write(web,connid,last,next-last); |
|
242 |
+ wk_write(web,connid,"/",1); |
|
243 |
+ wk_writestr(web,connid,newsl->config->rootdir); |
|
244 |
+ wk_write(web,connid,"/",1); |
|
245 |
+ last=next+3; |
|
246 |
+ } else { |
|
247 |
+ wk_write(web,connid,last,next-last+1); |
|
248 |
+ last=next+1; |
|
249 |
+ } |
|
250 |
+ } |
|
251 |
+ wk_write(web,connid,last,end-last); |
|
252 |
+ } |
|
253 |
+ return(0); |
|
236 | 254 |
} |
255 |
+ |
... | ... |
@@ -23,20 +23,23 @@ |
23 | 23 |
|
24 | 24 |
#define CONFIGFILE "newslettersan.cfg" |
25 | 25 |
#define CFLOGFILE "newslettersan.log" |
26 |
+#define CFROOTDIR "subscribe" |
|
26 | 27 |
|
27 | 28 |
static int signal_init(int signum, void (*fn)(int)); |
28 | 29 |
static void sigint(int signum); |
29 | 30 |
volatile int sigint_flag=0; |
30 | 31 |
|
32 |
+wk_action callback_post(wk *web, int connid, wk_uri *uri, void *userptr); |
|
31 | 33 |
wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
34 |
+int newsl_serve_buffer_with_rootdir(newslettersan *newsl, wk *web, int connid, char *data, int datalen, const char *mime); |
|
32 | 35 |
|
33 | 36 |
int |
34 | 37 |
main(int argc, char *argv[]) |
35 | 38 |
{ |
36 | 39 |
int timeout=500; |
37 | 40 |
int serverfd; |
38 |
- newslettersan *newsl,newslstore; |
|
39 |
- char *hostnameport; |
|
41 |
+ newslettersan *newsl,newslstore; |
|
42 |
+ char *hostnameport; |
|
40 | 43 |
char hostname[128]; |
41 | 44 |
char *host; |
42 | 45 |
long hostsize; |
... | ... |
@@ -51,9 +54,9 @@ main(int argc, char *argv[]) |
51 | 54 |
if(newslconfig_exists(CONFIGFILE)!=0) { |
52 | 55 |
log_setlogfile(CFLOGFILE); |
53 | 56 |
log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
54 |
- newslconfig_write(CONFIGFILE,CFLOGFILE); |
|
57 |
+ newslconfig_write(CONFIGFILE,CFLOGFILE,CFROOTDIR); |
|
55 | 58 |
} |
56 |
- if((newsl->config=newslconfig_init(CONFIGFILE))==NULL) { |
|
59 |
+ if((newsl->config=newslconfig_init(CONFIGFILE,CFLOGFILE,CFROOTDIR))==NULL) { |
|
57 | 60 |
log_setlogfile(CFLOGFILE); |
58 | 61 |
log_write("INIT","ERROR: insufficient memory or config file error"); |
59 | 62 |
return(1); |
... | ... |
@@ -82,7 +85,7 @@ main(int argc, char *argv[]) |
82 | 85 |
return(2); |
83 | 86 |
} |
84 | 87 |
sock_setunsafe(serverfd); |
85 |
- if((newsl->web=wk_init(serverfd,newsl->ssel,NULL,callback_http,NULL,NULL,newsl))==NULL) { |
|
88 |
+ if((newsl->web=wk_init(serverfd,newsl->ssel,NULL,callback_http,callback_post,NULL,newsl))==NULL) { |
|
86 | 89 |
sselect_free(newsl->ssel),newsl->ssel=NULL; |
87 | 90 |
log_write("INIT","ERROR: couldn't init web server"); |
88 | 91 |
return(2); |
... | ... |
@@ -120,25 +123,114 @@ sigint(int signum) |
120 | 123 |
sigint_flag=1; |
121 | 124 |
} |
122 | 125 |
|
126 |
+wk_action |
|
127 |
+callback_post(wk *web, int connid, wk_uri *uri, void *userptr) |
|
128 |
+{ |
|
129 |
+ newslettersan *newsl=(newslettersan *)userptr; |
|
130 |
+ char partialpath[1024]; |
|
131 |
+ int l; |
|
132 |
+ if(newsl==NULL) |
|
133 |
+ return(wkact_finished); |
|
134 |
+ /* check that URI starts with /$rootdir/ */ |
|
135 |
+ l=strlen(newsl->config->rootdir); |
|
136 |
+ if(uri->path[0]!='/' || memcmp(uri->path+1,newsl->config->rootdir,l)!=0 || |
|
137 |
+ uri->path[l+1]!='/') { |
|
138 |
+ return(wkact_finished); |
|
139 |
+ } |
|
140 |
+ /* copy the path below $rootdir into partialpath */ |
|
141 |
+ strncpy(partialpath,uri->path+1+l,sizeof(partialpath)-1); |
|
142 |
+ partialpath[sizeof(partialpath)-1]='\0'; |
|
143 |
+ /* set push variables for the specified URI */ |
|
144 |
+ /* to be able to retrieve them in callback_http */ |
|
145 |
+ if(strcmp(partialpath,"/addemail")==0) { |
|
146 |
+ wk_post_addvalid(web,connid,"email",NULL); |
|
147 |
+ } |
|
148 |
+ return(wkact_finished); |
|
149 |
+} |
|
150 |
+ |
|
123 | 151 |
wk_action |
124 | 152 |
callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
125 | 153 |
{ |
126 | 154 |
newslettersan *newsl=(newslettersan *)userptr; |
127 | 155 |
resindex *res; |
156 |
+ int l; |
|
128 | 157 |
char partialpath[1024]; |
129 |
- if(newsl==NULL) |
|
130 |
- return(wkact_finished); |
|
131 |
- strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
|
158 |
+ if(newsl==NULL) |
|
159 |
+ return(wkact_finished); |
|
160 |
+ /* redirect to the real root URI if request is "/" */ |
|
161 |
+ if(strcmp(uri->path,"/")==0) { |
|
162 |
+ partialpath[0]='/'; |
|
163 |
+ strncpy(partialpath+1,newsl->config->rootdir,sizeof(partialpath)-1); |
|
164 |
+ partialpath[sizeof(partialpath)-1]='\0'; |
|
165 |
+ if((l=strlen(partialpath))<(sizeof(partialpath)-2)) |
|
166 |
+ strcpy(partialpath+l,"/"); |
|
167 |
+ wk_serve_redirect(web,connid,partialpath); |
|
168 |
+ return(wkact_finished); |
|
169 |
+ } |
|
170 |
+ /* check that URI starts with /$rootdir/ */ |
|
171 |
+ l=strlen(newsl->config->rootdir); |
|
172 |
+ if(uri->path[0]!='/' || memcmp(uri->path+1,newsl->config->rootdir,l)!=0 || |
|
173 |
+ uri->path[l+1]!='/') { |
|
174 |
+ wk_serve_error(web,connid,wkerr_notfound); |
|
175 |
+ return(wkact_finished); |
|
176 |
+ } |
|
177 |
+ /* copy the path below $rootdir into partialpath */ |
|
178 |
+ strncpy(partialpath,uri->path+1+l,sizeof(partialpath)-1); |
|
132 | 179 |
partialpath[sizeof(partialpath)-1]='\0'; |
133 |
- if(strcmp(uri->path,"/")==0) |
|
134 |
- strcpy(partialpath,"/index.html"); |
|
180 |
+ /* change the root url to index.html if neccessary */ |
|
181 |
+ if(strcmp(partialpath,"/")==0) { |
|
182 |
+ strncpy(partialpath,"/index.html",sizeof(partialpath)); |
|
183 |
+ partialpath[sizeof(partialpath)-1]='\0'; |
|
184 |
+ } |
|
185 |
+ /* serve the requested page */ |
|
135 | 186 |
if(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL) { |
136 |
- log_write("HTTP","Serving in-memory file %s",partialpath+1); |
|
137 |
- wk_serve_etagset(web,connid,res->etag); |
|
138 |
- wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
139 |
- return(wkact_finished); |
|
140 |
- } |
|
141 |
- wk_serve_error(web,connid,wkerr_notfound); |
|
187 |
+ log_write("HTTP","Serving in-memory file %s",partialpath+1); |
|
188 |
+ wk_serve_etagset(web,connid,res->etag); |
|
189 |
+ newsl_serve_buffer_with_rootdir(newsl,web,connid,(char *) res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
190 |
+ return(wkact_finished); |
|
191 |
+ } else if(strcmp(partialpath,"/addemail")==0) { |
|
192 |
+ char *email; |
|
193 |
+ if((email=wk_post_get(web,connid,"email",NULL))==NULL) { |
|
194 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
195 |
+ return(wkact_finished); |
|
196 |
+ } |
|
197 |
+ #warning TODO: do something with the email |
|
198 |
+ wk_serve_buffer_as_file(web,connid,email,strlen(email),"text/plain"); |
|
199 |
+ return(wkact_finished); |
|
200 |
+ } |
|
201 |
+ wk_serve_error(web,connid,wkerr_notfound); |
|
142 | 202 |
return(wkact_finished); |
143 | 203 |
} |
144 | 204 |
|
205 |
+int |
|
206 |
+newsl_serve_buffer_with_rootdir(newslettersan *newsl, wk *web, int connid, char *data, int datalen, const char *mime) |
|
207 |
+{ |
|
208 |
+ int res; |
|
209 |
+ sbuf *buf; |
|
210 |
+ int sbufid; |
|
211 |
+ char *last,*next,*end; |
|
212 |
+ if(newsl==NULL || web==NULL || data==NULL || datalen<0) |
|
213 |
+ return(-1); /* sanity check failed */ |
|
214 |
+ if((sbufid=wk_sbufacquire(web))==-1 || (buf=wk_sbufget(web,sbufid))==NULL) |
|
215 |
+ return(-1); |
|
216 |
+ /* we copy the buffer substituting /~/ for /$rootdir/ */ |
|
217 |
+ end=data+datalen; |
|
218 |
+ for(last=data,next=((last+3)<=end)?memchr(last,'/',end-last-3):NULL;next!=NULL;next=((last+3)<=end)?memchr(last,'/',end-last-3):NULL) { |
|
219 |
+ if(memcmp(next,"/~/",3)==0) { |
|
220 |
+ sbuf_add(buf,last,next-last); |
|
221 |
+ sbuf_add(buf,"/",1); |
|
222 |
+ sbuf_addstr(buf,newsl->config->rootdir); |
|
223 |
+ sbuf_add(buf,"/",1); |
|
224 |
+ last=next+3; |
|
225 |
+ } else { |
|
226 |
+ sbuf_add(buf,last,next-last+1); |
|
227 |
+ last=next+1; |
|
228 |
+ } |
|
229 |
+ } |
|
230 |
+ sbuf_add(buf,last,end-last); |
|
231 |
+ /* send the constructed buffer */ |
|
232 |
+ res=wk_serve_buffer_as_file(web,connid,sbuf_ptr(buf),sbuf_count(buf),mime); |
|
233 |
+ wk_sbufrelease(web,sbufid),sbufid=-1,buf=NULL; |
|
234 |
+ return(res); |
|
235 |
+ |
|
236 |
+} |
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,144 @@ |
1 |
+/* |
|
2 |
+ * newslettersan.c |
|
3 |
+ * |
|
4 |
+ * Small newsletter web server |
|
5 |
+ * |
|
6 |
+ * Author: Dario Rodriguez dario@softhome.net |
|
7 |
+ * This program is licensed under the terms of the Affero GPL v1+ |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+#include <stdio.h> |
|
11 |
+#include <stdlib.h> |
|
12 |
+#include <unistd.h> |
|
13 |
+#include <string.h> |
|
14 |
+#include <signal.h> |
|
15 |
+#include <sys/types.h> |
|
16 |
+#include <sys/stat.h> |
|
17 |
+#include "gen_res.h" |
|
18 |
+#include "socklib.h" |
|
19 |
+#include "loglib.h" |
|
20 |
+#include "webkernel.h" |
|
21 |
+#include "newslettersan.h" |
|
22 |
+#include "newsl_config.h" |
|
23 |
+ |
|
24 |
+#define CONFIGFILE "newslettersan.cfg" |
|
25 |
+#define CFLOGFILE "newslettersan.log" |
|
26 |
+ |
|
27 |
+static int signal_init(int signum, void (*fn)(int)); |
|
28 |
+static void sigint(int signum); |
|
29 |
+volatile int sigint_flag=0; |
|
30 |
+ |
|
31 |
+wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
|
32 |
+ |
|
33 |
+int |
|
34 |
+main(int argc, char *argv[]) |
|
35 |
+{ |
|
36 |
+ int timeout=500; |
|
37 |
+ int serverfd; |
|
38 |
+ newslettersan *newsl,newslstore; |
|
39 |
+ char *hostnameport; |
|
40 |
+ char hostname[128]; |
|
41 |
+ char *host; |
|
42 |
+ long hostsize; |
|
43 |
+ char *ptr,*sep; |
|
44 |
+ memset(&newslstore,0,sizeof(newslstore)); |
|
45 |
+ newsl=&newslstore; |
|
46 |
+ if(argc!=2) { |
|
47 |
+ printf("Syntax: %s [ip:]port\n",argv[0]); |
|
48 |
+ return(1); |
|
49 |
+ } |
|
50 |
+ hostnameport=argv[1]; |
|
51 |
+ if(newslconfig_exists(CONFIGFILE)!=0) { |
|
52 |
+ log_setlogfile(CFLOGFILE); |
|
53 |
+ log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
|
54 |
+ newslconfig_write(CONFIGFILE,CFLOGFILE); |
|
55 |
+ } |
|
56 |
+ if((newsl->config=newslconfig_init(CONFIGFILE))==NULL) { |
|
57 |
+ log_setlogfile(CFLOGFILE); |
|
58 |
+ log_write("INIT","ERROR: insufficient memory or config file error"); |
|
59 |
+ return(1); |
|
60 |
+ } |
|
61 |
+ log_setlogfile((newsl->config->logfile!=NULL)?newsl->config->logfile:CFLOGFILE); |
|
62 |
+ if((newsl->ssel=sselect_init())==NULL) { |
|
63 |
+ log_write("INIT","ERROR: insufficient memory"); |
|
64 |
+ return(1); |
|
65 |
+ } |
|
66 |
+ if((sep=strchr(hostnameport,':'))!=NULL) { |
|
67 |
+ serverfd=-1; |
|
68 |
+ strncpy(hostname,hostnameport,sizeof(hostname)); |
|
69 |
+ hostname[sizeof(hostname)-1]='\0'; |
|
70 |
+ if((ptr=strchr(hostname,':'))!=NULL) |
|
71 |
+ *ptr='\0'; |
|
72 |
+ if((host=ipv4_genip(hostname,&hostsize))!=NULL) { |
|
73 |
+ serverfd=ipv4_serverbinded(host,hostsize,atoi(sep+1)); |
|
74 |
+ free(host),host=NULL; |
|
75 |
+ } |
|
76 |
+ } else { |
|
77 |
+ serverfd=ipv4_server(atoi(hostnameport)); |
|
78 |
+ } |
|
79 |
+ if(serverfd==-1) { |
|
80 |
+ sselect_free(newsl->ssel),newsl->ssel=NULL; |
|
81 |
+ log_write("INIT","ERROR: couldn't listen on port"); |
|
82 |
+ return(2); |
|
83 |
+ } |
|
84 |
+ sock_setunsafe(serverfd); |
|
85 |
+ if((newsl->web=wk_init(serverfd,newsl->ssel,NULL,callback_http,NULL,NULL,newsl))==NULL) { |
|
86 |
+ sselect_free(newsl->ssel),newsl->ssel=NULL; |
|
87 |
+ log_write("INIT","ERROR: couldn't init web server"); |
|
88 |
+ return(2); |
|
89 |
+ } |
|
90 |
+ sigint_flag=0; |
|
91 |
+ signal_init(SIGINT,sigint); |
|
92 |
+ log_write("INIT","Server initialized, waiting connections..."); |
|
93 |
+ while(!sigint_flag) { |
|
94 |
+ sselect_wait(newsl->ssel,timeout); |
|
95 |
+ if(sigint_flag) |
|
96 |
+ break; |
|
97 |
+ wk_service(newsl->web); |
|
98 |
+ } |
|
99 |
+ wk_free(newsl->web),newsl->web=NULL; |
|
100 |
+ close(serverfd),serverfd=-1; |
|
101 |
+ sselect_free(newsl->ssel),newsl->ssel=NULL; |
|
102 |
+ newslconfig_free(newsl->config),newsl->config=NULL; |
|
103 |
+ log_write("FINI","SIGINT detected, exiting..."); |
|
104 |
+ return(0); |
|
105 |
+} |
|
106 |
+ |
|
107 |
+static int |
|
108 |
+signal_init(int signum, void (*fn)(int)) |
|
109 |
+{ |
|
110 |
+ struct sigaction sa; |
|
111 |
+ sa.sa_handler=fn; |
|
112 |
+ sigemptyset(&sa.sa_mask); |
|
113 |
+ sa.sa_flags=0; |
|
114 |
+ return(sigaction(signum,&sa,0)); |
|
115 |
+} |
|
116 |
+ |
|
117 |
+static void |
|
118 |
+sigint(int signum) |
|
119 |
+{ |
|
120 |
+ sigint_flag=1; |
|
121 |
+} |
|
122 |
+ |
|
123 |
+wk_action |
|
124 |
+callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
|
125 |
+{ |
|
126 |
+ newslettersan *newsl=(newslettersan *)userptr; |
|
127 |
+ resindex *res; |
|
128 |
+ char partialpath[1024]; |
|
129 |
+ if(newsl==NULL) |
|
130 |
+ return(wkact_finished); |
|
131 |
+ strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
|
132 |
+ partialpath[sizeof(partialpath)-1]='\0'; |
|
133 |
+ if(strcmp(uri->path,"/")==0) |
|
134 |
+ strcpy(partialpath,"/index.html"); |
|
135 |
+ if(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL) { |
|
136 |
+ log_write("HTTP","Serving in-memory file %s",partialpath+1); |
|
137 |
+ wk_serve_etagset(web,connid,res->etag); |
|
138 |
+ wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
139 |
+ return(wkact_finished); |
|
140 |
+ } |
|
141 |
+ wk_serve_error(web,connid,wkerr_notfound); |
|
142 |
+ return(wkact_finished); |
|
143 |
+} |
|
144 |
+ |