- fix unsetting response headers
authorMichael Wallner <mike@php.net>
Tue, 17 Oct 2006 14:29:59 +0000 (14:29 +0000)
committerMichael Wallner <mike@php.net>
Tue, 17 Oct 2006 14:29:59 +0000 (14:29 +0000)
http_message_api.c
http_message_object.c
http_response_object.c
http_send_api.c
package2.xml
php_http.h
php_http_send_api.h
tests/HttpResponse_005.phpt

index 99bc01b30bc0b0a90ddd99989681672afb6e0f49..64707254587b7b1b363c9859624f6cc6ea3e60cd 100644 (file)
@@ -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;
                                }
                        }
index edc18a0499d549d1a7c026afd1e25c51e36aef2c..c984e960fa00a34e2da1a78f282c55784d1e8443 100644 (file)
@@ -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;
index 8b00412771d531ee6c6e051e6c9fadc119354ebb..52a1dd1cc1efc4b7f62ee5ed79976103c1c3adc5 100644 (file)
@@ -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;
 }
 /* }}} */
 
index d1a2ebeb08d3234c4dce327210b3c26cabbcb954..c76656ce7f0d084eacfab2535f0732d9e03e00c6 100644 (file)
@@ -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);
                
index fbf355756ab06f72c4e9396abda5bc42ba2ecf4e..966bc5895e01a53b76592735c0d621e91726a6a3 100644 (file)
@@ -30,7 +30,7 @@ support. Parallel requests are available for PHP 5 and greater.
  </lead>
  <date>2006-10-10</date>
  <version>
-  <release>1.3.2</release>
+  <release>1.3.3dev</release>
   <api>1.3.0</api>
  </version>
  <stability>
@@ -39,8 +39,7 @@ support. Parallel requests are available for PHP 5 and greater.
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
-* Fixed invalid detection whether a deflated response should be started
-* Fixed build --without-http-zlib-compression (bug #8872)
+* Fixed HttpResponse::setHeader("name", {omitted|NULL|""}) not unsetting header
 ]]></notes>
  <contents>
   <dir name="/">
index a23ac69f942d74260580ae67aa8afeb89a71a8f0..531bd388b170416a73dfec14265dc8534bc04ce8 100644 (file)
@@ -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"
index dd0b50a0db2ca9f2f8a548991519dd2b743e777b..98fb37b8f0692007e114f1cda3bcc5a94c8baf4a 100644 (file)
@@ -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);
index e7b2cdbbe764806480008dcc49dbc6b7d261cbb2..c43e7f819330591c0d1d241b918dbf0afd90d354 100644 (file)
@@ -20,6 +20,5 @@ HttpResponse::send();
 Status: 404
 X-Powered-By: PHP/%s
 Content-Type: text/plain
-Content-Disposition:
 
 File not found