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;
}
}
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;
#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)
/* ### 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.
*
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)) {
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;
}
/* }}} */
}
/* }}} */
+/* {{{ 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;
}
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);
</lead>
<date>2006-10-10</date>
<version>
- <release>1.3.2</release>
+ <release>1.3.3dev</release>
<api>1.3.0</api>
</version>
<stability>
</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="/">
#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"
#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);
Status: 404
X-Powered-By: PHP/%s
Content-Type: text/plain
-Content-Disposition:
File not found