From f554559b173302ed66167d8224023d05c5dabc81 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 17 Oct 2006 14:29:59 +0000 Subject: [PATCH] - fix unsetting response headers --- http_message_api.c | 18 ++------- http_message_object.c | 6 +-- http_response_object.c | 43 +++----------------- http_send_api.c | 80 ++++++++++++++++++++++++++++++++----- package2.xml | 5 +-- php_http.h | 2 +- php_http_send_api.h | 8 ++++ tests/HttpResponse_005.phpt | 1 - 8 files changed, 94 insertions(+), 69 deletions(-) diff --git a/http_message_api.c b/http_message_api.c index 99bc01b..6470725 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -480,24 +480,14 @@ PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC) case HTTP_MSG_RESPONSE: { char *key; + uint len; ulong idx; zval **val; - HashPosition pos1; + HashPosition pos; - FOREACH_HASH_KEYVAL(pos1, &message->hdrs, key, idx, val) { + FOREACH_HASH_KEYLENVAL(pos, &message->hdrs, key, len, idx, val) { if (key) { - if (Z_TYPE_PP(val) == IS_ARRAY) { - zend_bool first = 1; - zval **data; - HashPosition pos2; - - FOREACH_VAL(pos2, *val, data) { - http_send_header_ex(key, strlen(key), Z_STRVAL_PP(data), Z_STRLEN_PP(data), first, NULL); - first = 0; - } - } else { - http_send_header_ex(key, strlen(key), Z_STRVAL_PP(val), Z_STRLEN_PP(val), 1, NULL); - } + http_send_header_zval_ex(key, len-1, val, 1); key = NULL; } } diff --git a/http_message_object.c b/http_message_object.c index edc18a0..c984e96 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -637,13 +637,13 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) case HTTP_MSG_REQUEST: ASSOC_PROP(array, long, "responseCode", 0); ASSOC_STRINGL(array, "responseStatus", "", 0); - ASSOC_STRING(array, "requestMethod", msg->http.info.request.method); - ASSOC_STRING(array, "requestUrl", msg->http.info.request.url); + ASSOC_STRING(array, "requestMethod", msg->http.info.request.method?msg->http.info.request.method:""); + ASSOC_STRING(array, "requestUrl", msg->http.info.request.url?msg->http.info.request.url:""); break; case HTTP_MSG_RESPONSE: ASSOC_PROP(array, long, "responseCode", msg->http.info.response.code); - ASSOC_STRING(array, "responseStatus", msg->http.info.response.status); + ASSOC_STRING(array, "responseStatus", msg->http.info.response.status?msg->http.info.response.status:""); ASSOC_STRINGL(array, "requestMethod", "", 0); ASSOC_STRINGL(array, "requestUrl", "", 0); break; diff --git a/http_response_object.c b/http_response_object.c index 8b00412..52a1dd1 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -33,7 +33,7 @@ #define HTTP_RESPONSE_ME(method, visibility) PHP_ME(HttpResponse, method, HTTP_ARGS(HttpResponse, method), visibility|ZEND_ACC_STATIC) #define HTTP_RESPONSE_ALIAS(method, func) HTTP_STATIC_ME_ALIAS(method, func, HTTP_ARGS(HttpResponse, method)) -HTTP_BEGIN_ARGS(setHeader, 2) +HTTP_BEGIN_ARGS(setHeader, 1) HTTP_ARG_VAL(name, 0) HTTP_ARG_VAL(value, 0) HTTP_ARG_VAL(replace, 0) @@ -232,7 +232,7 @@ static void _http_grab_response_headers(void *data, void *arg TSRMLS_DC) /* ### USERLAND ### */ -/* {{{ proto static bool HttpResponse::setHeader(string name, mixed value[, bool replace = true]) +/* {{{ proto static bool HttpResponse::setHeader(string name[, mixed value[, bool replace = true]]) * * Send an HTTP header. * @@ -251,9 +251,9 @@ PHP_METHOD(HttpResponse, setHeader) zend_bool replace = 1; char *name; int name_len = 0; - zval *value = NULL, *orig = NULL; + zval *value = NULL; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/!|b", &name, &name_len, &value, &replace)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/!b", &name, &name_len, &value, &replace)) { RETURN_FALSE; } if (SG(headers_sent)) { @@ -264,39 +264,8 @@ PHP_METHOD(HttpResponse, setHeader) http_error(HE_WARNING, HTTP_E_HEADER, "Cannot send anonymous headers"); RETURN_FALSE; } - - /* delete header if value == null */ - if (!value || Z_TYPE_P(value) == IS_NULL) { - RETURN_SUCCESS(http_send_header_ex(name, name_len, "", 0, replace, NULL)); - } - /* send multiple header if replace is false and value is an array */ - if (!replace && Z_TYPE_P(value) == IS_ARRAY) { - zval **data; - HashPosition pos; - - FOREACH_VAL(pos, value, data) { - zval *orig = *data; - - convert_to_string_ex(data); - if (SUCCESS != http_send_header_ex(name, name_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), 0, NULL)) { - if (orig != *data) { - zval_ptr_dtor(data); - } - RETURN_FALSE; - } - if (orig != *data) { - zval_ptr_dtor(data); - } - } - RETURN_TRUE; - } - /* send standard header */ - orig = value; - convert_to_string_ex(&value); - RETVAL_SUCCESS(http_send_header_ex(name, name_len, Z_STRVAL_P(value), Z_STRLEN_P(value), replace, NULL)); - if (orig != value) { - zval_ptr_dtor(&value); - } + http_send_header_zval_ex(name, name_len, &value, replace); + RETURN_TRUE; } /* }}} */ diff --git a/http_send_api.c b/http_send_api.c index d1a2ebe..c76656c 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -174,21 +174,81 @@ PHP_MINIT_FUNCTION(http_send) } /* }}} */ +/* {{{ http_find_header */ +typedef struct { + const char *h; + size_t l; +} http_response_header_t; + +static int http_find_header(void *data, void *arg) +{ + http_response_header_t *h = arg; + sapi_header_struct *s = data; + + return (!strncasecmp(s->header, h->h, h->l)) && s->header[h->l] == ':'; +} +/* }}} */ + +/* {{{ void http_hide_header(char *) */ +PHP_HTTP_API void _http_hide_header_ex(const char *name, size_t name_len TSRMLS_DC) +{ + http_response_header_t h = {name, name_len}; + zend_llist_del_element(&SG(sapi_headers).headers, (void *) &h, http_find_header); +} +/* }}} */ + +/* {{{ void http_send_header_zval(char*, zval **, zend_bool) */ +PHP_HTTP_API void _http_send_header_zval_ex(const char *name, size_t name_len, zval **val, zend_bool replace TSRMLS_DC) +{ + if (!val || Z_TYPE_PP(val) == IS_NULL || (Z_TYPE_PP(val) == IS_STRING && !Z_STRLEN_PP(val))) { + http_hide_header_ex(name, name_len); + } else if (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT) { + zend_bool first = replace; + zval **data; + HashPosition pos; + + FOREACH_HASH_VAL(pos, HASH_OF(*val), data) { + zval *orig = *data; + + convert_to_string_ex(data); + http_send_header_ex(name, name_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), first, NULL); + if (orig != *data) { + zval_ptr_dtor(data); + } + first = 0; + } + } else { + zval *orig = *val; + + convert_to_string_ex(val); + http_send_header_ex(name, name_len, Z_STRVAL_PP(val), Z_STRLEN_PP(val), replace, NULL); + if (orig != *val) { + zval_ptr_dtor(val); + } + } +} +/* }}} */ /* {{{ STATUS http_send_header(char *, char *, zend_bool) */ PHP_HTTP_API STATUS _http_send_header_ex(const char *name, size_t name_len, const char *value, size_t value_len, zend_bool replace, char **sent_header TSRMLS_DC) { STATUS ret; - size_t header_len = sizeof(": ") + name_len + value_len + 1; - char *header = emalloc(header_len + 1); - - header[header_len] = '\0'; - header_len = snprintf(header, header_len, "%s: %s", name, value); - ret = http_send_header_string_ex(header, header_len, replace); - if (sent_header) { - *sent_header = header; + + if (value && value_len) { + size_t header_len = sizeof(": ") + name_len + value_len + 1; + char *header = emalloc(header_len + 1); + + header[header_len] = '\0'; + header_len = snprintf(header, header_len, "%s: %s", name, value); + ret = http_send_header_string_ex(header, header_len, replace); + if (sent_header) { + *sent_header = header; + } else { + efree(header); + } } else { - efree(header); + http_hide_header_ex(name, name_len); + ret = SUCCESS; } return ret; } @@ -451,8 +511,8 @@ PHP_HTTP_API STATUS _http_send_stream_ex(php_stream *file, zend_bool close_strea if ((!file) || php_stream_stat(file, &ssb)) { char *defct = sapi_get_default_content_type(TSRMLS_C); + http_hide_header("Content-Disposition"); http_send_content_type(defct, strlen(defct)); - http_send_header_string("Content-Disposition:"); http_error(HE_WARNING, HTTP_E_RESPONSE, "File not found; stat failed"); STR_FREE(defct); diff --git a/package2.xml b/package2.xml index fbf3557..966bc58 100644 --- a/package2.xml +++ b/package2.xml @@ -30,7 +30,7 @@ support. Parallel requests are available for PHP 5 and greater. 2006-10-10 - 1.3.2 + 1.3.3dev 1.3.0 @@ -39,8 +39,7 @@ support. Parallel requests are available for PHP 5 and greater. BSD, revised diff --git a/php_http.h b/php_http.h index a23ac69..531bd38 100644 --- a/php_http.h +++ b/php_http.h @@ -15,7 +15,7 @@ #ifndef PHP_EXT_HTTP_H #define PHP_EXT_HTTP_H -#define PHP_EXT_HTTP_VERSION "1.3.2" +#define PHP_EXT_HTTP_VERSION "1.3.3dev" #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/php_http_send_api.h b/php_http_send_api.h index dd0b50a..98fb37b 100644 --- a/php_http_send_api.h +++ b/php_http_send_api.h @@ -39,6 +39,14 @@ PHP_HTTP_API STATUS _http_send_header_ex(const char *name, size_t name_len, cons #define http_send_status_header_ex(s, h, l, r) _http_send_status_header_ex((s), (h), (l), (r) TSRMLS_CC) PHP_HTTP_API STATUS _http_send_status_header_ex(int status, const char *header, size_t header_len, zend_bool replace TSRMLS_DC); +#define http_send_header_zval(n, z, r) http_send_header_zval_ex((n), strlen(n), (z), (r)) +#define http_send_header_zval_ex(n, l, z, r) _http_send_header_zval_ex((n), (l), (z), (r) TSRMLS_CC) +PHP_HTTP_API void _http_send_header_zval_ex(const char *name, size_t name_len, zval **val, zend_bool replace TSRMLS_DC); + +#define http_hide_header(h) http_hide_header_ex((h), strlen(h)) +#define http_hide_header_ex(h, l) _http_hide_header_ex((h), (l) TSRMLS_CC) +PHP_HTTP_API void _http_hide_header_ex(const char *name, size_t name_len TSRMLS_DC); + #define http_send_last_modified(t) _http_send_last_modified_ex((t), NULL TSRMLS_CC) #define http_send_last_modified_ex(t, s) _http_send_last_modified_ex((t), (s) TSRMLS_CC) PHP_HTTP_API STATUS _http_send_last_modified_ex(time_t t, char **sent_header TSRMLS_DC); diff --git a/tests/HttpResponse_005.phpt b/tests/HttpResponse_005.phpt index e7b2cdb..c43e7f8 100644 --- a/tests/HttpResponse_005.phpt +++ b/tests/HttpResponse_005.phpt @@ -20,6 +20,5 @@ HttpResponse::send(); Status: 404 X-Powered-By: PHP/%s Content-Type: text/plain -Content-Disposition: File not found -- 2.30.2