- Improved performance of the message and header parser
authorMichael Wallner <mike@php.net>
Fri, 31 Mar 2006 11:07:54 +0000 (11:07 +0000)
committerMichael Wallner <mike@php.net>
Fri, 31 Mar 2006 11:07:54 +0000 (11:07 +0000)
* Fixed internal http_parse_headers() always returning success

http_functions.c
http_headers_api.c
http_info_api.c
package2.xml
php_http_api.h

index aeb41da2482de0316695c67b340968ec4b0a52f3..2cd1dfe554b4d5974253b35efed8eb37e5201186 100644 (file)
@@ -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;
        }
 }
index c778662f5f2029cd36760c883e7fd98512882bc2..7ac475692aff101d66d18fd7d0ca278350686bd6 100644 (file)
@@ -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;
 }
index 5140b6c953fe9cb70f49a6071960865c6ca33132..ec238fb4f937a727796aeefd82cf07eff1a46253 100644 (file)
@@ -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")])))) {
index 425433f4abb127e52dd9dfc9b29d9e2da8275f05..84a78d8a9c0fbcd100ee8133f8b56c96e726354a 100644 (file)
@@ -46,6 +46,8 @@ HttpResponse
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
+- Improved performance of the message and header parser
+* Fixed internal http_parse_headers() always returning success
 * Fixed missing "parentMessage" entry in print_r($HttpMessageObject)
 ]]></notes>
  <contents>
index 573b2a4f835d58ae444f66f09001d1413e0e1be5..f7d7db19f300b57fd92ee1bcfe13489d0f8d1b47 100644 (file)
@@ -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