- win32 build now has libcurl v7.16.0
[m6w6/ext-http] / http_send_api.c
index 2be92b62dec675c02fd141aaeb65dc3c30ac0391..1fe1d4d913433791a3cac81f49d28618ddafa156 100644 (file)
@@ -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 && *(http_encoding_stream **) buffer) {
+       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 && *(http_encoding_stream **) buffer) {
+       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);