Thu, 27 Oct 2016 16:56:00 +0200
adds support for CGI with request bodies
--- 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);