* rename http_parse_header to http_parse_headers
authorMichael Wallner <mike@php.net>
Thu, 10 Feb 2005 15:55:04 +0000 (15:55 +0000)
committerMichael Wallner <mike@php.net>
Thu, 10 Feb 2005 15:55:04 +0000 (15:55 +0000)
* HTTP_CRLF constant
* smarter http_parse_headers() with support for folded headers

http.c
http_api.c
php_http.h
php_http_api.h

diff --git a/http.c b/http.c
index e7e1960e3b5b5d427e643a0fa19e882837224cb2..6efc142e9745cf43fd8ff9be481736e480d1626c 100644 (file)
--- a/http.c
+++ b/http.c
@@ -71,7 +71,7 @@ function_entry http_functions[] = {
        PHP_FE(http_send_stream, NULL)
        PHP_FE(http_chunked_decode, NULL)
        PHP_FE(http_split_response, NULL)
-       PHP_FE(http_parse_header, NULL)
+       PHP_FE(http_parse_headers, NULL)
 #ifdef HTTP_HAVE_CURL
        PHP_FE(http_get, NULL)
        PHP_FE(http_head, NULL)
@@ -689,8 +689,8 @@ PHP_FUNCTION(http_split_response)
 }
 /* }}} */
 
-/* {{{ proto array http_parse_header(string header) */
-PHP_FUNCTION(http_parse_header)
+/* {{{ proto array http_parse_headers(string header) */
+PHP_FUNCTION(http_parse_headers)
 {
        char *header, *rnrn;
        int header_len;
@@ -698,13 +698,13 @@ PHP_FUNCTION(http_parse_header)
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &header, &header_len)) {
                RETURN_FALSE;
        }
-       
+
        array_init(return_value);
-       
-       if (rnrn = strstr(header, "\r\n\r\n")) {
+
+       if (rnrn = strstr(header, HTTP_CRLF HTTP_CRLF)) {
                header_len = rnrn - header + 2;
        }
-       if (SUCCESS != http_parse_header(header, header_len, return_value)) {
+       if (SUCCESS != http_parse_headers(header, header_len, return_value)) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP header");
                zval_dtor(return_value);
                RETURN_FALSE;
index f68f57e3d6aed62b6a6fec835f46e94ae3b1b286..6d21ca47e524f1601a3972171a5b98607b0b17e0 100644 (file)
@@ -1468,7 +1468,7 @@ PHP_HTTP_API STATUS _http_send_ranges(zval *zranges, const void *data, const siz
        }
 
        /* write boundary once more */
-       php_body_write("\r\n", 1 TSRMLS_CC);
+       php_body_write(HTTP_CRLF, 1 TSRMLS_CC);
        php_body_write(bound, strlen(bound) TSRMLS_CC);
 
        return SUCCESS;
@@ -1616,7 +1616,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded,
        char *d_ptr;
 
        *decoded_len = 0;
-       *decoded = (char *) ecalloc(1, encoded_len);
+       *decoded = (char *) ecalloc(encoded_len, 1);
        d_ptr = *decoded;
        e_ptr = encoded;
 
@@ -1636,8 +1636,22 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded,
                        hex_len[i++] = *e_ptr++;
                }
 
+               /* reached the end */
+               if (!strcmp(hex_len, "0")) {
+                       break;
+               }
+
+               /* new line */
+               if (strncmp(e_ptr, HTTP_CRLF, 2)) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                               "Invalid character (expected 0x0D 0x0A; got: %x %x)",
+                               *e_ptr, *(e_ptr + 1));
+                       efree(*decoded);
+                       return FAILURE;
+               }
+
                /* hex to long */
-               if (strcmp(hex_len, "0")) {
+               {
                        char *error = NULL;
                        chunk_len = strtol(hex_len, &error, 16);
                        if (error == hex_len) {
@@ -1646,20 +1660,9 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded,
                                efree(*decoded);
                                return FAILURE;
                        }
-               } else {
-                       break;
                }
 
-               /* new line */
-               if (*e_ptr++ != '\r' || *e_ptr++ != '\n') {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING,
-                               "Invalid character (expected 0x0A, 0x0D; got: %x)",
-                               *(e_ptr - 1));
-                       efree(*decoded);
-                       return FAILURE;
-               }
-
-               memcpy(d_ptr, e_ptr, chunk_len);
+               memcpy(d_ptr, e_ptr += 2, chunk_len);
                d_ptr += chunk_len;
                e_ptr += chunk_len + 2;
                *decoded_len += chunk_len;
@@ -1693,12 +1696,12 @@ PHP_HTTP_API STATUS _http_split_response(const zval *zresponse, zval *zheaders,
                Z_TYPE_P(zbody) = IS_NULL;
        }
 
-       return http_parse_header(header, body - Z_STRVAL_P(zresponse), zheaders);
+       return http_parse_headers(header, body - Z_STRVAL_P(zresponse), zheaders);
 }
 /* }}} */
 
-/* {{{ STATUS http_parse_header(char *, long, zval *) */
-PHP_HTTP_API STATUS _http_parse_header(char *header, long header_len, zval *array TSRMLS_DC)
+/* {{{ STATUS http_parse_headers(char *, long, zval *) */
+PHP_HTTP_API STATUS _http_parse_headers(char *header, int header_len, zval *array TSRMLS_DC)
 {
        char *colon = NULL, *line = NULL, *begin = header;
 
@@ -1708,30 +1711,27 @@ PHP_HTTP_API STATUS _http_parse_header(char *header, long header_len, zval *arra
 
        /* status code */
        if (!strncmp(header, "HTTP/1.", 7)) {
-               char *end = strstr(header, "\r\n");
+               char *end = strstr(header, HTTP_CRLF);
                add_assoc_stringl(array, "Status",
                        header + strlen("HTTP/1.x "),
                        end - (header + strlen("HTTP/1.x ")), 1);
                header = end + 2;
        }
-
+       
        line = header;
 
-       /*
-        * FIXXME: support for folded headers
-        */
        while (header_len > (line - begin)) {
                switch (*line++)
                {
                        case 0:
-                       case '\r':
-                               if (colon && (*line == '\n')) {
+                       case '\n':
+                               if (colon && (*line != ' ') && (*line != '\t')) {
                                        char *key = estrndup(header, colon - header);
-                                       add_assoc_stringl(array, key, colon + 2, line - colon - 3, 1);
+                                       add_assoc_stringl(array, key, colon + 2, line - colon - 4, 1);
                                        efree(key);
 
                                        colon = NULL;
-                                       header += line - header + 1;
+                                       header += line - header;
                                }
                        break;
 
index d6ac71abcf4db293e40cde168beabde5c0ed4767..b1ecf95d868789c406da437f1a2989dbfc3f22d4 100644 (file)
@@ -56,7 +56,7 @@ PHP_FUNCTION(http_send_file);
 PHP_FUNCTION(http_send_stream);
 PHP_FUNCTION(http_chunked_decode);
 PHP_FUNCTION(http_split_response);
-PHP_FUNCTION(http_parse_header);
+PHP_FUNCTION(http_parse_headers);
 #ifdef HTTP_HAVE_CURL
 PHP_FUNCTION(http_get);
 PHP_FUNCTION(http_head);
index de7714c34a3a667d3ea5011990e48f0605762408..101857e004b5ab5b2e409780508c7032aba85b71 100644 (file)
@@ -46,6 +46,9 @@ typedef enum {
 } http_send_mode;
 /* }}} */
 
+/* CR LF */
+#define HTTP_CRLF "\r\n"
+
 /* max URI length */
 #define HTTP_URI_MAXLEN 2048
 
@@ -152,8 +155,8 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, const size_t encod
 #define http_split_response(r, h, b) _http_split_response((r), (h), (b) TSRMLS_CC)
 PHP_HTTP_API STATUS _http_split_response(const zval *zresponse, zval *zheaders, zval *zbody TSRMLS_DC);
 
-#define http_parse_header(h, l, a) _http_parse_header((h), (l), (a) TSRMLS_CC)
-PHP_HTTP_API STATUS _http_parse_header(char *header, long header_len, zval *array TSRMLS_DC);
+#define http_parse_headers(h, l, a) _http_parse_headers((h), (l), (a) TSRMLS_CC)
+PHP_HTTP_API STATUS _http_parse_headers(char *header, int header_len, zval *array TSRMLS_DC);
 
 /* {{{ HAVE_CURL */
 #ifdef HTTP_HAVE_CURL