- add missing support for raw post data (HttpRequest)
[m6w6/ext-http] / http_response_object.c
index f4528f828252390421b0d64f83ba2cf1a9079c4d..68de2a43fde6a82cc9800fe3804e013a23761e25 100644 (file)
 #endif
 #include "php.h"
 
-#ifdef ZEND_ENGINE_2
+#include "missing.h"
+
+/* broken static properties in PHP 5.0 */
+#if defined(ZEND_ENGINE_2) && !defined(WONKY)
 
 #include "SAPI.h"
 #include "php_ini.h"
-#include "ext/standard/head.h"
 
 #include "php_http.h"
 #include "php_http_api.h"
 #include "php_http_send_api.h"
 #include "php_http_cache_api.h"
 
-#include "missing.h"
-
 ZEND_EXTERN_MODULE_GLOBALS(http);
 
-#define USE_STATIC_PROP()              USE_STATIC_PROP_EX(http_response_object_ce)
-#define GET_STATIC_PROP(n)             *GET_STATIC_PROP_EX(http_response_object_ce, n)
-#define SET_STATIC_PROP(n, v)  SET_STATIC_PROP_EX(http_response_object_ce, n, v)
-#define SET_STATIC_PROP_STRING(n, s, d) SET_STATIC_PROP_STRING_EX(http_response_object_ce, n, s, d)
-#define SET_STATIC_PROP_STRINGL(n, s, l, d) SET_STATIC_PROP_STRINGL_EX(http_response_object_ce, n, s, l, d)
+#define GET_STATIC_PROP(n)                     *GET_STATIC_PROP_EX(http_response_object_ce, n)
+#define UPD_STATIC_PROP(t, n, v)       UPD_STATIC_PROP_EX(http_response_object_ce, t, n, v)
+#define SET_STATIC_PROP(n, v)          SET_STATIC_PROP_EX(http_response_object_ce, n, v)
+#define UPD_STATIC_STRL(n, v, l)       UPD_STATIC_STRL_EX(http_response_object_ce, n, v, l)
 
 #define HTTP_BEGIN_ARGS(method, req_args)              HTTP_BEGIN_ARGS_EX(HttpResponse, method, 0, req_args)
 #define HTTP_EMPTY_ARGS(method, ret_ref)               HTTP_EMPTY_ARGS_EX(HttpResponse, method, ret_ref)
@@ -65,6 +64,11 @@ HTTP_BEGIN_ARGS(setETag, 1)
        HTTP_ARG_VAL(etag, 0)
 HTTP_END_ARGS;
 
+HTTP_EMPTY_ARGS(getLastModified, 0);
+HTTP_BEGIN_ARGS(setLastModified, 1)
+       HTTP_ARG_VAL(timestamp, 0)
+HTTP_END_ARGS;
+
 HTTP_EMPTY_ARGS(getCache, 0);
 HTTP_BEGIN_ARGS(setCache, 1)
        HTTP_ARG_VAL(cache, 0)
@@ -86,6 +90,11 @@ HTTP_BEGIN_ARGS(setContentType, 1)
        HTTP_ARG_VAL(content_type, 0)
 HTTP_END_ARGS;
 
+HTTP_BEGIN_ARGS(guessContentType, 1)
+       HTTP_ARG_VAL(magic_file, 0)
+       HTTP_ARG_VAL(magic_mode, 0)
+HTTP_END_ARGS;
+
 HTTP_EMPTY_ARGS(getContentDisposition, 0);
 HTTP_BEGIN_ARGS(setContentDisposition, 1)
        HTTP_ARG_VAL(filename, 0)
@@ -140,8 +149,6 @@ HTTP_EMPTY_ARGS(getRequestBody, 0);
 #define http_response_object_declare_default_properties() _http_response_object_declare_default_properties(TSRMLS_C)
 static inline void _http_response_object_declare_default_properties(TSRMLS_D);
 
-HashTable http_response_statics;
-
 zend_class_entry *http_response_object_ce;
 zend_function_entry http_response_object_fe[] = {
 
@@ -150,12 +157,17 @@ zend_function_entry http_response_object_fe[] = {
 
        HTTP_RESPONSE_ME(setETag, ZEND_ACC_PUBLIC)
        HTTP_RESPONSE_ME(getETag, ZEND_ACC_PUBLIC)
+       
+       HTTP_RESPONSE_ME(setLastModified, ZEND_ACC_PUBLIC)
+       HTTP_RESPONSE_ME(getLastModified, ZEND_ACC_PUBLIC)
 
        HTTP_RESPONSE_ME(setContentDisposition, ZEND_ACC_PUBLIC)
        HTTP_RESPONSE_ME(getContentDisposition, ZEND_ACC_PUBLIC)
 
        HTTP_RESPONSE_ME(setContentType, ZEND_ACC_PUBLIC)
        HTTP_RESPONSE_ME(getContentType, ZEND_ACC_PUBLIC)
+       
+       HTTP_RESPONSE_ME(guessContentType, ZEND_ACC_PUBLIC)
 
        HTTP_RESPONSE_ME(setCache, ZEND_ACC_PUBLIC)
        HTTP_RESPONSE_ME(getCache, ZEND_ACC_PUBLIC)
@@ -189,7 +201,7 @@ zend_function_entry http_response_object_fe[] = {
        HTTP_RESPONSE_ALIAS(getRequestHeaders, http_get_request_headers)
        HTTP_RESPONSE_ALIAS(getRequestBody, http_get_request_body)
 
-       {NULL, NULL, NULL}
+       EMPTY_FUNCTION_ENTRY
 };
 
 void _http_response_object_init(INIT_FUNC_ARGS)
@@ -239,7 +251,6 @@ PHP_METHOD(HttpResponse, setHeader)
                RETURN_FALSE;
        }
 
-       USE_STATIC_PROP();
        headers = GET_STATIC_PROP(headers);
 
        if (Z_TYPE_P(headers) != IS_ARRAY) {
@@ -256,7 +267,7 @@ PHP_METHOD(HttpResponse, setHeader)
        }
 
        /* convert old header to an array and add new one if header exists and replace == false */
-       if (replace || SUCCESS != zend_hash_find(Z_ARRVAL_P(headers), name, name_len + 1, (void **) &header)) {
+       if (replace || (SUCCESS != zend_hash_find(Z_ARRVAL_P(headers), name, name_len + 1, (void **) &header))) {
                RETURN_SUCCESS(add_assoc_stringl_ex(headers, name, name_len + 1, Z_STRVAL_P(value), Z_STRLEN_P(value), 1));
        } else {
                convert_to_array(*header);
@@ -286,7 +297,7 @@ PHP_METHOD(HttpResponse, getHeader)
                array_init(return_value);
                array_copy(headers, return_value);
        } else if (SUCCESS == zend_hash_find(Z_ARRVAL_P(headers), name, name_len + 1, (void **) &header)) {
-               RETURN_ZVAL(*header, ZVAL_PTR_DTOR, 1);
+               RETURN_ZVAL(*header, 1, 0);
        } else {
                RETURN_NULL();
        }
@@ -311,8 +322,7 @@ PHP_METHOD(HttpResponse, setCache)
                RETURN_FALSE;
        }
 
-       ZVAL_BOOL(GET_STATIC_PROP(cache), do_cache);
-       RETURN_TRUE;
+       RETURN_SUCCESS(UPD_STATIC_PROP(bool, cache, do_cache));
 }
 /* }}} */
 
@@ -332,7 +342,7 @@ PHP_METHOD(HttpResponse, getCache)
 
 /* {{{ proto static bool HttpResponse::setGzip(bool gzip)
  *
- * Enable on-thy-fly gzipping of the sent entity. NOT IMPLEMENTED YET.
+ * Enable on-thy-fly gzipping of the sent entity.
  */
 PHP_METHOD(HttpResponse, setGzip)
 {
@@ -342,8 +352,7 @@ PHP_METHOD(HttpResponse, setGzip)
                RETURN_FALSE;
        }
 
-       ZVAL_BOOL(GET_STATIC_PROP(gzip), do_gzip);
-       RETURN_TRUE;
+       RETURN_SUCCESS(UPD_STATIC_PROP(bool, gzip, do_gzip));
 }
 /* }}} */
 
@@ -372,8 +381,6 @@ PHP_METHOD(HttpResponse, setCacheControl)
        int cc_len;
        long max_age = 0;
 
-#define HTTP_CACHECONTROL_TEMPLATE "%s, must-revalidate, max_age=%ld"
-
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &ccontrol, &cc_len, &max_age)) {
                RETURN_FALSE;
        }
@@ -382,10 +389,9 @@ PHP_METHOD(HttpResponse, setCacheControl)
                http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol);
                RETURN_FALSE;
        } else {
-               USE_STATIC_PROP();
-               spprintf(&cctl, 0, HTTP_CACHECONTROL_TEMPLATE, ccontrol, max_age);
-               SET_STATIC_PROP_STRING(cacheControl, cctl, 0);
-               RETURN_TRUE;
+               size_t cctl_len = spprintf(&cctl, 0, "%s, must-revalidate, max_age=%ld", ccontrol, max_age);
+               RETVAL_SUCCESS(UPD_STATIC_STRL(cacheControl, cctl, cctl_len));
+               efree(cctl);
        }
 }
 /* }}} */
@@ -423,9 +429,7 @@ PHP_METHOD(HttpResponse, setContentType)
                RETURN_FALSE;
        }
 
-       USE_STATIC_PROP();
-       SET_STATIC_PROP_STRINGL(contentType, ctype, ctype_len, 1);
-       RETURN_TRUE;
+       RETURN_SUCCESS(UPD_STATIC_STRL(contentType, ctype, ctype_len));
 }
 /* }}} */
 
@@ -444,6 +448,52 @@ PHP_METHOD(HttpResponse, getContentType)
 }
 /* }}} */
 
+/* {{{ proto static string HttpResponse::guessContentType(string magic_file[, long magic_mode])
+ *
+ * Attempts to guess the content type of supplied payload through libmagic.
+ * See docs/KnownIssues.txt! 
+ */
+PHP_METHOD(HttpResponse, guessContentType)
+{
+       char *magic_file, *ct = NULL;
+       int magic_file_len;
+       long magic_mode = 0;
+       
+       RETVAL_NULL();
+       
+       SET_EH_THROW_HTTP();
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &magic_file, &magic_file_len, &magic_mode)) {
+               switch (Z_LVAL_P(GET_STATIC_PROP(mode))) {
+                       case SEND_DATA:
+                       {
+                               zval *data = GET_STATIC_PROP(data);
+                               ct = http_guess_content_type(magic_file, magic_mode, Z_STRVAL_P(data), Z_STRLEN_P(data), SEND_DATA);
+                       }
+                       break;
+                       
+                       case SEND_RSRC:
+                       {
+                               php_stream *s;
+                               zval *z = GET_STATIC_PROP(stream);
+                               z->type = IS_RESOURCE;
+                               php_stream_from_zval(s, &z);
+                               ct = http_guess_content_type(magic_file, magic_mode, s, 0, SEND_RSRC);
+                       }
+                       break;
+                       
+                       default:
+                               ct = http_guess_content_type(magic_file, magic_mode, Z_STRVAL_P(GET_STATIC_PROP(file)), 0, -1);
+                       break;
+               }
+               if (ct) {
+                       UPD_STATIC_PROP(string, contentType, ct);
+                       RETVAL_STRING(ct, 0);
+               }
+       }
+       SET_EH_NORMAL();
+}
+/* }}} */
+
 /* {{{ proto static bool HttpResponse::setContentDisposition(string filename[, bool inline = false])
  *
  * Set the Content-Disposition of the sent entity.  This setting aims to suggest
@@ -454,16 +504,16 @@ PHP_METHOD(HttpResponse, setContentDisposition)
 {
        char *file, *cd;
        int file_len;
+       size_t cd_len;
        zend_bool send_inline = 0;
 
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &file, &file_len, &send_inline)) {
                RETURN_FALSE;
        }
 
-       spprintf(&cd, 0, "%s; filename=\"%s\"", send_inline ? "inline" : "attachment", file);
-       USE_STATIC_PROP();
-       SET_STATIC_PROP_STRING(contentDisposition, cd, 0);
-       RETURN_TRUE;
+       cd_len = spprintf(&cd, 0, "%s; filename=\"%s\"", send_inline ? "inline" : "attachment", file);
+       RETVAL_SUCCESS(UPD_STATIC_STRL(contentDisposition, cd, cd_len));
+       efree(cd);
 }
 /* }}} */
 
@@ -495,15 +545,13 @@ PHP_METHOD(HttpResponse, setETag)
                RETURN_FALSE;
        }
 
-       USE_STATIC_PROP();
-       SET_STATIC_PROP_STRINGL(eTag, etag, etag_len, 1);
-       RETURN_TRUE;
+       RETURN_SUCCESS(UPD_STATIC_STRL(eTag, etag, etag_len));
 }
 /* }}} */
 
 /* {{{ proto static string HttpResponse::getETag()
  *
- * Get the previously set custom ETag.
+ * Get calculated or previously set custom ETag.
  */
 PHP_METHOD(HttpResponse, getETag)
 {
@@ -516,16 +564,47 @@ PHP_METHOD(HttpResponse, getETag)
 }
 /* }}} */
 
-/* {{{ proto static void HttpResponse::setThrottleDelay(double seconds)
+/* {{{ proto static bool HttpResponse::setLastModified(long timestamp)
+ *
+ * Set a custom Last-Modified date.
+ */
+PHP_METHOD(HttpResponse, setLastModified)
+{
+       long lm;
+       
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &lm)) {
+               RETURN_FALSE;
+       }
+       
+       RETURN_SUCCESS(UPD_STATIC_PROP(long, lastModified, lm));
+}
+/* }}} */
+
+/* {{{ proto static HttpResponse::getLastModified()
+ *
+ * Get calculated or previously set custom Last-Modified date.
+ */
+PHP_METHOD(HttpResponse, getLastModified)
+{
+       NO_ARGS;
+       
+       IF_RETVAL_USED {
+               RETURN_LONG(Z_LVAL_P(GET_STATIC_PROP(lastModified)));
+       }
+}
+/* }}} */
+
+/* {{{ proto static bool HttpResponse::setThrottleDelay(double seconds)
  *
  */
 PHP_METHOD(HttpResponse, setThrottleDelay)
 {
        double seconds;
 
-       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &seconds)) {
-               ZVAL_DOUBLE(GET_STATIC_PROP(throttleDelay), seconds);
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &seconds)) {
+               RETURN_FALSE;
        }
+       RETURN_SUCCESS(UPD_STATIC_PROP(double, throttleDelay, seconds));
 }
 /* }}} */
 
@@ -542,16 +621,17 @@ PHP_METHOD(HttpResponse, getThrottleDelay)
 }
 /* }}} */
 
-/* {{{ proto static void HttpResponse::setBufferSize(long bytes)
+/* {{{ proto static bool HttpResponse::setBufferSize(long bytes)
  *
  */
 PHP_METHOD(HttpResponse, setBufferSize)
 {
        long bytes;
 
-       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bytes)) {
-               ZVAL_LONG(GET_STATIC_PROP(bufferSize), bytes);
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bytes)) {
+               RETURN_FALSE;
        }
+       RETURN_SUCCESS(UPD_STATIC_PROP(long, bufferSize, bytes));
 }
 /* }}} */
 
@@ -579,14 +659,22 @@ PHP_METHOD(HttpResponse, setData)
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_data)) {
                RETURN_FALSE;
        }
-       convert_to_string_ex(&the_data);
+       if (Z_TYPE_P(the_data) != IS_STRING) {
+               convert_to_string_ex(&the_data);
+       }
 
-       USE_STATIC_PROP();
-       SET_STATIC_PROP(data, the_data);
-       ZVAL_LONG(GET_STATIC_PROP(lastModified), http_last_modified(the_data, SEND_DATA));
-       ZVAL_LONG(GET_STATIC_PROP(mode), SEND_DATA);
+       if (    (SUCCESS != SET_STATIC_PROP(data, the_data)) ||
+                       (SUCCESS != UPD_STATIC_PROP(long, mode, SEND_DATA))) {
+               RETURN_FALSE;
+       }
+       
+       if (!(Z_LVAL_P(GET_STATIC_PROP(lastModified)) > 0)) {
+               UPD_STATIC_PROP(long, lastModified, http_last_modified(the_data, SEND_DATA));
+       }
        if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
-               SET_STATIC_PROP_STRING(eTag, http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA), 0);
+               char *etag = http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA);
+               UPD_STATIC_PROP(string, eTag, etag);
+               efree(etag);
        }
 
        RETURN_TRUE;
@@ -616,19 +704,30 @@ PHP_METHOD(HttpResponse, setStream)
 {
        zval *the_stream;
        php_stream *the_real_stream;
+       php_stream_statbuf ssb;
 
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &the_stream)) {
                RETURN_FALSE;
        }
-       zend_list_addref(Z_LVAL_P(the_stream));
+       
        php_stream_from_zval(the_real_stream, &the_stream);
+       if (php_stream_stat(the_real_stream, &ssb)) {
+               RETURN_FALSE;
+       }
 
-       USE_STATIC_PROP();
-       ZVAL_LONG(GET_STATIC_PROP(stream), Z_LVAL_P(the_stream));
-       ZVAL_LONG(GET_STATIC_PROP(lastModified), http_last_modified(the_real_stream, SEND_RSRC));
-       ZVAL_LONG(GET_STATIC_PROP(mode), SEND_RSRC);
+       if (    (SUCCESS != UPD_STATIC_PROP(long, stream, Z_LVAL_P(the_stream))) ||
+                       (SUCCESS != UPD_STATIC_PROP(long, mode, SEND_RSRC))) {
+               RETURN_FALSE;
+       }
+       zend_list_addref(Z_LVAL_P(the_stream));
+       
+       if (!(Z_LVAL_P(GET_STATIC_PROP(lastModified)) > 0)) {
+               UPD_STATIC_PROP(long, lastModified, http_last_modified(the_real_stream, SEND_RSRC));
+       }
        if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
-               SET_STATIC_PROP_STRING(eTag, http_etag(the_real_stream, 0, SEND_RSRC), 0);
+               char *etag = http_etag(the_real_stream, 0, SEND_RSRC);
+               UPD_STATIC_PROP(string, eTag, etag);
+               efree(etag);
        }
 
        RETURN_TRUE;
@@ -655,19 +754,30 @@ PHP_METHOD(HttpResponse, getStream)
  */
 PHP_METHOD(HttpResponse, setFile)
 {
-       zval *the_file;
+       char *the_file;
+       int file_len;
+       php_stream_statbuf ssb;
 
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_file)) {
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &the_file, &file_len)) {
+               RETURN_FALSE;
+       }
+       
+       if (php_stream_stat_path(the_file, &ssb)) {
+               RETURN_FALSE;
+       }
+       
+       if (    (SUCCESS != UPD_STATIC_STRL(file, the_file, file_len)) ||
+                       (SUCCESS != UPD_STATIC_PROP(long, mode, -1))) {
                RETURN_FALSE;
        }
 
-       convert_to_string_ex(&the_file);
-       USE_STATIC_PROP();
-       SET_STATIC_PROP(file, the_file);
-       ZVAL_LONG(GET_STATIC_PROP(lastModified), http_last_modified(the_file, -1));
-       ZVAL_LONG(GET_STATIC_PROP(mode), -1);
+       if (!(Z_LVAL_P(GET_STATIC_PROP(lastModified)))) {
+               UPD_STATIC_PROP(long, lastModified, http_last_modified(the_file, -1));
+       }
        if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
-               SET_STATIC_PROP_STRING(eTag, http_etag(the_file, 0, -1), 0);
+               char *etag = http_etag(the_file, 0, -1);
+               UPD_STATIC_PROP(string, eTag, etag);
+               efree(etag);
        }
 
        RETURN_TRUE;
@@ -726,20 +836,20 @@ PHP_METHOD(HttpResponse, send)
        }
 
        /* capture mode */
-       if (Z_LVAL_P(GET_STATIC_PROP(catch))) {
-               zval the_data;
-
-               INIT_PZVAL(&the_data);
-               php_ob_get_buffer(&the_data TSRMLS_CC);
+       if (Z_BVAL_P(GET_STATIC_PROP(catch))) {
+               zval *the_data;
 
-               USE_STATIC_PROP();
-               SET_STATIC_PROP(data, &the_data);
+               MAKE_STD_ZVAL(the_data);
+               php_ob_get_buffer(the_data TSRMLS_CC);
+               SET_STATIC_PROP(data, the_data);
                ZVAL_LONG(GET_STATIC_PROP(mode), SEND_DATA);
 
                if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
-                       SET_STATIC_PROP_STRING(eTag, http_etag(Z_STRVAL(the_data), Z_STRLEN(the_data), SEND_DATA), 0);
+                       char *etag = http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA);
+                       UPD_STATIC_PROP(string, eTag, etag);
+                       efree(etag);
                }
-               zval_dtor(&the_data);
+               zval_ptr_dtor(&the_data);
 
                clean_ob = 1;
        }
@@ -765,11 +875,11 @@ PHP_METHOD(HttpResponse, send)
                                        zval **data;
 
                                        FOREACH_VAL(*value, data) {
-                                               http_send_header_ex(name, strlen(name), Z_STRVAL_PP(data), Z_STRLEN_PP(data), first);
+                                               http_send_header_ex(name, strlen(name), Z_STRVAL_PP(data), Z_STRLEN_PP(data), first, NULL);
                                                first = 0;
                                        }
                                } else {
-                                       http_send_header_ex(name, strlen(name), Z_STRVAL_PP(value), Z_STRLEN_PP(value), 1);
+                                       http_send_header_ex(name, strlen(name), Z_STRVAL_PP(value), Z_STRLEN_PP(value), 1, NULL);
                                }
                                name = NULL;
                        }
@@ -778,7 +888,7 @@ PHP_METHOD(HttpResponse, send)
 
        /* gzip */
        if (Z_LVAL_P(GET_STATIC_PROP(gzip))) {
-               php_start_ob_buffer_named("ob_gzhandler", 0, 1 TSRMLS_CC);
+               php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC);
        } else {
                php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC);
        }
@@ -816,7 +926,7 @@ PHP_METHOD(HttpResponse, send)
        {
                zval *cd = GET_STATIC_PROP(contentDisposition);
                if (Z_STRLEN_P(cd)) {
-                       http_send_header_ex("Content-Disposition", lenof("Content-Disposition"), Z_STRVAL_P(cd), Z_STRLEN_P(cd), 1);
+                       http_send_header_ex("Content-Disposition", lenof("Content-Disposition"), Z_STRVAL_P(cd), Z_STRLEN_P(cd), 1, NULL);
                }
        }
 
@@ -833,7 +943,7 @@ PHP_METHOD(HttpResponse, send)
                        case SEND_DATA:
                        {
                                zval *zdata = GET_STATIC_PROP(data);
-                               RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
+                               RETURN_SUCCESS(http_send_data_ex(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata), 1));
                        }
 
                        case SEND_RSRC:
@@ -842,12 +952,12 @@ PHP_METHOD(HttpResponse, send)
                                zval *the_stream = GET_STATIC_PROP(stream);
                                the_stream->type = IS_RESOURCE;
                                php_stream_from_zval(the_real_stream, &the_stream);
-                               RETURN_SUCCESS(http_send_stream(the_real_stream));
+                               RETURN_SUCCESS(http_send_stream_ex(the_real_stream, 0, 1));
                        }
 
                        default:
                        {
-                               RETURN_SUCCESS(http_send_file(Z_STRVAL_P(GET_STATIC_PROP(file))));
+                               RETURN_SUCCESS(http_send_file_ex(Z_STRVAL_P(GET_STATIC_PROP(file)), 1));
                        }
                }
        }
@@ -875,13 +985,15 @@ PHP_METHOD(HttpResponse, capture)
 
        INIT_PZVAL(&do_catch);
        ZVAL_LONG(&do_catch, 1);
-       USE_STATIC_PROP();
+
        SET_STATIC_PROP(catch, &do_catch);
 
        php_end_ob_buffers(0 TSRMLS_CC);
        php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC);
 
-       /* register shutdown function */
+#ifndef WONKY
+       /* register shutdown function --
+               messing around with ob and headers only works in PHP-5.1 or greater */
        {
                zval func, retval, arg, *argp[1];
 
@@ -897,10 +1009,11 @@ PHP_METHOD(HttpResponse, capture)
                call_user_function(EG(function_table), NULL, &func, &retval, 1, argp TSRMLS_CC);
                zval_dtor(&arg);
        }
+#endif
 }
 /* }}} */
 
-#endif /* ZEND_ENGINE_2 */
+#endif /* ZEND_ENGINE_2 && !WONKY */
 
 /*
  * Local variables: