160:389bd0e1ffa9 | 161:aadda87bad1b |
---|---|
30 | 30 |
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 <sys/types.h> | |
36 #include <signal.h> | |
37 #include <sys/wait.h> | |
38 | |
39 #include "../util/util.h" | 35 #include "../util/util.h" |
40 #include "../util/pblock.h" | 36 #include "../util/pblock.h" |
41 #include "../../ucx/string.h" | 37 #include "../../ucx/string.h" |
42 | 38 |
43 #include "../util/io.h" | 39 #include "../util/io.h" |
101 if(content_length > 0) { | 97 if(content_length > 0) { |
102 ssize_t n = 0; | 98 ssize_t n = 0; |
103 while(n < content_length) { | 99 while(n < content_length) { |
104 r = netbuf_getbytes(sn->inbuf, buf, 4096); | 100 r = netbuf_getbytes(sn->inbuf, buf, 4096); |
105 if(r <= 0) { | 101 if(r <= 0) { |
106 // TODO: handle error | 102 // TODO: handleerror |
107 log_ereport(LOG_FAILURE, "send-cgi: Cannot read request body"); | |
108 kill(cgip.pid, SIGTERM); | |
109 cgi_close(&cgip); | 103 cgi_close(&cgip); |
110 return REQ_ABORTED; | 104 return REQ_ABORTED; |
111 } | 105 } |
112 ssize_t w = write(cgip.in[1], buf, r); | 106 write(cgip.in[1], buf, r); |
113 if(w <= 0) { | |
114 // TODO: handle error | |
115 log_ereport( | |
116 LOG_FAILURE, | |
117 "send-cgi: Cannot send request body to cgi process"); | |
118 kill(cgip.pid, SIGTERM); | |
119 cgi_close(&cgip); | |
120 return REQ_ABORTED; | |
121 } | |
122 n += r; | 107 n += r; |
123 } | 108 } |
124 } | 109 } |
125 close(cgip.in[1]); | 110 close(cgip.in[1]); |
126 cgip.in[1] = -1; | 111 cgip.in[1] = -1; |
133 while((r = read(cgip.out[0], buf, 4096)) > 0) { | 118 while((r = read(cgip.out[0], buf, 4096)) > 0) { |
134 if(cgiheader) { | 119 if(cgiheader) { |
135 size_t pos; | 120 size_t pos; |
136 ret = cgi_parse_response(parser, buf, r, &pos); | 121 ret = cgi_parse_response(parser, buf, r, &pos); |
137 if(ret == -1) { | 122 if(ret == -1) { |
138 log_ereport( | |
139 LOG_FAILURE, | |
140 "broken cgi script response: path: %s", path); | |
141 protocol_status(sn, rq, 500, NULL); | 123 protocol_status(sn, rq, 500, NULL); |
142 result = REQ_ABORTED; | 124 result = REQ_ABORTED; |
143 break; | 125 break; |
126 } else if(ret == 0) { | |
127 | |
144 } else if(ret == 1) { | 128 } else if(ret == 1) { |
145 cgiheader = FALSE; | 129 cgiheader = FALSE; |
146 if(parser->status > 0) { | 130 if(parser->status > 0) { |
147 protocol_status(sn, rq, parser->status, parser->msg); | 131 protocol_status(sn, rq, parser->status, parser->msg); |
148 } | 132 } |
162 break; | 146 break; |
163 } | 147 } |
164 } | 148 } |
165 } | 149 } |
166 | 150 |
167 cgi_close(&cgip); // TODO: check return value | 151 cgi_close(&cgip); |
168 | 152 |
169 cgi_parser_free(parser); | 153 cgi_parser_free(parser); |
170 return result; | 154 return result; |
171 } | 155 } |
172 | 156 |
223 } | 207 } |
224 | 208 |
225 return REQ_PROCEED; | 209 return REQ_PROCEED; |
226 } | 210 } |
227 | 211 |
228 int cgi_close(CGIProcess *p) { | 212 void cgi_close(CGIProcess *p) { |
229 int status = -1; | |
230 waitpid(p->pid, &status, 0); | |
231 | |
232 if(p->in[0] != -1) { | 213 if(p->in[0] != -1) { |
233 close(p->in[0]); | 214 close(p->in[0]); |
234 } | 215 } |
235 if(p->in[1] != -1) { | 216 if(p->in[1] != -1) { |
236 close(p->in[1]); | 217 close(p->in[1]); |
239 close(p->out[0]); | 220 close(p->out[0]); |
240 } | 221 } |
241 if(p->out[1] != -1) { | 222 if(p->out[1] != -1) { |
242 close(p->out[1]); | 223 close(p->out[1]); |
243 } | 224 } |
244 | |
245 return 0; | |
246 } | 225 } |
247 | 226 |
248 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) { | 227 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) { |
249 CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser)); | 228 CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser)); |
250 parser->sn = sn; | 229 parser->sn = sn; |