From: Michael Wallner Date: Tue, 19 Jul 2005 23:00:34 +0000 (+0000) Subject: - reflection awareness of HttpRequest X-Git-Tag: RELEASE_0_10_0~35 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=73ca84f4751d2197ee39b92c3b924b8e64b0ff0d - reflection awareness of HttpRequest - added HttpResponse::catchOutput() # I'm pondering making HttpResponse a static class -- # is there even a need to instantiate an HttpResponse object? --- diff --git a/http_methods.c b/http_methods.c index 08959ed..c2b13ef 100644 --- a/http_methods.c +++ b/http_methods.c @@ -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: + *
+ * setContentType('text/html; charset=utf-8');
+ * $r->catchOutput(true);
+ * // script follows
+ * ?>
+ * 
+ */ +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; } diff --git a/http_request_object.c b/http_request_object.c index 444516f..4c3f69d 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -37,65 +37,170 @@ #endif #include +#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} }; diff --git a/http_response_object.c b/http_response_object.c index 45dcb1d..9f5d3c1 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -23,15 +23,22 @@ #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 */ /* diff --git a/php_http_request_object.h b/php_http_request_object.h index 011da9a..426d0ea 100644 --- a/php_http_request_object.h +++ b/php_http_request_object.h @@ -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); diff --git a/php_http_response_object.h b/php_http_response_object.h index 6484ac9..79e6fc5 100644 --- a/php_http_response_object.h +++ b/php_http_response_object.h @@ -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