X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_api.c;h=66d616d080be6007a694095f890442c3d1f3224a;hp=035c68e5fe6c5a330abbd99b345f0363b8e2d98c;hb=107576b154825ebac44f2cc08d97565a5349eca8;hpb=d4c80d57ea85f763fc5151aa68fab87a3aa4e800 diff --git a/http_api.c b/http_api.c index 035c68e..66d616d 100644 --- a/http_api.c +++ b/http_api.c @@ -1050,7 +1050,8 @@ PHP_HTTP_API char *_http_negotiate_q(const char *entry, const HashTable *support { zval *zaccept, zdelim, zarray, zentries, **zentry, **zsupp; char *q_ptr = NULL, *key = NULL; - int i = 0, idx = 0; + int i = 0; + ulong idx = 0; double qual; HTTP_GSC(zaccept, entry, estrdup(def)); @@ -1533,10 +1534,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 +1549,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 +1601,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) {