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
+