diff options
author | Christian Grothoff <christian@grothoff.org> | 2007-07-09 02:32:35 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2007-07-09 02:32:35 +0000 |
commit | 6bf6682ce48efc246f3d098c1e35de1213509f6b (patch) | |
tree | c656681eec37c8f9aed6181c093b089a4f4eded9 | |
parent | 8a7e30d0304855fc1a0f7a328cf77a6bbb0ae1c2 (diff) | |
download | libmicrohttpd-6bf6682ce48efc246f3d098c1e35de1213509f6b.tar.gz libmicrohttpd-6bf6682ce48efc246f3d098c1e35de1213509f6b.zip |
plus is space, support for multi-line headers
-rw-r--r-- | src/daemon/internal.h | 5 | ||||
-rw-r--r-- | src/daemon/session.c | 79 |
2 files changed, 76 insertions, 8 deletions
diff --git a/src/daemon/internal.h b/src/daemon/internal.h index 8d125a01..bcbe2724 100644 --- a/src/daemon/internal.h +++ b/src/daemon/internal.h | |||
@@ -176,6 +176,11 @@ struct MHD_Session { | |||
176 | char * url; | 176 | char * url; |
177 | 177 | ||
178 | /** | 178 | /** |
179 | * HTTP version string (i.e. http/1.1) | ||
180 | */ | ||
181 | char * version; | ||
182 | |||
183 | /** | ||
179 | * Buffer for reading requests. | 184 | * Buffer for reading requests. |
180 | */ | 185 | */ |
181 | char * read_buffer; | 186 | char * read_buffer; |
diff --git a/src/daemon/session.c b/src/daemon/session.c index 548506a0..48f88868 100644 --- a/src/daemon/session.c +++ b/src/daemon/session.c | |||
@@ -84,8 +84,8 @@ MHD_lookup_session_value(struct MHD_Session * session, | |||
84 | pos = session->headers_received; | 84 | pos = session->headers_received; |
85 | while (pos != NULL) { | 85 | while (pos != NULL) { |
86 | if ( (0 != (pos->kind & kind)) && | 86 | if ( (0 != (pos->kind & kind)) && |
87 | (0 == strcmp(key, | 87 | (0 == strcasecmp(key, |
88 | pos->header)) ) | 88 | pos->header)) ) |
89 | return pos->value; | 89 | return pos->value; |
90 | pos = pos->next; | 90 | pos = pos->next; |
91 | } | 91 | } |
@@ -227,11 +227,16 @@ MHD_session_add_header(struct MHD_Session * session, | |||
227 | session->headers_received = hdr; | 227 | session->headers_received = hdr; |
228 | } | 228 | } |
229 | 229 | ||
230 | /** | ||
231 | * Process escape sequences ('+'=space, %HH) | ||
232 | */ | ||
230 | static void | 233 | static void |
231 | MHD_http_unescape(char * val) { | 234 | MHD_http_unescape(char * val) { |
232 | char * esc; | 235 | char * esc; |
233 | unsigned int num; | 236 | unsigned int num; |
234 | 237 | ||
238 | while (NULL != (esc = strstr(val, "+"))) | ||
239 | *esc = ' '; | ||
235 | while (NULL != (esc = strstr(val, "%"))) { | 240 | while (NULL != (esc = strstr(val, "%"))) { |
236 | if ( (1 == sscanf(&esc[1], | 241 | if ( (1 == sscanf(&esc[1], |
237 | "%2x", | 242 | "%2x", |
@@ -344,17 +349,57 @@ MHD_parse_cookie_header(struct MHD_Session * session) { | |||
344 | */ | 349 | */ |
345 | static void | 350 | static void |
346 | MHD_parse_session_headers(struct MHD_Session * session) { | 351 | MHD_parse_session_headers(struct MHD_Session * session) { |
352 | char * last; | ||
347 | char * line; | 353 | char * line; |
348 | char * colon; | 354 | char * colon; |
349 | char * uri; | 355 | char * uri; |
350 | char * httpType; | 356 | char * httpType; |
351 | char * args; | 357 | char * args; |
358 | char * tmp; | ||
352 | const char * clen; | 359 | const char * clen; |
353 | unsigned long long cval; | 360 | unsigned long long cval; |
354 | 361 | ||
355 | if (session->bodyReceived == 1) | 362 | if (session->bodyReceived == 1) |
356 | abort(); | 363 | abort(); |
364 | last = NULL; | ||
357 | while (NULL != (line = MHD_get_next_header_line(session))) { | 365 | while (NULL != (line = MHD_get_next_header_line(session))) { |
366 | if (last != NULL) { | ||
367 | if ( (line[0] == ' ') || | ||
368 | (line[0] == '\t') ) { | ||
369 | /* value was continued on the next line, see | ||
370 | http://www.jmarshall.com/easy/http/ */ | ||
371 | if ( (strlen(line) + strlen(last) > | ||
372 | 4 * MHD_MAX_BUF_SIZE) ) { | ||
373 | free(line); | ||
374 | free(last); | ||
375 | last = NULL; | ||
376 | MHD_DLOG(session->daemon, | ||
377 | "Received excessively long header line (>%u), closing connection.\n", | ||
378 | 4 * MHD_MAX_BUF_SIZE); | ||
379 | CLOSE(session->socket_fd); | ||
380 | session->socket_fd = -1; | ||
381 | break; | ||
382 | } | ||
383 | tmp = malloc(strlen(line) + strlen(last) + 1); | ||
384 | strcpy(tmp, last); | ||
385 | free(last); | ||
386 | last = tmp; | ||
387 | tmp = line; | ||
388 | while ( (tmp[0] == ' ') || | ||
389 | (tmp[0] == '\t') ) | ||
390 | tmp++; /* skip whitespace at start of 2nd line */ | ||
391 | strcat(last, tmp); | ||
392 | free(line); | ||
393 | continue; /* possibly more than 2 lines... */ | ||
394 | } else { | ||
395 | MHD_session_add_header(session, | ||
396 | last, | ||
397 | colon, | ||
398 | MHD_HEADER_KIND); | ||
399 | free(last); | ||
400 | last = NULL; | ||
401 | } | ||
402 | } | ||
358 | if (session->url == NULL) { | 403 | if (session->url == NULL) { |
359 | /* line must be request line */ | 404 | /* line must be request line */ |
360 | uri = strstr(line, " "); | 405 | uri = strstr(line, " "); |
@@ -364,8 +409,10 @@ MHD_parse_session_headers(struct MHD_Session * session) { | |||
364 | session->method = strdup(line); | 409 | session->method = strdup(line); |
365 | uri++; | 410 | uri++; |
366 | httpType = strstr(uri, " "); | 411 | httpType = strstr(uri, " "); |
367 | if (httpType != NULL) | 412 | if (httpType != NULL) { |
368 | httpType[0] = '\0'; | 413 | httpType[0] = '\0'; |
414 | httpType++; | ||
415 | } | ||
369 | args = strstr(uri, "?"); | 416 | args = strstr(uri, "?"); |
370 | if (args != NULL) { | 417 | if (args != NULL) { |
371 | args[0] = '\0'; | 418 | args[0] = '\0'; |
@@ -374,7 +421,10 @@ MHD_parse_session_headers(struct MHD_Session * session) { | |||
374 | args); | 421 | args); |
375 | } | 422 | } |
376 | session->url = strdup(uri); | 423 | session->url = strdup(uri); |
377 | /* do we want to do anything with httpType? */ | 424 | if (httpType == NULL) |
425 | session->version = strdup(""); | ||
426 | else | ||
427 | session->version = strdup(httpType); | ||
378 | free(line); | 428 | free(line); |
379 | continue; | 429 | continue; |
380 | } | 430 | } |
@@ -412,7 +462,7 @@ MHD_parse_session_headers(struct MHD_Session * session) { | |||
412 | break; | 462 | break; |
413 | } | 463 | } |
414 | /* line should be normal header line, find colon */ | 464 | /* line should be normal header line, find colon */ |
415 | colon = strstr(line, ": "); | 465 | colon = strstr(line, ":"); |
416 | if (colon == NULL) { | 466 | if (colon == NULL) { |
417 | /* error in header line, die hard */ | 467 | /* error in header line, die hard */ |
418 | MHD_DLOG(session->daemon, | 468 | MHD_DLOG(session->daemon, |
@@ -421,12 +471,23 @@ MHD_parse_session_headers(struct MHD_Session * session) { | |||
421 | } | 471 | } |
422 | /* zero-terminate header */ | 472 | /* zero-terminate header */ |
423 | colon[0] = '\0'; | 473 | colon[0] = '\0'; |
424 | colon += 2; /* advance to value */ | 474 | colon++; /* advance to value */ |
475 | while ( (colon[0] != '\0') && | ||
476 | ( (colon[0] == ' ') || | ||
477 | (colon[0] == '\t') ) ) | ||
478 | colon++; | ||
479 | /* we do the actual adding of the session | ||
480 | header at the beginning of the while | ||
481 | loop since we need to be able to inspect | ||
482 | the *next* header line (in case it starts | ||
483 | with a space...) */ | ||
484 | } | ||
485 | if (last != NULL) { | ||
425 | MHD_session_add_header(session, | 486 | MHD_session_add_header(session, |
426 | line, | 487 | last, |
427 | colon, | 488 | colon, |
428 | MHD_HEADER_KIND); | 489 | MHD_HEADER_KIND); |
429 | free(line); | 490 | free(last); |
430 | } | 491 | } |
431 | MHD_parse_cookie_header(session); | 492 | MHD_parse_cookie_header(session); |
432 | return; | 493 | return; |
@@ -751,6 +812,8 @@ MHD_session_handle_write(struct MHD_Session * session) { | |||
751 | session->method = NULL; | 812 | session->method = NULL; |
752 | free(session->url); | 813 | free(session->url); |
753 | session->url = NULL; | 814 | session->url = NULL; |
815 | free(session->version); | ||
816 | session->version = NULL; | ||
754 | free(session->write_buffer); | 817 | free(session->write_buffer); |
755 | session->write_buffer = NULL; | 818 | session->write_buffer = NULL; |
756 | session->write_buffer_size = 0; | 819 | session->write_buffer_size = 0; |