X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_headers_api.c;h=933b4c8b003922b4490e8a442fd2dac30a20c8ae;hp=f820a1355891f7d2c7d45f0c836f3bfda9547187;hb=1076272e2da97d6df6c2f2423b92a1694709e65a;hpb=0ac32c9b8590e88a5f110cc8b3154001d5c0c089 diff --git a/http_headers_api.c b/http_headers_api.c index f820a13..933b4c8 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -22,6 +22,8 @@ #include #include "php.h" +#include "ext/standard/php_string.h" +#include "ext/standard/url.h" #include "php_http.h" #include "php_http_std_defs.h" @@ -237,10 +239,11 @@ PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_ /* }}} */ /* {{{ STATUS http_parse_headers(char *, size_t, HashTable *, zend_bool) */ -PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, size_t header_len, - HashTable *headers, zend_bool prettify TSRMLS_DC) +PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, + HashTable *headers, zend_bool prettify, + http_parse_headers_callback_t func, void **callback_data TSRMLS_DC) { - const char *colon = NULL, *line = NULL, *begin = header; + char *colon = NULL, *line = NULL, *begin = header; zval array; Z_ARRVAL(array) = headers; @@ -249,16 +252,6 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, size_t header_len return FAILURE; } - /* status code */ - if (!strncmp(header, "HTTP/1.", 7)) { - char *end = strstr(header, HTTP_CRLF); - size_t len = end - (header + lenof("HTTP/1.x ")); - char *val = estrndup(header + lenof("HTTP/1.x "), len); - - add_assoc_stringl(&array, "Status", val, len, 0); - header = end + 2; - } - line = header; while (header_len >= (line - begin)) { @@ -269,55 +262,66 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, size_t header_len case 0: --value_len; /* we don't have CR so value length is one char less */ case '\n': - if (colon && ((!(*line - 1)) || ((*line != ' ') && (*line != '\t')))) { - - /* skip empty key */ - if (header != colon) { - zval **previous = NULL; - char *value = empty_string; - int keylen = colon - header; - char *key = estrndup(header, keylen); - - if (prettify) { - key = pretty_key(key, keylen, 1, 1); + if ((!(*line - 1)) || ((*line != ' ') && (*line != '\t'))) { + /* response/request line */ + if ( (!strncmp(header, "HTTP/1.", lenof("HTTP/1."))) || + (!strncmp(line - lenof("HTTP/1.x\r") + value_len, "HTTP/1.", lenof("HTTP/1.")))) { + if (func) { + func(callback_data, header, header - (line + 1), &headers TSRMLS_CC); + Z_ARRVAL(array) = headers; } + } else + + /* "header: value" pair */ + if (colon) { + + /* skip empty key */ + if (header != colon) { + zval **previous = NULL; + char *value = empty_string; + int keylen = colon - header; + char *key = estrndup(header, keylen); + + if (prettify) { + key = pretty_key(key, keylen, 1, 1); + } - value_len += line - colon - 1; - - /* skip leading ws */ - while (isspace(*(++colon))) --value_len; - /* skip trailing ws */ - while (isspace(colon[value_len - 1])) --value_len; + value_len += line - colon - 1; - if (value_len > 0) { - value = estrndup(colon, value_len); - } else { - value_len = 0; - } + /* skip leading ws */ + while (isspace(*(++colon))) --value_len; + /* skip trailing ws */ + while (isspace(colon[value_len - 1])) --value_len; - /* if we already have got such a header make an array of those */ - if (SUCCESS == zend_hash_find(headers, key, keylen + 1, (void **) &previous)) { - /* already an array? - just add */ - if (Z_TYPE_PP(previous) == IS_ARRAY) { - add_next_index_stringl(*previous, value, value_len, 0); + if (value_len > 0) { + value = estrndup(colon, value_len); } else { - /* create the array */ - zval *new_array; - MAKE_STD_ZVAL(new_array); - array_init(new_array); - - add_next_index_stringl(new_array, Z_STRVAL_PP(previous), Z_STRLEN_PP(previous), 1); - add_next_index_stringl(new_array, value, value_len, 0); - add_assoc_zval(&array, key, new_array); + value_len = 0; } - previous = NULL; - } else { - add_assoc_stringl(&array, key, value, value_len, 0); + /* if we already have got such a header make an array of those */ + if (SUCCESS == zend_hash_find(headers, key, keylen + 1, (void **) &previous)) { + /* already an array? - just add */ + if (Z_TYPE_PP(previous) == IS_ARRAY) { + add_next_index_stringl(*previous, value, value_len, 0); + } else { + /* create the array */ + zval *new_array; + MAKE_STD_ZVAL(new_array); + array_init(new_array); + + add_next_index_stringl(new_array, Z_STRVAL_PP(previous), Z_STRLEN_PP(previous), 1); + add_next_index_stringl(new_array, value, value_len, 0); + add_assoc_zval(&array, key, new_array); + } + + previous = NULL; + } else { + add_assoc_stringl(&array, key, value, value_len, 0); + } + efree(key); } - efree(key); } - colon = NULL; value_len = 0; header += line - header; @@ -335,6 +339,24 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, size_t header_len } /* }}} */ +PHP_HTTP_API void _http_parse_headers_default_callback(void **cb_data, char *http_line, size_t line_length, HashTable **headers TSRMLS_DC) +{ + zval array; + Z_ARRVAL(array) = *headers; + + /* response */ + if (!strncmp(http_line, "HTTP/1.", lenof("HTTP/1."))) { + add_assoc_stringl(&array, "Response Status", http_line + lenof("HTTP/1.x "), line_length - lenof("HTTP/1.x \r\n"), 0); + } else + /* request */ + if (!strncmp(http_line + line_length - lenof("HTTP/1.x\r\n"), "HTTP/1.", lenof("HTTP/1."))) { + char *sep = strchr(http_line, ' '); + + add_assoc_stringl(&array, "Request Method", http_line, sep - http_line, 1); + add_assoc_stringl(&array, "Request Uri", sep + 1, strstr(sep, "HTTP/1.") - sep + 1 + 1, 1); + } +} + /* {{{ */ PHP_HTTP_API STATUS _http_parse_cookie(const char *cookie, HashTable *values TSRMLS_DC) {