Mercurial > urweb
comparison src/c/request.c @ 854:158d980889ac
Further refactoring of request.c to work with CGI
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 23 Jun 2009 15:40:35 -0400 |
parents | 19fdeef40ada |
children | 86ec89baee01 |
comparison
equal
deleted
inserted
replaced
853:19fdeef40ada | 854:158d980889ac |
---|---|
149 void uw_free_request_context(uw_request_context r) { | 149 void uw_free_request_context(uw_request_context r) { |
150 free(r->path_copy); | 150 free(r->path_copy); |
151 free(r); | 151 free(r); |
152 } | 152 } |
153 | 153 |
154 request_result uw_request(uw_request_context rc, uw_context ctx, char *request, size_t request_len, int sock) { | 154 request_result uw_request(uw_request_context rc, uw_context ctx, |
155 char *method, char *path, char *query_string, | |
156 char *body, size_t body_len, | |
157 int sock) { | |
155 int retries_left = MAX_RETRIES; | 158 int retries_left = MAX_RETRIES; |
156 char *s; | 159 char *s; |
157 failure_kind fk; | 160 failure_kind fk; |
158 int is_post = 0, do_normal_send = 1; | 161 int is_post = 0, do_normal_send = 1; |
159 char *boundary = NULL; | 162 char *boundary = NULL; |
160 size_t boundary_len; | 163 size_t boundary_len; |
161 char *cmd, *path, *headers, *inputs, *after_headers; | 164 char *inputs; |
162 | 165 |
163 if (!(s = strstr(request, "\r\n\r\n"))) { | 166 if (!strcmp(method, "POST")) { |
164 fprintf(stderr, "No end of headers found in request\n"); | |
165 return FAILED; | |
166 } | |
167 | |
168 s[2] = 0; | |
169 after_headers = s + 4; | |
170 | |
171 if (!(s = strstr(request, "\r\n"))) { | |
172 fprintf(stderr, "No newline in request\n"); | |
173 return FAILED; | |
174 } | |
175 | |
176 *s = 0; | |
177 headers = s + 2; | |
178 cmd = s = request; | |
179 | |
180 if (!strsep(&s, " ")) { | |
181 fprintf(stderr, "No first space in HTTP command\n"); | |
182 return FAILED; | |
183 } | |
184 | |
185 uw_set_headers(ctx, headers); | |
186 | |
187 if (!strcmp(cmd, "POST")) { | |
188 char *clen_s = uw_Basis_requestHeader(ctx, "Content-length"); | 167 char *clen_s = uw_Basis_requestHeader(ctx, "Content-length"); |
189 if (!clen_s) { | 168 if (!clen_s) { |
190 fprintf(stderr, "No Content-length with POST\n"); | 169 fprintf(stderr, "No Content-length with POST\n"); |
191 return FAILED; | 170 return FAILED; |
192 } | 171 } |
194 if (clen < 0) { | 173 if (clen < 0) { |
195 fprintf(stderr, "Negative Content-length with POST\n"); | 174 fprintf(stderr, "Negative Content-length with POST\n"); |
196 return FAILED; | 175 return FAILED; |
197 } | 176 } |
198 | 177 |
199 if (request + request_len - after_headers < clen) { | 178 if (body_len < clen) { |
200 fprintf(stderr, "Request doesn't contain all POST data (according to Content-Length)\n"); | 179 fprintf(stderr, "Request doesn't contain all POST data (according to Content-Length)\n"); |
201 return FAILED; | 180 return FAILED; |
202 } | 181 } |
203 | 182 |
204 is_post = 1; | 183 is_post = 1; |
213 boundary = clen_s + 28; | 192 boundary = clen_s + 28; |
214 boundary[0] = '-'; | 193 boundary[0] = '-'; |
215 boundary[1] = '-'; | 194 boundary[1] = '-'; |
216 boundary_len = strlen(boundary); | 195 boundary_len = strlen(boundary); |
217 } | 196 } |
218 } else if (strcmp(cmd, "GET")) { | 197 } else if (strcmp(method, "GET")) { |
219 fprintf(stderr, "Not ready for non-GET/POST command: %s\n", cmd); | 198 fprintf(stderr, "Not ready for non-GET/POST command: %s\n", method); |
220 return FAILED; | |
221 } | |
222 | |
223 path = s; | |
224 if (!strsep(&s, " ")) { | |
225 fprintf(stderr, "No second space in HTTP command\n"); | |
226 return FAILED; | 199 return FAILED; |
227 } | 200 } |
228 | 201 |
229 if (!strcmp(path, "/.msgs")) { | 202 if (!strcmp(path, "/.msgs")) { |
230 char *id = uw_Basis_requestHeader(ctx, "UrWeb-Client"); | 203 char *id = uw_Basis_requestHeader(ctx, "UrWeb-Client"); |
246 return FAILED; | 219 return FAILED; |
247 } | 220 } |
248 } | 221 } |
249 | 222 |
250 if (boundary) { | 223 if (boundary) { |
251 char *part = after_headers, *after_sub_headers, *header, *after_header; | 224 char *part = body, *after_sub_headers, *header, *after_header; |
252 size_t part_len; | 225 size_t part_len; |
253 | 226 |
254 part = strstr(part, boundary); | 227 part = strstr(part, boundary); |
255 if (!part) { | 228 if (!part) { |
256 fprintf(stderr, "Missing first multipart boundary\n"); | 229 fprintf(stderr, "Missing first multipart boundary\n"); |
327 } else if (!strcasecmp(header, "Content-Type")) { | 300 } else if (!strcasecmp(header, "Content-Type")) { |
328 type = colon; | 301 type = colon; |
329 } | 302 } |
330 } | 303 } |
331 | 304 |
332 part = memmem(after_sub_headers, request + request_len - after_sub_headers, boundary, boundary_len); | 305 part = memmem(after_sub_headers, body + body_len - after_sub_headers, boundary, boundary_len); |
333 if (!part) { | 306 if (!part) { |
334 fprintf(stderr, "Missing boundary after multipart payload\n"); | 307 fprintf(stderr, "Missing boundary after multipart payload\n"); |
335 return FAILED; | 308 return FAILED; |
336 } | 309 } |
337 part[-2] = 0; | 310 part[-2] = 0; |
351 return FAILED; | 324 return FAILED; |
352 } | 325 } |
353 } | 326 } |
354 } | 327 } |
355 else { | 328 else { |
356 if (is_post) | 329 inputs = is_post ? body : query_string; |
357 inputs = after_headers; | |
358 else if (inputs = strchr(path, '?')) | |
359 *inputs++ = 0; | |
360 | 330 |
361 if (inputs) { | 331 if (inputs) { |
362 char *name, *value; | 332 char *name, *value; |
363 | 333 |
364 while (*inputs) { | 334 while (*inputs) { |