- reflection awareness of HttpRequest
authorMichael Wallner <mike@php.net>
Tue, 19 Jul 2005 23:00:34 +0000 (23:00 +0000)
committerMichael Wallner <mike@php.net>
Tue, 19 Jul 2005 23:00:34 +0000 (23:00 +0000)
- added HttpResponse::catchOutput()

# I'm pondering making HttpResponse a static class --
# is there even a need to instantiate an HttpResponse object?

http_methods.c
http_request_object.c
http_response_object.c
php_http_request_object.h
php_http_response_object.h

index 08959ed0c152c9c2ec0e490bc5e57de4b23543cf..c2b13ef091daac92aaf4833e7cafd9439646f132 100644 (file)
@@ -53,8 +53,6 @@ ZEND_EXTERN_MODULE_GLOBALS(http);
  * Instantiates a new HttpResponse object, which can be used to send
  * any data/resource/file to an HTTP client with caching and multiple
  * ranges/resuming support.
- *
- * NOTE: GZIPping is not implemented yet.
  */
 PHP_METHOD(HttpResponse, __construct)
 {
@@ -70,6 +68,37 @@ PHP_METHOD(HttpResponse, __construct)
 }
 /* }}} */
 
+/* {{{ proto void HttpResponse::__destruct()
+ *
+ * -
+ */
+PHP_METHOD(HttpResponse, __destruct)
+{
+       getObject(http_response_object, obj);
+       zval *catch_ob = GET_PROP(obj, catch_ob), *sent = GET_PROP(obj, sent);
+       fprintf(stderr, "DTOR!\n"); fflush(stderr);
+       if (!Z_LVAL_P(sent) && Z_LVAL_P(catch_ob)) {
+               zval ob_data;
+
+               /* fetch catched output buffer */
+               if (SUCCESS == php_ob_get_buffer(&ob_data TSRMLS_CC)) {
+                       zval *lmod = GET_PROP(obj, lastModified);
+
+                       SET_PROP(obj, data, &ob_data);
+                       UPD_PROP(obj, long, send_mode, SEND_DATA);
+
+                       if (!Z_LVAL_P(lmod)) {
+                               UPD_PROP(obj, long, lastModified, http_last_modified(&ob_data, SEND_DATA));
+                       }
+                       zval_dtor(&ob_data);
+
+                       http_response_object_sendhandler(getThis(), obj, 1, return_value);
+                       RETVAL_NULL();
+               }
+       }
+}
+/* }}} */
+
 /* {{{ proto bool HttpResponse::setCache(bool cache)
  *
  * Whether it sould be attempted to cache the entitity.
@@ -527,15 +556,40 @@ PHP_METHOD(HttpResponse, getFile)
 PHP_METHOD(HttpResponse, send)
 {
        zend_bool clean_ob = 1;
-       zval *do_cache, *do_gzip;
+
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean_ob)) {
+               RETURN_FALSE;
+       }
+
+       http_response_object_sendhandler(getThis(), NULL, clean_ob, return_value);
+}
+/* }}} */
+
+/* {{{ proto bool HttpResponse::catchOutput([bool clean_ob = false])
+ *
+ * Use this method instead of HttpResponse::set*() and HttpResponse::send()
+ * to let HttpResponse catch and handle the scripts output (i.e. echo/print).
+ *
+ * Example:
+ * <pre>
+ * <?php
+ * $r = new HttpResponse(true, true);
+ * $r->setContentType('text/html; charset=utf-8');
+ * $r->catchOutput(true);
+ * // script follows
+ * ?>
+ * </pre>
+ */
+PHP_METHOD(HttpResponse, catchOutput)
+{
+       zend_bool clean_ob = 0;
        getObject(http_response_object, obj);
 
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean_ob)) {
                RETURN_FALSE;
        }
 
-       do_cache = GET_PROP(obj, cache);
-       do_gzip  = GET_PROP(obj, gzip);
+       UPD_PROP(obj, long, catch_ob, 1);
 
        if (clean_ob) {
                /* interrupt on-the-fly etag generation */
@@ -544,93 +598,13 @@ PHP_METHOD(HttpResponse, send)
                php_end_ob_buffers(0 TSRMLS_CC);
        }
 
-       /* gzip */
-       if (Z_LVAL_P(do_gzip)) {
-               php_start_ob_buffer_named("ob_gzhandler", 0, 1 TSRMLS_CC);
-       }
-
-       /* caching */
-       if (Z_LVAL_P(do_cache)) {
-               char *cc_hdr;
-               int cc_len;
-               zval *cctrl, *etag, *lmod, *ccraw;
-
-               etag  = GET_PROP(obj, eTag);
-               lmod  = GET_PROP(obj, lastModified);
-               cctrl = GET_PROP(obj, cacheControl);
-               ccraw = GET_PROP(obj, raw_cache_header);
-
-               if (Z_LVAL_P(ccraw)) {
-                       cc_hdr = Z_STRVAL_P(cctrl);
-                       cc_len = Z_STRLEN_P(cctrl);
-               } else {
-                       char cc_header[42] = {0};
-                       sprintf(cc_header, "%s, must-revalidate, max-age=0", Z_STRVAL_P(cctrl));
-                       cc_hdr = cc_header;
-                       cc_len = Z_STRLEN_P(cctrl) + lenof(", must-revalidate, max-age=0");
-               }
-
-               http_cache_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag), cc_hdr, cc_len);
-               http_cache_last_modified(Z_LVAL_P(lmod), Z_LVAL_P(lmod) ? Z_LVAL_P(lmod) : time(NULL), cc_hdr, cc_len);
-       }
-
-       /* content type */
-       {
-               zval *ctype = GET_PROP(obj, contentType);
-               if (Z_STRLEN_P(ctype)) {
-                       http_send_content_type(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype));
-               } else {
-                       http_send_content_type("application/x-octetstream", lenof("application/x-octetstream"));
-               }
-       }
-
-       /* content disposition */
-       {
-               zval *dispo_file = GET_PROP(obj, dispoFile);
-               if (Z_STRLEN_P(dispo_file)) {
-                       zval *dispo_inline = GET_PROP(obj, dispoInline);
-                       http_send_content_disposition(Z_STRVAL_P(dispo_file), Z_STRLEN_P(dispo_file), (zend_bool) Z_LVAL_P(dispo_inline));
-               }
-       }
-
-       /* throttling */
-       {
-               zval *send_buffersize, *throttle_delay;
-               send_buffersize = GET_PROP(obj, sendBuffersize);
-               throttle_delay  = GET_PROP(obj, throttleDelay);
-               HTTP_G(send).buffer_size    = Z_LVAL_P(send_buffersize);
-               HTTP_G(send).throttle_delay = Z_DVAL_P(throttle_delay);
-       }
-
-       /* send */
-       {
-               zval *send_mode = GET_PROP(obj, send_mode);
-               switch (Z_LVAL_P(send_mode))
-               {
-                       case SEND_DATA:
-                       {
-                               zval *zdata = GET_PROP(obj, data);
-                               RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
-                       }
-
-                       case SEND_RSRC:
-                       {
-                               php_stream *the_real_stream;
-                               zval *the_stream = GET_PROP(obj, stream);
-                               php_stream_from_zval(the_real_stream, &the_stream);
-                               RETURN_SUCCESS(http_send_stream(the_real_stream));
-                       }
-
-                       default:
-                       {
-                               zval *zfile = GET_PROP(obj, file);
-                               RETURN_SUCCESS(http_send_file(Z_STRVAL_P(zfile)));
-                       }
-               }
+       if (SUCCESS != php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC)) {
+               RETURN_FALSE;
        }
+       
+       RETURN_TRUE;
 }
 /* }}} */
-/* }}} */
 
 /* {{{ HttpMessage */
 
@@ -1399,11 +1373,11 @@ PHP_METHOD(HttpRequest, unsetCookies)
 }
 /* }}} */
 
-/* {{{ proto bool HttpRequest::setURL(string url)
+/* {{{ proto bool HttpRequest::setUrl(string url)
  *
  * Set the request URL.
  */
-PHP_METHOD(HttpRequest, setURL)
+PHP_METHOD(HttpRequest, setUrl)
 {
        char *URL = NULL;
        int URL_len;
@@ -1422,7 +1396,7 @@ PHP_METHOD(HttpRequest, setURL)
  *
  * Get the previously set request URL.
  */
-PHP_METHOD(HttpRequest, getURL)
+PHP_METHOD(HttpRequest, getUrl)
 {
        NO_ARGS;
 
@@ -1728,7 +1702,7 @@ PHP_METHOD(HttpRequest, addPostFile)
 }
 /* }}} */
 
-/* {{{ proto bool HttpRequest::setPostFiles()
+/* {{{ proto bool HttpRequest::setPostFiles(array post_files)
  *
  * Set files to post.
  * Overwrites previously set post files.
@@ -2123,7 +2097,8 @@ PHP_METHOD(HttpRequest, send)
        SET_EH_THROW_HTTP();
 
        if (obj->pool) {
-               http_error(E_WARNING, HTTP_E_CURL, "You cannot call HttpRequest::send() while attached to an HttpRequestPool");
+               http_error(E_WARNING, HTTP_E_CURL, "Cannot perform HttpRequest::send() while attached to an HttpRequestPool");
+               SET_EH_NORMAL();
                RETURN_FALSE;
        }
 
index 444516f53c450becab9bbdd728ca3c15c0b8697e..4c3f69dab1a6322784f9987ff5fc7fd848ff8a3b 100644 (file)
 #endif
 #include <curl/curl.h>
 
+#define HTTP_BEGIN_ARGS(method, req_args)              HTTP_BEGIN_ARGS_EX(HttpRequest, method, ZEND_RETURN_REFERENCE_AGNOSTIC, req_args)
+#define HTTP_EMPTY_ARGS(method, ret_ref)               HTTP_EMPTY_ARGS_EX(HttpRequest, method, ret_ref)
+#define HTTP_REQUEST_ME(method, visibility)            PHP_ME(HttpRequest, method, HTTP_ARGS(HttpRequest, method), visibility)
+
+HTTP_EMPTY_ARGS(__destruct, 0);
+HTTP_BEGIN_ARGS(__construct, 0)
+       HTTP_ARG_VAL(url, 0)
+       HTTP_ARG_VAL(method, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getOptions, 0);
+HTTP_EMPTY_ARGS(unsetOptions, 0);
+HTTP_BEGIN_ARGS(setOptions, 1)
+       HTTP_ARG_VAL(options, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getSslOptions, 0);
+HTTP_EMPTY_ARGS(unsetSslOptions, 0);
+HTTP_BEGIN_ARGS(setSslOptions, 1)
+       HTTP_ARG_VAL(ssl_options, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getHeaders, 0);
+HTTP_EMPTY_ARGS(unsetHeaders, 0);
+HTTP_BEGIN_ARGS(addHeaders, 1)
+       HTTP_ARG_VAL(headers, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getCookies, 0);
+HTTP_EMPTY_ARGS(unsetCookies, 0);
+HTTP_BEGIN_ARGS(addCookies, 1)
+       HTTP_ARG_VAL(cookies, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getUrl, 0);
+HTTP_BEGIN_ARGS(setUrl, 1)
+       HTTP_ARG_VAL(url, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getMethod, 0);
+HTTP_BEGIN_ARGS(setMethod, 1)
+       HTTP_ARG_VAL(request_method, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getContentType, 0);
+HTTP_BEGIN_ARGS(setContentType, 1)
+       HTTP_ARG_VAL(content_type, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getQueryData, 0);
+HTTP_EMPTY_ARGS(unsetQueryData, 0);
+HTTP_BEGIN_ARGS(setQueryData, 1)
+       HTTP_ARG_VAL(query_data, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(addQueryData, 1)
+       HTTP_ARG_VAL(query_data, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getPostFields, 0);
+HTTP_EMPTY_ARGS(unsetPostFields, 0);
+HTTP_BEGIN_ARGS(setPostFields, 1)
+       HTTP_ARG_VAL(post_fields, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(addPostFields, 1)
+       HTTP_ARG_VAL(post_fields, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getPostFiles, 0);
+HTTP_EMPTY_ARGS(unsetPostFiles, 0);
+HTTP_BEGIN_ARGS(setPostFiles, 1)
+       HTTP_ARG_VAL(post_files, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(addPostFile, 2)
+       HTTP_ARG_VAL(formname, 0)
+       HTTP_ARG_VAL(filename, 0)
+       HTTP_ARG_VAL(content_type, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getPutFile, 0);
+HTTP_EMPTY_ARGS(unsetPutFile, 0);
+HTTP_BEGIN_ARGS(setPutFile, 1)
+       HTTP_ARG_VAL(filename, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getResponseData, 0);
+HTTP_BEGIN_ARGS(getResponseHeader, 0)
+       HTTP_ARG_VAL(name, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(getResponseCookie, 0)
+       HTTP_ARG_VAL(name, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getResponseBody, 0);
+HTTP_EMPTY_ARGS(getResponseCode, 0);
+HTTP_BEGIN_ARGS(getResponseInfo, 0)
+       HTTP_ARG_VAL(name, 0)
+HTTP_END_ARGS;
+
+HTTP_EMPTY_ARGS(getResponseMessage, 1);
+HTTP_EMPTY_ARGS(send, 0);
+
 #define http_request_object_declare_default_properties() _http_request_object_declare_default_properties(TSRMLS_C)
 static inline void _http_request_object_declare_default_properties(TSRMLS_D);
 
 zend_class_entry *http_request_object_ce;
 zend_function_entry http_request_object_fe[] = {
-       PHP_ME(HttpRequest, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-       PHP_ME(HttpRequest, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
-
-       PHP_ME(HttpRequest, setOptions, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getOptions, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetOptions, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, setSslOptions, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getSslOptions, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetSslOptions, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, addHeaders, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getHeaders, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetHeaders, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, addCookies, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getCookies, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetCookies, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setMethod, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getMethod, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setURL, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getURL, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setContentType, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getContentType, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setQueryData, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getQueryData, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, addQueryData, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetQueryData, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setPostFields, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getPostFields, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, addPostFields, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetPostFields, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setPostFiles, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, addPostFile, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getPostFiles, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetPostFiles, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, setPutFile, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getPutFile, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, unsetPutFile, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, send, NULL, ZEND_ACC_PUBLIC)
-
-       PHP_ME(HttpRequest, getResponseData, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getResponseHeader, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getResponseCookie, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getResponseCode, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getResponseBody, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getResponseInfo, NULL, ZEND_ACC_PUBLIC)
-       PHP_ME(HttpRequest, getResponseMessage, NULL, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+       HTTP_REQUEST_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
+
+       HTTP_REQUEST_ME(setOptions, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getOptions, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetOptions, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(setSslOptions, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getSslOptions, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetSslOptions, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(addHeaders, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getHeaders, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetHeaders, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(addCookies, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getCookies, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetCookies, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setMethod, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getMethod, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setUrl, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getUrl, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setContentType, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getContentType, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setQueryData, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getQueryData, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(addQueryData, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetQueryData, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setPostFields, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getPostFields, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(addPostFields, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetPostFields, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setPostFiles, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(addPostFile, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getPostFiles, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetPostFiles, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(setPutFile, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getPutFile, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(unsetPutFile, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(send, ZEND_ACC_PUBLIC)
+
+       HTTP_REQUEST_ME(getResponseData, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getResponseHeader, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getResponseCookie, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getResponseCode, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getResponseBody, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getResponseInfo, ZEND_ACC_PUBLIC)
+       HTTP_REQUEST_ME(getResponseMessage, ZEND_ACC_PUBLIC)
 
        {NULL, NULL, NULL}
 };
index 45dcb1db4ef79061a2a9497952f87bbee018da41..9f5d3c14befa4e6608e8c2a6458405fb4343ce1d 100644 (file)
 
 #ifdef ZEND_ENGINE_2
 
+#include "php_http.h"
+#include "php_http_api.h"
 #include "php_http_std_defs.h"
 #include "php_http_response_object.h"
+#include "php_http_send_api.h"
+#include "php_http_cache_api.h"
 
 #include "missing.h"
 
+ZEND_EXTERN_MODULE_GLOBALS(http);
+
 #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)
 #define HTTP_RESPONSE_ME(method, visibility)   PHP_ME(HttpResponse, method, HTTP_ARGS(HttpResponse, method), visibility)
 
+HTTP_EMPTY_ARGS(__destruct, 0);
 HTTP_BEGIN_ARGS(__construct, 0)
        HTTP_ARG_VAL(cache, 0)
        HTTP_ARG_VAL(gzip, 0)
@@ -98,12 +105,17 @@ HTTP_BEGIN_ARGS(send, 0)
        HTTP_ARG_VAL(clean_ob, 0)
 HTTP_END_ARGS;
 
+HTTP_BEGIN_ARGS(catchOutput, 0)
+       HTTP_ARG_VAL(clean_ob, 0)
+HTTP_END_ARGS;
+
 #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);
 
 zend_class_entry *http_response_object_ce;
 zend_function_entry http_response_object_fe[] = {
        HTTP_RESPONSE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+       HTTP_RESPONSE_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
 
        HTTP_RESPONSE_ME(setETag, ZEND_ACC_PUBLIC)
        HTTP_RESPONSE_ME(getETag, ZEND_ACC_PUBLIC)
@@ -139,6 +151,7 @@ zend_function_entry http_response_object_fe[] = {
        HTTP_RESPONSE_ME(getStream, ZEND_ACC_PUBLIC)
 
        HTTP_RESPONSE_ME(send, ZEND_ACC_PUBLIC)
+       HTTP_RESPONSE_ME(catchOutput, ZEND_ACC_PUBLIC)
 
        {NULL, NULL, NULL}
 };
@@ -187,6 +200,8 @@ static inline void _http_response_object_declare_default_properties(TSRMLS_D)
 
        DCL_PROP(PRIVATE, long, raw_cache_header, 0);
        DCL_PROP(PRIVATE, long, send_mode, -1);
+       DCL_PROP(PRIVATE, long, sent, 0);
+       DCL_PROP(PRIVATE, long, catch_ob, 0);
 }
 
 void _http_response_object_free(zend_object *object TSRMLS_DC)
@@ -200,6 +215,111 @@ void _http_response_object_free(zend_object *object TSRMLS_DC)
        efree(o);
 }
 
+void _http_response_object_sendhandler(zval *this_ptr, http_response_object *obj, zend_bool clean_ob, zval *return_value TSRMLS_DC)
+{
+       zval *do_cache, *do_gzip;
+
+       if (!obj) {
+               getObject(http_response_object, o);
+               obj = o;
+       }
+
+       do_cache = GET_PROP(obj, cache);
+       do_gzip  = GET_PROP(obj, gzip);
+
+       if (clean_ob) {
+               /* interrupt on-the-fly etag generation */
+               HTTP_G(etag).started = 0;
+               /* discard previous output buffers */
+               php_end_ob_buffers(0 TSRMLS_CC);
+       }
+
+       /* gzip */
+       if (Z_LVAL_P(do_gzip)) {
+               php_start_ob_buffer_named("ob_gzhandler", 0, 1 TSRMLS_CC);
+       }
+
+       /* caching */
+       if (Z_LVAL_P(do_cache)) {
+               char *cc_hdr;
+               int cc_len;
+               zval *cctrl, *etag, *lmod, *ccraw;
+
+               etag  = GET_PROP(obj, eTag);
+               lmod  = GET_PROP(obj, lastModified);
+               cctrl = GET_PROP(obj, cacheControl);
+               ccraw = GET_PROP(obj, raw_cache_header);
+
+               if (Z_LVAL_P(ccraw)) {
+                       cc_hdr = Z_STRVAL_P(cctrl);
+                       cc_len = Z_STRLEN_P(cctrl);
+               } else {
+                       char cc_header[42] = {0};
+                       sprintf(cc_header, "%s, must-revalidate, max-age=0", Z_STRVAL_P(cctrl));
+                       cc_hdr = cc_header;
+                       cc_len = Z_STRLEN_P(cctrl) + lenof(", must-revalidate, max-age=0");
+               }
+
+               http_cache_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag), cc_hdr, cc_len);
+               http_cache_last_modified(Z_LVAL_P(lmod), Z_LVAL_P(lmod) ? Z_LVAL_P(lmod) : time(NULL), cc_hdr, cc_len);
+       }
+
+       /* content type */
+       {
+               zval *ctype = GET_PROP(obj, contentType);
+               if (Z_STRLEN_P(ctype)) {
+                       http_send_content_type(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype));
+               } else {
+                       http_send_content_type("application/x-octetstream", lenof("application/x-octetstream"));
+               }
+       }
+
+       /* content disposition */
+       {
+               zval *dispo_file = GET_PROP(obj, dispoFile);
+               if (Z_STRLEN_P(dispo_file)) {
+                       zval *dispo_inline = GET_PROP(obj, dispoInline);
+                       http_send_content_disposition(Z_STRVAL_P(dispo_file), Z_STRLEN_P(dispo_file), (zend_bool) Z_LVAL_P(dispo_inline));
+               }
+       }
+
+       /* throttling */
+       {
+               zval *send_buffersize, *throttle_delay;
+               send_buffersize = GET_PROP(obj, sendBuffersize);
+               throttle_delay  = GET_PROP(obj, throttleDelay);
+               HTTP_G(send).buffer_size    = Z_LVAL_P(send_buffersize);
+               HTTP_G(send).throttle_delay = Z_DVAL_P(throttle_delay);
+       }
+
+       /* send */
+       {
+               zval *send_mode = GET_PROP(obj, send_mode);
+               switch (Z_LVAL_P(send_mode))
+               {
+                       case SEND_DATA:
+                       {
+                               zval *zdata = GET_PROP(obj, data);
+                               RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
+                       }
+
+                       case SEND_RSRC:
+                       {
+                               php_stream *the_real_stream;
+                               zval *the_stream = GET_PROP(obj, stream);
+                               php_stream_from_zval(the_real_stream, &the_stream);
+                               RETURN_SUCCESS(http_send_stream(the_real_stream));
+                       }
+
+                       default:
+                       {
+                               zval *zfile = GET_PROP(obj, file);
+                               RETURN_SUCCESS(http_send_file(Z_STRVAL_P(zfile)));
+                       }
+               }
+       }
+}
+
 #endif /* ZEND_ENGINE_2 */
 
 /*
index 011da9a6eb49b965ac9425f88a0cdc4a6017e0b6..426d0ea00b6e60fb4c0fee1cad9c31f1f9732ab9 100644 (file)
@@ -68,8 +68,8 @@ PHP_METHOD(HttpRequest, getCookies);
 PHP_METHOD(HttpRequest, unsetCookies);
 PHP_METHOD(HttpRequest, setMethod);
 PHP_METHOD(HttpRequest, getMethod);
-PHP_METHOD(HttpRequest, setURL);
-PHP_METHOD(HttpRequest, getURL);
+PHP_METHOD(HttpRequest, setUrl);
+PHP_METHOD(HttpRequest, getUrl);
 PHP_METHOD(HttpRequest, setContentType);
 PHP_METHOD(HttpRequest, getContentType);
 PHP_METHOD(HttpRequest, setQueryData);
index 6484ac90cb19ef126d3f2a6d219035c83ec256a1..79e6fc5e3b6e1bd101b161d0a3af55886ce90571 100644 (file)
@@ -33,7 +33,11 @@ extern zend_object_value _http_response_object_new(zend_class_entry *ce TSRMLS_D
 #define http_response_object_free _http_response_object_free
 extern void _http_response_object_free(zend_object *object TSRMLS_DC);
 
+#define http_response_object_sendhandler(z, o, c, r) _http_response_object_sendhandler((z), (o), (c), (r) TSRMLS_CC)
+extern void _http_response_object_sendhandler(zval *this_ptr, http_response_object *obj, zend_bool clean_ob, zval *return_value TSRMLS_DC);
+
 PHP_METHOD(HttpResponse, __construct);
+PHP_METHOD(HttpResponse, __destruct);
 PHP_METHOD(HttpResponse, setETag);
 PHP_METHOD(HttpResponse, getETag);
 PHP_METHOD(HttpResponse, setContentDisposition);
@@ -57,6 +61,7 @@ PHP_METHOD(HttpResponse, getFile);
 PHP_METHOD(HttpResponse, setStream);
 PHP_METHOD(HttpResponse, getStream);
 PHP_METHOD(HttpResponse, send);
+PHP_METHOD(HttpResponse, catchOutput);
 
 #endif
 #endif