Browse code

Cleanup: change tabs to spaces.

Dario Rodriguez authored on 03/11/2022 18:21:15
Showing 1 changed files
... ...
@@ -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);
Browse code

Add language field (hidden) in the subscribe form

Dario Rodriguez authored on 20/05/2015 14:47:40
Showing 1 changed files
... ...
@@ -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);
Browse code

Add missing brace at end of source file

Dario Rodriguez authored on 18/05/2015 22:16:49
Showing 1 changed files
... ...
@@ -252,4 +252,3 @@ newsl_serve_buffer_with_rootdir(newslettersan *newsl, wk *web, int connid, char
252 252
         }
253 253
         return(0);
254 254
 }
255
-
Browse code

rewrite newsl_serve_buffer_with_rootdir so it can rewrite large buffers (not limited by the size of one sbuf)

Dario Rodriguez authored on 18/05/2015 19:48:11
Showing 1 changed files
... ...
@@ -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
+
Browse code

Add simple form to ask for the e-mail and get the reply via POST request

Dario Rodriguez authored on 05/05/2015 19:14:56
Showing 1 changed files
... ...
@@ -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
+}
Browse code

Basic webserver part (blatantly ripped from kakumei)

Dario Rodriguez authored on 23/04/2015 20:11:31
Showing 1 changed files
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
+