From f41f0417afd1d0ad0609fde76a99d907117ed669 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 31 Mar 2006 11:07:54 +0000 Subject: [PATCH] - Improved performance of the message and header parser * Fixed internal http_parse_headers() always returning success --- http_functions.c | 1 + http_headers_api.c | 18 ++++++------------ http_info_api.c | 2 +- package2.xml | 2 ++ php_http_api.h | 23 ++++++++++++++--------- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/http_functions.c b/http_functions.c index aeb41da..2cd1dfe 100644 --- a/http_functions.c +++ b/http_functions.c @@ -1034,6 +1034,7 @@ PHP_FUNCTION(http_parse_headers) array_init(return_value); if (SUCCESS != http_parse_headers(header, return_value)) { zval_dtor(return_value); + http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Failed to parse headers"); RETURN_FALSE; } } diff --git a/http_headers_api.c b/http_headers_api.c index c778662..7ac4756 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -326,22 +326,14 @@ PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *headers, zend_bool prettify, http_info_callback callback_func, void **callback_data TSRMLS_DC) { - const char *colon = NULL, *line = NULL, *begin = header; - const char *body = http_locate_body(header); - size_t header_len; + const char *colon = NULL, *line = header; zval array; INIT_ZARR(array, headers); - if (body) { - header_len = body - header; - } else { - header_len = strlen(header) + 1; - } - line = header; - - if (header_len) do { + do { int value_len = 0; + switch (*line++) { case ':': @@ -403,6 +395,8 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *header } efree(key); } + } else { + return FAILURE; } colon = NULL; value_len = 0; @@ -410,7 +404,7 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *header } break; } - } while (header_len > (size_t) (line - begin)); + } while (*(line-1) && !(*(line-1) == '\n' && (*line == '\n' || *line == '\r'))); return SUCCESS; } diff --git a/http_info_api.c b/http_info_api.c index 5140b6c..ec238fb 100644 --- a/http_info_api.c +++ b/http_info_api.c @@ -75,7 +75,7 @@ PHP_HTTP_API STATUS _http_info_parse_ex(const char *pre_header, http_info *info, /* there must be HTTP/1.x in the line * and nothing than SPACE or NUL after HTTP/1.x */ - if ( (!(http = strstr(pre_header, "HTTP/1."))) || + if ( (!(http = php_memnstr((char *) pre_header, "HTTP/1.", lenof("HTTP/1."), (char *)end))) || (!(http < end)) || (!isdigit(http[lenof("HTTP/1.")])) || (http[lenof("HTTP/1.1")] && (!isspace(http[lenof("HTTP/1.1")])))) { diff --git a/package2.xml b/package2.xml index 425433f..84a78d8 100644 --- a/package2.xml +++ b/package2.xml @@ -46,6 +46,8 @@ HttpResponse BSD, revised diff --git a/php_http_api.h b/php_http_api.h index 573b2a4..f7d7db1 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -122,16 +122,21 @@ PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D); #define http_locate_body _http_locate_body static inline const char *_http_locate_body(const char *message) { - const char *cr = strstr(message, "\r\n\r\n"); - const char *lf = strstr(message, "\n\n"); - - if (lf && cr) { - return MIN(lf + 2, cr + 4); - } else if (lf || cr) { - return MAX(lf + 2, cr + 4); - } else { - return NULL; + const char *body = NULL, *msg = message; + + while (*msg) { + if (*msg == '\n') { + if (*(msg+1) == '\n') { + body = msg + 2; + break; + } else if (*(msg+1) == '\r' && *(msg+2) == '\n' && msg != message && *(msg-1) == '\r') { + body = msg + 3; + break; + } + } + ++msg; } + return body; } #define http_locate_eol _http_locate_eol -- 2.30.2