From 96d32e2bd4a5d2b0741addf6f59b46d7d8749937 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 10 Feb 2005 15:55:04 +0000 Subject: [PATCH] * rename http_parse_header to http_parse_headers * HTTP_CRLF constant * smarter http_parse_headers() with support for folded headers --- http.c | 14 ++++++------- http_api.c | 54 +++++++++++++++++++++++++------------------------- php_http.h | 2 +- php_http_api.h | 7 +++++-- 4 files changed, 40 insertions(+), 37 deletions(-) diff --git a/http.c b/http.c index e7e1960..6efc142 100644 --- 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; diff --git a/http_api.c b/http_api.c index f68f57e..6d21ca4 100644 --- a/http_api.c +++ b/http_api.c @@ -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; diff --git a/php_http.h b/php_http.h index d6ac71a..b1ecf95 100644 --- a/php_http.h +++ b/php_http.h @@ -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); diff --git a/php_http_api.h b/php_http_api.h index de7714c..101857e 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -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 -- 2.30.2