src/server/safs/cgi.c

changeset 119
155cbab9eefd
parent 118
38bf6dd8f4e7
child 120
d2eb5fd97df0
equal deleted inserted replaced
118:38bf6dd8f4e7 119:155cbab9eefd
31 #include <stdio.h> 31 #include <stdio.h>
32 #include <stdlib.h> 32 #include <stdlib.h>
33 #include <unistd.h> 33 #include <unistd.h>
34 34
35 #include "../util/util.h" 35 #include "../util/util.h"
36 #include "../util/pblock.h"
36 #include "../../ucx/string.h" 37 #include "../../ucx/string.h"
37 38
38 #include "cgiutils.h" 39 #include "cgiutils.h"
39 40
40 #define CGI_VARS 32 41 #define CGI_VARS 32
41 42
42 #define CGI_RESPONSE_PARSER_BUFLEN 2048 43 #define CGI_RESPONSE_PARSER_BUFLEN 2048
43 #define CGI_RESPONSE_MAX_LINE_LENGTH 512 44 #define CGI_RESPONSE_MAX_LINE_LENGTH 512
44 45
45 int send_cgi(pblock *pb, Session *sn, Request *rq) { 46 int send_cgi(pblock *pb, Session *sn, Request *rq) {
46 char *path = pblock_findval("path", rq->vars); 47 char *path = pblock_findkeyval(pb_key_path, rq->vars);
48 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
49 int64_t content_length = 0;
50
51 if(ctlen) {
52 if(!util_strtoint(ctlen, &content_length)) {
53 log_ereport(
54 LOG_FAILURE,
55 "send-cgi: content-length header is not an integer");
56 protocol_status(sn, rq, 400, NULL);
57 return REQ_ABORTED;
58 }
59 }
47 60
48 struct stat s; 61 struct stat s;
49 if(stat(path, &s)) { 62 if(stat(path, &s)) {
50 int statuscode = util_errno2status(errno); 63 int statuscode = util_errno2status(errno);
51 protocol_status(sn, rq, statuscode, NULL); 64 protocol_status(sn, rq, statuscode, NULL);
69 int ret = cgi_start(&cgip, path, argv, env); 82 int ret = cgi_start(&cgip, path, argv, env);
70 if(ret != REQ_PROCEED) { 83 if(ret != REQ_PROCEED) {
71 return ret; 84 return ret;
72 } 85 }
73 86
74 // TODO: send http body 87 char buf[4096]; // I/O buffer
88 ssize_t r;
89
90 if(content_length > 0) {
91 ssize_t n = 0;
92 while(n < content_length) {
93 r = netbuf_getbytes(sn->inbuf, buf, 4096);
94 if(r <= 0) {
95 // TODO: handleerror
96 return REQ_ABORTED;
97 }
98 write(cgip.in[1], buf, r);
99 n += r;
100 }
101 }
75 close(cgip.in[1]); 102 close(cgip.in[1]);
76 103
77 // read from child 104 // read from child
78 CGIResponseParser *parser = cgi_parser_new(sn, rq); 105 CGIResponseParser *parser = cgi_parser_new(sn, rq);
79 WSBool cgiheader = TRUE; 106 WSBool cgiheader = TRUE;
80 107
81 char buf[4096];
82 ssize_t r;
83 while((r = read(cgip.out[0], buf, 4096)) > 0) { 108 while((r = read(cgip.out[0], buf, 4096)) > 0) {
84 if(cgiheader) { 109 if(cgiheader) {
85 size_t pos; 110 size_t pos;
86 int ret = cgi_parse_response(parser, buf, r, &pos); 111 int ret = cgi_parse_response(parser, buf, r, &pos);
87 if(ret == -1) { 112 if(ret == -1) {

mercurial