adds support for CGI with request bodies

Thu, 27 Oct 2016 16:56:00 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 27 Oct 2016 16:56:00 +0200
changeset 119
155cbab9eefd
parent 118
38bf6dd8f4e7
child 120
d2eb5fd97df0

adds support for CGI with request bodies

src/server/safs/cgi.c file | annotate | diff | comparison | revisions
src/server/util/util.c file | annotate | diff | comparison | revisions
src/server/util/util.h file | annotate | diff | comparison | revisions
--- a/src/server/safs/cgi.c	Wed Oct 26 15:53:56 2016 +0200
+++ b/src/server/safs/cgi.c	Thu Oct 27 16:56:00 2016 +0200
@@ -33,6 +33,7 @@
 #include <unistd.h>
 
 #include "../util/util.h"
+#include "../util/pblock.h"
 #include "../../ucx/string.h"
 
 #include "cgiutils.h"
@@ -43,7 +44,19 @@
 #define CGI_RESPONSE_MAX_LINE_LENGTH    512
 
 int send_cgi(pblock *pb, Session *sn, Request *rq) {  
-    char *path = pblock_findval("path", rq->vars);
+    char *path = pblock_findkeyval(pb_key_path, rq->vars);
+    char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
+    int64_t content_length = 0;
+    
+    if(ctlen) {
+        if(!util_strtoint(ctlen, &content_length)) {
+            log_ereport(
+                    LOG_FAILURE,
+                    "send-cgi: content-length header is not an integer");
+            protocol_status(sn, rq, 400, NULL);
+            return REQ_ABORTED;
+        }
+    }
     
     struct stat s;
     if(stat(path, &s)) {
@@ -71,15 +84,27 @@
         return ret;
     }
     
-    // TODO: send http body
+    char buf[4096]; // I/O buffer
+    ssize_t r;
+    
+    if(content_length > 0) {
+        ssize_t n = 0;
+        while(n < content_length) {
+            r = netbuf_getbytes(sn->inbuf, buf, 4096);
+            if(r <= 0) {
+                // TODO: handleerror
+                return REQ_ABORTED; 
+            }
+            write(cgip.in[1], buf, r);
+            n += r;
+        }
+    }
     close(cgip.in[1]);
     
     // read from child
     CGIResponseParser *parser = cgi_parser_new(sn, rq);
     WSBool cgiheader = TRUE;
     
-    char buf[4096];
-    ssize_t r;
     while((r = read(cgip.out[0], buf, 4096)) > 0) {
         if(cgiheader) {
             size_t pos;
--- a/src/server/util/util.c	Wed Oct 26 15:53:56 2016 +0200
+++ b/src/server/util/util.c	Thu Oct 27 16:56:00 2016 +0200
@@ -381,6 +381,18 @@
     return def;
 }
 
+NSAPI_PUBLIC int util_strtoint(char *str, int64_t *value) {
+    char *end;
+    errno = 0;
+    int64_t val = strtoll(str, &end, 0);
+    if(errno == 0) {
+        *value = val;
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
 
 /* ------------------------------ util_itoa ------------------------------- */
 /*
--- a/src/server/util/util.h	Wed Oct 26 15:53:56 2016 +0200
+++ b/src/server/util/util.h	Thu Oct 27 16:56:00 2016 +0200
@@ -195,6 +195,9 @@
 NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def);
 int util_getboolean_s(sstr_t s, int def);
 
+// new
+NSAPI_PUBLIC int util_strtoint(char *str, int64_t *value);
+
 // TODO
 //NSAPI_PUBLIC PRIntervalTime INTutil_getinterval(const char *v, PRIntervalTime def);
 

mercurial