From 9f564f1bb81519679a4cb362b868e9b1f93cd8a8 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 24 Mar 2005 16:30:12 +0000 Subject: [PATCH] * added http_parse_cookie() * http_parse_headers() now makes an array out of headers with equal name --- http_api.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++--- php_http_api.h | 3 ++ 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/http_api.c b/http_api.c index 035c68e..5b23de2 100644 --- a/http_api.c +++ b/http_api.c @@ -1533,10 +1533,12 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, /* skip empty key */ if (header != colon) { - char *key = estrndup(header, colon - header); + zval **previous = NULL; + int keylen = colon - header; + char *key = estrndup(header, keylen); if (prettify) { - key = pretty_key(key, colon - header, 1, 1); + key = pretty_key(key, keylen, 1, 1); } value_len += line - colon - 1; @@ -1546,11 +1548,37 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, /* skip trailing ws */ while (isspace(colon[value_len - 1])) --value_len; - if (value_len < 1) { + /* 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) { + if (value_len > 0) { + add_next_index_stringl(*previous, colon, value_len, 1); + } else { + add_next_index_stringl(*previous, "", 0, 1); + } + } 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); + if (value_len > 0) { + add_next_index_stringl(new_array, colon, value_len, 1); + } else { + add_next_index_stringl(new_array, "", 0, 1); + } + + add_assoc_zval(&array, key, new_array); + } + + previous = NULL; + } else if (value_len > 0) { + add_assoc_stringl(&array, key, colon, value_len, 1); + } else { /* hm, empty header? */ add_assoc_stringl(&array, key, "", 0, 1); - } else { - add_assoc_stringl(&array, key, colon, value_len, 1); } efree(key); } @@ -1572,6 +1600,78 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, } /* }}} */ +/* {{{ */ +PHP_HTTP_API STATUS _http_parse_cookie(const char *cookie, HashTable *values TSRMLS_DC) +{ + const char *key = cookie, *val = NULL; + int vallen = 0, keylen = 0, done = 0; + zval array; + + Z_ARRVAL(array) = values; + + if (!(val = strchr(cookie, '='))) { + return FAILURE; + } + +#define HTTP_COOKIE_VAL(array, k, str, len) \ + { \ + const char *encoded = str; \ + char *decoded = NULL; \ + int decoded_len = 0, encoded_len = len; \ + decoded = estrndup(encoded, encoded_len); \ + decoded_len = php_url_decode(decoded, encoded_len); \ + add_assoc_stringl(array, k, decoded, decoded_len, 0); \ + } +#define HTTP_COOKIE_FIXKEY() \ + { \ + while (isspace(*key)) ++key; \ + keylen = val - key; \ + while (isspace(key[keylen - 1])) --keylen; \ + } +#define HTTP_COOKIE_FIXVAL() \ + { \ + ++val; \ + while (isspace(*val)) ++val; \ + vallen = key - val; \ + while (isspace(val[vallen - 1])) --vallen; \ + } + + HTTP_COOKIE_FIXKEY(); + HTTP_COOKIE_VAL(&array, "name", key, keylen); + + /* just a name=value cookie */ + if (!(key = strchr(val, ';'))) { + key = val + strlen(val); + HTTP_COOKIE_FIXVAL(); + HTTP_COOKIE_VAL(&array, "value", val, vallen); + } + /* additional info appended */ + else { + char *keydup = NULL; + + HTTP_COOKIE_FIXVAL(); + HTTP_COOKIE_VAL(&array, "value", val, vallen); + + do { + if (!(val = strchr(key, '='))) { + break; + } + ++key; + HTTP_COOKIE_FIXKEY(); + keydup = estrndup(key, keylen); + if (!(key = strchr(val, ';'))) { + done = 1; + key = val + strlen(val); + } + HTTP_COOKIE_FIXVAL(); + HTTP_COOKIE_VAL(&array, keydup, val, vallen); + efree(keydup); + } while (!done); + } + return SUCCESS; +} +/* }}} */ + /* {{{ void http_get_request_headers_ex(HashTable *, zend_bool) */ PHP_HTTP_API void _http_get_request_headers_ex(HashTable *headers, zend_bool prettify TSRMLS_DC) { diff --git a/php_http_api.h b/php_http_api.h index e9898ce..baa8860 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -144,6 +144,9 @@ PHP_HTTP_API STATUS _http_split_response_ex(char *response, size_t repsonse_len, #define http_parse_headers_ex(h, l, ht, p) _http_parse_headers_ex((h), (l), (ht), (p) TSRMLS_CC) PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, HashTable *headers, zend_bool prettify TSRMLS_DC); +#define http_parse_cookie(c, ht) _http_parse_cookie((c), (ht) TSRMLS_CC) +PHP_HTTP_API STATUS _http_parse_cookie(const char *cookie, HashTable *values TSRMLS_DC); + #define http_get_request_headers(h) _http_get_request_headers_ex(Z_ARRVAL_P(h), 1 TSRMLS_CC) #define http_get_request_headers_ex(h, p) _http_get_request_headers_ex((h), (s) TSRMLS_CC) PHP_HTTP_API void _http_get_request_headers_ex(HashTable *headers, zend_bool prettify TSRMLS_DC); -- 2.30.2