src/server/safs/cgi.c

changeset 124
85985e88f63b
parent 123
9c639e4941cf
child 125
c913d515be1e
equal deleted inserted replaced
123:9c639e4941cf 124:85985e88f63b
82 int ret = cgi_start(&cgip, path, argv, env); 82 int ret = cgi_start(&cgip, path, argv, env);
83 if(ret != REQ_PROCEED) { 83 if(ret != REQ_PROCEED) {
84 return ret; 84 return ret;
85 } 85 }
86 86
87 util_env_free(env);
88
87 char buf[4096]; // I/O buffer 89 char buf[4096]; // I/O buffer
88 ssize_t r; 90 ssize_t r;
89 91
90 if(content_length > 0) { 92 if(content_length > 0) {
91 ssize_t n = 0; 93 ssize_t n = 0;
109 if(cgiheader) { 111 if(cgiheader) {
110 size_t pos; 112 size_t pos;
111 int ret = cgi_parse_response(parser, buf, r, &pos); 113 int ret = cgi_parse_response(parser, buf, r, &pos);
112 if(ret == -1) { 114 if(ret == -1) {
113 protocol_status(sn, rq, 500, NULL); 115 protocol_status(sn, rq, 500, NULL);
116 cgi_parser_free(parser);
114 return REQ_ABORTED; 117 return REQ_ABORTED;
115 } else if(ret == 0) { 118 } else if(ret == 0) {
116 119
117 } else if(ret == 1) { 120 } else if(ret == 1) {
118 cgiheader = FALSE; 121 cgiheader = FALSE;
122 if(parser->status > 0) {
123 protocol_status(sn, rq, parser->status, parser->msg);
124 }
119 http_start_response(sn, rq); 125 http_start_response(sn, rq);
120 if(pos < r) { 126 if(pos < r) {
121 net_write(sn->csd, buf+pos, r-pos); 127 net_write(sn->csd, buf+pos, r-pos);
122 } 128 }
123 } 129 }
124 } else { 130 } else {
125 net_write(sn->csd, buf, r); 131 net_write(sn->csd, buf, r);
126 } 132 }
127 } 133 }
128 134
135 cgi_parser_free(parser);
129 return REQ_PROCEED; 136 return REQ_PROCEED;
130 } 137 }
131 138
132 int cgi_start(CGIProcess *p, char *path, char *const argv[], char *const envp[]) { 139 int cgi_start(CGIProcess *p, char *path, char *const argv[], char *const envp[]) {
133 if(pipe(p->in) || pipe(p->out)) { 140 if(pipe(p->in) || pipe(p->out)) {
186 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) { 193 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) {
187 CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser)); 194 CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser));
188 parser->sn = sn; 195 parser->sn = sn;
189 parser->rq = rq; 196 parser->rq = rq;
190 parser->tmp = ucx_buffer_new(NULL, 64, UCX_BUFFER_AUTOEXTEND); 197 parser->tmp = ucx_buffer_new(NULL, 64, UCX_BUFFER_AUTOEXTEND);
198 parser->status = 0;
199 parser->msg = NULL;
191 return parser; 200 return parser;
201 }
202
203 void cgi_parser_free(CGIResponseParser *parser) {
204 if(parser->tmp) {
205 ucx_buffer_free(parser->tmp);
206 }
207 pool_free(parser->sn->pool, parser);
192 } 208 }
193 209
194 /* 210 /*
195 * parses a cgi response line and adds the response header to rq->srvhdrs 211 * parses a cgi response line and adds the response header to rq->srvhdrs
196 * returns 0: incomplete line 212 * returns 0: incomplete line
227 value = sstrtrim(value); 243 value = sstrtrim(value);
228 244
229 if(name.length == 0 || value.length == 0) { 245 if(name.length == 0 || value.length == 0) {
230 return -1; 246 return -1;
231 } 247 }
232 pblock_nvlinsert( 248
233 name.ptr, 249 if(!sstrcmp(name, S("status"))) {
234 name.length, 250 sstr_t codestr = value;
235 value.ptr, 251 int i;
236 value.length, 252 for(i=0;i<codestr.length;i++) {
237 parser->rq->srvhdrs); 253 if(!isdigit(codestr.ptr[i])) {
254 break;
255 }
256 if(i > 2) {
257 break;
258 }
259 }
260 codestr.ptr[i] = '\0';
261
262 int64_t s = 0;
263 util_strtoint(codestr.ptr, &s);
264 parser->status = (int)s;
265
266 sstr_t msg = sstrtrim(sstrsubs(value, i + 1));
267
268 if(msg.length > 0) {
269 parser->msg = sstrdup_pool(parser->sn->pool, msg).ptr;
270 }
271 } else {
272 pblock_nvlinsert(
273 name.ptr,
274 name.length,
275 value.ptr,
276 value.length,
277 parser->rq->srvhdrs);
278 }
238 279
239 line_begin = i+1; 280 line_begin = i+1;
240 value_begin = line_begin; 281 value_begin = line_begin;
241 space = TRUE; 282 space = TRUE;
242 } else if(!isspace(c)) { 283 } else if(!isspace(c)) {

mercurial