libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 6bf6682ce48efc246f3d098c1e35de1213509f6b
parent 8a7e30d0304855fc1a0f7a328cf77a6bbb0ae1c2
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon,  9 Jul 2007 02:32:35 +0000

plus is space, support for multi-line headers

Diffstat:
Msrc/daemon/internal.h | 5+++++
Msrc/daemon/session.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/src/daemon/internal.h b/src/daemon/internal.h @@ -176,6 +176,11 @@ struct MHD_Session { char * url; /** + * HTTP version string (i.e. http/1.1) + */ + char * version; + + /** * Buffer for reading requests. */ char * read_buffer; diff --git a/src/daemon/session.c b/src/daemon/session.c @@ -84,8 +84,8 @@ MHD_lookup_session_value(struct MHD_Session * session, pos = session->headers_received; while (pos != NULL) { if ( (0 != (pos->kind & kind)) && - (0 == strcmp(key, - pos->header)) ) + (0 == strcasecmp(key, + pos->header)) ) return pos->value; pos = pos->next; } @@ -227,11 +227,16 @@ MHD_session_add_header(struct MHD_Session * session, session->headers_received = hdr; } +/** + * Process escape sequences ('+'=space, %HH) + */ static void MHD_http_unescape(char * val) { char * esc; unsigned int num; + while (NULL != (esc = strstr(val, "+"))) + *esc = ' '; while (NULL != (esc = strstr(val, "%"))) { if ( (1 == sscanf(&esc[1], "%2x", @@ -344,17 +349,57 @@ MHD_parse_cookie_header(struct MHD_Session * session) { */ static void MHD_parse_session_headers(struct MHD_Session * session) { + char * last; char * line; char * colon; char * uri; char * httpType; char * args; + char * tmp; const char * clen; unsigned long long cval; if (session->bodyReceived == 1) abort(); + last = NULL; while (NULL != (line = MHD_get_next_header_line(session))) { + if (last != NULL) { + if ( (line[0] == ' ') || + (line[0] == '\t') ) { + /* value was continued on the next line, see + http://www.jmarshall.com/easy/http/ */ + if ( (strlen(line) + strlen(last) > + 4 * MHD_MAX_BUF_SIZE) ) { + free(line); + free(last); + last = NULL; + MHD_DLOG(session->daemon, + "Received excessively long header line (>%u), closing connection.\n", + 4 * MHD_MAX_BUF_SIZE); + CLOSE(session->socket_fd); + session->socket_fd = -1; + break; + } + tmp = malloc(strlen(line) + strlen(last) + 1); + strcpy(tmp, last); + free(last); + last = tmp; + tmp = line; + while ( (tmp[0] == ' ') || + (tmp[0] == '\t') ) + tmp++; /* skip whitespace at start of 2nd line */ + strcat(last, tmp); + free(line); + continue; /* possibly more than 2 lines... */ + } else { + MHD_session_add_header(session, + last, + colon, + MHD_HEADER_KIND); + free(last); + last = NULL; + } + } if (session->url == NULL) { /* line must be request line */ uri = strstr(line, " "); @@ -364,8 +409,10 @@ MHD_parse_session_headers(struct MHD_Session * session) { session->method = strdup(line); uri++; httpType = strstr(uri, " "); - if (httpType != NULL) + if (httpType != NULL) { httpType[0] = '\0'; + httpType++; + } args = strstr(uri, "?"); if (args != NULL) { args[0] = '\0'; @@ -374,7 +421,10 @@ MHD_parse_session_headers(struct MHD_Session * session) { args); } session->url = strdup(uri); - /* do we want to do anything with httpType? */ + if (httpType == NULL) + session->version = strdup(""); + else + session->version = strdup(httpType); free(line); continue; } @@ -412,7 +462,7 @@ MHD_parse_session_headers(struct MHD_Session * session) { break; } /* line should be normal header line, find colon */ - colon = strstr(line, ": "); + colon = strstr(line, ":"); if (colon == NULL) { /* error in header line, die hard */ MHD_DLOG(session->daemon, @@ -421,12 +471,23 @@ MHD_parse_session_headers(struct MHD_Session * session) { } /* zero-terminate header */ colon[0] = '\0'; - colon += 2; /* advance to value */ + colon++; /* advance to value */ + while ( (colon[0] != '\0') && + ( (colon[0] == ' ') || + (colon[0] == '\t') ) ) + colon++; + /* we do the actual adding of the session + header at the beginning of the while + loop since we need to be able to inspect + the *next* header line (in case it starts + with a space...) */ + } + if (last != NULL) { MHD_session_add_header(session, - line, + last, colon, MHD_HEADER_KIND); - free(line); + free(last); } MHD_parse_cookie_header(session); return; @@ -751,6 +812,8 @@ MHD_session_handle_write(struct MHD_Session * session) { session->method = NULL; free(session->url); session->url = NULL; + free(session->version); + session->version = NULL; free(session->write_buffer); session->write_buffer = NULL; session->write_buffer_size = 0;