aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2007-07-09 02:32:35 +0000
committerChristian Grothoff <christian@grothoff.org>2007-07-09 02:32:35 +0000
commit6bf6682ce48efc246f3d098c1e35de1213509f6b (patch)
treec656681eec37c8f9aed6181c093b089a4f4eded9
parent8a7e30d0304855fc1a0f7a328cf77a6bbb0ae1c2 (diff)
downloadlibmicrohttpd-6bf6682ce48efc246f3d098c1e35de1213509f6b.tar.gz
libmicrohttpd-6bf6682ce48efc246f3d098c1e35de1213509f6b.zip
plus is space, support for multi-line headers
-rw-r--r--src/daemon/internal.h5
-rw-r--r--src/daemon/session.c79
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 */
230static void 233static void
231MHD_http_unescape(char * val) { 234MHD_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 */
345static void 350static void
346MHD_parse_session_headers(struct MHD_Session * session) { 351MHD_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;