X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=http_send_api.c;h=1fe1d4d913433791a3cac81f49d28618ddafa156;hb=5b55dee0720e8969d8b6ddd7fa3ef7a7f415abcc;hp=0c1fe57cfdbcadbd0d12a6183ee6debf365837f3;hpb=82e177a071d35372367f9f5255b3e2c553c8bffd;p=m6w6%2Fext-http diff --git a/http_send_api.c b/http_send_api.c index 0c1fe57..1fe1d4d 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -51,7 +51,7 @@ static inline void _http_send_response_start(void **buffer, size_t content_lengt { int encoding; - if ((encoding = http_encoding_response_start(content_length))) { + if ((encoding = http_encoding_response_start(content_length, 0))) { #ifdef HTTP_HAVE_ZLIB *buffer = http_encoding_deflate_stream_init(NULL, (encoding == HTTP_ENCODING_GZIP) ? @@ -65,7 +65,7 @@ static inline void _http_send_response_start(void **buffer, size_t content_lengt #define http_send_response_data_plain(b, d, dl) _http_send_response_data_plain((b), (d), (dl) TSRMLS_CC) static inline void _http_send_response_data_plain(void **buffer, const char *data, size_t data_len TSRMLS_DC) { - if (HTTP_G->send.deflate.encoding) { + if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) { #ifdef HTTP_HAVE_ZLIB char *encoded; size_t encoded_len; @@ -137,7 +137,7 @@ static inline void _http_send_response_data_fetch(void **buffer, const void *dat #define http_send_response_finish(b) _http_send_response_finish((b) TSRMLS_CC) static inline void _http_send_response_finish(void **buffer TSRMLS_DC) { - if (HTTP_G->send.deflate.encoding) { + if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) { #ifdef HTTP_HAVE_ZLIB char *encoded = NULL; size_t encoded_len = 0; @@ -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 || !*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);