From 68a779badeace396e3a86caf9cb86b7e70ff636a Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 9 Feb 2005 20:10:20 +0000 Subject: [PATCH] * separate http_parse_header() function (doesn't support folded headers yet) --- http.c | 29 +++++++++++++++++++- http_api.c | 72 ++++++++++++++++++++++++++++++-------------------- php_http.h | 1 + php_http_api.h | 5 +++- 4 files changed, 76 insertions(+), 31 deletions(-) diff --git a/http.c b/http.c index e432ef0..e7e1960 100644 --- a/http.c +++ b/http.c @@ -71,6 +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) #ifdef HTTP_HAVE_CURL PHP_FE(http_get, NULL) PHP_FE(http_head, NULL) @@ -677,7 +678,10 @@ PHP_FUNCTION(http_split_response) MAKE_STD_ZVAL(zheaders); array_init(zheaders); - http_split_response(zresponse, zheaders, zbody); + if (SUCCESS != http_split_response(zresponse, zheaders, zbody)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP response"); + RETURN_FALSE; + } array_init(return_value); add_index_zval(return_value, 0, zheaders); @@ -685,6 +689,29 @@ PHP_FUNCTION(http_split_response) } /* }}} */ +/* {{{ proto array http_parse_header(string header) */ +PHP_FUNCTION(http_parse_header) +{ + char *header, *rnrn; + int header_len; + + 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")) { + header_len = rnrn - header + 2; + } + if (SUCCESS != http_parse_header(header, header_len, return_value)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP header"); + zval_dtor(return_value); + RETURN_FALSE; + } +} +/* }}}*/ + /* {{{ HAVE_CURL */ #ifdef HTTP_HAVE_CURL diff --git a/http_api.c b/http_api.c index 9cb81ba..f68f57e 100644 --- a/http_api.c +++ b/http_api.c @@ -1669,8 +1669,8 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, } /* }}} */ -/* {{{ proto void http_split_response(zval *, zval *, zval *) */ -PHP_HTTP_API void _http_split_response(const zval *zresponse, zval *zheaders, +/* {{{ proto STATUS http_split_response(zval *, zval *, zval *) */ +PHP_HTTP_API STATUS _http_split_response(const zval *zresponse, zval *zheaders, zval *zbody TSRMLS_DC) { char *header, *response, *body = NULL; @@ -1693,42 +1693,56 @@ PHP_HTTP_API void _http_split_response(const zval *zresponse, zval *zheaders, Z_TYPE_P(zbody) = IS_NULL; } - /* check for HTTP status - FIXXME: strchr() */ + return http_parse_header(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) +{ + char *colon = NULL, *line = NULL, *begin = header; + + if (header_len < 8) { + return FAILURE; + } + + /* status code */ if (!strncmp(header, "HTTP/1.", 7)) { - char *end = strchr(header, '\r'); - add_assoc_stringl(zheaders, "Status", + char *end = strstr(header, "\r\n"); + add_assoc_stringl(array, "Status", header + strlen("HTTP/1.x "), end - (header + strlen("HTTP/1.x ")), 1); header = end + 2; } - /* split headers */ - { - char *colon = NULL, *line = header; - while ( (line - Z_STRVAL_P(zresponse) + 3) < - (body - Z_STRVAL_P(zresponse))) { - switch (*line++) - { - case '\r': - if (colon && (*line == '\n')) { - char *key = estrndup(header, colon - header); - add_assoc_stringl(zheaders, key, - colon + 2, line - colon - 3, 1); - efree(key); - - colon = NULL; - header += line - header + 1; - } - break; + line = header; - case ':': - if (!colon) { - colon = line - 1; - } - break; - } + /* + * FIXXME: support for folded headers + */ + while (header_len > (line - begin)) { + switch (*line++) + { + case 0: + case '\r': + if (colon && (*line == '\n')) { + char *key = estrndup(header, colon - header); + add_assoc_stringl(array, key, colon + 2, line - colon - 3, 1); + efree(key); + + colon = NULL; + header += line - header + 1; + } + break; + + case ':': + if (!colon) { + colon = line - 1; + } + break; } } + return SUCCESS; } /* }}} */ diff --git a/php_http.h b/php_http.h index cf955a8..d6ac71a 100644 --- a/php_http.h +++ b/php_http.h @@ -56,6 +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); #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 61ae827..de7714c 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -150,7 +150,10 @@ PHP_HTTP_API STATUS _http_send_file(const zval *zfile TSRMLS_DC); PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, const size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC); #define http_split_response(r, h, b) _http_split_response((r), (h), (b) TSRMLS_CC) -PHP_HTTP_API void _http_split_response(const zval *zresponse, zval *zheaders, zval *zbody TSRMLS_DC); +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); /* {{{ HAVE_CURL */ #ifdef HTTP_HAVE_CURL -- 2.30.2