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)) { |