From: Michael Wallner Date: Wed, 20 Nov 2013 13:18:11 +0000 (+0000) Subject: removed awkward custom error handling and http\Object base class X-Git-Tag: RELEASE_2_1_0_RC3~10^2^2~1 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=8b8cdb96032f50d57dbdad74ae45336d01a7f0c5;p=m6w6%2Fext-http removed awkward custom error handling and http\Object base class --- diff --git a/Exceptions.txt b/Exceptions.txt new file mode 100644 index 0000000..f666ee9 --- /dev/null +++ b/Exceptions.txt @@ -0,0 +1,4 @@ +# Throw Exceptions: + +* on setters, that return self +* on getters, that return objects diff --git a/KnownIssues.txt b/KnownIssues.txt index 5f47b6d..4c2ad80 100644 --- a/KnownIssues.txt +++ b/KnownIssues.txt @@ -15,14 +15,11 @@ Internals: as libcurl saves the cookies to the file on curl_easy_destroy(), cookies are not saved until the CURL handle will be recycled. Thus one would either need to - * run PHP with http.persistent.handles.limit = 0 - * call http_persistent_handles_clean() every request - * call $HttpRequest->flushCookies(), which is available + * run PHP with raphf.persistent_handles.limit = 0 + * call raphf\persistent_handles_clean() every request + * call $client->flushCookies(), which is available since libcurl v7.17.1 and does not work with the procedural API - Anyway, none of these options is really perfect, so using - HttpRequestDatashare with cookies enabled is probably the - best thing to do. HTTP and Proxy authentication information (username/password) can not be unset with NULL prior libcurl v7.19.6 and separate options for setting username and password--which work--are only available since v7.19.6. diff --git a/TODO b/TODO index b46bf1f..db7d39d 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,8 @@ * let http_info.request.url be a php_url * let the message body be a simple query string unless files are added +* php_http_message_serialize reverses the chain twice; remove that * revisit error handling - \ No newline at end of file + * ditch http\Object + * interfacize http\Exception + * subclass Exceptions + * zend_throw_exception \ No newline at end of file diff --git a/config9.m4 b/config9.m4 index ea6c692..aff67ca 100644 --- a/config9.m4 +++ b/config9.m4 @@ -166,7 +166,11 @@ dnl ---- AC_MSG_RESULT([found: $CURL_CONFIG]) fi - dnl Debian stable has currently 7.18.2 + dnl RHEL6: 7.19.7 + dnl SUSE11: 7.19.7 + dnl Debian wheezy: 7.26.0 + dnl Debian sqeeze: 7.21.0 + dnl Debian ancient 7.18.2 AC_MSG_CHECKING([for curl version >= 7.18.2]) CURL_VERSION=`$CURL_CONFIG --version | $SED -e 's/[[^0-9\.]]//g'` AC_MSG_RESULT([$CURL_VERSION]) @@ -443,7 +447,7 @@ dnl ---- php_http_exception.c \ php_http_filter.c \ php_http_header_parser.c \ - php_http_headers.c \ + php_http_header.c \ php_http_info.c \ php_http_message_body.c \ php_http_message.c \ @@ -495,7 +499,7 @@ dnl ---- php_http_filter.h \ php_http.h \ php_http_header_parser.h \ - php_http_headers.h \ + php_http_header.h \ php_http_info.h \ php_http_message_body.h \ php_http_message.h \ diff --git a/package.xml b/package.xml index 401fce1..5467a83 100644 --- a/package.xml +++ b/package.xml @@ -30,7 +30,7 @@ support. Parallel requests are available for PHP 5 and greater. 2013-08-12 - 2.0.0beta5 + 2.0.0RC1 2.0.0 @@ -41,12 +41,12 @@ support. Parallel requests are available for PHP 5 and greater. errorHandling. -* The request ecosystem has been modularized to support different libraries, though for the moment only libcurl is supported. +Documentation: +http://devel-m6w6.rhcloud.com/mdref/http + +Code Coverage: +http://dev.iworks.at/ext-http/lcov/ext/http/ + ]]> @@ -91,8 +91,8 @@ Extended HTTP support. Again. Keep in mind that it's got the major version 2, be - - + + @@ -210,15 +210,6 @@ Extended HTTP support. Again. Keep in mind that it's got the major version 2, be - - - - - - - - - diff --git a/php_http.c b/php_http.c index 62c1f8d..2ed94c8 100644 --- a/php_http.c +++ b/php_http.c @@ -134,7 +134,6 @@ PHP_MINIT_FUNCTION(http) REGISTER_INI_ENTRIES(); if (0 - || SUCCESS != PHP_MINIT_CALL(http_object) || SUCCESS != PHP_MINIT_CALL(http_exception) || SUCCESS != PHP_MINIT_CALL(http_cookie) || SUCCESS != PHP_MINIT_CALL(http_encoding) diff --git a/php_http_api.h b/php_http_api.h index ec4a989..42d34fc 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -30,6 +30,8 @@ #include #include +#include + #ifdef PHP_WIN32 # define PHP_HTTP_API __declspec(dllexport) @@ -42,9 +44,6 @@ /* make functions that return SUCCESS|FAILURE more obvious */ typedef int STATUS; -/* inline doc */ -#define _RETURNS(type) - #if (defined(HAVE_ICONV) || defined(PHP_HTTP_HAVE_EXT_ICONV)) && (PHP_HTTP_SHARED_DEPS || !defined(COMPILE_DL_ICONV)) # define PHP_HTTP_HAVE_ICONV #endif @@ -95,7 +94,7 @@ typedef int STATUS; #include "php_http_exception.h" #include "php_http_filter.h" #include "php_http_header_parser.h" -#include "php_http_headers.h" +#include "php_http_header.h" #include "php_http_message_body.h" #include "php_http_message_parser.h" #include "php_http_negotiate.h" diff --git a/php_http_client.c b/php_http_client.c index 34a1272..6dced66 100644 --- a/php_http_client.c +++ b/php_http_client.c @@ -20,12 +20,12 @@ */ static HashTable php_http_client_drivers; -PHP_HTTP_API STATUS php_http_client_driver_add(php_http_client_driver_t *driver) +STATUS php_http_client_driver_add(php_http_client_driver_t *driver) { return zend_hash_add(&php_http_client_drivers, driver->name_str, driver->name_len + 1, (void *) driver, sizeof(php_http_client_driver_t), NULL); } -PHP_HTTP_API STATUS php_http_client_driver_get(const char *name_str, size_t name_len, php_http_client_driver_t *driver) +STATUS php_http_client_driver_get(const char *name_str, size_t name_len, php_http_client_driver_t *driver) { php_http_client_driver_t *tmp; @@ -49,7 +49,7 @@ static int apply_driver_list(void *p, void *arg TSRMLS_DC) return ZEND_HASH_APPLY_KEEP; } -PHP_HTTP_API void php_http_client_driver_list(HashTable *ht TSRMLS_DC) +void php_http_client_driver_list(HashTable *ht TSRMLS_DC) { zend_hash_apply_with_argument(&php_http_client_drivers, apply_driver_list, ht TSRMLS_CC); } @@ -157,7 +157,7 @@ static void queue_dtor(void *enqueued) } } -PHP_HTTP_API php_http_client_t *php_http_client_init(php_http_client_t *h, php_http_client_ops_t *ops, php_resource_factory_t *rf, void *init_arg TSRMLS_DC) +php_http_client_t *php_http_client_init(php_http_client_t *h, php_http_client_ops_t *ops, php_resource_factory_t *rf, void *init_arg TSRMLS_DC) { php_http_client_t *free_h = NULL; @@ -178,9 +178,9 @@ PHP_HTTP_API php_http_client_t *php_http_client_init(php_http_client_t *h, php_h if (h->ops->init) { if (!(h = h->ops->init(h, init_arg))) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Could not initialize client"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize client"); if (free_h) { - efree(h); + efree(free_h); } } } @@ -188,7 +188,7 @@ PHP_HTTP_API php_http_client_t *php_http_client_init(php_http_client_t *h, php_h return h; } -PHP_HTTP_API php_http_client_t *php_http_client_copy(php_http_client_t *from, php_http_client_t *to) +php_http_client_t *php_http_client_copy(php_http_client_t *from, php_http_client_t *to) { if (from->ops->copy) { return from->ops->copy(from, to); @@ -197,7 +197,7 @@ PHP_HTTP_API php_http_client_t *php_http_client_copy(php_http_client_t *from, ph return NULL; } -PHP_HTTP_API void php_http_client_dtor(php_http_client_t *h) +void php_http_client_dtor(php_http_client_t *h) { php_http_client_reset(h); @@ -208,7 +208,7 @@ PHP_HTTP_API void php_http_client_dtor(php_http_client_t *h) php_resource_factory_free(&h->rf); } -PHP_HTTP_API void php_http_client_free(php_http_client_t **h) { +void php_http_client_free(php_http_client_t **h) { if (*h) { php_http_client_dtor(*h); efree(*h); @@ -216,13 +216,13 @@ PHP_HTTP_API void php_http_client_free(php_http_client_t **h) { } } -PHP_HTTP_API STATUS php_http_client_enqueue(php_http_client_t *h, php_http_client_enqueue_t *enqueue) +STATUS php_http_client_enqueue(php_http_client_t *h, php_http_client_enqueue_t *enqueue) { TSRMLS_FETCH_FROM_CTX(h->ts); if (h->ops->enqueue) { if (php_http_client_enqueued(h, enqueue->request, NULL)) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Failed to enqueue request; request already in queue"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enqueue request; request already in queue"); return FAILURE; } return h->ops->enqueue(h, enqueue); @@ -231,7 +231,7 @@ PHP_HTTP_API STATUS php_http_client_enqueue(php_http_client_t *h, php_http_clien return FAILURE; } -PHP_HTTP_API STATUS php_http_client_dequeue(php_http_client_t *h, php_http_message_t *request) +STATUS php_http_client_dequeue(php_http_client_t *h, php_http_message_t *request) { TSRMLS_FETCH_FROM_CTX(h->ts); @@ -239,7 +239,7 @@ PHP_HTTP_API STATUS php_http_client_dequeue(php_http_client_t *h, php_http_messa php_http_client_enqueue_t *enqueue = php_http_client_enqueued(h, request, NULL); if (!enqueue) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Failed to dequeue request; request not in queue"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to dequeue request; request not in queue"); return FAILURE; } return h->ops->dequeue(h, enqueue); @@ -247,7 +247,7 @@ PHP_HTTP_API STATUS php_http_client_dequeue(php_http_client_t *h, php_http_messa return FAILURE; } -PHP_HTTP_API php_http_client_enqueue_t *php_http_client_enqueued(php_http_client_t *h, void *compare_arg, php_http_client_enqueue_cmp_func_t compare_func) +php_http_client_enqueue_t *php_http_client_enqueued(php_http_client_t *h, void *compare_arg, php_http_client_enqueue_cmp_func_t compare_func) { zend_llist_element *el = NULL; @@ -267,7 +267,7 @@ PHP_HTTP_API php_http_client_enqueue_t *php_http_client_enqueued(php_http_client return el ? (php_http_client_enqueue_t *) el->data : NULL; } -PHP_HTTP_API STATUS php_http_client_wait(php_http_client_t *h, struct timeval *custom_timeout) +STATUS php_http_client_wait(php_http_client_t *h, struct timeval *custom_timeout) { if (h->ops->wait) { return h->ops->wait(h, custom_timeout); @@ -276,7 +276,7 @@ PHP_HTTP_API STATUS php_http_client_wait(php_http_client_t *h, struct timeval *c return FAILURE; } -PHP_HTTP_API int php_http_client_once(php_http_client_t *h) +int php_http_client_once(php_http_client_t *h) { if (h->ops->once) { return h->ops->once(h); @@ -285,7 +285,7 @@ PHP_HTTP_API int php_http_client_once(php_http_client_t *h) return FAILURE; } -PHP_HTTP_API STATUS php_http_client_exec(php_http_client_t *h) +STATUS php_http_client_exec(php_http_client_t *h) { if (h->ops->exec) { return h->ops->exec(h); @@ -294,7 +294,7 @@ PHP_HTTP_API STATUS php_http_client_exec(php_http_client_t *h) return FAILURE; } -PHP_HTTP_API void php_http_client_reset(php_http_client_t *h) +void php_http_client_reset(php_http_client_t *h) { if (h->ops->reset) { h->ops->reset(h); @@ -304,7 +304,7 @@ PHP_HTTP_API void php_http_client_reset(php_http_client_t *h) zend_llist_clean(&h->responses); } -PHP_HTTP_API STATUS php_http_client_setopt(php_http_client_t *h, php_http_client_setopt_opt_t opt, void *arg) +STATUS php_http_client_setopt(php_http_client_t *h, php_http_client_setopt_opt_t opt, void *arg) { if (h->ops->setopt) { return h->ops->setopt(h, opt, arg); @@ -313,7 +313,7 @@ PHP_HTTP_API STATUS php_http_client_setopt(php_http_client_t *h, php_http_client return FAILURE; } -PHP_HTTP_API STATUS php_http_client_getopt(php_http_client_t *h, php_http_client_getopt_opt_t opt, void *arg, void *res_ptr) +STATUS php_http_client_getopt(php_http_client_t *h, php_http_client_getopt_opt_t opt, void *arg, void *res_ptr) { if (h->ops->getopt) { return h->ops->getopt(h, opt, arg, res_ptr); @@ -418,11 +418,12 @@ static STATUS handle_response(void *arg, php_http_client_t *client, php_http_cli if (e->closure.fci.size) { zval *retval = NULL; + zend_error_handling zeh; zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 1, &zresponse); - with_error_handling(EH_NORMAL, NULL) { - zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL TSRMLS_CC); - } end_error_handling(); + zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); + zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL TSRMLS_CC); + zend_restore_error_handling(&zeh TSRMLS_CC); zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 0); if (retval) { @@ -449,6 +450,7 @@ static STATUS handle_response(void *arg, php_http_client_t *client, php_http_cli static void handle_progress(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, php_http_client_progress_state_t *progress) { zval *zrequest, *zprogress, *retval = NULL, *zclient; + zend_error_handling zeh; TSRMLS_FETCH_FROM_CTX(client->ts); MAKE_STD_ZVAL(zclient); @@ -464,9 +466,9 @@ static void handle_progress(void *arg, php_http_client_t *client, php_http_clien add_property_double(zprogress, "dlnow", progress->dl.now); add_property_double(zprogress, "ultotal", progress->ul.total); add_property_double(zprogress, "ulnow", progress->ul.now); - with_error_handling(EH_NORMAL, NULL) { - zend_call_method_with_2_params(&zclient, NULL, NULL, "notify", &retval, zrequest, zprogress); - } end_error_handling(); + zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); + zend_call_method_with_2_params(&zclient, NULL, NULL, "notify", &retval, zrequest, zprogress); + zend_restore_error_handling(&zeh TSRMLS_CC); zval_ptr_dtor(&zclient); zval_ptr_dtor(&zrequest); zval_ptr_dtor(&zprogress); @@ -489,63 +491,64 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_construct, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { char *driver_str = NULL, *persistent_handle_str = NULL; int driver_len = 0, persistent_handle_len = 0; + php_http_client_driver_t driver; + php_resource_factory_t *rf = NULL; + php_http_client_object_t *obj; + zval *os; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &driver_str, &driver_len, &persistent_handle_str, &persistent_handle_len)) { - php_http_client_driver_t driver; + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &driver_str, &driver_len, &persistent_handle_str, &persistent_handle_len), invalid_arg, return); - if (SUCCESS == php_http_client_driver_get(driver_str, driver_len, &driver)) { - php_resource_factory_t *rf = NULL; - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *os; + if (SUCCESS != php_http_client_driver_get(driver_str, driver_len, &driver)) { + php_http_throw(unexpected_val, "Failed to locate \"%s\" client request handler", driver_str); + return; + } - MAKE_STD_ZVAL(os); - object_init_ex(os, spl_ce_SplObjectStorage); - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), os TSRMLS_CC); - zval_ptr_dtor(&os); + MAKE_STD_ZVAL(os); + object_init_ex(os, spl_ce_SplObjectStorage); + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), os TSRMLS_CC); + zval_ptr_dtor(&os); - if (persistent_handle_len) { - char *name_str; - size_t name_len; - php_persistent_handle_factory_t *pf; + if (persistent_handle_len) { + char *name_str; + size_t name_len; + php_persistent_handle_factory_t *pf; - name_len = spprintf(&name_str, 0, "http\\Client\\%s", driver.name_str); - php_http_pretty_key(name_str + sizeof("http\\Client"), driver.name_len, 1, 1); + name_len = spprintf(&name_str, 0, "http\\Client\\%s", driver.name_str); + php_http_pretty_key(name_str + sizeof("http\\Client"), driver.name_len, 1, 1); - if ((pf = php_persistent_handle_concede(NULL , name_str, name_len, persistent_handle_str, persistent_handle_len, NULL, NULL TSRMLS_CC))) { - rf = php_resource_factory_init(NULL, php_persistent_handle_get_resource_factory_ops(), pf, (void (*)(void *)) php_persistent_handle_abandon); - } + if ((pf = php_persistent_handle_concede(NULL , name_str, name_len, persistent_handle_str, persistent_handle_len, NULL, NULL TSRMLS_CC))) { + rf = php_resource_factory_init(NULL, php_persistent_handle_get_resource_factory_ops(), pf, (void (*)(void *)) php_persistent_handle_abandon); + } - efree(name_str); - } + efree(name_str); + } - if ((obj->client = php_http_client_init(NULL, driver.client_ops, rf, NULL TSRMLS_CC))) { - obj->client->callback.response.func = handle_response; - obj->client->callback.response.arg = obj; - obj->client->callback.progress.func = handle_progress; - obj->client->callback.progress.arg = obj; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - obj->client->responses.dtor = response_dtor; - } - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Failed to locate \"%s\" client request handler", driver_str); - } - } - } end_error_handling(); + php_http_expect(obj->client = php_http_client_init(NULL, driver.client_ops, rf, NULL TSRMLS_CC), runtime, return); + + obj->client->callback.response.func = handle_response; + obj->client->callback.response.arg = obj; + obj->client->callback.progress.func = handle_progress; + obj->client->callback.progress.arg = obj; + + obj->client->responses.dtor = response_dtor; } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_reset, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, reset) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_client_object_t *obj; + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + obj->iterator = 0; + php_http_client_reset(obj->client); - obj->iterator = 0; - php_http_client_reset(obj->client); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -602,38 +605,43 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_enqueue, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, enqueue) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *request; - zend_fcall_info fci = empty_fcall_info; - zend_fcall_info_cache fcc = empty_fcall_info_cache; + zval *request; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_http_client_object_t *obj; + php_http_message_object_t *msg_obj; + php_http_client_enqueue_t q; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|f", &request, php_http_client_request_class_entry, &fci, &fcc)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *msg_obj = zend_object_store_get_object(request TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|f", &request, php_http_client_request_class_entry, &fci, &fcc), invalid_arg, return); - if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Failed to enqueue request; request already in queue"); - } else { - php_http_client_enqueue_t q; - q.request = msg_obj->message; - q.options = combined_options(getThis(), request TSRMLS_CC); - q.dtor = msg_queue_dtor; - q.opaque = msg_obj; - q.closure.fci = fci; - q.closure.fcc = fcc; - - if (fci.size) { - Z_ADDREF_P(fci.function_name); - if (fci.object_ptr) { - Z_ADDREF_P(fci.object_ptr); - } - } + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + msg_obj = zend_object_store_get_object(request TSRMLS_CC); - zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); - php_http_client_enqueue(obj->client, &q); - } + if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { + php_http_throw(bad_method_call, "Failed to enqueue request; request already in queue", NULL); + return; + } + + q.request = msg_obj->message; + q.options = combined_options(getThis(), request TSRMLS_CC); + q.dtor = msg_queue_dtor; + q.opaque = msg_obj; + q.closure.fci = fci; + q.closure.fcc = fcc; + + if (fci.size) { + Z_ADDREF_P(fci.function_name); + if (fci.object_ptr) { + Z_ADDREF_P(fci.object_ptr); } - } end_error_handling(); + } + + zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); + + php_http_expect(SUCCESS == php_http_client_enqueue(obj->client, &q), runtime, + msg_queue_dtor(&q); + return; + ); RETVAL_ZVAL(getThis(), 1, 0); } @@ -643,16 +651,21 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_dequeue, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, dequeue) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *request; + zval *request; + php_http_client_object_t *obj; + php_http_message_object_t *msg_obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *msg_obj = zend_object_store_get_object(request TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry), invalid_arg, return); - php_http_client_dequeue(obj->client, msg_obj->message); - } - } end_error_handling(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + msg_obj = zend_object_store_get_object(request TSRMLS_CC); + + if (!php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { + php_http_throw(bad_method_call, "Failed to dequeue request; request not in queue", NULL); + return; + } + + php_http_expect(SUCCESS == php_http_client_dequeue(obj->client, msg_obj->message), runtime, return); RETVAL_ZVAL(getThis(), 1, 0); } @@ -663,36 +676,42 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_requeue, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, requeue) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *request; - zend_fcall_info fci = empty_fcall_info; - zend_fcall_info_cache fcc = empty_fcall_info_cache; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|f", &request, php_http_client_request_class_entry, &fci, &fcc)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *msg_obj = zend_object_store_get_object(request TSRMLS_CC); - php_http_client_enqueue_t q; - q.request = msg_obj->message; - q.options = combined_options(getThis(), request TSRMLS_CC); - q.dtor = msg_queue_dtor; - q.opaque = msg_obj; - q.closure.fci = fci; - q.closure.fcc = fcc; - - if (fci.size) { - Z_ADDREF_P(fci.function_name); - if (fci.object_ptr) { - Z_ADDREF_P(fci.object_ptr); - } - } + zval *request; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_http_client_object_t *obj; + php_http_message_object_t *msg_obj; + php_http_client_enqueue_t q; - zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); - if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { - php_http_client_dequeue(obj->client, msg_obj->message); - } - php_http_client_enqueue(obj->client, &q); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|f", &request, php_http_client_request_class_entry, &fci, &fcc), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + msg_obj = zend_object_store_get_object(request TSRMLS_CC); + + if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { + php_http_expect(SUCCESS == php_http_client_dequeue(obj->client, msg_obj->message), runtime, return); + } + + q.request = msg_obj->message; + q.options = combined_options(getThis(), request TSRMLS_CC); + q.dtor = msg_queue_dtor; + q.opaque = msg_obj; + q.closure.fci = fci; + q.closure.fcc = fcc; + + if (fci.size) { + Z_ADDREF_P(fci.function_name); + if (fci.object_ptr) { + Z_ADDREF_P(fci.object_ptr); } - } end_error_handling(); + } + + zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); + + php_http_expect(SUCCESS == php_http_client_enqueue(obj->client, &q), runtime, + msg_queue_dtor(&q); + return; + ); RETVAL_ZVAL(getThis(), 1, 0); } @@ -714,35 +733,39 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getResponse) { zval *zrequest = NULL; + php_http_client_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O", &zrequest, php_http_client_request_class_entry)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O", &zrequest, php_http_client_request_class_entry), invalid_arg, return); - if (!zrequest) { - /* pop off the last respone */ - if (obj->client->responses.tail) { - php_http_message_object_t *response_obj = *(php_http_message_object_t **) obj->client->responses.tail->data; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - /* pop off and go */ - if (response_obj) { - RETVAL_OBJVAL(response_obj->zv, 1); - zend_llist_remove_tail(&obj->client->responses); - } - } - } else { - /* lookup the response with the request */ - zend_llist_element *el = NULL; - php_http_message_object_t *req_obj = zend_object_store_get_object(zrequest TSRMLS_CC); + if (zrequest) { + /* lookup the response with the request */ + zend_llist_element *el = NULL; + php_http_message_object_t *req_obj = zend_object_store_get_object(zrequest TSRMLS_CC); - for (el = obj->client->responses.head; el; el = el->next) { - php_http_message_object_t *response_obj = *(php_http_message_object_t **) el->data; + for (el = obj->client->responses.head; el; el = el->next) { + php_http_message_object_t *response_obj = *(php_http_message_object_t **) el->data; - if (response_obj->message->parent == req_obj->message) { - RETVAL_OBJVAL(response_obj->zv, 1); - break; - } + if (response_obj->message->parent == req_obj->message) { + RETURN_OBJVAL(response_obj->zv, 1); } } + + /* not found for the request! */ + php_http_throw(unexpected_val, "Could not find response for the request", NULL); + return; + } + + /* pop off the last response */ + if (obj->client->responses.tail) { + php_http_message_object_t *response_obj = *(php_http_message_object_t **) obj->client->responses.tail->data; + + /* pop off and go */ + if (response_obj) { + RETVAL_OBJVAL(response_obj->zv, 1); + zend_llist_remove_tail(&obj->client->responses); + } } } @@ -750,25 +773,25 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getHistory, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getHistory) { - if (SUCCESS == zend_parse_parameters_none()) { - zval *zhistory = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("history"), 0 TSRMLS_CC); - RETVAL_ZVAL(zhistory, 1, 0); - } + zval *zhistory; + + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + zhistory = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("history"), 0 TSRMLS_CC); + RETVAL_ZVAL(zhistory, 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_send, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, send) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_client_object_t *obj; - php_http_client_exec(obj->client); - } end_error_handling(); - } - } end_error_handling(); + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + php_http_expect(SUCCESS == php_http_client_exec(obj->client), runtime, return); RETVAL_ZVAL(getThis(), 1, 0); } @@ -808,12 +831,14 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, enablePipelining) { zend_bool enable = 1; + php_http_client_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + php_http_expect(SUCCESS == php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_ENABLE_PIPELINING, &enable), unexpected_val, return); - php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_ENABLE_PIPELINING, &enable); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -823,12 +848,14 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, enableEvents) { zend_bool enable = 1; + php_http_client_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + php_http_expect(SUCCESS == php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_USE_EVENTS, &enable), unexpected_val, return); - php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_USE_EVENTS, &enable); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -848,31 +875,34 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_notify, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, notify) { - zval *request = NULL, *zprogress = NULL; + zval *request = NULL, *zprogress = NULL, *observers, **args[3]; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!o!", &request, php_http_client_request_class_entry, &zprogress)) { - zval **args[3], *observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!o!", &request, php_http_client_request_class_entry, &zprogress), invalid_arg, return); - if (Z_TYPE_P(observers) == IS_OBJECT) { - Z_ADDREF_P(getThis()); - args[0] = &getThis(); - if (request) { - Z_ADDREF_P(request); - } - args[1] = &request; - if (zprogress) { - Z_ADDREF_P(zprogress); - } - args[2] = &zprogress; - spl_iterator_apply(observers, notify, args TSRMLS_CC); - zval_ptr_dtor(&getThis()); - if (request) { - zval_ptr_dtor(&request); - } - if (zprogress) { - zval_ptr_dtor(&zprogress); - } - } + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + + if (Z_TYPE_P(observers) != IS_OBJECT) { + php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); + return; + } + + Z_ADDREF_P(getThis()); + args[0] = &getThis(); + if (request) { + Z_ADDREF_P(request); + } + args[1] = &request; + if (zprogress) { + Z_ADDREF_P(zprogress); + } + args[2] = &zprogress; + spl_iterator_apply(observers, notify, args TSRMLS_CC); + zval_ptr_dtor(&getThis()); + if (request) { + zval_ptr_dtor(&request); + } + if (zprogress) { + zval_ptr_dtor(&zprogress); } RETVAL_ZVAL(getThis(), 1, 0); @@ -883,14 +913,20 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_attach, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, attach) { - zval *observer; + zval *observers, *observer, *retval = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &observer, spl_ce_SplObserver)) { - zval *retval = NULL, *observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); - zend_call_method_with_1_params(&observers, NULL, NULL, "attach", &retval, observer); - if (retval) { - zval_ptr_dtor(&retval); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &observer, spl_ce_SplObserver), invalid_arg, return); + + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + + if (Z_TYPE_P(observers) != IS_OBJECT) { + php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); + return; + } + + zend_call_method_with_1_params(&observers, NULL, NULL, "attach", &retval, observer); + if (retval) { + zval_ptr_dtor(&retval); } RETVAL_ZVAL(getThis(), 1, 0); @@ -901,11 +937,19 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_detach, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, detach) { - zval *observer; + zval *observers, *observer, *retval = NULL; + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &observer, spl_ce_SplObserver), invalid_arg, return); + + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &observer, spl_ce_SplObserver)) { - zval *retval, *observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); - zend_call_method_with_1_params(&observers, NULL, NULL, "detach", &retval, observer); + if (Z_TYPE_P(observers) != IS_OBJECT) { + php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); + return; + } + + zend_call_method_with_1_params(&observers, NULL, NULL, "detach", &retval, observer); + if (retval) { zval_ptr_dtor(&retval); } @@ -916,12 +960,18 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getObservers, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getObservers) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - zval *observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); - RETVAL_ZVAL(observers, 1, 0); - } - } end_error_handling(); + zval *observers; + + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + + if (Z_TYPE_P(observers) != IS_OBJECT) { + php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); + return; + } + + RETVAL_ZVAL(observers, 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getProgressInfo, 0, 0, 1) @@ -930,25 +980,25 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getProgressInfo) { zval *request; + php_http_client_object_t *obj; + php_http_message_object_t *req_obj; + php_http_client_progress_state_t *progress; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *req_obj = zend_object_store_get_object(request TSRMLS_CC); - php_http_client_progress_state_t *progress; - - if (SUCCESS == php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_PROGRESS_INFO, req_obj->message, &progress)) { - object_init(return_value); - add_property_bool(return_value, "started", progress->started); - add_property_bool(return_value, "finished", progress->finished); - add_property_string(return_value, "info", STR_PTR(progress->info), 1); - add_property_double(return_value, "dltotal", progress->dl.total); - add_property_double(return_value, "dlnow", progress->dl.now); - add_property_double(return_value, "ultotal", progress->ul.total); - add_property_double(return_value, "ulnow", progress->ul.now); - } - } - } end_error_handling(); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + req_obj = zend_object_store_get_object(request TSRMLS_CC); + + php_http_expect(SUCCESS == php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_PROGRESS_INFO, req_obj->message, &progress), unexpected_val, return); + + object_init(return_value); + add_property_bool(return_value, "started", progress->started); + add_property_bool(return_value, "finished", progress->finished); + add_property_string(return_value, "info", STR_PTR(progress->info), 1); + add_property_double(return_value, "dltotal", progress->dl.total); + add_property_double(return_value, "dlnow", progress->dl.now); + add_property_double(return_value, "ultotal", progress->ul.total); + add_property_double(return_value, "ulnow", progress->ul.now); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getTransferInfo, 0, 0, 1) @@ -957,18 +1007,18 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getTransferInfo) { zval *request; + HashTable *info; + php_http_client_object_t *obj; + php_http_message_object_t *req_obj; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry)) { - HashTable *info; - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *req_obj = zend_object_store_get_object(request TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry), invalid_arg, return); - object_init(return_value); - info = HASH_OF(return_value); - php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_TRANSFER_INFO, req_obj->message, &info); - } - } end_error_handling(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + req_obj = zend_object_store_get_object(request TSRMLS_CC); + + object_init(return_value); + info = HASH_OF(return_value); + php_http_expect(SUCCESS == php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_TRANSFER_INFO, req_obj->message, &info), unexpected_val, return); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_setOptions, 0, 0, 0) @@ -978,11 +1028,11 @@ static PHP_METHOD(HttpClient, setOptions) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set(getThis(), opts TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set(getThis(), opts TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getOptions, 0, 0, 0) @@ -1002,11 +1052,11 @@ static PHP_METHOD(HttpClient, setSslOptions) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_addSslOptions, 0, 0, 0) @@ -1016,11 +1066,11 @@ static PHP_METHOD(HttpClient, addSslOptions) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getSslOptions, 0, 0, 0) @@ -1039,11 +1089,11 @@ static PHP_METHOD(HttpClient, setCookies) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set_subr(getThis(), ZEND_STRS("cookies"), opts, 1 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set_subr(getThis(), ZEND_STRS("cookies"), opts, 1 TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_addCookies, 0, 0, 0) @@ -1053,11 +1103,11 @@ static PHP_METHOD(HttpClient, addCookies) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set_subr(getThis(), ZEND_STRS("cookies"), opts, 0 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set_subr(getThis(), ZEND_STRS("cookies"), opts, 0 TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getCookies, 0, 0, 0) diff --git a/php_http_client_curl.c b/php_http_client_curl.c index 2dfd3d7..fbb950a 100644 --- a/php_http_client_curl.c +++ b/php_http_client_curl.c @@ -516,7 +516,7 @@ static void php_http_curlm_responsehandler(php_http_client_t *context) if (msg && CURLMSG_DONE == msg->msg) { if (CURLE_OK != msg->data.result) { php_http_curle_storage_t *st = php_http_curle_get_storage(msg->easy_handle); - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "%s; %s (%s)", curl_easy_strerror(msg->data.result), STR_PTR(st->errorbuffer), STR_PTR(st->url)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s; %s (%s)", curl_easy_strerror(msg->data.result), STR_PTR(st->errorbuffer), STR_PTR(st->url)); } if ((enqueue = php_http_client_enqueued(context, msg->easy_handle, compare_queue))) { @@ -570,7 +570,7 @@ static void php_http_curlm_timeout_callback(int socket, short action, void *even while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle, CURL_SOCKET_TIMEOUT, 0, &curl->unfinished))); if (CURLM_OK != rc) { - php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "%s", curl_multi_strerror(rc)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc)); } php_http_curlm_responsehandler(context); @@ -592,7 +592,7 @@ static void php_http_curlm_event_callback(int socket, short action, void *event_ while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle, socket, etoca(action), &curl->unfinished))); if (CURLM_OK != rc) { - php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "%s", curl_multi_strerror(rc)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc)); } php_http_curlm_responsehandler(context); @@ -643,7 +643,7 @@ static int php_http_curlm_socket_callback(CURL *easy, curl_socket_t sock, int ac return 0; default: - php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "Unknown socket action %d", action); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown socket action %d", action); return -1; } @@ -1307,7 +1307,7 @@ static STATUS php_http_curle_set_option(php_http_option_t *opt, zval *val, void break; } if (rv != SUCCESS) { - php_http_error(HE_NOTICE, PHP_HTTP_E_CLIENT, "Could not set option %s", opt->name.s); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s", opt->name.s); } return rv; } @@ -1370,7 +1370,7 @@ static php_http_client_curl_handler_t *php_http_client_curl_handler_init(php_htt TSRMLS_FETCH_FROM_CTX(h->ts); if (!(handle = php_resource_factory_handle_ctor(rf, NULL TSRMLS_CC))) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Failed to initialize curl handle"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize curl handle"); return NULL; } @@ -1420,7 +1420,7 @@ static STATUS php_http_client_curl_handler_prepare(php_http_client_curl_handler_ /* request url */ if (!PHP_HTTP_INFO(msg).request.url) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Cannot request empty URL"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot request empty URL"); return FAILURE; } storage->errorbuffer[0] = '\0'; @@ -1452,7 +1452,7 @@ static STATUS php_http_client_curl_handler_prepare(php_http_client_curl_handler_ if (PHP_HTTP_INFO(msg).request.method) { curl_easy_setopt(curl->handle, CURLOPT_CUSTOMREQUEST, PHP_HTTP_INFO(msg).request.method); } else { - php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_METHOD, "Cannot use empty request method"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot use empty request method"); return FAILURE; } break; @@ -1540,7 +1540,7 @@ static php_http_client_t *php_http_client_curl_init(php_http_client_t *h, void * TSRMLS_FETCH_FROM_CTX(h->ts); if (!handle && !(handle = php_resource_factory_handle_ctor(h->rf, NULL TSRMLS_CC))) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_POOL, "Failed to initialize curl handle"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize curl handle"); return NULL; } @@ -1588,14 +1588,14 @@ static php_resource_factory_t *create_rf(const char *url TSRMLS_DC) php_resource_factory_t *rf = NULL; if (!url || !*url) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Cannot request empty URL"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot request empty URL"); return NULL; } purl = php_url_parse(url); if (!purl) { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Could not parse URL '%s'", url); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse URL '%s'", url); return NULL; } else { char *id_str = NULL; @@ -1657,7 +1657,7 @@ static STATUS php_http_client_curl_enqueue(php_http_client_t *h, php_http_client return SUCCESS; } else { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_POOL, "Could not enqueue request: %s", curl_multi_strerror(rs)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs)); return FAILURE; } } @@ -1673,7 +1673,7 @@ static STATUS php_http_client_curl_dequeue(php_http_client_t *h, php_http_client zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue); return SUCCESS; } else { - php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Could not dequeue request: %s", curl_multi_strerror(rs)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not dequeue request: %s", curl_multi_strerror(rs)); } return FAILURE; @@ -1706,7 +1706,7 @@ static STATUS php_http_client_curl_wait(php_http_client_t *h, struct timeval *cu if (curl->useevents) { TSRMLS_FETCH_FROM_CTX(h->ts); - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "not implemented"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "not implemented"); return FAILURE; } #endif @@ -1747,7 +1747,7 @@ static int php_http_client_curl_once(php_http_client_t *h) #if PHP_HTTP_HAVE_EVENT if (curl->useevents) { TSRMLS_FETCH_FROM_CTX(h->ts); - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "not implemented"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "not implemented"); return FAILURE; } #endif @@ -1777,7 +1777,7 @@ static STATUS php_http_client_curl_exec(php_http_client_t *h) #endif if (ev_rc < 0) { - php_http_error(HE_ERROR, PHP_HTTP_E_RUNTIME, "Error in event_base_dispatch()"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in event_base_dispatch()"); return FAILURE; } } while (curl->unfinished); @@ -1788,9 +1788,9 @@ static STATUS php_http_client_curl_exec(php_http_client_t *h) if (SUCCESS != php_http_client_curl_wait(h, NULL)) { #ifdef PHP_WIN32 /* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */ - php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "WinSock error: %d", WSAGetLastError()); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "WinSock error: %d", WSAGetLastError()); #else - php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, strerror(errno)); #endif return FAILURE; } @@ -1881,7 +1881,7 @@ static php_http_client_ops_t php_http_client_curl_ops = { php_http_client_curl_getopt }; -PHP_HTTP_API php_http_client_ops_t *php_http_client_curl_get_ops(void) +php_http_client_ops_t *php_http_client_curl_get_ops(void) { return &php_http_client_curl_ops; } diff --git a/php_http_client_request.c b/php_http_client_request.c index db8ef51..12f2014 100644 --- a/php_http_client_request.c +++ b/php_http_client_request.c @@ -16,6 +16,13 @@ void php_http_client_options_set_subr(zval *this_ptr, char *key, size_t len, zva void php_http_client_options_set(zval *this_ptr, zval *opts TSRMLS_DC); void php_http_client_options_get_subr(zval *this_ptr, char *key, size_t len, zval *return_value TSRMLS_DC); +#define PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj) \ + do { \ + if (!obj->message) { \ + obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, NULL TSRMLS_CC); \ + } \ + } while(0) + ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest___construct, 0, 0, 0) ZEND_ARG_INFO(0, method) ZEND_ARG_INFO(0, url) @@ -27,31 +34,30 @@ static PHP_METHOD(HttpClientRequest, __construct) char *meth_str = NULL, *url_str = NULL; int meth_len = 0, url_len = 0; zval *zheaders = NULL, *zbody = NULL; + php_http_message_object_t *obj; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!a!O!", &meth_str, &meth_len, &url_str, &url_len, &zheaders, &zbody, php_http_message_body_class_entry)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!a!O!", &meth_str, &meth_len, &url_str, &url_len, &zheaders, &zbody, php_http_message_body_class_entry), invalid_arg, return); - if (obj->message) { - php_http_message_set_type(obj->message, PHP_HTTP_REQUEST); - } else { - obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, NULL TSRMLS_CC); - } + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (zbody) { - php_http_message_object_set_body(obj, zbody TSRMLS_CC); - } - if (meth_str && meth_len) { - PHP_HTTP_INFO(obj->message).request.method = estrndup(meth_str, meth_len); - } - if (url_str && url_len) { - PHP_HTTP_INFO(obj->message).request.url = estrndup(url_str, url_len); - } - if (zheaders) { - array_copy(Z_ARRVAL_P(zheaders), &obj->message->hdrs); - } - } - } end_error_handling(); + if (obj->message) { + php_http_message_set_type(obj->message, PHP_HTTP_REQUEST); + } else { + obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, NULL TSRMLS_CC); + } + + if (zbody) { + php_http_expect(SUCCESS == php_http_message_object_set_body(obj, zbody TSRMLS_CC), unexpected_val, return); + } + if (meth_str && meth_len) { + PHP_HTTP_INFO(obj->message).request.method = estrndup(meth_str, meth_len); + } + if (url_str && url_len) { + PHP_HTTP_INFO(obj->message).request.url = estrndup(url_str, url_len); + } + if (zheaders) { + array_copy(Z_ARRVAL_P(zheaders), &obj->message->hdrs); + } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setContentType, 0, 0, 1) @@ -61,23 +67,24 @@ static PHP_METHOD(HttpClientRequest, setContentType) { char *ct_str; int ct_len; + php_http_message_object_t *obj; + zval *zct; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ct_str, &ct_len)) { - int invalid = 0; + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ct_str, &ct_len), invalid_arg, return); - if (ct_len) { - PHP_HTTP_CHECK_CONTENT_TYPE(ct_str, invalid = 1); - } + if (ct_len && !strchr(ct_str, '/')) { + php_http_throw(unexpected_val, "Content type \"%s\" does not seem to contain a primary and a secondary part", ct_str); + return; + } - if (!invalid) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *zct; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj); + + MAKE_STD_ZVAL(zct); + ZVAL_STRINGL(zct, ct_str, ct_len, 1); + zend_hash_update(&obj->message->hdrs, "Content-Type", sizeof("Content-Type"), (void *) &zct, sizeof(void *), NULL); - MAKE_STD_ZVAL(zct); - ZVAL_STRINGL(zct, ct_str, ct_len, 1); - zend_hash_update(&obj->message->hdrs, "Content-Type", sizeof("Content-Type"), (void *) &zct, sizeof(void *), NULL); - } - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -89,6 +96,8 @@ static PHP_METHOD(HttpClientRequest, getContentType) php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); zval *zct; + PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj); + php_http_message_update_headers(obj->message); zct = php_http_message_header(obj->message, ZEND_STRL("Content-Type"), 1); if (zct) { @@ -103,41 +112,48 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClientRequest, setQuery) { zval *qdata = NULL; + php_http_message_object_t *obj; + php_url *old_url = NULL, new_url = {NULL}; + char empty[] = ""; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &qdata)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_url *old_url = NULL, new_url = {NULL}; - char empty[] = ""; + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &qdata), invalid_arg, return); - if (qdata) { - zval arr, str; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - INIT_PZVAL(&arr); - array_init(&arr); - INIT_PZVAL(&str); - ZVAL_NULL(&str); + PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj); - php_http_querystring_update(&arr, qdata, &str TSRMLS_CC); - new_url.query = Z_STRVAL(str); - zval_dtor(&arr); - } else { - new_url.query = &empty[0]; - } + if (qdata) { + zval arr, str; - if (obj->message->http.info.request.url) { - old_url = php_url_parse(obj->message->http.info.request.url); - efree(obj->message->http.info.request.url); - } + INIT_PZVAL(&arr); + array_init(&arr); + INIT_PZVAL(&str); + ZVAL_NULL(&str); + + php_http_expect(SUCCESS == php_http_querystring_update(&arr, qdata, &str TSRMLS_CC), bad_querystring, + zval_dtor(&arr); + return; + ); + new_url.query = Z_STRVAL(str); + zval_dtor(&arr); + } else { + new_url.query = &empty[0]; + } - php_http_url(PHP_HTTP_URL_REPLACE, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC); + if (obj->message->http.info.request.url) { + old_url = php_url_parse(obj->message->http.info.request.url); + efree(obj->message->http.info.request.url); + } - if (old_url) { - php_url_free(old_url); - } - if (new_url.query != &empty[0]) { - STR_FREE(new_url.query); - } + php_http_url(PHP_HTTP_URL_REPLACE, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC); + + if (old_url) { + php_url_free(old_url); } + if (new_url.query != &empty[0]) { + STR_FREE(new_url.query); + } + RETVAL_ZVAL(getThis(), 1, 0); } @@ -148,6 +164,8 @@ static PHP_METHOD(HttpClientRequest, getQuery) if (SUCCESS == zend_parse_parameters_none()) { php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj); + if (obj->message->http.info.request.url) { php_url *purl = php_url_parse(obj->message->http.info.request.url); @@ -167,35 +185,40 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_addQuery, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClientRequest, addQuery) { - zval *qdata; + zval *qdata, arr, str; + php_http_message_object_t *obj; + php_url *old_url = NULL, new_url = {NULL}; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &qdata)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_url *old_url = NULL, new_url = {NULL}; + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &qdata), invalid_arg, return); - zval arr, str; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - INIT_PZVAL(&arr); - array_init(&arr); - INIT_PZVAL(&str); - ZVAL_NULL(&str); + PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj); - php_http_querystring_update(&arr, qdata, &str TSRMLS_CC); - new_url.query = Z_STRVAL(str); - zval_dtor(&arr); + INIT_PZVAL(&arr); + array_init(&arr); + INIT_PZVAL(&str); + ZVAL_NULL(&str); - if (obj->message->http.info.request.url) { - old_url = php_url_parse(obj->message->http.info.request.url); - efree(obj->message->http.info.request.url); - } + php_http_expect(SUCCESS == php_http_querystring_update(&arr, qdata, &str TSRMLS_CC), bad_querystring, + zval_dtor(&arr); + return; + ); + new_url.query = Z_STRVAL(str); + zval_dtor(&arr); + + if (obj->message->http.info.request.url) { + old_url = php_url_parse(obj->message->http.info.request.url); + efree(obj->message->http.info.request.url); + } - php_http_url(PHP_HTTP_URL_JOIN_QUERY, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC); + php_http_url(PHP_HTTP_URL_JOIN_QUERY, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC); - if (old_url) { - php_url_free(old_url); - } - STR_FREE(new_url.query); + if (old_url) { + php_url_free(old_url); } + STR_FREE(new_url.query); + RETVAL_ZVAL(getThis(), 1, 0); } @@ -206,11 +229,11 @@ static PHP_METHOD(HttpClientRequest, setOptions) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set(getThis(), opts TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set(getThis(), opts TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getOptions, 0, 0, 0) @@ -221,7 +244,6 @@ static PHP_METHOD(HttpClientRequest, getOptions) zval *zoptions = zend_read_property(php_http_client_request_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); RETURN_ZVAL(zoptions, 1, 0); } - RETURN_FALSE; } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setSslOptions, 0, 0, 0) @@ -231,11 +253,11 @@ static PHP_METHOD(HttpClientRequest, setSslOptions) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_addSslOptions, 0, 0, 0) @@ -245,11 +267,11 @@ static PHP_METHOD(HttpClientRequest, addSslOptions) { zval *opts = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC); + + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getSslOptions, 0, 0, 0) diff --git a/php_http_client_response.c b/php_http_client_response.c index 26e8517..b269caf 100644 --- a/php_http_client_response.c +++ b/php_http_client_response.c @@ -89,29 +89,28 @@ static PHP_METHOD(HttpClientResponse, getTransferInfo) { char *info_name = NULL; int info_len = 0; - zval *infop, *info; + zval *info; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &info_name, &info_len)) { - return; - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &info_name, &info_len), invalid_arg, return); info = zend_read_property(php_http_client_response_class_entry, getThis(), ZEND_STRL("transferInfo"), 0 TSRMLS_CC); /* request completed? */ - if (Z_TYPE_P(info) == IS_OBJECT) { - if (info_len && info_name) { - infop = zend_read_property(NULL, info, php_http_pretty_key(info_name, info_len, 0, 0), info_len, 0 TSRMLS_CC); - - if (infop) { - RETURN_ZVAL(infop, 1, 0); - } else { - php_http_error(HE_NOTICE, PHP_HTTP_E_INVALID_PARAM, "Could not find transfer info named %s", info_name); - } - } else { - RETURN_ZVAL(info, 1, 0); + if (Z_TYPE_P(info) != IS_OBJECT) { + php_http_throw(bad_method_call, "Incomplete state", NULL); + return; + } + + if (info_len && info_name) { + info = zend_read_property(NULL, info, php_http_pretty_key(info_name, info_len, 0, 0), info_len, 0 TSRMLS_CC); + + if (!info) { + php_http_throw(unexpected_val, "Could not find transfer info with name '%s'", info_name); + return; } } - RETURN_FALSE; + + RETURN_ZVAL(info, 1, 0); } static zend_function_entry php_http_client_response_methods[] = { @@ -128,6 +127,7 @@ PHP_MINIT_FUNCTION(http_client_response) INIT_NS_CLASS_ENTRY(ce, "http\\Client", "Response", php_http_client_response_methods); php_http_client_response_class_entry = zend_register_internal_class_ex(&ce, php_http_message_class_entry, NULL TSRMLS_CC); + zend_declare_property_null(php_http_client_response_class_entry, ZEND_STRL("transferInfo"), ZEND_ACC_PROTECTED TSRMLS_CC); return SUCCESS; } diff --git a/php_http_cookie.c b/php_http_cookie.c index dd8339b..1234e38 100644 --- a/php_http_cookie.c +++ b/php_http_cookie.c @@ -12,7 +12,7 @@ #include "php_http_api.h" -PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_init(php_http_cookie_list_t *list TSRMLS_DC) +php_http_cookie_list_t *php_http_cookie_list_init(php_http_cookie_list_t *list TSRMLS_DC) { if (!list) { list = emalloc(sizeof(*list)); @@ -32,7 +32,7 @@ PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_init(php_http_cookie_l return list; } -PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_copy(php_http_cookie_list_t *from, php_http_cookie_list_t *to) +php_http_cookie_list_t *php_http_cookie_list_copy(php_http_cookie_list_t *from, php_http_cookie_list_t *to) { TSRMLS_FETCH_FROM_CTX(from->ts); @@ -50,7 +50,7 @@ PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_copy(php_http_cookie_l return to; } -PHP_HTTP_API void php_http_cookie_list_dtor(php_http_cookie_list_t *list) +void php_http_cookie_list_dtor(php_http_cookie_list_t *list) { if (list) { zend_hash_destroy(&list->cookies); @@ -63,7 +63,7 @@ PHP_HTTP_API void php_http_cookie_list_dtor(php_http_cookie_list_t *list) -PHP_HTTP_API void php_http_cookie_list_free(php_http_cookie_list_t **list) +void php_http_cookie_list_free(php_http_cookie_list_t **list) { if (*list) { php_http_cookie_list_dtor(*list); @@ -72,7 +72,7 @@ PHP_HTTP_API void php_http_cookie_list_free(php_http_cookie_list_t **list) } } -PHP_HTTP_API const char *php_http_cookie_list_get_cookie(php_http_cookie_list_t *list, const char *name, size_t name_len, zval **zcookie) +const char *php_http_cookie_list_get_cookie(php_http_cookie_list_t *list, const char *name, size_t name_len, zval **zcookie) { zval **cookie; if ((SUCCESS != zend_symtable_find(&list->cookies, name, name_len + 1, (void *) &cookie)) || (Z_TYPE_PP(cookie) != IS_STRING)) { @@ -84,7 +84,7 @@ PHP_HTTP_API const char *php_http_cookie_list_get_cookie(php_http_cookie_list_t return Z_STRVAL_PP(cookie); } -PHP_HTTP_API const char *php_http_cookie_list_get_extra(php_http_cookie_list_t *list, const char *name, size_t name_len, zval **zextra) +const char *php_http_cookie_list_get_extra(php_http_cookie_list_t *list, const char *name, size_t name_len, zval **zextra) { zval **extra; @@ -97,7 +97,7 @@ PHP_HTTP_API const char *php_http_cookie_list_get_extra(php_http_cookie_list_t * return Z_STRVAL_PP(extra); } -PHP_HTTP_API void php_http_cookie_list_add_cookie(php_http_cookie_list_t *list, const char *name, size_t name_len, const char *value, size_t value_len) +void php_http_cookie_list_add_cookie(php_http_cookie_list_t *list, const char *name, size_t name_len, const char *value, size_t value_len) { zval *cookie_value; @@ -106,7 +106,7 @@ PHP_HTTP_API void php_http_cookie_list_add_cookie(php_http_cookie_list_t *list, zend_symtable_update(&list->cookies, name, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL); } -PHP_HTTP_API void php_http_cookie_list_add_extra(php_http_cookie_list_t *list, const char *name, size_t name_len, const char *value, size_t value_len) +void php_http_cookie_list_add_extra(php_http_cookie_list_t *list, const char *name, size_t name_len, const char *value, size_t value_len) { zval *cookie_value; @@ -169,7 +169,7 @@ static void add_entry(php_http_cookie_list_t *list, char **allowed_extras, long zval_ptr_dtor(&arg); } -PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_parse(php_http_cookie_list_t *list, const char *str, size_t len, long flags, char **allowed_extras TSRMLS_DC) +php_http_cookie_list_t *php_http_cookie_list_parse(php_http_cookie_list_t *list, const char *str, size_t len, long flags, char **allowed_extras TSRMLS_DC) { php_http_params_opts_t opts; HashTable params; @@ -203,7 +203,7 @@ PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_parse(php_http_cookie_ return list; } -PHP_HTTP_API void php_http_cookie_list_to_struct(php_http_cookie_list_t *list, zval *strct) +void php_http_cookie_list_to_struct(php_http_cookie_list_t *list, zval *strct) { zval array, *cookies, *extras; TSRMLS_FETCH_FROM_CTX(list->ts); @@ -227,7 +227,7 @@ PHP_HTTP_API void php_http_cookie_list_to_struct(php_http_cookie_list_t *list, z add_assoc_string(&array, "domain", STR_PTR(list->domain), 1); } -PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_from_struct(php_http_cookie_list_t *list, zval *strct TSRMLS_DC) +php_http_cookie_list_t *php_http_cookie_list_from_struct(php_http_cookie_list_t *list, zval *strct TSRMLS_DC) { zval **tmp, *cpy; HashTable *ht = HASH_OF(strct); @@ -302,7 +302,7 @@ static inline void append_encoded(php_http_buffer_t *buf, const char *key, size_ efree(enc_str[1]); } -PHP_HTTP_API void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, size_t *len) +void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, size_t *len) { php_http_buffer_t buf; zval **val; @@ -426,85 +426,88 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie___construct, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *zcookie = NULL; - long flags = 0; - HashTable *allowed_extras = NULL; + php_http_cookie_object_t *obj; + zval *zcookie = NULL; + long flags = 0; + char **ae = NULL; + HashTable *allowed_extras = NULL; + zend_error_handling zeh; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!lH", &zcookie, &flags, &allowed_extras)) { - if (zcookie) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - char **ae = NULL; + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!lH", &zcookie, &flags, &allowed_extras), invalid_arg, return); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (allowed_extras && zend_hash_num_elements(allowed_extras)) { - char **ae_ptr = safe_emalloc(zend_hash_num_elements(allowed_extras) + 1, sizeof(char *), 0); - HashPosition pos; - zval **val; + zend_replace_error_handling(EH_THROW, php_http_exception_runtime_class_entry, &zeh TSRMLS_CC); + if (zcookie) { - ae = ae_ptr; - FOREACH_HASH_VAL(pos, allowed_extras, val) { - zval *cpy = php_http_ztyp(IS_STRING, *val); + if (allowed_extras && zend_hash_num_elements(allowed_extras)) { + char **ae_ptr = safe_emalloc(zend_hash_num_elements(allowed_extras) + 1, sizeof(char *), 0); + HashPosition pos; + zval **val; - *ae_ptr++ = estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)); - zval_ptr_dtor(&cpy); - } - *ae_ptr = NULL; - } + ae = ae_ptr; + FOREACH_HASH_VAL(pos, allowed_extras, val) { + zval *cpy = php_http_ztyp(IS_STRING, *val); - switch (Z_TYPE_P(zcookie)) { - case IS_OBJECT: - if (instanceof_function(Z_OBJCE_P(zcookie), php_http_cookie_class_entry TSRMLS_CC)) { - php_http_cookie_object_t *zco = zend_object_store_get_object(zcookie TSRMLS_CC); - - if (zco->list) { - obj->list = php_http_cookie_list_copy(zco->list, NULL); - } - break; - } - /* no break */ - case IS_ARRAY: - obj->list = php_http_cookie_list_from_struct(obj->list, zcookie TSRMLS_CC); - break; - default: { - zval *cpy = php_http_ztyp(IS_STRING, zcookie); - - obj->list = php_http_cookie_list_parse(obj->list, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy), flags, ae TSRMLS_CC); - zval_ptr_dtor(&cpy); - break; - } - } + *ae_ptr++ = estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)); + zval_ptr_dtor(&cpy); + } + *ae_ptr = NULL; + } - if (ae) { - char **ae_ptr; + switch (Z_TYPE_P(zcookie)) { + case IS_OBJECT: + if (instanceof_function(Z_OBJCE_P(zcookie), php_http_cookie_class_entry TSRMLS_CC)) { + php_http_cookie_object_t *zco = zend_object_store_get_object(zcookie TSRMLS_CC); - for (ae_ptr = ae; *ae_ptr; ++ae_ptr) { - efree(*ae_ptr); - } - efree(ae); + if (zco->list) { + obj->list = php_http_cookie_list_copy(zco->list, NULL); } - } end_error_handling(); + break; + } + /* no break */ + case IS_ARRAY: + obj->list = php_http_cookie_list_from_struct(obj->list, zcookie TSRMLS_CC); + break; + default: { + zval *cpy = php_http_ztyp(IS_STRING, zcookie); + + obj->list = php_http_cookie_list_parse(obj->list, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy), flags, ae TSRMLS_CC); + zval_ptr_dtor(&cpy); + break; } } - PHP_HTTP_COOKIE_OBJECT_INIT(obj); - } end_error_handling(); + + if (ae) { + char **ae_ptr; + + for (ae_ptr = ae; *ae_ptr; ++ae_ptr) { + efree(*ae_ptr); + } + efree(ae); + } + } + zend_restore_error_handling(&zeh TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getCookies, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, getCookies) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + php_http_cookie_object_t *obj; - array_init(return_value); - array_copy(&obj->list->cookies, Z_ARRVAL_P(return_value)); + if (SUCCESS != zend_parse_parameters_none()) { return; } - RETURN_FALSE; + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + array_init(return_value); + array_copy(&obj->list->cookies, Z_ARRVAL_P(return_value)); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_setCookies, 0, 0, 0) @@ -513,17 +516,19 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, setCookies) { HashTable *cookies = NULL; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H", &cookies)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H", &cookies), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zend_hash_clean(&obj->list->cookies); - if (cookies) { - array_copy(cookies, &obj->list->cookies); - } + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + zend_hash_clean(&obj->list->cookies); + if (cookies) { + array_copy(cookies, &obj->list->cookies); } + RETVAL_ZVAL(getThis(), 1, 0); } @@ -533,14 +538,16 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, addCookies) { HashTable *cookies = NULL; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &cookies)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &cookies), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + array_join(cookies, &obj->list->cookies, 1, ARRAY_JOIN_STRONLY); - array_join(cookies, &obj->list->cookies, 1, ARRAY_JOIN_STRONLY); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -548,14 +555,18 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getExtras, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, getExtras) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_cookie_object_t *obj; - PHP_HTTP_COOKIE_OBJECT_INIT(obj); - - array_init(return_value); - array_copy(&obj->list->extras, Z_ARRVAL_P(return_value)); + if (SUCCESS != zend_parse_parameters_none()) { + return; } + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + array_init(return_value); + array_copy(&obj->list->extras, Z_ARRVAL_P(return_value)); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_setExtras, 0, 0, 0) @@ -564,17 +575,19 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, setExtras) { HashTable *extras = NULL; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H", &extras)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H", &extras), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zend_hash_clean(&obj->list->extras); - if (extras) { - array_copy(extras, &obj->list->extras); - } + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + zend_hash_clean(&obj->list->extras); + if (extras) { + array_copy(extras, &obj->list->extras); } + RETVAL_ZVAL(getThis(), 1, 0); } @@ -584,14 +597,16 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, addExtras) { HashTable *extras = NULL; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &extras)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &extras), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + array_join(extras, &obj->list->extras, 1, ARRAY_JOIN_STRONLY); - array_join(extras, &obj->list->extras, 1, ARRAY_JOIN_STRONLY); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -602,16 +617,19 @@ static PHP_METHOD(HttpCookie, getCookie) { char *name_str; int name_len; + zval *zvalue; + php_http_cookie_object_t *obj; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { + return; + } - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *zvalue; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + PHP_HTTP_COOKIE_OBJECT_INIT(obj); - if (php_http_cookie_list_get_cookie(obj->list, name_str, name_len, &zvalue)) { - RETURN_ZVAL(zvalue, 1, 0); - } + if (php_http_cookie_list_get_cookie(obj->list, name_str, name_len, &zvalue)) { + RETURN_ZVAL(zvalue, 1, 0); } } @@ -623,18 +641,20 @@ static PHP_METHOD(HttpCookie, setCookie) { char *name_str, *value_str = NULL; int name_len, value_len = 0; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &name_str, &name_len, &value_str, &value_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &name_str, &name_len, &value_str, &value_len), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (!value_str) { - php_http_cookie_list_del_cookie(obj->list, name_str, name_len); - } else { - php_http_cookie_list_add_cookie(obj->list, name_str, name_len, value_str, value_len); - } + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + if (!value_str) { + php_http_cookie_list_del_cookie(obj->list, name_str, name_len); + } else { + php_http_cookie_list_add_cookie(obj->list, name_str, name_len, value_str, value_len); } + RETVAL_ZVAL(getThis(), 1, 0); } @@ -646,14 +666,16 @@ static PHP_METHOD(HttpCookie, addCookie) { char *name_str, *value_str; int name_len, value_len; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name_str, &name_len, &value_str, &value_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name_str, &name_len, &value_str, &value_len), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + php_http_cookie_list_add_cookie(obj->list, name_str, name_len, value_str, value_len); - php_http_cookie_list_add_cookie(obj->list, name_str, name_len, value_str, value_len); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -664,16 +686,19 @@ static PHP_METHOD(HttpCookie, getExtra) { char *name_str; int name_len; + zval *zvalue; + php_http_cookie_object_t *obj; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { + return; + } - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - zval *zvalue; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + PHP_HTTP_COOKIE_OBJECT_INIT(obj); - if (php_http_cookie_list_get_extra(obj->list, name_str, name_len, &zvalue)) { - RETURN_ZVAL(zvalue, 1, 0); - } + if (php_http_cookie_list_get_extra(obj->list, name_str, name_len, &zvalue)) { + RETURN_ZVAL(zvalue, 1, 0); } } @@ -685,18 +710,20 @@ static PHP_METHOD(HttpCookie, setExtra) { char *name_str, *value_str = NULL; int name_len, value_len = 0; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &name_str, &name_len, &value_str, &value_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &name_str, &name_len, &value_str, &value_len), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (!value_str) { - php_http_cookie_list_del_extra(obj->list, name_str, name_len); - } else { - php_http_cookie_list_add_extra(obj->list, name_str, name_len, value_str, value_len); - } + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + if (!value_str) { + php_http_cookie_list_del_extra(obj->list, name_str, name_len); + } else { + php_http_cookie_list_add_extra(obj->list, name_str, name_len, value_str, value_len); } + RETVAL_ZVAL(getThis(), 1, 0); } @@ -708,14 +735,16 @@ static PHP_METHOD(HttpCookie, addExtra) { char *name_str, *value_str; int name_len, value_len; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name_str, &name_len, &value_str, &value_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name_str, &name_len, &value_str, &value_len), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + php_http_cookie_list_add_extra(obj->list, name_str, name_len, value_str, value_len); - php_http_cookie_list_add_extra(obj->list, name_str, name_len, value_str, value_len); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -723,15 +752,18 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getDomain, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, getDomain) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_cookie_object_t *obj; + + if (SUCCESS != zend_parse_parameters_none()) { + return; + } - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (obj->list->domain) { - RETURN_STRING(obj->list->domain, 1); - } - RETURN_NULL(); + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + if (obj->list->domain) { + RETURN_STRING(obj->list->domain, 1); } } @@ -742,14 +774,16 @@ static PHP_METHOD(HttpCookie, setDomain) { char *domain_str = NULL; int domain_len = 0; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &domain_str, &domain_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &domain_str, &domain_len), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + STR_SET(obj->list->domain, domain_str ? estrndup(domain_str, domain_len) : NULL); - STR_SET(obj->list->domain, domain_str ? estrndup(domain_str, domain_len) : NULL); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -757,15 +791,18 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getPath, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, getPath) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_cookie_object_t *obj; - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + if (SUCCESS != zend_parse_parameters_none()) { + return; + } - if (obj->list->path) { - RETURN_STRING(obj->list->path, 1); - } - RETURN_NULL(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + if (obj->list->path) { + RETURN_STRING(obj->list->path, 1); } } @@ -776,14 +813,16 @@ static PHP_METHOD(HttpCookie, setPath) { char *path_str = NULL; int path_len = 0; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &path_str, &path_len)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &path_str, &path_len), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + STR_SET(obj->list->path, path_str ? estrndup(path_str, path_len) : NULL); - STR_SET(obj->list->path, path_str ? estrndup(path_str, path_len) : NULL); - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -791,13 +830,17 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getExpires, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, getExpires) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + php_http_cookie_object_t *obj; - RETURN_LONG(obj->list->expires); + if (SUCCESS != zend_parse_parameters_none()) { + return; } + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + RETURN_LONG(obj->list->expires); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_setExpires, 0, 0, 0) @@ -806,14 +849,16 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, setExpires) { long ts = -1; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ts)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ts), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + obj->list->expires = ts; - obj->list->expires = ts; - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -821,13 +866,17 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getMaxAge, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, getMaxAge) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_cookie_object_t *obj; - PHP_HTTP_COOKIE_OBJECT_INIT(obj); - - RETURN_LONG(obj->list->max_age); + if (SUCCESS != zend_parse_parameters_none()) { + return; } + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + RETURN_LONG(obj->list->max_age); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_setMaxAge, 0, 0, 0) @@ -836,14 +885,16 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, setMaxAge) { long ts = -1; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ts)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ts), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + obj->list->max_age = ts; - obj->list->max_age = ts; - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -851,13 +902,17 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_getFlags, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, getFlags) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + php_http_cookie_object_t *obj; - RETURN_LONG(obj->list->flags); + if (SUCCESS != zend_parse_parameters_none()) { + return; } + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + RETURN_LONG(obj->list->flags); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_setFlags, 0, 0, 0) @@ -866,14 +921,16 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, setFlags) { long flags = 0; + php_http_cookie_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags)) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags), invalid_arg, return); - PHP_HTTP_COOKIE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + obj->list->flags = flags; - obj->list->flags = flags; - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -881,31 +938,39 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_toString, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, toString) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - char *str; - size_t len; + php_http_cookie_object_t *obj; + char *str; + size_t len; - PHP_HTTP_COOKIE_OBJECT_INIT(obj); - - php_http_cookie_list_to_string(obj->list, &str, &len); - RETURN_STRINGL(str, len, 0); + if (SUCCESS != zend_parse_parameters_none()) { + RETURN_EMPTY_STRING(); } - RETURN_EMPTY_STRING(); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + php_http_cookie_list_to_string(obj->list, &str, &len); + + RETURN_STRINGL(str, len, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_toArray, 0, 0, 0) ZEND_END_ARG_INFO();; static PHP_METHOD(HttpCookie, toArray) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_cookie_object_t *obj; - PHP_HTTP_COOKIE_OBJECT_INIT(obj); - - array_init(return_value); - php_http_cookie_list_to_struct(obj->list, return_value); + if (SUCCESS != zend_parse_parameters_none()) { + return; } + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_COOKIE_OBJECT_INIT(obj); + + array_init(return_value); + php_http_cookie_list_to_struct(obj->list, return_value); } static zend_function_entry php_http_cookie_methods[] = { @@ -949,7 +1014,7 @@ PHP_MINIT_FUNCTION(http_cookie) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Cookie", php_http_cookie_methods); - php_http_cookie_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_cookie_class_entry = zend_register_internal_class(&ce TSRMLS_CC); php_http_cookie_class_entry->create_object = php_http_cookie_object_new; memcpy(&php_http_cookie_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_http_cookie_object_handlers.clone_obj = php_http_cookie_object_clone; diff --git a/php_http_encoding.c b/php_http_encoding.c index 27f1de7..3c5393b 100644 --- a/php_http_encoding.c +++ b/php_http_encoding.c @@ -28,7 +28,7 @@ static inline int eol_match(char **line, int *eol_len) } } -PHP_HTTP_API const char *php_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC) +const char *php_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC) { int eol_len = 0; char *n_ptr = NULL; @@ -50,14 +50,14 @@ PHP_HTTP_API const char *php_http_encoding_dechunk(const char *encoded, size_t e * not encoded data and return a copy */ if (e_ptr == encoded) { - php_http_error(HE_NOTICE, PHP_HTTP_E_ENCODING, "Data does not seem to be chunked encoded"); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Data does not seem to be chunked encoded"); memcpy(*decoded, encoded, encoded_len); *decoded_len = encoded_len; decoded[*decoded_len] = '\0'; return encoded + encoded_len; } else { efree(*decoded); - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Expected chunk size at pos %tu of %zu but got trash", n_ptr - encoded, encoded_len); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected chunk size at pos %tu of %zu but got trash", n_ptr - encoded, encoded_len); return NULL; } } @@ -80,16 +80,16 @@ PHP_HTTP_API const char *php_http_encoding_dechunk(const char *encoded, size_t e /* there should be CRLF after the chunk size, but we'll ignore SP+ too */ if (*n_ptr && !eol_match(&n_ptr, &eol_len)) { if (eol_len == 2) { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Expected CRLF at pos %tu of %zu but got 0x%02X 0x%02X", n_ptr - encoded, encoded_len, *n_ptr, *(n_ptr + 1)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected CRLF at pos %tu of %zu but got 0x%02X 0x%02X", n_ptr - encoded, encoded_len, *n_ptr, *(n_ptr + 1)); } else { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Expected LF at pos %tu of %zu but got 0x%02X", n_ptr - encoded, encoded_len, *n_ptr); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected LF at pos %tu of %zu but got 0x%02X", n_ptr - encoded, encoded_len, *n_ptr); } } n_ptr += eol_len; /* chunk size pretends more data than we actually got, so it's probably a truncated message */ if (chunk_len > (rest = encoded + encoded_len - n_ptr)) { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Truncated message: chunk size %lu exceeds remaining data size %lu at pos %tu of %zu", chunk_len, rest, n_ptr - encoded, encoded_len); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Truncated message: chunk size %lu exceeds remaining data size %lu at pos %tu of %zu", chunk_len, rest, n_ptr - encoded, encoded_len); chunk_len = rest; } @@ -149,7 +149,7 @@ static inline int php_http_inflate_rounds(z_stream *Z, int flush, char **buf, si return status; } -PHP_HTTP_API STATUS php_http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC) +STATUS php_http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC) { int status, level, wbits, strategy; z_stream Z; @@ -186,11 +186,11 @@ PHP_HTTP_API STATUS php_http_encoding_deflate(int flags, const char *data, size_ } } - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Could not deflate data: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not deflate data: %s", zError(status)); return FAILURE; } -PHP_HTTP_API STATUS php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC) +STATUS php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC) { z_stream Z; int status, wbits = PHP_HTTP_WINDOW_BITS_ANY; @@ -228,11 +228,11 @@ retry_raw_inflate: } } - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Could not inflate data: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not inflate data: %s", zError(status)); return FAILURE; } -PHP_HTTP_API php_http_encoding_stream_t *php_http_encoding_stream_init(php_http_encoding_stream_t *s, php_http_encoding_stream_ops_t *ops, unsigned flags TSRMLS_DC) +php_http_encoding_stream_t *php_http_encoding_stream_init(php_http_encoding_stream_t *s, php_http_encoding_stream_ops_t *ops, unsigned flags TSRMLS_DC) { int freeme; @@ -260,7 +260,7 @@ PHP_HTTP_API php_http_encoding_stream_t *php_http_encoding_stream_init(php_http_ return NULL; } -PHP_HTTP_API php_http_encoding_stream_t *php_http_encoding_stream_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to) +php_http_encoding_stream_t *php_http_encoding_stream_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to) { TSRMLS_FETCH_FROM_CTX(from->ts); @@ -291,7 +291,7 @@ PHP_HTTP_API php_http_encoding_stream_t *php_http_encoding_stream_copy(php_http_ return NULL; } -PHP_HTTP_API STATUS php_http_encoding_stream_reset(php_http_encoding_stream_t **s) +STATUS php_http_encoding_stream_reset(php_http_encoding_stream_t **s) { php_http_encoding_stream_t *ss; if ((*s)->ops->dtor) { @@ -304,7 +304,7 @@ PHP_HTTP_API STATUS php_http_encoding_stream_reset(php_http_encoding_stream_t ** return FAILURE; } -PHP_HTTP_API STATUS php_http_encoding_stream_update(php_http_encoding_stream_t *s, const char *in_str, size_t in_len, char **out_str, size_t *out_len) +STATUS php_http_encoding_stream_update(php_http_encoding_stream_t *s, const char *in_str, size_t in_len, char **out_str, size_t *out_len) { if (!s->ops->update) { return FAILURE; @@ -312,7 +312,7 @@ PHP_HTTP_API STATUS php_http_encoding_stream_update(php_http_encoding_stream_t * return s->ops->update(s, in_str, in_len, out_str, out_len); } -PHP_HTTP_API STATUS php_http_encoding_stream_flush(php_http_encoding_stream_t *s, char **out_str, size_t *out_len) +STATUS php_http_encoding_stream_flush(php_http_encoding_stream_t *s, char **out_str, size_t *out_len) { if (!s->ops->flush) { *out_str = NULL; @@ -322,7 +322,7 @@ PHP_HTTP_API STATUS php_http_encoding_stream_flush(php_http_encoding_stream_t *s return s->ops->flush(s, out_str, out_len); } -PHP_HTTP_API zend_bool php_http_encoding_stream_done(php_http_encoding_stream_t *s) +zend_bool php_http_encoding_stream_done(php_http_encoding_stream_t *s) { if (!s->ops->done) { return 0; @@ -330,7 +330,7 @@ PHP_HTTP_API zend_bool php_http_encoding_stream_done(php_http_encoding_stream_t return s->ops->done(s); } -PHP_HTTP_API STATUS php_http_encoding_stream_finish(php_http_encoding_stream_t *s, char **out_str, size_t *out_len) +STATUS php_http_encoding_stream_finish(php_http_encoding_stream_t *s, char **out_str, size_t *out_len) { if (!s->ops->finish) { *out_str = NULL; @@ -340,14 +340,14 @@ PHP_HTTP_API STATUS php_http_encoding_stream_finish(php_http_encoding_stream_t * return s->ops->finish(s, out_str, out_len); } -PHP_HTTP_API void php_http_encoding_stream_dtor(php_http_encoding_stream_t *s) +void php_http_encoding_stream_dtor(php_http_encoding_stream_t *s) { if (s->ops->dtor) { s->ops->dtor(s); } } -PHP_HTTP_API void php_http_encoding_stream_free(php_http_encoding_stream_t **s) +void php_http_encoding_stream_free(php_http_encoding_stream_t **s) { if (*s) { if ((*s)->ops->dtor) { @@ -383,7 +383,7 @@ static php_http_encoding_stream_t *deflate_init(php_http_encoding_stream_t *s) status = Z_MEM_ERROR; } pefree(ctx, p); - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to initialize deflate encoding stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize deflate encoding stream: %s", zError(status)); return NULL; } @@ -404,7 +404,7 @@ static php_http_encoding_stream_t *inflate_init(php_http_encoding_stream_t *s) status = Z_MEM_ERROR; } pefree(ctx, p); - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to initialize inflate stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize inflate stream: %s", zError(status)); return NULL; } @@ -438,7 +438,7 @@ static php_http_encoding_stream_t *deflate_copy(php_http_encoding_stream_t *from deflateEnd(to_ctx); status = Z_MEM_ERROR; } - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to copy deflate encoding stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to copy deflate encoding stream: %s", zError(status)); return NULL; } @@ -457,7 +457,7 @@ static php_http_encoding_stream_t *inflate_copy(php_http_encoding_stream_t *from inflateEnd(to_ctx); status = Z_MEM_ERROR; } - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to copy inflate encoding stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to copy inflate encoding stream: %s", zError(status)); return NULL; } @@ -475,7 +475,7 @@ static php_http_encoding_stream_t *dechunk_copy(php_http_encoding_stream_t *from return to; } pefree(to_ctx, p); - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to copy inflate encoding stream: out of memory"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to copy inflate encoding stream: out of memory"); return NULL; } @@ -516,7 +516,7 @@ static STATUS deflate_update(php_http_encoding_stream_t *s, const char *data, si STR_SET(*encoded, NULL); *encoded_len = 0; - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to update deflate stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to update deflate stream: %s", zError(status)); return FAILURE; } @@ -555,7 +555,7 @@ retry_raw_inflate: break; } - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to update inflate stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to update inflate stream: %s", zError(status)); return FAILURE; } @@ -566,7 +566,7 @@ static STATUS dechunk_update(php_http_encoding_stream_t *s, const char *data, si TSRMLS_FETCH_FROM_CTX(s->ts); if (ctx->zeroed) { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Dechunk encoding stream has already reached the end of chunked input"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dechunk encoding stream has already reached the end of chunked input"); return FAILURE; } if ((PHP_HTTP_BUFFER_NOMEM == php_http_buffer_append(&ctx->buffer, data, data_len)) || !php_http_buffer_fix(&ctx->buffer)) { @@ -646,7 +646,7 @@ static STATUS dechunk_update(php_http_encoding_stream_t *s, const char *data, si /* if strtoul() stops at the beginning of the buffered data there's something oddly wrong, i.e. bad input */ if (stop == ctx->buffer.data) { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to parse chunk len from '%.*s'", MIN(16, ctx->buffer.used), ctx->buffer.data); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse chunk len from '%.*s'", (int) MIN(16, ctx->buffer.used), ctx->buffer.data); php_http_buffer_dtor(&tmp); return FAILURE; } @@ -712,7 +712,7 @@ static STATUS deflate_flush(php_http_encoding_stream_t *s, char **encoded, size_ STR_SET(*encoded, NULL); *encoded_len = 0; - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to flush deflate stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to flush deflate stream: %s", zError(status)); return FAILURE; } @@ -769,7 +769,7 @@ static STATUS deflate_finish(php_http_encoding_stream_t *s, char **encoded, size STR_SET(*encoded, NULL); *encoded_len = 0; - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to finish deflate stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to finish deflate stream: %s", zError(status)); return FAILURE; } @@ -808,7 +808,7 @@ static STATUS inflate_finish(php_http_encoding_stream_t *s, char **decoded, size STR_SET(*decoded, NULL); *decoded_len = 0; - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Failed to finish inflate stream: %s", zError(status)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to finish inflate stream: %s", zError(status)); return FAILURE; } @@ -878,7 +878,7 @@ static php_http_encoding_stream_ops_t php_http_encoding_deflate_ops = { deflate_dtor }; -PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_deflate_ops(void) +php_http_encoding_stream_ops_t *php_http_encoding_stream_get_deflate_ops(void) { return &php_http_encoding_deflate_ops; } @@ -893,7 +893,7 @@ static php_http_encoding_stream_ops_t php_http_encoding_inflate_ops = { inflate_dtor }; -PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_inflate_ops(void) +php_http_encoding_stream_ops_t *php_http_encoding_stream_get_inflate_ops(void) { return &php_http_encoding_inflate_ops; } @@ -908,7 +908,7 @@ static php_http_encoding_stream_ops_t php_http_encoding_dechunk_ops = { dechunk_dtor }; -PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_dechunk_ops(void) +php_http_encoding_stream_ops_t *php_http_encoding_stream_get_dechunk_ops(void) { return &php_http_encoding_dechunk_ops; } @@ -969,36 +969,31 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpEncodingStream___construct, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpEncodingStream, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - long flags = 0; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags)) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_http_encoding_stream_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - - if (!obj->stream) { - php_http_encoding_stream_ops_t *ops = NULL; - - if (instanceof_function(obj->zo.ce, php_http_deflate_stream_class_entry TSRMLS_CC)) { - ops = &php_http_encoding_deflate_ops; - } else if (instanceof_function(obj->zo.ce, php_http_inflate_stream_class_entry TSRMLS_CC)) { - ops = &php_http_encoding_inflate_ops; - } else if (instanceof_function(obj->zo.ce, php_http_dechunk_stream_class_entry TSRMLS_CC)) { - ops = &php_http_encoding_dechunk_ops; - } + long flags = 0; + php_http_encoding_stream_object_t *obj; + php_http_encoding_stream_ops_t *ops; - if (ops) { - obj->stream = php_http_encoding_stream_init(obj->stream, ops, flags TSRMLS_CC); - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "Unknown HttpEncodingStream class %s", obj->zo.ce->name); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags), invalid_arg, return); - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_ENCODING, "HttpEncodingStream cannot be initialized twice"); - } - } end_error_handling(); - } - } end_error_handling(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (obj->stream) { + php_http_throw(bad_method_call, "http\\Encoding\\Stream cannot be initialized twice", NULL); + return; + } + + if (instanceof_function(obj->zo.ce, php_http_deflate_stream_class_entry TSRMLS_CC)) { + ops = &php_http_encoding_deflate_ops; + } else if (instanceof_function(obj->zo.ce, php_http_inflate_stream_class_entry TSRMLS_CC)) { + ops = &php_http_encoding_inflate_ops; + } else if (instanceof_function(obj->zo.ce, php_http_dechunk_stream_class_entry TSRMLS_CC)) { + ops = &php_http_encoding_dechunk_ops; + } else { + php_http_throw(runtime, "Unknown http\\Encoding\\Stream class '%s'", obj->zo.ce->name); + return; + } + + php_http_expect(obj->stream = php_http_encoding_stream_init(obj->stream, ops, flags TSRMLS_CC), runtime, return); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEncodingStream_update, 0, 0, 1) @@ -1184,7 +1179,7 @@ PHP_MINIT_FUNCTION(http_encoding) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http\\Encoding", "Stream", php_http_encoding_stream_methods); - php_http_encoding_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_encoding_stream_class_entry = zend_register_internal_class(&ce TSRMLS_CC); php_http_encoding_stream_class_entry->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; php_http_encoding_stream_class_entry->create_object = php_http_encoding_stream_object_new; memcpy(&php_http_encoding_stream_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); diff --git a/php_http_env.c b/php_http_env.c index 7a68f8a..c98701b 100644 --- a/php_http_env.c +++ b/php_http_env.c @@ -96,7 +96,7 @@ PHP_RSHUTDOWN_FUNCTION(http_env) return SUCCESS; } -PHP_HTTP_API void php_http_env_get_request_headers(HashTable *headers TSRMLS_DC) +void php_http_env_get_request_headers(HashTable *headers TSRMLS_DC) { php_http_array_hashkey_t key = php_http_array_hashkey_init(0); zval **hsv, **header; @@ -137,7 +137,7 @@ PHP_HTTP_API void php_http_env_get_request_headers(HashTable *headers TSRMLS_DC) } } -PHP_HTTP_API char *php_http_env_get_request_header(const char *name_str, size_t name_len, size_t *len, php_http_message_t *request TSRMLS_DC) +char *php_http_env_get_request_header(const char *name_str, size_t name_len, size_t *len, php_http_message_t *request TSRMLS_DC) { HashTable *request_headers; zval **zvalue = NULL; @@ -165,7 +165,7 @@ PHP_HTTP_API char *php_http_env_get_request_header(const char *name_str, size_t return val; } -PHP_HTTP_API int php_http_env_got_request_header(const char *name_str, size_t name_len, php_http_message_t *request TSRMLS_DC) +int php_http_env_got_request_header(const char *name_str, size_t name_len, php_http_message_t *request TSRMLS_DC) { HashTable *request_headers; char *key = php_http_pretty_key(estrndup(name_str, name_len), name_len, 1, 1); @@ -183,7 +183,7 @@ PHP_HTTP_API int php_http_env_got_request_header(const char *name_str, size_t na return got; } -PHP_HTTP_API zval *php_http_env_get_superglobal(const char *key, size_t key_len TSRMLS_DC) +zval *php_http_env_get_superglobal(const char *key, size_t key_len TSRMLS_DC) { zval **hsv; @@ -196,7 +196,7 @@ PHP_HTTP_API zval *php_http_env_get_superglobal(const char *key, size_t key_len return *hsv; } -PHP_HTTP_API zval *php_http_env_get_server_var(const char *key, size_t key_len, zend_bool check TSRMLS_DC) +zval *php_http_env_get_server_var(const char *key, size_t key_len, zend_bool check TSRMLS_DC) { zval *hsv, **var; char *env; @@ -226,7 +226,7 @@ PHP_HTTP_API zval *php_http_env_get_server_var(const char *key, size_t key_len, return *var; } -PHP_HTTP_API php_http_message_body_t *php_http_env_get_request_body(TSRMLS_D) +php_http_message_body_t *php_http_env_get_request_body(TSRMLS_D) { if (!PHP_HTTP_G->env.request.body) { php_stream *s = php_stream_temp_new(); @@ -266,7 +266,7 @@ PHP_HTTP_API php_http_message_body_t *php_http_env_get_request_body(TSRMLS_D) return PHP_HTTP_G->env.request.body; } -PHP_HTTP_API const char *php_http_env_get_request_method(php_http_message_t *request TSRMLS_DC) +const char *php_http_env_get_request_method(php_http_message_t *request TSRMLS_DC) { const char *m; @@ -279,7 +279,7 @@ PHP_HTTP_API const char *php_http_env_get_request_method(php_http_message_t *req return m ? m : "GET"; } -PHP_HTTP_API php_http_range_status_t php_http_env_get_request_ranges(HashTable *ranges, size_t length, php_http_message_t *request TSRMLS_DC) +php_http_range_status_t php_http_env_get_request_ranges(HashTable *ranges, size_t length, php_http_message_t *request TSRMLS_DC) { zval *zentry; char *range, *rp, c; @@ -432,7 +432,7 @@ static void grab_headers(void *data, void *arg TSRMLS_DC) php_http_buffer_appends(PHP_HTTP_BUFFER(arg), PHP_HTTP_CRLF); } -PHP_HTTP_API STATUS php_http_env_get_response_headers(HashTable *headers_ht TSRMLS_DC) +STATUS php_http_env_get_response_headers(HashTable *headers_ht TSRMLS_DC) { STATUS status; php_http_buffer_t headers; @@ -441,13 +441,13 @@ PHP_HTTP_API STATUS php_http_env_get_response_headers(HashTable *headers_ht TSRM zend_llist_apply_with_argument(&SG(sapi_headers).headers, grab_headers, &headers TSRMLS_CC); php_http_buffer_fix(&headers); - status = php_http_headers_parse(headers.data, headers.used, headers_ht, NULL, NULL TSRMLS_CC); + status = php_http_header_parse(headers.data, headers.used, headers_ht, NULL, NULL TSRMLS_CC); php_http_buffer_dtor(&headers); return status; } -PHP_HTTP_API char *php_http_env_get_response_header(const char *name_str, size_t name_len TSRMLS_DC) +char *php_http_env_get_response_header(const char *name_str, size_t name_len TSRMLS_DC) { char *val = NULL; HashTable headers; @@ -471,18 +471,18 @@ PHP_HTTP_API char *php_http_env_get_response_header(const char *name_str, size_t return val; } -PHP_HTTP_API long php_http_env_get_response_code(TSRMLS_D) +long php_http_env_get_response_code(TSRMLS_D) { long code = SG(sapi_headers).http_response_code; return code ? code : 200; } -PHP_HTTP_API STATUS php_http_env_set_response_code(long http_code TSRMLS_DC) +STATUS php_http_env_set_response_code(long http_code TSRMLS_DC) { return sapi_header_op(SAPI_HEADER_SET_STATUS, (void *) http_code TSRMLS_CC); } -PHP_HTTP_API STATUS php_http_env_set_response_status_line(long code, php_http_version_t *v TSRMLS_DC) +STATUS php_http_env_set_response_status_line(long code, php_http_version_t *v TSRMLS_DC) { sapi_header_line h = {NULL, 0, 0}; STATUS ret; @@ -494,12 +494,12 @@ PHP_HTTP_API STATUS php_http_env_set_response_status_line(long code, php_http_ve return ret; } -PHP_HTTP_API STATUS php_http_env_set_response_protocol_version(php_http_version_t *v TSRMLS_DC) +STATUS php_http_env_set_response_protocol_version(php_http_version_t *v TSRMLS_DC) { return php_http_env_set_response_status_line(php_http_env_get_response_code(TSRMLS_C), v TSRMLS_CC); } -PHP_HTTP_API STATUS php_http_env_set_response_header(long http_code, const char *header_str, size_t header_len, zend_bool replace TSRMLS_DC) +STATUS php_http_env_set_response_header(long http_code, const char *header_str, size_t header_len, zend_bool replace TSRMLS_DC) { sapi_header_line h = {estrndup(header_str, header_len), header_len, http_code}; STATUS ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, (void *) &h TSRMLS_CC); @@ -507,7 +507,7 @@ PHP_HTTP_API STATUS php_http_env_set_response_header(long http_code, const char return ret; } -PHP_HTTP_API STATUS php_http_env_set_response_header_va(long http_code, zend_bool replace, const char *fmt, va_list argv TSRMLS_DC) +STATUS php_http_env_set_response_header_va(long http_code, zend_bool replace, const char *fmt, va_list argv TSRMLS_DC) { STATUS ret = FAILURE; sapi_header_line h = {NULL, 0, http_code}; @@ -523,7 +523,7 @@ PHP_HTTP_API STATUS php_http_env_set_response_header_va(long http_code, zend_boo return ret; } -PHP_HTTP_API STATUS php_http_env_set_response_header_format(long http_code, zend_bool replace TSRMLS_DC, const char *fmt, ...) +STATUS php_http_env_set_response_header_format(long http_code, zend_bool replace TSRMLS_DC, const char *fmt, ...) { STATUS ret; va_list args; @@ -535,7 +535,7 @@ PHP_HTTP_API STATUS php_http_env_set_response_header_format(long http_code, zend return ret; } -PHP_HTTP_API STATUS php_http_env_set_response_header_value(long http_code, const char *name_str, size_t name_len, zval *value, zend_bool replace TSRMLS_DC) +STATUS php_http_env_set_response_header_value(long http_code, const char *name_str, size_t name_len, zval *value, zend_bool replace TSRMLS_DC) { if (!value) { sapi_header_line h = {(char *) name_str, name_len, http_code}; @@ -673,7 +673,7 @@ static PHP_HTTP_STRLIST(php_http_env_response_status) = PHP_HTTP_STRLIST_STOP ; -PHP_HTTP_API const char *php_http_env_get_response_status_for_code(unsigned code) +const char *php_http_env_get_response_status_for_code(unsigned code) { return php_http_strlist_find(php_http_env_response_status, 100, code); } @@ -707,18 +707,16 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnv_getRequestBody, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpEnv, getRequestBody) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zend_class_entry *class_entry = php_http_message_body_class_entry; + zend_object_value ov; + php_http_message_body_t *body; + zend_class_entry *class_entry = php_http_message_body_class_entry; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &class_entry)) { - zend_object_value ov; - php_http_message_body_t *body = php_http_env_get_request_body(TSRMLS_C); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &class_entry), invalid_arg, return); - if (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_message_body_object_new_ex, php_http_message_body_class_entry, php_http_message_body_init(&body, NULL TSRMLS_CC), NULL TSRMLS_CC)) { - RETVAL_OBJVAL(ov, 0); - } - } - } end_error_handling(); + body = php_http_env_get_request_body(TSRMLS_C); + if (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_message_body_object_new_ex, php_http_message_body_class_entry, body, NULL TSRMLS_CC)) { + RETVAL_OBJVAL(ov, 0); + } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnv_getResponseStatusForCode, 0, 0, 1) @@ -1005,7 +1003,7 @@ PHP_MINIT_FUNCTION(http_env) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Env", php_http_env_methods); - php_http_env_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_env_class_entry = zend_register_internal_class(&ce TSRMLS_CC); #ifdef PHP_HTTP_HAVE_JSON php_http_env_register_json_handler(TSRMLS_C); diff --git a/php_http_env_request.c b/php_http_env_request.c index a19ad63..01c2f6d 100644 --- a/php_http_env_request.c +++ b/php_http_env_request.c @@ -115,42 +115,43 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvRequest___construct, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpEnvRequest, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_object_t *obj; + zval *zsg, *zqs; - if (SUCCESS == zend_parse_parameters_none()) { - zval *zsg, *zqs; + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - obj->message = php_http_message_init_env(obj->message, PHP_HTTP_REQUEST TSRMLS_CC); - obj->body = NULL; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj->body = NULL; - zsg = php_http_env_get_superglobal(ZEND_STRL("_GET") TSRMLS_CC); - MAKE_STD_ZVAL(zqs); - object_init_ex(zqs, php_http_querystring_class_entry); - if (SUCCESS == php_http_querystring_ctor(zqs, zsg TSRMLS_CC)) { - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("query"), zqs TSRMLS_CC); - } - zval_ptr_dtor(&zqs); + php_http_expect(obj->message = php_http_message_init_env(obj->message, PHP_HTTP_REQUEST TSRMLS_CC), unexpected_val, return); - zsg = php_http_env_get_superglobal(ZEND_STRL("_POST") TSRMLS_CC); - MAKE_STD_ZVAL(zqs); - object_init_ex(zqs, php_http_querystring_class_entry); - if (SUCCESS == php_http_querystring_ctor(zqs, zsg TSRMLS_CC)) { - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("form"), zqs TSRMLS_CC); - } + zsg = php_http_env_get_superglobal(ZEND_STRL("_GET") TSRMLS_CC); + MAKE_STD_ZVAL(zqs); + object_init_ex(zqs, php_http_querystring_class_entry); + php_http_expect(SUCCESS == php_http_querystring_ctor(zqs, zsg TSRMLS_CC), unexpected_val, zval_ptr_dtor(&zqs); - - MAKE_STD_ZVAL(zqs); - array_init(zqs); - if ((zsg = php_http_env_get_superglobal(ZEND_STRL("_FILES") TSRMLS_CC))) { - zend_hash_apply_with_arguments(Z_ARRVAL_P(zsg) TSRMLS_CC, grab_files, 1, zqs); - } - - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("files"), zqs TSRMLS_CC); + return; + ); + zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("query"), zqs TSRMLS_CC); + zval_ptr_dtor(&zqs); + + zsg = php_http_env_get_superglobal(ZEND_STRL("_POST") TSRMLS_CC); + MAKE_STD_ZVAL(zqs); + object_init_ex(zqs, php_http_querystring_class_entry); + php_http_expect(SUCCESS == php_http_querystring_ctor(zqs, zsg TSRMLS_CC), unexpected_val, zval_ptr_dtor(&zqs); - } - PHP_HTTP_ENV_REQUEST_OBJECT_INIT(obj); - } end_error_handling(); + return; + ); + zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("form"), zqs TSRMLS_CC); + zval_ptr_dtor(&zqs); + + MAKE_STD_ZVAL(zqs); + array_init(zqs); + if ((zsg = php_http_env_get_superglobal(ZEND_STRL("_FILES") TSRMLS_CC))) { + zend_hash_apply_with_arguments(Z_ARRVAL_P(zsg) TSRMLS_CC, grab_files, 1, zqs); + } + zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("files"), zqs TSRMLS_CC); + zval_ptr_dtor(&zqs); } #define call_querystring_get(prop) \ diff --git a/php_http_env_response.c b/php_http_env_response.c index 6784187..cb52752 100644 --- a/php_http_env_response.c +++ b/php_http_env_response.c @@ -109,7 +109,7 @@ static php_http_message_t *get_request(zval *options TSRMLS_DC) return request; } -PHP_HTTP_API php_http_cache_status_t php_http_env_is_response_cached_by_etag(zval *options, const char *header_str, size_t header_len, php_http_message_t *request TSRMLS_DC) +php_http_cache_status_t php_http_env_is_response_cached_by_etag(zval *options, const char *header_str, size_t header_len, php_http_message_t *request TSRMLS_DC) { php_http_cache_status_t ret = PHP_HTTP_CACHE_NO; int free_etag = 0; @@ -151,7 +151,7 @@ PHP_HTTP_API php_http_cache_status_t php_http_env_is_response_cached_by_etag(zva return ret; } -PHP_HTTP_API php_http_cache_status_t php_http_env_is_response_cached_by_last_modified(zval *options, const char *header_str, size_t header_len, php_http_message_t *request TSRMLS_DC) +php_http_cache_status_t php_http_env_is_response_cached_by_last_modified(zval *options, const char *header_str, size_t header_len, php_http_message_t *request TSRMLS_DC) { php_http_cache_status_t ret = PHP_HTTP_CACHE_NO; char *header; @@ -202,7 +202,7 @@ static zend_bool php_http_env_response_is_cacheable(php_http_env_response_t *r, return 0; } - if (php_http_env_got_request_header(ZEND_STRL("Authorizsation"), request TSRMLS_CC)) { + if (php_http_env_got_request_header(ZEND_STRL("Authorization"), request TSRMLS_CC)) { return 0; } @@ -259,7 +259,7 @@ static STATUS php_http_env_response_send_data(php_http_env_response_t *r, const return SUCCESS; } -PHP_HTTP_API php_http_env_response_t *php_http_env_response_init(php_http_env_response_t *r, zval *options, php_http_env_response_ops_t *ops, void *init_arg TSRMLS_DC) +php_http_env_response_t *php_http_env_response_init(php_http_env_response_t *r, zval *options, php_http_env_response_ops_t *ops, void *init_arg TSRMLS_DC) { zend_bool free_r; @@ -293,7 +293,7 @@ PHP_HTTP_API php_http_env_response_t *php_http_env_response_init(php_http_env_re return r; } -PHP_HTTP_API void php_http_env_response_dtor(php_http_env_response_t *r) +void php_http_env_response_dtor(php_http_env_response_t *r) { if (r->ops->dtor) { r->ops->dtor(r); @@ -307,7 +307,7 @@ PHP_HTTP_API void php_http_env_response_dtor(php_http_env_response_t *r) } } -PHP_HTTP_API void php_http_env_response_free(php_http_env_response_t **r) +void php_http_env_response_free(php_http_env_response_t **r) { if (*r) { php_http_env_response_dtor(*r); @@ -358,7 +358,7 @@ static STATUS php_http_env_response_send_head(php_http_env_response_t *r, php_ht if ((zoption = get_option(options, ZEND_STRL("headers") TSRMLS_CC))) { if (Z_TYPE_P(zoption) == IS_ARRAY) { - php_http_headers_to_callback(Z_ARRVAL_P(zoption), 0, (php_http_pass_format_callback_t) r->ops->set_header, r TSRMLS_CC); + php_http_header_to_callback(Z_ARRVAL_P(zoption), 0, (php_http_pass_format_callback_t) r->ops->set_header, r TSRMLS_CC); } zval_ptr_dtor(&zoption); } @@ -371,11 +371,9 @@ static STATUS php_http_env_response_send_head(php_http_env_response_t *r, php_ht zval *zoption_copy = php_http_ztyp(IS_STRING, zoption); zval_ptr_dtor(&zoption); - if (Z_STRLEN_P(zoption_copy)) { - PHP_HTTP_CHECK_CONTENT_TYPE(Z_STRVAL_P(zoption_copy), ret = FAILURE) else { - if (SUCCESS == (ret = r->ops->set_header(r, "Content-Type: %.*s", Z_STRLEN_P(zoption_copy), Z_STRVAL_P(zoption_copy)))) { - r->content.type = estrndup(Z_STRVAL_P(zoption_copy), Z_STRLEN_P(zoption_copy)); - } + if (Z_STRLEN_P(zoption_copy) && strchr(Z_STRVAL_P(zoption_copy), '/')) { + if (SUCCESS == (ret = r->ops->set_header(r, "Content-Type: %.*s", Z_STRLEN_P(zoption_copy), Z_STRVAL_P(zoption_copy)))) { + r->content.type = estrndup(Z_STRVAL_P(zoption_copy), Z_STRLEN_P(zoption_copy)); } } zval_ptr_dtor(&zoption_copy); @@ -582,10 +580,11 @@ static STATUS php_http_env_response_send_body(php_http_env_response_t *r) && 2 == php_http_array_list(Z_ARRVAL_PP(range) TSRMLS_CC, 2, &begin, &end) ) { /* send chunk */ - php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_env_response_send_data, r, Z_LVAL_PP(begin), Z_LVAL_PP(end) - Z_LVAL_PP(begin) + 1); - php_http_env_response_send_done(r); + ret = php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_env_response_send_data, r, Z_LVAL_PP(begin), Z_LVAL_PP(end) - Z_LVAL_PP(begin) + 1); + if (ret == SUCCESS) { + ret = php_http_env_response_send_done(r); + } zend_hash_destroy(&r->range.values); - ret = SUCCESS; } else { /* this should never happen */ zend_hash_destroy(&r->range.values); @@ -614,23 +613,28 @@ static STATUS php_http_env_response_send_body(php_http_env_response_t *r) Z_LVAL_PP(end), r->content.length ); - php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_env_response_send_data, r, Z_LVAL_PP(begin), Z_LVAL_PP(end) - Z_LVAL_PP(begin) + 1); + ret = php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_env_response_send_data, r, Z_LVAL_PP(begin), Z_LVAL_PP(end) - Z_LVAL_PP(begin) + 1); } } - php_http_buffer_appendf(r->buffer, PHP_HTTP_CRLF "--%s--", r->range.boundary); - php_http_env_response_send_done(r); + + if (ret == SUCCESS) { + php_http_buffer_appendf(r->buffer, PHP_HTTP_CRLF "--%s--", r->range.boundary); + ret = php_http_env_response_send_done(r); + } zend_hash_destroy(&r->range.values); } } else { - php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_env_response_send_data, r, 0, 0); - php_http_env_response_send_done(r); + ret = php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_env_response_send_data, r, 0, 0); + if (ret == SUCCESS) { + ret = php_http_env_response_send_done(r); + } } } return ret; } -PHP_HTTP_API STATUS php_http_env_response_send(php_http_env_response_t *r) +STATUS php_http_env_response_send(php_http_env_response_t *r) { php_http_message_t *request; php_http_message_body_t *body; @@ -695,14 +699,17 @@ PHP_HTTP_API STATUS php_http_env_response_send(php_http_env_response_t *r) } if (SUCCESS != php_http_env_response_send_head(r, request)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to send response headers"); return FAILURE; } if (SUCCESS != php_http_env_response_send_body(r)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to send response body"); return FAILURE; } if (SUCCESS != r->ops->finish(r)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to finish response"); return FAILURE; } @@ -803,7 +810,7 @@ static php_http_env_response_ops_t php_http_env_response_sapi_ops = { php_http_env_response_sapi_finish }; -PHP_HTTP_API php_http_env_response_ops_t *php_http_env_response_get_sapi_ops(void) +php_http_env_response_ops_t *php_http_env_response_get_sapi_ops(void) { return &php_http_env_response_sapi_ops; } @@ -1042,7 +1049,7 @@ static php_http_env_response_ops_t php_http_env_response_stream_ops = { php_http_env_response_stream_finish }; -PHP_HTTP_API php_http_env_response_ops_t *php_http_env_response_get_stream_ops(void) +php_http_env_response_ops_t *php_http_env_response_get_stream_ops(void) { return &php_http_env_response_stream_ops; } @@ -1058,17 +1065,13 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse___construct, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpEnvResponse, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_object_t *obj; - if (SUCCESS == zend_parse_parameters_none()) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - obj->message = php_http_message_init_env(obj->message, PHP_HTTP_RESPONSE TSRMLS_CC); - } end_error_handling(); - } - PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj); - } end_error_handling(); + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(obj->message = php_http_message_init_env(obj->message, PHP_HTTP_RESPONSE TSRMLS_CC), unexpected_val, return); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse___invoke, 0, 0, 1) @@ -1101,10 +1104,10 @@ static PHP_METHOD(HttpEnvResponse, setEnvRequest) { zval *env_req = NULL; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O", &env_req, php_http_message_class_entry)) { - set_option(getThis(), ZEND_STRL("request"), IS_OBJECT, env_req, 0 TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O", &env_req, php_http_message_class_entry), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("request"), IS_OBJECT, env_req, 0 TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setContentType, 0, 0, 1) @@ -1115,10 +1118,10 @@ static PHP_METHOD(HttpEnvResponse, setContentType) char *ct_str = NULL; int ct_len = 0; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &ct_str, &ct_len)) { - set_option(getThis(), ZEND_STRL("contentType"), IS_STRING, ct_str, ct_len TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &ct_str, &ct_len), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("contentType"), IS_STRING, ct_str, ct_len TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setContentDisposition, 0, 0, 1) @@ -1128,10 +1131,10 @@ static PHP_METHOD(HttpEnvResponse, setContentDisposition) { zval *zdisposition; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zdisposition)) { - zend_update_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("contentDisposition"), zdisposition TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zdisposition), invalid_arg, return); + + zend_update_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("contentDisposition"), zdisposition TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setContentEncoding, 0, 0, 1) @@ -1141,10 +1144,10 @@ static PHP_METHOD(HttpEnvResponse, setContentEncoding) { long ce; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ce)) { - set_option(getThis(), ZEND_STRL("contentEncoding"), IS_LONG, &ce, 0 TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ce), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("contentEncoding"), IS_LONG, &ce, 0 TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setCacheControl, 0, 0, 1) @@ -1155,10 +1158,10 @@ static PHP_METHOD(HttpEnvResponse, setCacheControl) char *cc_str = NULL; int cc_len = 0; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &cc_str, &cc_len)) { - set_option(getThis(), ZEND_STRL("cacheControl"), IS_STRING, cc_str, cc_len TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &cc_str, &cc_len), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("cacheControl"), IS_STRING, cc_str, cc_len TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setLastModified, 0, 0, 1) @@ -1168,10 +1171,10 @@ static PHP_METHOD(HttpEnvResponse, setLastModified) { long last_modified; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &last_modified)) { - set_option(getThis(), ZEND_STRL("lastModified"), IS_LONG, &last_modified, 0 TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &last_modified), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("lastModified"), IS_LONG, &last_modified, 0 TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_isCachedByLastModified, 0, 0, 0) @@ -1200,10 +1203,10 @@ static PHP_METHOD(HttpEnvResponse, setEtag) char *etag_str = NULL; int etag_len = 0; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &etag_str, &etag_len)) { - set_option(getThis(), ZEND_STRL("etag"), IS_STRING, etag_str, etag_len TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &etag_str, &etag_len), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("etag"), IS_STRING, etag_str, etag_len TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_isCachedByEtag, 0, 0, 0) @@ -1232,11 +1235,11 @@ static PHP_METHOD(HttpEnvResponse, setThrottleRate) long chunk_size; double delay = 1; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|d", &chunk_size, &delay)) { - set_option(getThis(), ZEND_STRL("throttleDelay"), IS_DOUBLE, &delay, 0 TSRMLS_CC); - set_option(getThis(), ZEND_STRL("throttleChunk"), IS_LONG, &chunk_size, 0 TSRMLS_CC); - RETVAL_ZVAL(getThis(), 1, 0); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|d", &chunk_size, &delay), invalid_arg, return); + + set_option(getThis(), ZEND_STRL("throttleDelay"), IS_DOUBLE, &delay, 0 TSRMLS_CC); + set_option(getThis(), ZEND_STRL("throttleChunk"), IS_LONG, &chunk_size, 0 TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_send, 0, 0, 0) diff --git a/php_http_etag.c b/php_http_etag.c index b9c0333..72a7927 100644 --- a/php_http_etag.c +++ b/php_http_etag.c @@ -20,7 +20,7 @@ #include #include -PHP_HTTP_API php_http_etag_t *php_http_etag_init(const char *mode TSRMLS_DC) +php_http_etag_t *php_http_etag_init(const char *mode TSRMLS_DC) { void *ctx; php_http_etag_t *e; @@ -52,7 +52,7 @@ PHP_HTTP_API php_http_etag_t *php_http_etag_init(const char *mode TSRMLS_DC) return e; } -PHP_HTTP_API char *php_http_etag_finish(php_http_etag_t *e) +char *php_http_etag_finish(php_http_etag_t *e) { unsigned char digest[128] = {0}; char *etag = NULL; @@ -90,7 +90,7 @@ PHP_HTTP_API char *php_http_etag_finish(php_http_etag_t *e) return etag; } -PHP_HTTP_API size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t data_len) +size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t data_len) { if (!strcasecmp(e->mode, "crc32b")) { uint i, c = *((uint *) e->ctx); diff --git a/php_http_exception.c b/php_http_exception.c index 2ce163a..00add62 100644 --- a/php_http_exception.c +++ b/php_http_exception.c @@ -12,7 +12,7 @@ #include "php_http_api.h" -#include +#include #ifndef PHP_HTTP_DBG_EXCEPTIONS # define PHP_HTTP_DBG_EXCEPTIONS 0 @@ -30,33 +30,83 @@ static void php_http_exception_hook(zval *ex TSRMLS_DC) } #endif -zend_class_entry *php_http_exception_class_entry; +zend_class_entry *php_http_exception_interface_class_entry; +zend_class_entry *php_http_exception_runtime_class_entry; +zend_class_entry *php_http_exception_unexpected_val_class_entry; +zend_class_entry *php_http_exception_bad_method_call_class_entry; +zend_class_entry *php_http_exception_invalid_arg_class_entry; +zend_class_entry *php_http_exception_bad_header_class_entry; +zend_class_entry *php_http_exception_bad_url_class_entry; +zend_class_entry *php_http_exception_bad_message_class_entry; +zend_class_entry *php_http_exception_bad_conversion_class_entry; +zend_class_entry *php_http_exception_bad_querystring_class_entry; PHP_MINIT_FUNCTION(http_exception) { - zend_class_entry ce = {0}; + zend_class_entry *cep, ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Exception", NULL); - php_http_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); - - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_UNKNOWN"), PHP_HTTP_E_UNKNOWN TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_RUNTIME"), PHP_HTTP_E_RUNTIME TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_INVALID_PARAM"), PHP_HTTP_E_INVALID_PARAM TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_HEADER"), PHP_HTTP_E_HEADER TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_MALFORMED_HEADERS"), PHP_HTTP_E_MALFORMED_HEADERS TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_MESSAGE"), PHP_HTTP_E_MESSAGE TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_MESSAGE_TYPE"), PHP_HTTP_E_MESSAGE_TYPE TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_MESSAGE_BODY"), PHP_HTTP_E_MESSAGE_BODY TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_ENCODING"), PHP_HTTP_E_ENCODING TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_CLIENT"), PHP_HTTP_E_CLIENT TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_CLIENT_POOL"), PHP_HTTP_E_CLIENT_POOL TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_CLIENT_DATASHARE"), PHP_HTTP_E_CLIENT_DATASHARE TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_SOCKET"), PHP_HTTP_E_SOCKET TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_RESPONSE"), PHP_HTTP_E_RESPONSE TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_URL"), PHP_HTTP_E_URL TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_QUERYSTRING"), PHP_HTTP_E_QUERYSTRING TSRMLS_CC); - zend_declare_class_constant_long(php_http_exception_class_entry, ZEND_STRL("E_COOKIE"), PHP_HTTP_E_COOKIE TSRMLS_CC); + php_http_exception_interface_class_entry = zend_register_internal_interface(&ce TSRMLS_CC); + /* + * Would be great to only have a few exceptions and rather more identifying + * error codes, but zend_replace_error_handling() does not accept any codes. + */ + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "RuntimeException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_runtime_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "UnexpectedValueException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_UnexpectedValueException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_unexpected_val_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "BadMethodCallException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_BadMethodCallException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_bad_method_call_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "InvalidArgumentException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_invalid_arg_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "BadHeaderException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_DomainException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_bad_header_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "BadUrlException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_DomainException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_bad_url_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "BadMessageException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_DomainException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_bad_message_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "BadConversionException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_DomainException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_bad_conversion_class_entry = cep; + + memset(&ce, 0, sizeof(ce)); + INIT_NS_CLASS_ENTRY(ce, "http\\Exception", "BadQueryStringException", NULL); + cep = zend_register_internal_class_ex(&ce, spl_ce_DomainException, NULL TSRMLS_CC); + zend_class_implements(cep TSRMLS_CC, 1, php_http_exception_interface_class_entry); + php_http_exception_bad_querystring_class_entry = cep; + #if PHP_HTTP_DBG_EXCEPTIONS zend_throw_exception_hook = php_http_exception_hook; #endif diff --git a/php_http_exception.h b/php_http_exception.h index d7e5ee7..82a4b55 100644 --- a/php_http_exception.h +++ b/php_http_exception.h @@ -13,7 +13,33 @@ #ifndef PHP_HTTP_EXCEPTION_H #define PHP_HTTP_EXCEPTION_H -PHP_HTTP_API zend_class_entry *php_http_exception_class_entry; +/* short hand for zend_throw_exception_ex */ +#define php_http_throw(e, fmt, ...) \ + zend_throw_exception_ex(php_http_exception_ ##e## _class_entry, 0 TSRMLS_CC, fmt, __VA_ARGS__) + +/* wrap a call with replaced zend_error_handling */ +#define php_http_expect(test, e, fail) \ + do { \ + zend_error_handling __zeh; \ + zend_replace_error_handling(EH_THROW, php_http_exception_ ##e## _class_entry, &__zeh TSRMLS_CC); \ + if (!(test)) { \ + zend_restore_error_handling(&__zeh TSRMLS_CC); \ + fail; \ + } \ + zend_restore_error_handling(&__zeh TSRMLS_CC); \ + } while(0) + +PHP_HTTP_API zend_class_entry *php_http_exception_interface_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_runtime_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_unexpected_val_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_bad_method_call_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_invalid_arg_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_bad_header_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_bad_url_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_bad_message_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_bad_conversion_class_entry; +PHP_HTTP_API zend_class_entry *php_http_exception_bad_querystring_class_entry; + PHP_MINIT_FUNCTION(http_exception); #endif diff --git a/php_http_header.c b/php_http_header.c new file mode 100644 index 0000000..08e643b --- /dev/null +++ b/php_http_header.c @@ -0,0 +1,388 @@ +/* + +--------------------------------------------------------------------+ + | PECL :: http | + +--------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met. | + +--------------------------------------------------------------------+ + | Copyright (c) 2004-2013, Michael Wallner | + +--------------------------------------------------------------------+ +*/ + +#include "php_http_api.h" + +STATUS php_http_header_parse(const char *header, size_t length, HashTable *headers, php_http_info_callback_t callback_func, void **callback_data TSRMLS_DC) +{ + php_http_header_parser_t ctx; + php_http_buffer_t buf; + php_http_header_parser_state_t rs; + + if (!php_http_buffer_from_string_ex(&buf, header, length)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not allocate buffer"); + return FAILURE; + } + + if (!php_http_header_parser_init(&ctx TSRMLS_CC)) { + php_http_buffer_dtor(&buf); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize header parser"); + return FAILURE; + } + + rs = php_http_header_parser_parse(&ctx, &buf, PHP_HTTP_HEADER_PARSER_CLEANUP, headers, callback_func, callback_data); + php_http_header_parser_dtor(&ctx); + php_http_buffer_dtor(&buf); + + if (rs == PHP_HTTP_HEADER_PARSER_STATE_FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse headers"); + return FAILURE; + } + + return SUCCESS; +} + +void php_http_header_to_callback(HashTable *headers, zend_bool crlf, php_http_pass_format_callback_t cb, void *cb_arg TSRMLS_DC) +{ + HashPosition pos1, pos2; + php_http_array_hashkey_t key = php_http_array_hashkey_init(0); + zval **header, **single_header; + + FOREACH_HASH_KEYVAL(pos1, headers, key, header) { + if (key.type == HASH_KEY_IS_STRING) { + if (key.len == sizeof("Set-Cookie") && !strcasecmp(key.str, "Set-Cookie") && Z_TYPE_PP(header) == IS_ARRAY) { + FOREACH_VAL(pos2, *header, single_header) { + if (Z_TYPE_PP(single_header) == IS_ARRAY) { + php_http_cookie_list_t *cookie = php_http_cookie_list_from_struct(NULL, *single_header TSRMLS_CC); + + if (cookie) { + char *buf; + size_t len; + + php_http_cookie_list_to_string(cookie, &buf, &len); + cb(cb_arg, crlf ? "Set-Cookie: %s" PHP_HTTP_CRLF : "Set-Cookie: %s", buf); + php_http_cookie_list_free(&cookie); + efree(buf); + } + } else { + zval *strval = php_http_header_value_to_string(*single_header TSRMLS_CC); + + cb(cb_arg, crlf ? "Set-Cookie: %s" PHP_HTTP_CRLF : "Set-Cookie: %s", Z_STRVAL_P(strval)); + zval_ptr_dtor(&strval); + } + } + } else { + zval *strval = php_http_header_value_to_string(*header TSRMLS_CC); + + cb(cb_arg, crlf ? "%s: %s" PHP_HTTP_CRLF : "%s: %s", key.str, Z_STRVAL_P(strval)); + zval_ptr_dtor(&strval); + } + } + } +} + +void php_http_header_to_string(php_http_buffer_t *str, HashTable *headers TSRMLS_DC) +{ + php_http_header_to_callback(headers, 1, (php_http_pass_format_callback_t) php_http_buffer_appendf, str TSRMLS_CC); +} + +zval *php_http_header_value_to_string(zval *header TSRMLS_DC) +{ + zval *ret; + + if (Z_TYPE_P(header) == IS_BOOL) { + MAKE_STD_ZVAL(ret); + ZVAL_STRING(ret, Z_BVAL_P(header) ? "true" : "false", 1); + } else if (Z_TYPE_P(header) == IS_ARRAY) { + zval **val; + HashPosition pos; + php_http_buffer_t str; + + php_http_buffer_init(&str); + MAKE_STD_ZVAL(ret); + FOREACH_VAL(pos,header, val) { + zval *strval = php_http_header_value_to_string(*val TSRMLS_CC); + + php_http_buffer_appendf(&str, str.used ? ", %s":"%s", Z_STRVAL_P(strval)); + zval_ptr_dtor(&strval); + } + php_http_buffer_fix(&str); + ZVAL_STRINGL(ret, str.data, str.used, 0); + } else { + ret = php_http_zsep(1, IS_STRING, header); + } + + return ret; +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader___construct, 0, 0, 0) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, __construct) +{ + char *name_str = NULL, *value_str = NULL; + int name_len = 0, value_len = 0; + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!", &name_str, &name_len, &value_str, &value_len), invalid_arg, return); + + if (name_str && name_len) { + char *pretty_str = estrndup(name_str, name_len); + zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("name"), php_http_pretty_key(pretty_str, name_len, 1, 1), name_len TSRMLS_CC); + efree(pretty_str); + } + if (value_str && value_len) { + zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("value"), value_str, value_len TSRMLS_CC); + } +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_serialize, 0, 0, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, serialize) +{ + if (SUCCESS == zend_parse_parameters_none()) { + php_http_buffer_t buf; + zval *zname, *zvalue; + + php_http_buffer_init(&buf); + zname = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("name"), 0 TSRMLS_CC)); + php_http_buffer_append(&buf, Z_STRVAL_P(zname), Z_STRLEN_P(zname)); + zval_ptr_dtor(&zname); + zvalue = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0 TSRMLS_CC)); + if (Z_STRLEN_P(zvalue)) { + php_http_buffer_appends(&buf, ": "); + php_http_buffer_append(&buf, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue)); + } else { + php_http_buffer_appends(&buf, ":"); + } + zval_ptr_dtor(&zvalue); + + RETURN_PHP_HTTP_BUFFER_VAL(&buf); + } + RETURN_EMPTY_STRING(); +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_unserialize, 0, 0, 1) + ZEND_ARG_INFO(0, serialized) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, unserialize) +{ + char *serialized_str; + int serialized_len; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized_str, &serialized_len)) { + HashTable ht; + + zend_hash_init(&ht, 1, NULL, ZVAL_PTR_DTOR, 0); + if (SUCCESS == php_http_header_parse(serialized_str, serialized_len, &ht, NULL, NULL TSRMLS_CC)) { + if (zend_hash_num_elements(&ht)) { + zval **val, *cpy; + char *str; + uint len; + ulong idx; + + zend_hash_internal_pointer_reset(&ht); + switch (zend_hash_get_current_key_ex(&ht, &str, &len, &idx, 0, NULL)) { + case HASH_KEY_IS_STRING: + zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("name"), str, len - 1 TSRMLS_CC); + break; + case HASH_KEY_IS_LONG: + zend_update_property_long(php_http_header_class_entry, getThis(), ZEND_STRL("name"), idx TSRMLS_CC); + break; + default: + break; + } + zend_hash_get_current_data(&ht, (void *) &val); + cpy = php_http_zsep(1, IS_STRING, *val); + zend_update_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), cpy TSRMLS_CC); + zval_ptr_dtor(&cpy); + } + } + zend_hash_destroy(&ht); + } + +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_match, 0, 0, 1) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, match) +{ + char *val_str; + int val_len; + long flags = PHP_HTTP_MATCH_LOOSE; + zval *zvalue; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &val_str, &val_len, &flags)) { + return; + } + + zvalue = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0 TSRMLS_CC)); + RETVAL_BOOL(php_http_match(Z_STRVAL_P(zvalue), val_str, flags)); + zval_ptr_dtor(&zvalue); +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_negotiate, 0, 0, 1) + ZEND_ARG_INFO(0, supported) + ZEND_ARG_INFO(1, result) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, negotiate) +{ + HashTable *supported, *rs; + zval *zname, *zvalue, *rs_array = NULL; + char *sep_str = NULL; + size_t sep_len = 0; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H|z", &supported, &rs_array)) { + return; + } + if (rs_array) { + zval_dtor(rs_array); + array_init(rs_array); + } + + zname = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("name"), 0 TSRMLS_CC)); + if (!strcasecmp(Z_STRVAL_P(zname), "Accept")) { + sep_str = "/"; + sep_len = 1; + } else if (!strcasecmp(Z_STRVAL_P(zname), "Accept-Language")) { + sep_str = "-"; + sep_len = 1; + } + zval_ptr_dtor(&zname); + + zvalue = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0 TSRMLS_CC)); + if ((rs = php_http_negotiate(Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), supported, sep_str, sep_len TSRMLS_CC))) { + PHP_HTTP_DO_NEGOTIATE_HANDLE_RESULT(rs, supported, rs_array); + } else { + PHP_HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array); + } + zval_ptr_dtor(&zvalue); +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_getParams, 0, 0, 0) + ZEND_ARG_INFO(0, param_sep) + ZEND_ARG_INFO(0, arg_sep) + ZEND_ARG_INFO(0, val_sep) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, getParams) +{ + zval zctor, *zparams_obj, **zargs = NULL; + + INIT_PZVAL(&zctor); + ZVAL_STRINGL(&zctor, "__construct", lenof("__construct"), 0); + + MAKE_STD_ZVAL(zparams_obj); + object_init_ex(zparams_obj, php_http_params_class_entry); + + zargs = (zval **) ecalloc(ZEND_NUM_ARGS()+1, sizeof(zval *)); + zargs[0] = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("value"), 0 TSRMLS_CC); + if (ZEND_NUM_ARGS()) { + zend_get_parameters_array(ZEND_NUM_ARGS(), ZEND_NUM_ARGS(), &zargs[1]); + } + + if (SUCCESS == call_user_function(NULL, &zparams_obj, &zctor, return_value, ZEND_NUM_ARGS()+1, zargs TSRMLS_CC)) { + RETVAL_ZVAL(zparams_obj, 0, 1); + } + + if (zargs) { + efree(zargs); + } +} + +ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_parse, 0, 0, 1) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, header_class) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, parse) +{ + char *header_str; + int header_len; + zend_class_entry *ce = NULL; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C", &header_str, &header_len, &ce)) { + array_init(return_value); + + if (SUCCESS != php_http_header_parse(header_str, header_len, Z_ARRVAL_P(return_value), NULL, NULL TSRMLS_CC)) { + zval_dtor(return_value); + RETURN_FALSE; + } else { + if (ce && instanceof_function(ce, php_http_header_class_entry TSRMLS_CC)) { + HashPosition pos; + php_http_array_hashkey_t key = php_http_array_hashkey_init(0); + zval **val; + + FOREACH_KEYVAL(pos, return_value, key, val) { + zval *zho, *zkey, *zvalue; + + Z_ADDREF_PP(val); + zvalue = *val; + + MAKE_STD_ZVAL(zkey); + if (key.type == HASH_KEY_IS_LONG) { + ZVAL_LONG(zkey, key.num); + } else { + ZVAL_STRINGL(zkey, key.str, key.len - 1, 1); + } + + MAKE_STD_ZVAL(zho); + object_init_ex(zho, ce); + zend_call_method_with_2_params(&zho, ce, NULL, "__construct", NULL, zkey, zvalue); + + if (key.type == HASH_KEY_IS_LONG) { + zend_hash_index_update(Z_ARRVAL_P(return_value), key.num, (void *) &zho, sizeof(zval *), NULL); + } else { + zend_hash_update(Z_ARRVAL_P(return_value), key.str, key.len, (void *) &zho, sizeof(zval *), NULL); + } + + zval_ptr_dtor(&zvalue); + zval_ptr_dtor(&zkey); + } + } + } + } +} + +static zend_function_entry php_http_header_methods[] = { + PHP_ME(HttpHeader, __construct, ai_HttpHeader___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) + PHP_ME(HttpHeader, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC) + ZEND_MALIAS(HttpHeader, __toString, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC) + ZEND_MALIAS(HttpHeader, toString, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, unserialize, ai_HttpHeader_unserialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, match, ai_HttpHeader_match, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, negotiate, ai_HttpHeader_negotiate, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, getParams, ai_HttpHeader_getParams, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, parse, ai_HttpHeader_parse, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + EMPTY_FUNCTION_ENTRY +}; + +zend_class_entry *php_http_header_class_entry; + +PHP_MINIT_FUNCTION(http_header) +{ + zend_class_entry ce = {0}; + + INIT_NS_CLASS_ENTRY(ce, "http", "Header", php_http_header_methods); + php_http_header_class_entry = zend_register_internal_class(&ce TSRMLS_CC); + zend_class_implements(php_http_header_class_entry TSRMLS_CC, 1, zend_ce_serializable); + zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_LOOSE"), PHP_HTTP_MATCH_LOOSE TSRMLS_CC); + zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_CASE"), PHP_HTTP_MATCH_CASE TSRMLS_CC); + zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_WORD"), PHP_HTTP_MATCH_WORD TSRMLS_CC); + zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_FULL"), PHP_HTTP_MATCH_FULL TSRMLS_CC); + zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_STRICT"), PHP_HTTP_MATCH_STRICT TSRMLS_CC); + zend_declare_property_null(php_http_header_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_http_header_class_entry, ZEND_STRL("value"), ZEND_ACC_PUBLIC TSRMLS_CC); + + return SUCCESS; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ + diff --git a/php_http_header.h b/php_http_header.h new file mode 100644 index 0000000..2c0d2e8 --- /dev/null +++ b/php_http_header.h @@ -0,0 +1,38 @@ +/* + +--------------------------------------------------------------------+ + | PECL :: http | + +--------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met. | + +--------------------------------------------------------------------+ + | Copyright (c) 2004-2013, Michael Wallner | + +--------------------------------------------------------------------+ +*/ + +#ifndef PHP_HTTP_HEADERS_H +#define PHP_HTTP_HEADERS_H + +#include "php_http_info.h" + +PHP_HTTP_API STATUS php_http_header_parse(const char *header, size_t length, HashTable *headers, php_http_info_callback_t callback_func, void **callback_data TSRMLS_DC); + +PHP_HTTP_API void php_http_header_to_callback(HashTable *headers, zend_bool crlf, php_http_pass_format_callback_t cb, void *cb_arg TSRMLS_DC); +PHP_HTTP_API void php_http_header_to_string(php_http_buffer_t *str, HashTable *headers TSRMLS_DC); + +PHP_HTTP_API zval *php_http_header_value_to_string(zval *header TSRMLS_DC); + +PHP_HTTP_API zend_class_entry *php_http_header_class_entry; +PHP_MINIT_FUNCTION(http_header); + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ + diff --git a/php_http_header_parser.c b/php_http_header_parser.c index 8636ed3..e7fc886 100644 --- a/php_http_header_parser.c +++ b/php_http_header_parser.c @@ -26,7 +26,7 @@ static const php_http_header_parser_state_spec_t php_http_header_parser_states[] {PHP_HTTP_HEADER_PARSER_STATE_DONE, 0} }; -PHP_HTTP_API php_http_header_parser_t *php_http_header_parser_init(php_http_header_parser_t *parser TSRMLS_DC) +php_http_header_parser_t *php_http_header_parser_init(php_http_header_parser_t *parser TSRMLS_DC) { if (!parser) { parser = emalloc(sizeof(*parser)); @@ -38,7 +38,7 @@ PHP_HTTP_API php_http_header_parser_t *php_http_header_parser_init(php_http_head return parser; } -PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_push(php_http_header_parser_t *parser, unsigned argc, ...) +php_http_header_parser_state_t php_http_header_parser_state_push(php_http_header_parser_t *parser, unsigned argc, ...) { va_list va_args; unsigned i; @@ -54,7 +54,7 @@ PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_push(ph return state; } -PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_is(php_http_header_parser_t *parser) +php_http_header_parser_state_t php_http_header_parser_state_is(php_http_header_parser_t *parser) { php_http_header_parser_state_t *state; @@ -64,7 +64,7 @@ PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_is(php_ return PHP_HTTP_HEADER_PARSER_STATE_START; } -PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_pop(php_http_header_parser_t *parser) +php_http_header_parser_state_t php_http_header_parser_state_pop(php_http_header_parser_t *parser) { php_http_header_parser_state_t state, *state_ptr; if (SUCCESS == zend_stack_top(&parser->stack, (void *) &state_ptr)) { @@ -75,7 +75,7 @@ PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_pop(php return PHP_HTTP_HEADER_PARSER_STATE_START; } -PHP_HTTP_API void php_http_header_parser_dtor(php_http_header_parser_t *parser) +void php_http_header_parser_dtor(php_http_header_parser_t *parser) { zend_stack_destroy(&parser->stack); php_http_info_dtor(&parser->info); @@ -83,7 +83,7 @@ PHP_HTTP_API void php_http_header_parser_dtor(php_http_header_parser_t *parser) STR_FREE(parser->_val.str); } -PHP_HTTP_API void php_http_header_parser_free(php_http_header_parser_t **parser) +void php_http_header_parser_free(php_http_header_parser_t **parser) { if (*parser) { php_http_header_parser_dtor(*parser); @@ -92,7 +92,7 @@ PHP_HTTP_API void php_http_header_parser_free(php_http_header_parser_t **parser) } } -PHP_HTTP_API STATUS php_http_header_parser_parse(php_http_header_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, HashTable *headers, php_http_info_callback_t callback_func, void *callback_arg) +STATUS php_http_header_parser_parse(php_http_header_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, HashTable *headers, php_http_info_callback_t callback_func, void *callback_arg) { TSRMLS_FETCH_FROM_CTX(parser->ts); diff --git a/php_http_headers.c b/php_http_headers.c deleted file mode 100644 index eaa6105..0000000 --- a/php_http_headers.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - +--------------------------------------------------------------------+ - | PECL :: http | - +--------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met. | - +--------------------------------------------------------------------+ - | Copyright (c) 2004-2013, Michael Wallner | - +--------------------------------------------------------------------+ -*/ - -#include "php_http_api.h" - -PHP_HTTP_API STATUS php_http_headers_parse(const char *header, size_t length, HashTable *headers, php_http_info_callback_t callback_func, void **callback_data TSRMLS_DC) -{ - php_http_header_parser_t ctx; - php_http_buffer_t buf; - php_http_header_parser_state_t rs; - - if (!php_http_buffer_from_string_ex(&buf, header, length)) { - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "Could not allocate buffer"); - return FAILURE; - } - - if (!php_http_header_parser_init(&ctx TSRMLS_CC)) { - php_http_buffer_dtor(&buf); - php_http_error(HE_WARNING, PHP_HTTP_E_HEADER, "Could not initialize header parser"); - return FAILURE; - } - - rs = php_http_header_parser_parse(&ctx, &buf, PHP_HTTP_HEADER_PARSER_CLEANUP, headers, callback_func, callback_data); - php_http_header_parser_dtor(&ctx); - php_http_buffer_dtor(&buf); - - if (rs == PHP_HTTP_HEADER_PARSER_STATE_FAILURE) { - php_http_error(HE_WARNING, PHP_HTTP_E_MALFORMED_HEADERS, "Could not parse headers"); - return FAILURE; - } - - return SUCCESS; -} - -PHP_HTTP_API void php_http_headers_to_callback(HashTable *headers, zend_bool crlf, php_http_pass_format_callback_t cb, void *cb_arg TSRMLS_DC) -{ - HashPosition pos1, pos2; - php_http_array_hashkey_t key = php_http_array_hashkey_init(0); - zval **header, **single_header; - - FOREACH_HASH_KEYVAL(pos1, headers, key, header) { - if (key.type == HASH_KEY_IS_STRING) { - if (key.len == sizeof("Set-Cookie") && !strcasecmp(key.str, "Set-Cookie") && Z_TYPE_PP(header) == IS_ARRAY) { - FOREACH_VAL(pos2, *header, single_header) { - if (Z_TYPE_PP(single_header) == IS_ARRAY) { - php_http_cookie_list_t *cookie = php_http_cookie_list_from_struct(NULL, *single_header TSRMLS_CC); - - if (cookie) { - char *buf; - size_t len; - - php_http_cookie_list_to_string(cookie, &buf, &len); - cb(cb_arg, crlf ? "Set-Cookie: %s" PHP_HTTP_CRLF : "Set-Cookie: %s", buf); - php_http_cookie_list_free(&cookie); - efree(buf); - } - } else { - zval *strval = php_http_header_value_to_string(*single_header TSRMLS_CC); - - cb(cb_arg, crlf ? "Set-Cookie: %s" PHP_HTTP_CRLF : "Set-Cookie: %s", Z_STRVAL_P(strval)); - zval_ptr_dtor(&strval); - } - } - } else { - zval *strval = php_http_header_value_to_string(*header TSRMLS_CC); - - cb(cb_arg, crlf ? "%s: %s" PHP_HTTP_CRLF : "%s: %s", key.str, Z_STRVAL_P(strval)); - zval_ptr_dtor(&strval); - } - } - } -} - -PHP_HTTP_API void php_http_headers_to_string(php_http_buffer_t *str, HashTable *headers TSRMLS_DC) -{ - php_http_headers_to_callback(headers, 1, (php_http_pass_format_callback_t) php_http_buffer_appendf, str TSRMLS_CC); -} - -PHP_HTTP_API zval *php_http_header_value_to_string(zval *header TSRMLS_DC) -{ - zval *ret; - - if (Z_TYPE_P(header) == IS_BOOL) { - MAKE_STD_ZVAL(ret); - ZVAL_STRING(ret, Z_BVAL_P(header) ? "true" : "false", 1); - } else if (Z_TYPE_P(header) == IS_ARRAY) { - zval **val; - HashPosition pos; - php_http_buffer_t str; - - php_http_buffer_init(&str); - MAKE_STD_ZVAL(ret); - FOREACH_VAL(pos,header, val) { - zval *strval = php_http_header_value_to_string(*val TSRMLS_CC); - - php_http_buffer_appendf(&str, str.used ? ", %s":"%s", Z_STRVAL_P(strval)); - zval_ptr_dtor(&strval); - } - php_http_buffer_fix(&str); - ZVAL_STRINGL(ret, str.data, str.used, 0); - } else { - ret = php_http_zsep(1, IS_STRING, header); - } - - return ret; -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader___construct, 0, 0, 0) - ZEND_ARG_INFO(0, name) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, __construct) -{ - char *name_str = NULL, *value_str = NULL; - int name_len = 0, value_len = 0; - - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!", &name_str, &name_len, &value_str, &value_len)) { - if (name_str && name_len) { - char *pretty_str = estrndup(name_str, name_len); - zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("name"), php_http_pretty_key(pretty_str, name_len, 1, 1), name_len TSRMLS_CC); - efree(pretty_str); - } - if (value_str && value_len) { - zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("value"), value_str, value_len TSRMLS_CC); - } - } - } end_error_handling(); -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_serialize, 0, 0, 0) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, serialize) -{ - php_http_buffer_t buf; - zval *zname, *zvalue; - - php_http_buffer_init(&buf); - zname = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("name"), 0 TSRMLS_CC)); - php_http_buffer_append(&buf, Z_STRVAL_P(zname), Z_STRLEN_P(zname)); - zval_ptr_dtor(&zname); - zvalue = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0 TSRMLS_CC)); - if (Z_STRLEN_P(zvalue)) { - php_http_buffer_appends(&buf, ": "); - php_http_buffer_append(&buf, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue)); - } else { - php_http_buffer_appends(&buf, ":"); - } - zval_ptr_dtor(&zvalue); - - RETURN_PHP_HTTP_BUFFER_VAL(&buf); -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_unserialize, 0, 0, 1) - ZEND_ARG_INFO(0, serialized) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, unserialize) -{ - char *serialized_str; - int serialized_len; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized_str, &serialized_len)) { - HashTable ht; - - zend_hash_init(&ht, 1, NULL, ZVAL_PTR_DTOR, 0); - if (SUCCESS == php_http_headers_parse(serialized_str, serialized_len, &ht, NULL, NULL TSRMLS_CC)) { - if (zend_hash_num_elements(&ht)) { - zval **val, *cpy; - char *str; - uint len; - ulong idx; - - zend_hash_internal_pointer_reset(&ht); - switch (zend_hash_get_current_key_ex(&ht, &str, &len, &idx, 0, NULL)) { - case HASH_KEY_IS_STRING: - zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("name"), str, len - 1 TSRMLS_CC); - break; - case HASH_KEY_IS_LONG: - zend_update_property_long(php_http_header_class_entry, getThis(), ZEND_STRL("name"), idx TSRMLS_CC); - break; - default: - break; - } - zend_hash_get_current_data(&ht, (void *) &val); - cpy = php_http_zsep(1, IS_STRING, *val); - zend_update_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), cpy TSRMLS_CC); - zval_ptr_dtor(&cpy); - } - } - zend_hash_destroy(&ht); - } - -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_match, 0, 0, 1) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, match) -{ - char *val_str; - int val_len; - long flags = PHP_HTTP_MATCH_LOOSE; - zval *zvalue; - - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &val_str, &val_len, &flags)) { - return; - } - - zvalue = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0 TSRMLS_CC)); - RETVAL_BOOL(php_http_match(Z_STRVAL_P(zvalue), val_str, flags)); - zval_ptr_dtor(&zvalue); -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_negotiate, 0, 0, 1) - ZEND_ARG_INFO(0, supported) - ZEND_ARG_INFO(1, result) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, negotiate) -{ - HashTable *supported, *rs; - zval *zname, *zvalue, *rs_array = NULL; - char *sep_str = NULL; - size_t sep_len = 0; - - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H|z", &supported, &rs_array)) { - return; - } - if (rs_array) { - zval_dtor(rs_array); - array_init(rs_array); - } - - zname = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("name"), 0 TSRMLS_CC)); - if (!strcasecmp(Z_STRVAL_P(zname), "Accept")) { - sep_str = "/"; - sep_len = 1; - } else if (!strcasecmp(Z_STRVAL_P(zname), "Accept-Language")) { - sep_str = "-"; - sep_len = 1; - } - zval_ptr_dtor(&zname); - - zvalue = php_http_ztyp(IS_STRING, zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0 TSRMLS_CC)); - if ((rs = php_http_negotiate(Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), supported, sep_str, sep_len TSRMLS_CC))) { - PHP_HTTP_DO_NEGOTIATE_HANDLE_RESULT(rs, supported, rs_array); - } else { - PHP_HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array); - } - zval_ptr_dtor(&zvalue); -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_getParams, 0, 0, 0) - ZEND_ARG_INFO(0, param_sep) - ZEND_ARG_INFO(0, arg_sep) - ZEND_ARG_INFO(0, val_sep) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, getParams) -{ - zval zctor, *zparams_obj, **zargs = NULL; - - INIT_PZVAL(&zctor); - ZVAL_STRINGL(&zctor, "__construct", lenof("__construct"), 0); - - MAKE_STD_ZVAL(zparams_obj); - object_init_ex(zparams_obj, php_http_params_class_entry); - - zargs = (zval **) ecalloc(ZEND_NUM_ARGS()+1, sizeof(zval *)); - zargs[0] = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("value"), 0 TSRMLS_CC); - if (ZEND_NUM_ARGS()) { - zend_get_parameters_array(ZEND_NUM_ARGS(), ZEND_NUM_ARGS(), &zargs[1]); - } - - if (SUCCESS == call_user_function(NULL, &zparams_obj, &zctor, return_value, ZEND_NUM_ARGS()+1, zargs TSRMLS_CC)) { - RETVAL_ZVAL(zparams_obj, 0, 1); - } - - if (zargs) { - efree(zargs); - } -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_parse, 0, 0, 1) - ZEND_ARG_INFO(0, string) - ZEND_ARG_INFO(0, header_class) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpHeader, parse) -{ - char *header_str; - int header_len; - zend_class_entry *ce = NULL; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C", &header_str, &header_len, &ce)) { - array_init(return_value); - - if (SUCCESS != php_http_headers_parse(header_str, header_len, Z_ARRVAL_P(return_value), NULL, NULL TSRMLS_CC)) { - php_http_error(HE_WARNING, PHP_HTTP_E_MALFORMED_HEADERS, "Could not parse headers"); - zval_dtor(return_value); - RETVAL_NULL(); - } else { - if (ce && instanceof_function(ce, php_http_header_class_entry TSRMLS_CC)) { - HashPosition pos; - php_http_array_hashkey_t key = php_http_array_hashkey_init(0); - zval **val; - - FOREACH_KEYVAL(pos, return_value, key, val) { - zval *zho, *zkey, *zvalue; - - Z_ADDREF_PP(val); - zvalue = *val; - - MAKE_STD_ZVAL(zkey); - if (key.type == HASH_KEY_IS_LONG) { - ZVAL_LONG(zkey, key.num); - } else { - ZVAL_STRINGL(zkey, key.str, key.len - 1, 1); - } - - MAKE_STD_ZVAL(zho); - object_init_ex(zho, ce); - zend_call_method_with_2_params(&zho, ce, NULL, "__construct", NULL, zkey, zvalue); - - if (key.type == HASH_KEY_IS_LONG) { - zend_hash_index_update(Z_ARRVAL_P(return_value), key.num, (void *) &zho, sizeof(zval *), NULL); - } else { - zend_hash_update(Z_ARRVAL_P(return_value), key.str, key.len, (void *) &zho, sizeof(zval *), NULL); - } - - zval_ptr_dtor(&zvalue); - zval_ptr_dtor(&zkey); - } - } - } - } -} - -static zend_function_entry php_http_header_methods[] = { - PHP_ME(HttpHeader, __construct, ai_HttpHeader___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) - PHP_ME(HttpHeader, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC) - ZEND_MALIAS(HttpHeader, __toString, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC) - ZEND_MALIAS(HttpHeader, toString, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC) - PHP_ME(HttpHeader, unserialize, ai_HttpHeader_unserialize, ZEND_ACC_PUBLIC) - PHP_ME(HttpHeader, match, ai_HttpHeader_match, ZEND_ACC_PUBLIC) - PHP_ME(HttpHeader, negotiate, ai_HttpHeader_negotiate, ZEND_ACC_PUBLIC) - PHP_ME(HttpHeader, getParams, ai_HttpHeader_getParams, ZEND_ACC_PUBLIC) - PHP_ME(HttpHeader, parse, ai_HttpHeader_parse, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - EMPTY_FUNCTION_ENTRY -}; - -zend_class_entry *php_http_header_class_entry; - -PHP_MINIT_FUNCTION(http_header) -{ - zend_class_entry ce = {0}; - - INIT_NS_CLASS_ENTRY(ce, "http", "Header", php_http_header_methods); - php_http_header_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); - zend_class_implements(php_http_header_class_entry TSRMLS_CC, 1, zend_ce_serializable); - zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_LOOSE"), PHP_HTTP_MATCH_LOOSE TSRMLS_CC); - zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_CASE"), PHP_HTTP_MATCH_CASE TSRMLS_CC); - zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_WORD"), PHP_HTTP_MATCH_WORD TSRMLS_CC); - zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_FULL"), PHP_HTTP_MATCH_FULL TSRMLS_CC); - zend_declare_class_constant_long(php_http_header_class_entry, ZEND_STRL("MATCH_STRICT"), PHP_HTTP_MATCH_STRICT TSRMLS_CC); - zend_declare_property_null(php_http_header_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_header_class_entry, ZEND_STRL("value"), ZEND_ACC_PUBLIC TSRMLS_CC); - - return SUCCESS; -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ - diff --git a/php_http_headers.h b/php_http_headers.h deleted file mode 100644 index 88a988a..0000000 --- a/php_http_headers.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - +--------------------------------------------------------------------+ - | PECL :: http | - +--------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met. | - +--------------------------------------------------------------------+ - | Copyright (c) 2004-2013, Michael Wallner | - +--------------------------------------------------------------------+ -*/ - -#ifndef PHP_HTTP_HEADERS_H -#define PHP_HTTP_HEADERS_H - -#include "php_http_info.h" - -PHP_HTTP_API STATUS php_http_headers_parse(const char *header, size_t length, HashTable *headers, php_http_info_callback_t callback_func, void **callback_data TSRMLS_DC); - -PHP_HTTP_API void php_http_headers_to_callback(HashTable *headers, zend_bool crlf, php_http_pass_format_callback_t cb, void *cb_arg TSRMLS_DC); -PHP_HTTP_API void php_http_headers_to_string(php_http_buffer_t *str, HashTable *headers TSRMLS_DC); - -PHP_HTTP_API zval *php_http_header_value_to_string(zval *header TSRMLS_DC); - -PHP_HTTP_API zend_class_entry *php_http_header_class_entry; -PHP_MINIT_FUNCTION(http_header); - -#endif - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ - diff --git a/php_http_info.c b/php_http_info.c index baccfc1..dca784f 100644 --- a/php_http_info.c +++ b/php_http_info.c @@ -12,7 +12,7 @@ #include "php_http_api.h" -PHP_HTTP_API php_http_info_t *php_http_info_init(php_http_info_t *i TSRMLS_DC) +php_http_info_t *php_http_info_init(php_http_info_t *i TSRMLS_DC) { if (!i) { i = emalloc(sizeof(*i)); @@ -23,7 +23,7 @@ PHP_HTTP_API php_http_info_t *php_http_info_init(php_http_info_t *i TSRMLS_DC) return i; } -PHP_HTTP_API void php_http_info_dtor(php_http_info_t *i) +void php_http_info_dtor(php_http_info_t *i) { switch (i->type) { case PHP_HTTP_REQUEST: @@ -40,7 +40,7 @@ PHP_HTTP_API void php_http_info_dtor(php_http_info_t *i) } } -PHP_HTTP_API void php_http_info_free(php_http_info_t **i) +void php_http_info_free(php_http_info_t **i) { if (*i) { php_http_info_dtor(*i); @@ -49,7 +49,7 @@ PHP_HTTP_API void php_http_info_free(php_http_info_t **i) } } -PHP_HTTP_API php_http_info_t *php_http_info_parse(php_http_info_t *info, const char *pre_header TSRMLS_DC) +php_http_info_t *php_http_info_parse(php_http_info_t *info, const char *pre_header TSRMLS_DC) { const char *end, *http; zend_bool free_info = !info; diff --git a/php_http_message.c b/php_http_message.c index 1c33703..f3509a4 100644 --- a/php_http_message.c +++ b/php_http_message.c @@ -14,7 +14,7 @@ static void message_headers(php_http_message_t *msg, php_http_buffer_t *str); -PHP_HTTP_API zend_bool php_http_message_info_callback(php_http_message_t **message, HashTable **headers, php_http_info_t *info TSRMLS_DC) +zend_bool php_http_message_info_callback(php_http_message_t **message, HashTable **headers, php_http_info_t *info TSRMLS_DC) { php_http_message_t *old = *message; @@ -34,7 +34,7 @@ PHP_HTTP_API zend_bool php_http_message_info_callback(php_http_message_t **messa return old != *message; } -PHP_HTTP_API php_http_message_t *php_http_message_init(php_http_message_t *message, php_http_message_type_t type, php_http_message_body_t *body TSRMLS_DC) +php_http_message_t *php_http_message_init(php_http_message_t *message, php_http_message_type_t type, php_http_message_body_t *body TSRMLS_DC) { if (!message) { message = emalloc(sizeof(*message)); @@ -51,7 +51,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_init(php_http_message_t *messa return message; } -PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *message, php_http_message_type_t type TSRMLS_DC) +php_http_message_t *php_http_message_init_env(php_http_message_t *message, php_http_message_type_t type TSRMLS_DC) { int free_msg = !message; zval *sval, tval; @@ -88,10 +88,10 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m #if PHP_VERSION_ID >= 50400 if (php_output_get_level(TSRMLS_C)) { if (php_output_get_status(TSRMLS_C) & PHP_OUTPUT_SENT) { - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "Could not fetch response body, output has already been sent at %s:%d", php_output_get_start_filename(TSRMLS_C), php_output_get_start_lineno(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body, output has already been sent at %s:%d", php_output_get_start_filename(TSRMLS_C), php_output_get_start_lineno(TSRMLS_C)); goto error; } else if (SUCCESS != php_output_get_contents(&tval TSRMLS_CC)) { - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "Could not fetch response body"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body"); goto error; } else { php_http_message_body_append(message->body, Z_STRVAL(tval), Z_STRLEN(tval)); @@ -116,7 +116,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m return message; } -PHP_HTTP_API php_http_message_t *php_http_message_parse(php_http_message_t *msg, const char *str, size_t len, zend_bool greedy TSRMLS_DC) +php_http_message_t *php_http_message_parse(php_http_message_t *msg, const char *str, size_t len, zend_bool greedy TSRMLS_DC) { php_http_message_parser_t p; php_http_buffer_t buf; @@ -146,7 +146,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_parse(php_http_message_t *msg, return msg; } -PHP_HTTP_API zval *php_http_message_header(php_http_message_t *msg, const char *key_str, size_t key_len, int join) +zval *php_http_message_header(php_http_message_t *msg, const char *key_str, size_t key_len, int join) { zval *ret = NULL, **header; char *key = php_http_pretty_key(estrndup(key_str, key_len), key_len, 1, 1); @@ -167,7 +167,7 @@ PHP_HTTP_API zval *php_http_message_header(php_http_message_t *msg, const char * return ret; } -PHP_HTTP_API zend_bool php_http_message_is_multipart(php_http_message_t *msg, char **boundary) +zend_bool php_http_message_is_multipart(php_http_message_t *msg, char **boundary) { zval *ct = php_http_message_header(msg, ZEND_STRL("Content-Type"), 1); zend_bool is_multipart = 0; @@ -226,7 +226,7 @@ PHP_HTTP_API zend_bool php_http_message_is_multipart(php_http_message_t *msg, ch } /* */ -PHP_HTTP_API void php_http_message_set_type(php_http_message_t *message, php_http_message_type_t type) +void php_http_message_set_type(php_http_message_t *message, php_http_message_type_t type) { /* just act if different */ if (type != message->type) { @@ -251,7 +251,7 @@ PHP_HTTP_API void php_http_message_set_type(php_http_message_t *message, php_htt } } -PHP_HTTP_API void php_http_message_set_info(php_http_message_t *message, php_http_info_t *info) +void php_http_message_set_info(php_http_message_t *message, php_http_info_t *info) { php_http_message_set_type(message, info->type); message->http.version = info->http.version; @@ -271,7 +271,7 @@ PHP_HTTP_API void php_http_message_set_info(php_http_message_t *message, php_htt } } -PHP_HTTP_API void php_http_message_update_headers(php_http_message_t *msg) +void php_http_message_update_headers(php_http_message_t *msg) { zval *h; size_t size; @@ -321,10 +321,10 @@ static void message_headers(php_http_message_t *msg, php_http_buffer_t *str) } php_http_message_update_headers(msg); - php_http_headers_to_string(str, &msg->hdrs TSRMLS_CC); + php_http_header_to_string(str, &msg->hdrs TSRMLS_CC); } -PHP_HTTP_API void php_http_message_to_callback(php_http_message_t *msg, php_http_pass_callback_t cb, void *cb_arg) +void php_http_message_to_callback(php_http_message_t *msg, php_http_pass_callback_t cb, void *cb_arg) { php_http_buffer_t str; @@ -339,7 +339,7 @@ PHP_HTTP_API void php_http_message_to_callback(php_http_message_t *msg, php_http } } -PHP_HTTP_API void php_http_message_to_string(php_http_message_t *msg, char **string, size_t *length) +void php_http_message_to_string(php_http_message_t *msg, char **string, size_t *length) { php_http_buffer_t str; char *data; @@ -359,7 +359,7 @@ PHP_HTTP_API void php_http_message_to_string(php_http_message_t *msg, char **str php_http_buffer_dtor(&str); } -PHP_HTTP_API void php_http_message_serialize(php_http_message_t *message, char **string, size_t *length) +void php_http_message_serialize(php_http_message_t *message, char **string, size_t *length) { char *buf; php_http_buffer_t str; @@ -382,7 +382,7 @@ PHP_HTTP_API void php_http_message_serialize(php_http_message_t *message, char * php_http_buffer_dtor(&str); } -PHP_HTTP_API php_http_message_t *php_http_message_reverse(php_http_message_t *msg) +php_http_message_t *php_http_message_reverse(php_http_message_t *msg) { int i, c = 0; @@ -408,7 +408,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_reverse(php_http_message_t *ms return msg; } -PHP_HTTP_API php_http_message_t *php_http_message_zip(php_http_message_t *one, php_http_message_t *two) +php_http_message_t *php_http_message_zip(php_http_message_t *one, php_http_message_t *two) { php_http_message_t *dst = php_http_message_copy(one, NULL), *src = php_http_message_copy(two, NULL), *tmp_dst, *tmp_src, *ret = dst; @@ -426,7 +426,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_zip(php_http_message_t *one, p return ret; } -PHP_HTTP_API php_http_message_t *php_http_message_copy_ex(php_http_message_t *from, php_http_message_t *to, zend_bool parents) +php_http_message_t *php_http_message_copy_ex(php_http_message_t *from, php_http_message_t *to, zend_bool parents) { php_http_message_t *temp, *copy = NULL; php_http_info_t info; @@ -456,12 +456,12 @@ PHP_HTTP_API php_http_message_t *php_http_message_copy_ex(php_http_message_t *fr return copy; } -PHP_HTTP_API php_http_message_t *php_http_message_copy(php_http_message_t *from, php_http_message_t *to) +php_http_message_t *php_http_message_copy(php_http_message_t *from, php_http_message_t *to) { return php_http_message_copy_ex(from, to, 1); } -PHP_HTTP_API void php_http_message_dtor(php_http_message_t *message) +void php_http_message_dtor(php_http_message_t *message) { if (message) { zend_hash_destroy(&message->hdrs); @@ -483,7 +483,7 @@ PHP_HTTP_API void php_http_message_dtor(php_http_message_t *message) } } -PHP_HTTP_API void php_http_message_free(php_http_message_t **message) +void php_http_message_free(php_http_message_t **message) { if (*message) { if ((*message)->parent) { @@ -711,13 +711,7 @@ void php_http_message_object_prepend(zval *this_ptr, zval *prepend, zend_bool to /* add ref */ zend_objects_store_add_ref(prepend TSRMLS_CC); - /* - while (prepend_obj->parent) { - m.value.obj = prepend_obj->parent->zv; - zend_objects_store_add_ref(&m TSRMLS_CC); - prepend_obj = zend_object_store_get_object(&m TSRMLS_CC); - } - */ + if (!top) { prepend_obj->parent = save_parent_obj; prepend_obj->message->parent = save_parent_msg; @@ -736,7 +730,7 @@ STATUS php_http_message_object_set_body(php_http_message_object_t *msg_obj, zval case IS_RESOURCE: php_stream_from_zval_no_verify(s, &zbody); if (!s) { - php_http_error(HE_THROW, PHP_HTTP_E_CLIENT, "not a valid stream resource"); + php_http_throw(unexpected_val, "The stream is not a valid resource", NULL); return FAILURE; } @@ -993,64 +987,75 @@ static PHP_METHOD(HttpMessage, __construct) zval *zmessage = NULL; php_http_message_t *msg = NULL; php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + zend_error_handling zeh; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!b", &zmessage, &greedy) && zmessage) { - if (Z_TYPE_P(zmessage) == IS_RESOURCE) { - php_stream *s; - php_http_message_parser_t p; - - php_stream_from_zval(s, &zmessage); - if (s && php_http_message_parser_init(&p TSRMLS_CC)) { - unsigned flags = (greedy ? PHP_HTTP_MESSAGE_PARSER_GREEDY : 0); - - php_http_message_parser_parse_stream(&p, s, flags, &msg); - php_http_message_parser_dtor(&p); - } - - if (!msg) { - php_http_error(HE_THROW, PHP_HTTP_E_MESSAGE, "could not parse message from stream"); - } - } else { - zmessage = php_http_ztyp(IS_STRING, zmessage); - if (!(msg = php_http_message_parse(NULL, Z_STRVAL_P(zmessage), Z_STRLEN_P(zmessage), greedy TSRMLS_CC))) { - php_http_error(HE_THROW, PHP_HTTP_E_MESSAGE, "could not parse message: %.*s", MIN(25, Z_STRLEN_P(zmessage)), Z_STRVAL_P(zmessage)); - } - zval_ptr_dtor(&zmessage); - } + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!b", &zmessage, &greedy), invalid_arg, return); + + zend_replace_error_handling(EH_THROW, php_http_exception_bad_message_class_entry, &zeh TSRMLS_CC); + if (zmessage && Z_TYPE_P(zmessage) == IS_RESOURCE) { + php_stream *s; + php_http_message_parser_t p; + zend_error_handling zeh; - if (msg) { - php_http_message_dtor(obj->message); - obj->message = msg; - if (obj->message->parent) { - php_http_message_object_new_ex(Z_OBJCE_P(getThis()), obj->message->parent, &obj->parent TSRMLS_CC); + zend_replace_error_handling(EH_THROW, php_http_exception_unexpected_val_class_entry, &zeh TSRMLS_CC); + php_stream_from_zval(s, &zmessage); + zend_restore_error_handling(&zeh TSRMLS_CC); + + if (s && php_http_message_parser_init(&p TSRMLS_CC)) { + unsigned flags = (greedy ? PHP_HTTP_MESSAGE_PARSER_GREEDY : 0); + + if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse_stream(&p, s, flags, &msg)) { + if (!EG(exception)) { + php_http_throw(bad_message, "Could not parse message from stream", NULL); } } + + php_http_message_parser_dtor(&p); } - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - } end_error_handling(); + if (!msg && !EG(exception)) { + php_http_throw(bad_message, "Empty message received from stream", NULL); + } + } else if (zmessage) { + zmessage = php_http_ztyp(IS_STRING, zmessage); + msg = php_http_message_parse(NULL, Z_STRVAL_P(zmessage), Z_STRLEN_P(zmessage), greedy TSRMLS_CC); + + if (!msg && !EG(exception)) { + php_http_throw(bad_message, "Could not parse message: %.*s", MIN(25, Z_STRLEN_P(zmessage)), Z_STRVAL_P(zmessage)); + } + zval_ptr_dtor(&zmessage); + } + + if (msg) { + php_http_message_dtor(obj->message); + obj->message = msg; + if (obj->message->parent) { + php_http_message_object_new_ex(Z_OBJCE_P(getThis()), obj->message->parent, &obj->parent TSRMLS_CC); + } + } + zend_restore_error_handling(&zeh TSRMLS_CC); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getBody, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, getBody) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_object_t *obj; - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - if (!obj->body) { - php_http_message_body_addref(obj->message->body); - php_http_new(NULL, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, obj->message->body, (void *) &obj->body TSRMLS_CC); - } - if (obj->body) { - RETVAL_OBJVAL(obj->body->zv, 1); - } - } - } end_error_handling(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (!obj->body) { + php_http_message_body_addref(obj->message->body); + php_http_new(NULL, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, obj->message->body, (void *) &obj->body TSRMLS_CC); + } + if (obj->body) { + RETVAL_OBJVAL(obj->body->zv, 1); + } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setBody, 0, 0, 1) @@ -1123,7 +1128,7 @@ static PHP_METHOD(HttpMessage, getHeader) return; } else { - php_http_error(HE_WARNING, PHP_HTTP_E_INVALID_PARAM, "Class '%s' is not as descendant of http\\Header", header_ce->name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class '%s' is not as descendant of http\\Header", header_ce->name); } } } @@ -1302,20 +1307,22 @@ static PHP_METHOD(HttpMessage, setInfo) { char *str; int len; + php_http_message_object_t *obj; php_http_info_t inf; - if ( SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - if (php_http_info_parse(&inf, str TSRMLS_CC)) { - php_http_message_set_info(obj->message, &inf); - php_http_info_dtor(&inf); - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_MALFORMED_HEADERS, "Could not parse message info '%s'", str); - } + if (!php_http_info_parse(&inf, str TSRMLS_CC)) { + php_http_throw(bad_header, "Could not parse message info '%s'", str); + return; } + + php_http_message_set_info(obj->message, &inf); + php_http_info_dtor(&inf); + RETVAL_ZVAL(getThis(), 1, 0); } @@ -1342,17 +1349,18 @@ static PHP_METHOD(HttpMessage, setHttpVersion) { char *v_str; int v_len; + php_http_version_t version; + php_http_message_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &v_str, &v_len)) { - php_http_version_t version; - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &v_str, &v_len), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + php_http_expect(php_http_version_parse(&version, v_str TSRMLS_CC), unexpected_val, return); + + obj->message->http.version = version; - if (php_http_version_parse(&version, v_str TSRMLS_CC)) { - obj->message->http.version = version; - } - } RETVAL_ZVAL(getThis(), 1, 0); } @@ -1365,33 +1373,44 @@ static PHP_METHOD(HttpMessage, getResponseCode) PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - PHP_HTTP_MESSAGE_TYPE_CHECK(RESPONSE, obj->message, RETURN_FALSE); + if (obj->message->type != PHP_HTTP_RESPONSE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not if type response"); + RETURN_FALSE; + } + RETURN_LONG(obj->message->http.info.response.code); } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setResponseCode, 0, 0, 1) ZEND_ARG_INFO(0, response_code) + ZEND_ARG_INFO(0, strict) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, setResponseCode) { long code; zend_bool strict = 1; + php_http_message_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &code, &strict)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &code, &strict), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - PHP_HTTP_MESSAGE_TYPE_CHECK(RESPONSE, obj->message, RETURN_FALSE); - if (strict && (code < 100 || code > 599)) { - php_http_error(HE_WARNING, PHP_HTTP_E_INVALID_PARAM, "Invalid response code (100-599): %ld", code); - RETURN_FALSE; - } + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (obj->message->type != PHP_HTTP_RESPONSE) { + php_http_throw(bad_method_call, "http\\Message is not of type response", NULL); + return; + } - obj->message->http.info.response.code = code; - STR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(code))); + if (strict && (code < 100 || code > 599)) { + php_http_throw(invalid_arg, "Invalid response code (100-599): %ld", code); + return; } + + obj->message->http.info.response.code = code; + STR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(code))); + RETVAL_ZVAL(getThis(), 1, 0); } @@ -1404,7 +1423,10 @@ static PHP_METHOD(HttpMessage, getResponseStatus) PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - PHP_HTTP_MESSAGE_TYPE_CHECK(RESPONSE, obj->message, RETURN_FALSE); + if (obj->message->type != PHP_HTTP_RESPONSE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not of type response"); + } + if (obj->message->http.info.response.status) { RETURN_STRING(obj->message->http.info.response.status, 1); } else { @@ -1420,15 +1442,19 @@ static PHP_METHOD(HttpMessage, setResponseStatus) { char *status; int status_len; + php_http_message_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &status, &status_len)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &status, &status_len), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - PHP_HTTP_MESSAGE_TYPE_CHECK(RESPONSE, obj->message, RETURN_FALSE); - STR_SET(obj->message->http.info.response.status, estrndup(status, status_len)); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (obj->message->type != PHP_HTTP_RESPONSE) { + php_http_throw(bad_method_call, "http\\Message is not of type response", NULL); } + + STR_SET(obj->message->http.info.response.status, estrndup(status, status_len)); RETVAL_ZVAL(getThis(), 1, 0); } @@ -1441,7 +1467,11 @@ static PHP_METHOD(HttpMessage, getRequestMethod) PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - PHP_HTTP_MESSAGE_TYPE_CHECK(REQUEST, obj->message, RETURN_FALSE); + if (obj->message->type != PHP_HTTP_REQUEST) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not of type request"); + RETURN_FALSE; + } + if (obj->message->http.info.request.method) { RETURN_STRING(obj->message->http.info.request.method, 1); } else { @@ -1457,20 +1487,25 @@ static PHP_METHOD(HttpMessage, setRequestMethod) { char *method; int method_len; + php_http_message_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - PHP_HTTP_MESSAGE_TYPE_CHECK(REQUEST, obj->message, RETURN_FALSE); - if (method_len < 1) { - php_http_error(HE_WARNING, PHP_HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestMethod to an empty string"); - RETURN_FALSE; - } + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (obj->message->type != PHP_HTTP_REQUEST) { + php_http_throw(bad_method_call, "http\\Message is not of type request", NULL); + return; + } - STR_SET(obj->message->http.info.request.method, estrndup(method, method_len)); + if (method_len < 1) { + php_http_throw(invalid_arg, "Cannot set http\\Message's request method to an empty string", NULL); + return; } + + STR_SET(obj->message->http.info.request.method, estrndup(method, method_len)); RETVAL_ZVAL(getThis(), 1, 0); } @@ -1483,7 +1518,11 @@ static PHP_METHOD(HttpMessage, getRequestUrl) PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - PHP_HTTP_MESSAGE_TYPE_CHECK(REQUEST, obj->message, RETURN_FALSE); + if (obj->message->type != PHP_HTTP_REQUEST) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not of type request"); + RETURN_FALSE; + } + if (obj->message->http.info.request.url) { RETURN_STRING(obj->message->http.info.request.url, 1); } else { @@ -1499,19 +1538,25 @@ static PHP_METHOD(HttpMessage, setRequestUrl) { char *url_str; int url_len; + php_http_message_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url_str, &url_len)) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url_str, &url_len), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - PHP_HTTP_MESSAGE_TYPE_CHECK(REQUEST, obj->message, RETURN_FALSE); - if (url_len < 1) { - php_http_error(HE_WARNING, PHP_HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestUrl to an empty string"); - RETURN_FALSE; - } - STR_SET(obj->message->http.info.request.url, estrndup(url_str, url_len)); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (obj->message->type != PHP_HTTP_REQUEST) { + php_http_throw(bad_method_call, "http\\Message is not of type request", NULL); + return; } + + if (url_len < 1) { + php_http_throw(invalid_arg, "Cannot set http\\Message's request url to an empty string", NULL); + return; + } + + STR_SET(obj->message->http.info.request.url, estrndup(url_str, url_len)); RETVAL_ZVAL(getThis(), 1, 0); } @@ -1519,19 +1564,20 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getParentMessage, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, getParentMessage) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_object_t *obj; - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - if (obj->message->parent) { - RETVAL_OBJVAL(obj->parent->zv, 1); - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "HttpMessage does not have a parent message"); - } - } - } end_error_handling(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (!obj->message->parent) { + php_http_throw(unexpected_val, "http\\Message has not parent message", NULL); + return; + } + + RETVAL_OBJVAL(obj->parent->zv, 1); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage___toString, 0, 0, 0) @@ -1641,7 +1687,7 @@ static PHP_METHOD(HttpMessage, unserialize) obj->message = msg; } else { obj->message = php_http_message_init(NULL, 0, NULL TSRMLS_CC); - php_http_error(HE_ERROR, PHP_HTTP_E_RUNTIME, "Could not unserialize HttpMessage"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not unserialize http\\Message"); } } } @@ -1650,15 +1696,15 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_detach, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, detach) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_object_t *obj; - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - RETVAL_OBJVAL(php_http_message_object_new_ex(obj->zo.ce, php_http_message_copy_ex(obj->message, NULL, 0), NULL TSRMLS_CC), 0); - } - } end_error_handling(); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + RETVAL_OBJVAL(php_http_message_object_new_ex(obj->zo.ce, php_http_message_copy_ex(obj->message, NULL, 0), NULL TSRMLS_CC), 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_prepend, 0, 0, 1) @@ -1669,36 +1715,37 @@ static PHP_METHOD(HttpMessage, prepend) { zval *prepend; zend_bool top = 1; + php_http_message_t *msg[2]; + php_http_message_object_t *obj, *prepend_obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, php_http_message_class_entry, &top)) { - php_http_message_t *msg[2]; - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *prepend_obj = zend_object_store_get_object(prepend TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, php_http_message_class_entry, &top), invalid_arg, return); - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - PHP_HTTP_MESSAGE_OBJECT_INIT(prepend_obj); - - /* safety check */ - for (msg[0] = obj->message; msg[0]; msg[0] = msg[0]->parent) { - for (msg[1] = prepend_obj->message; msg[1]; msg[1] = msg[1]->parent) { - if (msg[0] == msg[1]) { - php_http_error(HE_THROW, PHP_HTTP_E_INVALID_PARAM, "Cannot prepend a message located within the same message chain"); - return; - } + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + prepend_obj = zend_object_store_get_object(prepend TSRMLS_CC); + PHP_HTTP_MESSAGE_OBJECT_INIT(prepend_obj); + + /* safety check */ + for (msg[0] = obj->message; msg[0]; msg[0] = msg[0]->parent) { + for (msg[1] = prepend_obj->message; msg[1]; msg[1] = msg[1]->parent) { + if (msg[0] == msg[1]) { + php_http_throw(unexpected_val, "Cannot prepend a message located within the same message chain", NULL); + return; } } - - php_http_message_object_prepend(getThis(), prepend, top TSRMLS_CC); } + + php_http_message_object_prepend(getThis(), prepend, top TSRMLS_CC); + RETURN_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_reverse, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, reverse) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_message_object_reverse(getThis(), return_value TSRMLS_CC); - } + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + php_http_message_object_reverse(getThis(), return_value TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_isMultipart, 0, 0, 0) @@ -1727,21 +1774,26 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_splitMultipartBody, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, splitMultipartBody) { - if (SUCCESS == zend_parse_parameters_none()) { - php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - char *boundary = NULL; + php_http_message_object_t *obj; + php_http_message_t *msg; + char *boundary = NULL; - PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - if (php_http_message_is_multipart(obj->message, &boundary)) { - php_http_message_t *msg; + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if ((msg = php_http_message_body_split(obj->message->body, boundary))) { - RETVAL_OBJVAL(php_http_message_object_new_ex(php_http_message_class_entry, msg, NULL TSRMLS_CC), 0); - } - } - STR_FREE(boundary); + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + if (!php_http_message_is_multipart(obj->message, &boundary)) { + php_http_throw(bad_method_call, "http\\Message is not a multipart message", NULL); + return; } + + php_http_expect(msg = php_http_message_body_split(obj->message->body, boundary), bad_message, return); + + STR_FREE(boundary); + + RETURN_OBJVAL(php_http_message_object_new_ex(php_http_message_class_entry, msg, NULL TSRMLS_CC), 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_count, 0, 0, 0) @@ -1757,7 +1809,6 @@ static PHP_METHOD(HttpMessage, count) php_http_message_count(i, obj->message); RETURN_LONG(i); } - RETURN_FALSE; } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_rewind, 0, 0, 0) @@ -1897,7 +1948,7 @@ PHP_MINIT_FUNCTION(http_message) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Message", php_http_message_methods); - php_http_message_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_message_class_entry = zend_register_internal_class(&ce TSRMLS_CC); php_http_message_class_entry->create_object = php_http_message_object_new; memcpy(&php_http_message_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_http_message_object_handlers.clone_obj = php_http_message_object_clone; diff --git a/php_http_message.h b/php_http_message.h index ea747fe..32af834 100644 --- a/php_http_message.h +++ b/php_http_message.h @@ -18,11 +18,6 @@ /* required minimum length of an HTTP message "HTTP/1.1" */ #define PHP_HTTP_MESSAGE_MIN_SIZE 8 #define PHP_HTTP_MESSAGE_TYPE(TYPE, msg) ((msg) && ((msg)->type == PHP_HTTP_ ##TYPE)) -#define PHP_HTTP_MESSAGE_TYPE_CHECK(type, msg, action) \ - if (!PHP_HTTP_MESSAGE_TYPE(type, (msg))) { \ - php_http_error(HE_NOTICE, PHP_HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type "#type); \ - action; \ - } typedef php_http_info_type_t php_http_message_type_t; typedef struct php_http_message php_http_message_t; diff --git a/php_http_message_body.c b/php_http_message_body.c index f48dbd6..2749fac 100644 --- a/php_http_message_body.c +++ b/php_http_message_body.c @@ -24,13 +24,14 @@ php_http_message_body_appendf(body, "--%s" PHP_HTTP_CRLF, php_http_message_body_boundary(body)); \ } \ } while(0) + #define BOUNDARY_CLOSE(body) \ php_http_message_body_appendf(body, PHP_HTTP_CRLF "--%s--" PHP_HTTP_CRLF, php_http_message_body_boundary(body)) static STATUS add_recursive_fields(php_http_message_body_t *body, const char *name, zval *value); static STATUS add_recursive_files(php_http_message_body_t *body, const char *name, zval *value); -PHP_HTTP_API php_http_message_body_t *php_http_message_body_init(php_http_message_body_t **body_ptr, php_stream *stream TSRMLS_DC) +php_http_message_body_t *php_http_message_body_init(php_http_message_body_t **body_ptr, php_stream *stream TSRMLS_DC) { php_http_message_body_t *body; @@ -57,12 +58,12 @@ PHP_HTTP_API php_http_message_body_t *php_http_message_body_init(php_http_messag return body; } -PHP_HTTP_API unsigned php_http_message_body_addref(php_http_message_body_t *body) +unsigned php_http_message_body_addref(php_http_message_body_t *body) { return ++body->refcount; } -PHP_HTTP_API php_http_message_body_t *php_http_message_body_copy(php_http_message_body_t *from, php_http_message_body_t *to) +php_http_message_body_t *php_http_message_body_copy(php_http_message_body_t *from, php_http_message_body_t *to) { if (from) { TSRMLS_FETCH_FROM_CTX(from->ts); @@ -86,14 +87,14 @@ PHP_HTTP_API php_http_message_body_t *php_http_message_body_copy(php_http_messag return to; } -PHP_HTTP_API void php_http_message_body_free(php_http_message_body_t **body_ptr) +void php_http_message_body_free(php_http_message_body_t **body_ptr) { if (*body_ptr) { php_http_message_body_t *body = *body_ptr; if (!--body->refcount) { TSRMLS_FETCH_FROM_CTX(body->ts); - /* NO FIXME: shows leakinfo in DEBUG mode */ + /* NOFIXME: shows leakinfo in DEBUG mode */ zend_list_delete(body->stream_id); STR_FREE(body->boundary); efree(body); @@ -102,14 +103,14 @@ PHP_HTTP_API void php_http_message_body_free(php_http_message_body_t **body_ptr) } } -PHP_HTTP_API const php_stream_statbuf *php_http_message_body_stat(php_http_message_body_t *body) +const php_stream_statbuf *php_http_message_body_stat(php_http_message_body_t *body) { TSRMLS_FETCH_FROM_CTX(body->ts); php_stream_stat(php_http_message_body_stream(body), &body->ssb); return &body->ssb; } -PHP_HTTP_API const char *php_http_message_body_boundary(php_http_message_body_t *body) +const char *php_http_message_body_boundary(php_http_message_body_t *body) { if (!body->boundary) { union { double dbl; int num[2]; } data; @@ -121,7 +122,7 @@ PHP_HTTP_API const char *php_http_message_body_boundary(php_http_message_body_t return body->boundary; } -PHP_HTTP_API char *php_http_message_body_etag(php_http_message_body_t *body) +char *php_http_message_body_etag(php_http_message_body_t *body) { const php_stream_statbuf *ssb = php_http_message_body_stat(body); TSRMLS_FETCH_FROM_CTX(body->ts); @@ -144,7 +145,7 @@ PHP_HTTP_API char *php_http_message_body_etag(php_http_message_body_t *body) } } -PHP_HTTP_API void php_http_message_body_to_string(php_http_message_body_t *body, char **buf, size_t *len, off_t offset, size_t forlen) +void php_http_message_body_to_string(php_http_message_body_t *body, char **buf, size_t *len, off_t offset, size_t forlen) { php_stream *s = php_http_message_body_stream(body); TSRMLS_FETCH_FROM_CTX(body->ts); @@ -156,19 +157,20 @@ PHP_HTTP_API void php_http_message_body_to_string(php_http_message_body_t *body, *len = php_stream_copy_to_mem(s, buf, forlen, 0); } -PHP_HTTP_API void php_http_message_body_to_stream(php_http_message_body_t *body, php_stream *dst, off_t offset, size_t forlen) +STATUS php_http_message_body_to_stream(php_http_message_body_t *body, php_stream *dst, off_t offset, size_t forlen) { php_stream *s = php_http_message_body_stream(body); TSRMLS_FETCH_FROM_CTX(body->ts); php_stream_seek(s, offset, SEEK_SET); + if (!forlen) { forlen = -1; } - php_stream_copy_to_stream_ex(s, dst, forlen, NULL); + return php_stream_copy_to_stream_ex(s, dst, forlen, NULL); } -PHP_HTTP_API void php_http_message_body_to_callback(php_http_message_body_t *body, php_http_pass_callback_t cb, void *cb_arg, off_t offset, size_t forlen) +STATUS php_http_message_body_to_callback(php_http_message_body_t *body, php_http_pass_callback_t cb, void *cb_arg, off_t offset, size_t forlen) { php_stream *s = php_http_message_body_stream(body); char *buf = emalloc(0x1000); @@ -183,7 +185,9 @@ PHP_HTTP_API void php_http_message_body_to_callback(php_http_message_body_t *bod size_t read = php_stream_read(s, buf, MIN(forlen, 0x1000)); if (read) { - cb(cb_arg, buf, read); + if (-1 == cb(cb_arg, buf, read)) { + return FAILURE; + } } if (read < MIN(forlen, sizeof(buf))) { @@ -195,22 +199,34 @@ PHP_HTTP_API void php_http_message_body_to_callback(php_http_message_body_t *bod } } efree(buf); + + return SUCCESS; } -PHP_HTTP_API size_t php_http_message_body_append(php_http_message_body_t *body, const char *buf, size_t len) +size_t php_http_message_body_append(php_http_message_body_t *body, const char *buf, size_t len) { php_stream *s; + size_t written; TSRMLS_FETCH_FROM_CTX(body->ts); if (!(s = php_http_message_body_stream(body))) { return -1; } - php_stream_seek(s, 0, SEEK_END); - return php_stream_write(s, buf, len); + if (s->ops->seek) { + php_stream_seek(s, 0, SEEK_END); + } + + written = php_stream_write(s, buf, len); + + if (written != len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to append %zu bytes to body; wrote %zu", len, written); + } + + return len; } -PHP_HTTP_API size_t php_http_message_body_appendf(php_http_message_body_t *body, const char *fmt, ...) +size_t php_http_message_body_appendf(php_http_message_body_t *body, const char *fmt, ...) { va_list argv; char *print_str; @@ -226,7 +242,7 @@ PHP_HTTP_API size_t php_http_message_body_appendf(php_http_message_body_t *body, return print_len; } -PHP_HTTP_API STATUS php_http_message_body_add_form(php_http_message_body_t *body, HashTable *fields, HashTable *files) +STATUS php_http_message_body_add_form(php_http_message_body_t *body, HashTable *fields, HashTable *files) { zval tmp; @@ -246,7 +262,7 @@ PHP_HTTP_API STATUS php_http_message_body_add_form(php_http_message_body_t *body return SUCCESS; } -PHP_HTTP_API void php_http_message_body_add_part(php_http_message_body_t *body, php_http_message_t *part) +void php_http_message_body_add_part(php_http_message_body_t *body, php_http_message_t *part) { TSRMLS_FETCH_FROM_CTX(body->ts); @@ -256,7 +272,7 @@ PHP_HTTP_API void php_http_message_body_add_part(php_http_message_body_t *body, } -PHP_HTTP_API STATUS php_http_message_body_add_form_field(php_http_message_body_t *body, const char *name, const char *value_str, size_t value_len) +STATUS php_http_message_body_add_form_field(php_http_message_body_t *body, const char *name, const char *value_str, size_t value_len) { char *safe_name; TSRMLS_FETCH_FROM_CTX(body->ts); @@ -277,7 +293,7 @@ PHP_HTTP_API STATUS php_http_message_body_add_form_field(php_http_message_body_t return SUCCESS; } -PHP_HTTP_API STATUS php_http_message_body_add_form_file(php_http_message_body_t *body, const char *name, const char *ctype, const char *path, php_stream *in) +STATUS php_http_message_body_add_form_file(php_http_message_body_t *body, const char *name, const char *ctype, const char *path, php_stream *in) { char *safe_name, *path_dup = estrdup(path), *bname; size_t bname_len; @@ -363,7 +379,7 @@ static STATUS add_recursive_files(php_http_message_body_t *body, const char *nam TSRMLS_FETCH_FROM_CTX(body->ts); if (Z_TYPE_P(value) != IS_ARRAY && Z_TYPE_P(value) != IS_OBJECT) { - php_http_error(HE_WARNING, PHP_HTTP_E_MESSAGE_BODY, "Expected array or object (name, type, file) for message body file to add"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array or object (name, type, file) for message body file to add"); return FAILURE; } @@ -495,7 +511,7 @@ static size_t splitbody(void *opaque, char *buf, size_t len TSRMLS_DC) len = 0; } else { /* let this be garbage */ - php_http_error(HE_WARNING, PHP_HTTP_E_MESSAGE_BODY, "Malformed multipart boundary at pos %zu", consumed); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Malformed multipart boundary at pos %zu", consumed); return -1; } } @@ -513,7 +529,7 @@ static size_t splitbody(void *opaque, char *buf, size_t len TSRMLS_DC) return consumed; } -PHP_HTTP_API php_http_message_t *php_http_message_body_split(php_http_message_body_t *body, const char *boundary) +php_http_message_t *php_http_message_body_split(php_http_message_body_t *body, const char *boundary) { php_stream *s = php_http_message_body_stream(body); php_http_buffer_t *tmp = NULL; @@ -609,21 +625,16 @@ PHP_METHOD(HttpMessageBody, __construct) zval *zstream = NULL; php_stream *stream; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r!", &zstream)) { - if (zstream) { - php_stream_from_zval(stream, &zstream); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r!", &zstream), invalid_arg, return); - if (stream) { - if (obj->body) { - php_http_message_body_free(&obj->body); - } - obj->body = php_http_message_body_init(NULL, stream TSRMLS_CC); - } - } - PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + if (zstream) { + php_http_expect(php_stream_from_zval_no_verify(stream, &zstream), unexpected_val, return); + + if (obj->body) { + php_http_message_body_free(&obj->body); } - } end_error_handling(); + obj->body = php_http_message_body_init(NULL, stream TSRMLS_CC); + } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody___toString, 0, 0, 0) @@ -746,17 +757,17 @@ PHP_METHOD(HttpMessageBody, append) { char *str; int len; + php_http_message_body_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) { - php_http_message_body_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len), invalid_arg, return); - PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (len != php_http_message_body_append(obj->body, str, len)) { - php_http_error(HE_WARNING, PHP_HTTP_E_MESSAGE_BODY, "Could not append to body"); - } - RETURN_ZVAL(getThis(), 1, 0); - } + PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + + php_http_expect(len == php_http_message_body_append(obj->body, str, len), runtime, return); + + RETURN_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody_addForm, 0, 0, 0) @@ -766,15 +777,17 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpMessageBody, addForm) { HashTable *fields = NULL, *files = NULL; + php_http_message_body_object_t *obj; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h!h!", &fields, &files)) { - php_http_message_body_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h!h!", &fields, &files), invalid_arg, return); - PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_body_add_form(obj->body, fields, files); - RETURN_ZVAL(getThis(), 1, 0); - } + PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + + php_http_expect(SUCCESS == php_http_message_body_add_form(obj->body, fields, files), runtime, return); + + RETURN_ZVAL(getThis(), 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody_addPart, 0, 0, 1) @@ -783,14 +796,22 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpMessageBody, addPart) { zval *zobj; + php_http_message_body_object_t *obj; + php_http_message_object_t *mobj; + zend_error_handling zeh; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zobj, php_http_message_class_entry)) { - php_http_message_body_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - php_http_message_object_t *mobj = zend_object_store_get_object(zobj TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zobj, php_http_message_class_entry), invalid_arg, return); - PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + obj = zend_object_store_get_object(getThis() TSRMLS_CC); + mobj = zend_object_store_get_object(zobj TSRMLS_CC); + + PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + + zend_replace_error_handling(EH_THROW, php_http_exception_runtime_class_entry, &zeh TSRMLS_CC); + php_http_message_body_add_part(obj->body, mobj->message); + zend_restore_error_handling(&zeh TSRMLS_CC); - php_http_message_body_add_part(obj->body, mobj->message); + if (!EG(exception)) { RETURN_ZVAL(getThis(), 1, 0); } } @@ -847,7 +868,7 @@ PHP_METHOD(HttpMessageBody, stat) RETURN_LONG(sb->sb.st_ctime); break; default: - php_http_error(HE_WARNING, PHP_HTTP_E_MESSAGE_BODY, "unknown stat field: '%s' (should be one of [s]ize, [a]time, [m]time or [c]time)", field_str); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown stat field: '%s' (should be one of [s]ize, [a]time, [m]time or [c]time)", field_str); break; } } else { @@ -886,7 +907,7 @@ PHP_MINIT_FUNCTION(http_message_body) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http\\Message", "Body", php_http_message_body_methods); - php_http_message_body_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_message_body_class_entry = zend_register_internal_class(&ce TSRMLS_CC); php_http_message_body_class_entry->create_object = php_http_message_body_object_new; memcpy(&php_http_message_body_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_http_message_body_object_handlers.clone_obj = php_http_message_body_object_clone; diff --git a/php_http_message_body.h b/php_http_message_body.h index 10b87bc..028ad62 100644 --- a/php_http_message_body.h +++ b/php_http_message_body.h @@ -35,8 +35,8 @@ PHP_HTTP_API void php_http_message_body_add_part(php_http_message_body_t *body, PHP_HTTP_API size_t php_http_message_body_append(php_http_message_body_t *body, const char *buf, size_t len); PHP_HTTP_API size_t php_http_message_body_appendf(php_http_message_body_t *body, const char *fmt, ...); PHP_HTTP_API void php_http_message_body_to_string(php_http_message_body_t *body, char **buf, size_t *len, off_t offset, size_t forlen); -PHP_HTTP_API void php_http_message_body_to_stream(php_http_message_body_t *body, php_stream *s, off_t offset, size_t forlen); -PHP_HTTP_API void php_http_message_body_to_callback(php_http_message_body_t *body, php_http_pass_callback_t cb, void *cb_arg, off_t offset, size_t forlen); +PHP_HTTP_API STATUS php_http_message_body_to_stream(php_http_message_body_t *body, php_stream *s, off_t offset, size_t forlen); +PHP_HTTP_API STATUS php_http_message_body_to_callback(php_http_message_body_t *body, php_http_pass_callback_t cb, void *cb_arg, off_t offset, size_t forlen); PHP_HTTP_API void php_http_message_body_free(php_http_message_body_t **body); PHP_HTTP_API const php_stream_statbuf *php_http_message_body_stat(php_http_message_body_t *body); #define php_http_message_body_size(b) (php_http_message_body_stat((b))->sb.st_size) diff --git a/php_http_message_parser.c b/php_http_message_parser.c index d6e7c26..b64eb00 100644 --- a/php_http_message_parser.c +++ b/php_http_message_parser.c @@ -44,7 +44,7 @@ const char *php_http_message_parser_state_name(php_http_message_parser_state_t s } #endif -PHP_HTTP_API php_http_message_parser_t *php_http_message_parser_init(php_http_message_parser_t *parser TSRMLS_DC) +php_http_message_parser_t *php_http_message_parser_init(php_http_message_parser_t *parser TSRMLS_DC) { if (!parser) { parser = emalloc(sizeof(*parser)); @@ -59,7 +59,7 @@ PHP_HTTP_API php_http_message_parser_t *php_http_message_parser_init(php_http_me return parser; } -PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_push(php_http_message_parser_t *parser, unsigned argc, ...) +php_http_message_parser_state_t php_http_message_parser_state_push(php_http_message_parser_t *parser, unsigned argc, ...) { php_http_message_parser_state_t state; va_list va_args; @@ -75,7 +75,7 @@ PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_push( return state; } -PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_is(php_http_message_parser_t *parser) +php_http_message_parser_state_t php_http_message_parser_state_is(php_http_message_parser_t *parser) { php_http_message_parser_state_t *state; @@ -85,7 +85,7 @@ PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_is(ph return PHP_HTTP_MESSAGE_PARSER_STATE_START; } -PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_pop(php_http_message_parser_t *parser) +php_http_message_parser_state_t php_http_message_parser_state_pop(php_http_message_parser_t *parser) { php_http_message_parser_state_t state, *state_ptr; if (SUCCESS == zend_stack_top(&parser->stack, (void *) &state_ptr)) { @@ -96,7 +96,7 @@ PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_pop(p return PHP_HTTP_MESSAGE_PARSER_STATE_START; } -PHP_HTTP_API void php_http_message_parser_dtor(php_http_message_parser_t *parser) +void php_http_message_parser_dtor(php_http_message_parser_t *parser) { php_http_header_parser_dtor(&parser->header); zend_stack_destroy(&parser->stack); @@ -108,7 +108,7 @@ PHP_HTTP_API void php_http_message_parser_dtor(php_http_message_parser_t *parser } } -PHP_HTTP_API void php_http_message_parser_free(php_http_message_parser_t **parser) +void php_http_message_parser_free(php_http_message_parser_t **parser) { if (*parser) { php_http_message_parser_dtor(*parser); @@ -117,7 +117,7 @@ PHP_HTTP_API void php_http_message_parser_free(php_http_message_parser_t **parse } } -PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_parse_stream(php_http_message_parser_t *parser, php_stream *s, unsigned flags, php_http_message_t **message) +php_http_message_parser_state_t php_http_message_parser_parse_stream(php_http_message_parser_t *parser, php_stream *s, unsigned flags, php_http_message_t **message) { php_http_buffer_t buf; php_http_message_parser_state_t state = PHP_HTTP_MESSAGE_PARSER_STATE_START; @@ -186,7 +186,7 @@ PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_parse_strea } -PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message) +php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message) { char *str = NULL; size_t len = 0; diff --git a/php_http_misc.c b/php_http_misc.c index 3ad9988..0ba19f9 100644 --- a/php_http_misc.c +++ b/php_http_misc.c @@ -17,7 +17,7 @@ /* SLEEP */ -PHP_HTTP_API void php_http_sleep(double s) +void php_http_sleep(double s) { #if defined(PHP_WIN32) Sleep((DWORD) PHP_HTTP_MSEC(s)); @@ -142,7 +142,7 @@ int php_http_select_str(const char *cmp, int argc, ...) /* ARRAYS */ -PHP_HTTP_API unsigned php_http_array_list(HashTable *ht TSRMLS_DC, unsigned argc, ...) +unsigned php_http_array_list(HashTable *ht TSRMLS_DC, unsigned argc, ...) { HashPosition pos; unsigned argl = 0; @@ -229,7 +229,7 @@ int php_http_array_apply_merge_func(void *pDest TSRMLS_DC, int num_args, va_list /* PASS CALLBACK */ -PHP_HTTP_API size_t php_http_pass_fcall_callback(void *cb_arg, const char *str, size_t len) +size_t php_http_pass_fcall_callback(void *cb_arg, const char *str, size_t len) { php_http_pass_fcall_arg_t *fcd = cb_arg; zval *zdata; @@ -245,78 +245,9 @@ PHP_HTTP_API size_t php_http_pass_fcall_callback(void *cb_arg, const char *str, return len; } -/* ERROR */ - -static inline int scope_error_handling(long type TSRMLS_DC) -{ - if ((type == E_THROW) || (EG(error_handling) == EH_THROW)) { - return EH_THROW; - } - - if (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), php_http_object_class_entry TSRMLS_CC)) { - return php_http_object_get_error_handling(EG(This) TSRMLS_CC); - } - - return EH_NORMAL; -} - -void php_http_error(long type TSRMLS_DC, long code, const char *format, ...) -{ - va_list args; - - va_start(args, format); - switch (scope_error_handling(type TSRMLS_CC)) { - case EH_THROW: { - char *message; - zend_class_entry *ce = php_http_exception_class_entry; - - /* FIXME wat? */ - if (0&& EG(exception_class) && instanceof_function(EG(exception_class), ce TSRMLS_CC)) { - ce = EG(exception_class); - } - - vspprintf(&message, 0, format, args); - zend_throw_exception(ce, message, code TSRMLS_CC); - efree(message); - break; - } - case EH_NORMAL: - php_verror(NULL, "", type, format, args TSRMLS_CC); - break; - case EH_SUPPRESS: - break; - } - va_end(args); -} /* ZEND */ -STATUS php_http_method_call(zval *object, const char *method_str, size_t method_len, int argc, zval **argv[], zval **retval_ptr TSRMLS_DC) -{ - zend_fcall_info fci; - zval zmethod; - zval *retval; - STATUS rv; - - fci.size = sizeof(fci); - fci.object_ptr = object; - fci.function_name = &zmethod; - fci.retval_ptr_ptr = retval_ptr ? retval_ptr : &retval; - fci.param_count = argc; - fci.params = argv; - fci.no_separation = 1; - fci.symbol_table = NULL; - fci.function_table = NULL; - - INIT_PZVAL(&zmethod); - ZVAL_STRINGL(&zmethod, method_str, method_len, 0); - rv = zend_call_function(&fci, NULL TSRMLS_CC); - - if (!retval_ptr && retval) { - zval_ptr_dtor(&retval); - } - return rv; -} /* * Local variables: * tab-width: 4 diff --git a/php_http_misc.h b/php_http_misc.h index 358c75b..17cfec7 100644 --- a/php_http_misc.h +++ b/php_http_misc.h @@ -41,14 +41,6 @@ PHP_HTTP_API void php_http_sleep(double s); /* STRING UTILITIES */ -#define PHP_HTTP_CHECK_CONTENT_TYPE(ct, action) \ - if (!strchr((ct), '/')) { \ - php_http_error(HE_WARNING, PHP_HTTP_E_INVALID_PARAM, \ - "Content type \"%s\" does not seem to contain a primary and a secondary part", (ct)); \ - action; \ - } - - #ifndef STR_SET # define STR_SET(STR, SET) \ { \ @@ -197,8 +189,6 @@ static inline STATUS php_http_ini_entry(const char *name_str, size_t name_len, c return FAILURE; } -STATUS php_http_method_call(zval *object, const char *method_str, size_t method_len, int argc, zval **argv[], zval **retval_ptr TSRMLS_DC); - /* return object(values) */ #define RETVAL_OBJECT(o, addref) \ RETVAL_OBJVAL((o)->value.obj, addref) @@ -319,49 +309,6 @@ typedef struct php_http_pass_fcall_arg { PHP_HTTP_API size_t php_http_pass_fcall_callback(void *cb_arg, const char *str, size_t len); -/* ERROR */ - -extern void php_http_error(long type TSRMLS_DC, long code, const char *format, ...); - -#define with_error_handling(eh, ec) \ - { \ - zend_error_handling __eh; \ - zend_replace_error_handling((eh), (ec), &__eh TSRMLS_CC); - -#define end_error_handling() \ - zend_restore_error_handling(&__eh TSRMLS_CC); \ - } - -#ifndef E_THROW -# define E_THROW -1 -#endif -#define HE_THROW E_THROW TSRMLS_CC -#define HE_NOTICE E_NOTICE TSRMLS_CC -#define HE_WARNING E_WARNING TSRMLS_CC -#define HE_ERROR E_ERROR TSRMLS_CC - -typedef enum php_http_error { - PHP_HTTP_E_UNKNOWN = 0, - PHP_HTTP_E_RUNTIME, - PHP_HTTP_E_INVALID_PARAM, - PHP_HTTP_E_HEADER, - PHP_HTTP_E_MALFORMED_HEADERS, - PHP_HTTP_E_REQUEST_METHOD, - PHP_HTTP_E_MESSAGE, - PHP_HTTP_E_MESSAGE_TYPE, - PHP_HTTP_E_MESSAGE_BODY, - PHP_HTTP_E_ENCODING, - PHP_HTTP_E_CLIENT, - PHP_HTTP_E_CLIENT_POOL, - PHP_HTTP_E_CLIENT_DATASHARE, - PHP_HTTP_E_REQUEST_FACTORY, - PHP_HTTP_E_SOCKET, - PHP_HTTP_E_RESPONSE, - PHP_HTTP_E_URL, - PHP_HTTP_E_QUERYSTRING, - PHP_HTTP_E_COOKIE, -} php_http_error_t; - #endif /* diff --git a/php_http_negotiate.c b/php_http_negotiate.c index ad2357e..ae10ddf 100644 --- a/php_http_negotiate.c +++ b/php_http_negotiate.c @@ -99,7 +99,7 @@ static int php_http_negotiate_reduce(void *p TSRMLS_DC, int num_args, va_list ar return ZEND_HASH_APPLY_KEEP; } -PHP_HTTP_API HashTable *php_http_negotiate(const char *value_str, size_t value_len, HashTable *supported, const char *primary_sep_str, size_t primary_sep_len TSRMLS_DC) +HashTable *php_http_negotiate(const char *value_str, size_t value_len, HashTable *supported, const char *primary_sep_str, size_t primary_sep_len TSRMLS_DC) { HashTable *result = NULL; diff --git a/php_http_object.c b/php_http_object.c index 4ec54d3..d4785f1 100644 --- a/php_http_object.c +++ b/php_http_object.c @@ -12,46 +12,6 @@ #include "php_http_api.h" -PHP_HTTP_API STATUS php_http_new(zend_object_value *ovp, zend_class_entry *ce, php_http_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC) -{ - zend_object_value ov; - - if (!ce) { - ce = parent_ce; - } else if (parent_ce && !instanceof_function(ce, parent_ce TSRMLS_CC)) { - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "Class %s does not extend %s", ce->name, parent_ce->name); - return FAILURE; - } - - ov = create(ce, intern_ptr, obj_ptr TSRMLS_CC); - if (ovp) { - *ovp = ov; - } - return SUCCESS; -} - -PHP_HTTP_API zend_error_handling_t php_http_object_get_error_handling(zval *object TSRMLS_DC) -{ - zval *zeh, *lzeh; - long eh; - - zeh = zend_read_property(Z_OBJCE_P(object), object, ZEND_STRL("errorHandling"), 0 TSRMLS_CC); - if (Z_TYPE_P(zeh) != IS_NULL) { - lzeh = php_http_ztyp(IS_LONG, zeh); - eh = Z_LVAL_P(lzeh); - zval_ptr_dtor(&lzeh); - return eh; - } - zeh = zend_read_static_property(php_http_object_class_entry, ZEND_STRL("defaultErrorHandling"), 0 TSRMLS_CC); - if (Z_TYPE_P(zeh) != IS_NULL) { - lzeh = php_http_ztyp(IS_LONG, zeh); - eh = Z_LVAL_P(lzeh); - zval_ptr_dtor(&lzeh); - return eh; - } - return EH_NORMAL; -} - zend_object_value php_http_object_new(zend_class_entry *ce TSRMLS_DC) { return php_http_object_new_ex(ce, NULL, NULL TSRMLS_CC); @@ -75,116 +35,51 @@ zend_object_value php_http_object_new_ex(zend_class_entry *ce, void *nothing, ph return o->zv; } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpObject_getErrorHandling, 0, 0, 0) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpObject, getErrorHandling) +STATUS php_http_new(zend_object_value *ovp, zend_class_entry *ce, php_http_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC) { - zval *zeh = zend_read_property(php_http_object_class_entry, getThis(), ZEND_STRL("errorHandling"), 0 TSRMLS_CC); - RETURN_ZVAL(zeh, 1, 0); -} + zend_object_value ov; -ZEND_BEGIN_ARG_INFO_EX(ai_HttpObject_setErrorHandling, 0, 0, 1) - ZEND_ARG_INFO(0, eh) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpObject, setErrorHandling) -{ - long eh; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &eh)) { - switch (eh) { - case EH_NORMAL: - case EH_SUPPRESS: - case EH_THROW: - zend_update_property_long(php_http_object_class_entry, getThis(), ZEND_STRL("errorHandling"), eh TSRMLS_CC); - break; - - default: - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "unknown error handling code (%ld)", eh); - break; - } + if (!ce) { + ce = parent_ce; + } else if (parent_ce && !instanceof_function(ce, parent_ce TSRMLS_CC)) { + php_http_throw(unexpected_val, "Class %s does not extend %s", ce->name, parent_ce->name); + return FAILURE; } - RETURN_ZVAL(getThis(), 1, 0); -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpObject_getDefaultErrorHandling, 0, 0, 0) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpObject, getDefaultErrorHandling) -{ - zval *zdeh = zend_read_static_property(php_http_object_class_entry, ZEND_STRL("defaultErrorHandling"), 0 TSRMLS_CC); - RETURN_ZVAL(zdeh, 1, 0); -} - -ZEND_BEGIN_ARG_INFO_EX(ai_HttpObject_setDefaultErrorHandling, 0, 0, 1) - ZEND_ARG_INFO(0, eh) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpObject, setDefaultErrorHandling) -{ - long eh; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &eh)) { - switch (eh) { - case EH_NORMAL: - case EH_SUPPRESS: - case EH_THROW: - zend_update_static_property_long(php_http_object_class_entry, ZEND_STRL("defaultErrorHandling"), eh TSRMLS_CC); - break; - - default: - php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "unknown error handling code (%ld)", eh); - break; - } + ov = create(ce, intern_ptr, obj_ptr TSRMLS_CC); + if (ovp) { + *ovp = ov; } + return SUCCESS; } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpObject_triggerError, 0, 0, 3) - ZEND_ARG_INFO(0, error_type) - ZEND_ARG_INFO(0, error_code) - ZEND_ARG_INFO(0, error_message) -ZEND_END_ARG_INFO(); -PHP_METHOD(HttpObject, triggerError) +STATUS php_http_method_call(zval *object, const char *method_str, size_t method_len, int argc, zval **argv[], zval **retval_ptr TSRMLS_DC) { - long eh, code; - char *msg_str; - int msg_len; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lls", &eh, &code, &msg_str, &msg_len)) { - php_http_error(eh TSRMLS_CC, code, "%.*s", msg_len, msg_str); + zend_fcall_info fci; + zval zmethod; + zval *retval; + STATUS rv; + + fci.size = sizeof(fci); + fci.object_ptr = object; + fci.function_name = &zmethod; + fci.retval_ptr_ptr = retval_ptr ? retval_ptr : &retval; + fci.param_count = argc; + fci.params = argv; + fci.no_separation = 1; + fci.symbol_table = NULL; + fci.function_table = NULL; + + INIT_PZVAL(&zmethod); + ZVAL_STRINGL(&zmethod, method_str, method_len, 0); + rv = zend_call_function(&fci, NULL TSRMLS_CC); + + if (!retval_ptr && retval) { + zval_ptr_dtor(&retval); } + return rv; } -static zend_function_entry php_http_object_methods[] = { - PHP_ME(HttpObject, setErrorHandling, ai_HttpObject_setErrorHandling, ZEND_ACC_PUBLIC) - PHP_ME(HttpObject, getErrorHandling, ai_HttpObject_getErrorHandling, ZEND_ACC_PUBLIC) - PHP_ME(HttpObject, setDefaultErrorHandling, ai_HttpObject_setDefaultErrorHandling, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(HttpObject, getDefaultErrorHandling, ai_HttpObject_getDefaultErrorHandling, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(HttpObject, triggerError, ai_HttpObject_triggerError, ZEND_ACC_PUBLIC) - - EMPTY_FUNCTION_ENTRY -}; - -zend_class_entry *php_http_object_class_entry; - -PHP_MINIT_FUNCTION(http_object) -{ - zend_class_entry ce = {0}; - - INIT_NS_CLASS_ENTRY(ce, "http", "Object", php_http_object_methods); - php_http_object_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); - php_http_object_class_entry->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; - php_http_object_class_entry->create_object = php_http_object_new; - - zend_declare_property_null(php_http_object_class_entry, ZEND_STRL("defaultErrorHandling"), (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC); - zend_declare_property_null(php_http_object_class_entry, ZEND_STRL("errorHandling"), ZEND_ACC_PROTECTED TSRMLS_CC); - - zend_declare_class_constant_long(php_http_object_class_entry, ZEND_STRL("EH_NORMAL"), EH_NORMAL TSRMLS_CC); - zend_declare_class_constant_long(php_http_object_class_entry, ZEND_STRL("EH_SUPPRESS"), EH_SUPPRESS TSRMLS_CC); - zend_declare_class_constant_long(php_http_object_class_entry, ZEND_STRL("EH_THROW"), EH_THROW TSRMLS_CC); - - return SUCCESS; -} - - /* * Local variables: * tab-width: 4 diff --git a/php_http_object.h b/php_http_object.h index 7c88f20..a3786bb 100644 --- a/php_http_object.h +++ b/php_http_object.h @@ -13,22 +13,18 @@ #ifndef PHP_HTTP_OBJECT_H #define PHP_HTTP_OBJECT_H -typedef zend_object_value (*php_http_new_t)(zend_class_entry *ce, void *, void ** TSRMLS_DC); - -PHP_HTTP_API STATUS php_http_new(zend_object_value *ov, zend_class_entry *ce, php_http_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC); - typedef struct php_http_object { zend_object zo; zend_object_value zv; } php_http_object_t; -PHP_HTTP_API zend_class_entry *php_http_object_class_entry; -PHP_MINIT_FUNCTION(http_object); - zend_object_value php_http_object_new(zend_class_entry *ce TSRMLS_DC); zend_object_value php_http_object_new_ex(zend_class_entry *ce, void *nothing, php_http_object_t **ptr TSRMLS_DC); -PHP_HTTP_API zend_error_handling_t php_http_object_get_error_handling(zval *object TSRMLS_DC); +typedef zend_object_value (*php_http_new_t)(zend_class_entry *ce, void *, void ** TSRMLS_DC); + +STATUS php_http_new(zend_object_value *ov, zend_class_entry *ce, php_http_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC); +STATUS php_http_method_call(zval *object, const char *method_str, size_t method_len, int argc, zval **argv[], zval **retval_ptr TSRMLS_DC); #endif diff --git a/php_http_options.c b/php_http_options.c index 07a5d7b..ca455a7 100644 --- a/php_http_options.c +++ b/php_http_options.c @@ -12,7 +12,7 @@ #include "php_http_api.h" -PHP_HTTP_API php_http_options_t *php_http_options_init(php_http_options_t *registry, zend_bool persistent) +php_http_options_t *php_http_options_init(php_http_options_t *registry, zend_bool persistent) { if (!registry) { registry = pecalloc(1, sizeof(*registry), persistent); @@ -26,7 +26,7 @@ PHP_HTTP_API php_http_options_t *php_http_options_init(php_http_options_t *regis return registry; } -PHP_HTTP_API STATUS php_http_options_apply(php_http_options_t *registry, HashTable *options, void *userdata) +STATUS php_http_options_apply(php_http_options_t *registry, HashTable *options, void *userdata) { HashPosition pos; zval *val; @@ -47,12 +47,12 @@ PHP_HTTP_API STATUS php_http_options_apply(php_http_options_t *registry, HashTab return SUCCESS; } -PHP_HTTP_API void php_http_options_dtor(php_http_options_t *registry) +void php_http_options_dtor(php_http_options_t *registry) { zend_hash_destroy(®istry->options); } -PHP_HTTP_API void php_http_options_free(php_http_options_t **registry) +void php_http_options_free(php_http_options_t **registry) { if (*registry) { php_http_options_dtor(*registry); @@ -61,7 +61,7 @@ PHP_HTTP_API void php_http_options_free(php_http_options_t **registry) } } -PHP_HTTP_API php_http_option_t *php_http_option_register(php_http_options_t *registry, const char *name_str, size_t name_len, ulong option, zend_uchar type) +php_http_option_t *php_http_option_register(php_http_options_t *registry, const char *name_str, size_t name_len, ulong option, zend_uchar type) { php_http_option_t opt, *dst = NULL; @@ -102,7 +102,7 @@ PHP_HTTP_API php_http_option_t *php_http_option_register(php_http_options_t *reg return dst; } -PHP_HTTP_API zval *php_http_option_get(php_http_option_t *opt, HashTable *options, void *userdata) +zval *php_http_option_get(php_http_option_t *opt, HashTable *options, void *userdata) { if (options) { zval **zoption; diff --git a/php_http_params.c b/php_http_params.c index f823495..c64df95 100644 --- a/php_http_params.c +++ b/php_http_params.c @@ -24,7 +24,7 @@ static php_http_params_opts_t def_opts = { PHP_HTTP_PARAMS_DEFAULT }; -PHP_HTTP_API php_http_params_opts_t *php_http_params_opts_default_get(php_http_params_opts_t *opts) +php_http_params_opts_t *php_http_params_opts_default_get(php_http_params_opts_t *opts) { if (!opts) { opts = emalloc(sizeof(*opts)); @@ -121,7 +121,7 @@ static void sanitize_dimension(zval *zv TSRMLS_DC) case '[': if (++level > PG(max_input_nesting_level)) { zval_ptr_dtor(&arr); - php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Max input nesting level of %ld exceeded", PG(max_input_nesting_level)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Max input nesting level of %ld exceeded", (long) PG(max_input_nesting_level)); return; } if (ptr - var == 0) { @@ -478,7 +478,7 @@ static void skip_sep(size_t skip, php_http_params_state_t *state, php_http_param } } -PHP_HTTP_API HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t *opts TSRMLS_DC) +HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t *opts TSRMLS_DC) { php_http_params_state_t state = {{NULL,0}, {NULL,0}, {NULL,0}, {NULL,0}, {NULL,NULL,NULL}, 0, 0}; @@ -629,7 +629,7 @@ static void shift_param(php_http_buffer_t *buf, char *key_str, size_t key_len, z } } -PHP_HTTP_API php_http_buffer_t *php_http_params_to_string(php_http_buffer_t *buf, HashTable *params, const char *pss, size_t psl, const char *ass, size_t asl, const char *vss, size_t vsl, unsigned flags TSRMLS_DC) +php_http_buffer_t *php_http_params_to_string(php_http_buffer_t *buf, HashTable *params, const char *pss, size_t psl, const char *ass, size_t asl, const char *vss, size_t vsl, unsigned flags TSRMLS_DC) { zval **zparam; HashPosition pos, pos1; @@ -676,7 +676,7 @@ PHP_HTTP_API php_http_buffer_t *php_http_params_to_string(php_http_buffer_t *buf return buf; } -PHP_HTTP_API php_http_params_token_t **php_http_params_separator_init(zval *zv TSRMLS_DC) +php_http_params_token_t **php_http_params_separator_init(zval *zv TSRMLS_DC) { zval **sep; HashPosition pos; @@ -706,7 +706,7 @@ PHP_HTTP_API php_http_params_token_t **php_http_params_separator_init(zval *zv T return ret; } -PHP_HTTP_API void php_http_params_separator_free(php_http_params_token_t **separator) +void php_http_params_separator_free(php_http_params_token_t **separator) { php_http_params_token_t **sep = separator; if (sep) { @@ -728,66 +728,69 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams___construct, 0, 0, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpParams, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *zcopy, *zparams = NULL, *param_sep = NULL, *arg_sep = NULL, *val_sep = NULL; - long flags = PHP_HTTP_PARAMS_DEFAULT; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!/z/z/z/l", &zparams, ¶m_sep, &arg_sep, &val_sep, &flags)) { - switch (ZEND_NUM_ARGS()) { - case 5: - zend_update_property_long(php_http_params_class_entry, getThis(), ZEND_STRL("flags"), flags TSRMLS_CC); - /* no break */ - case 4: - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep TSRMLS_CC); - /* no break */ - case 3: - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep TSRMLS_CC); - /* no break */ - case 2: - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep TSRMLS_CC); - /* no break */ - } + zval *zcopy, *zparams = NULL, *param_sep = NULL, *arg_sep = NULL, *val_sep = NULL; + long flags = PHP_HTTP_PARAMS_DEFAULT; + zend_error_handling zeh; - if (zparams) { - switch (Z_TYPE_P(zparams)) { - case IS_OBJECT: - case IS_ARRAY: - zcopy = php_http_zsep(1, IS_ARRAY, zparams); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zcopy TSRMLS_CC); - zval_ptr_dtor(&zcopy); - break; - default: - zcopy = php_http_ztyp(IS_STRING, zparams); - if (Z_STRLEN_P(zcopy)) { - php_http_params_opts_t opts = { - {Z_STRVAL_P(zcopy), Z_STRLEN_P(zcopy)}, - php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0 TSRMLS_CC) TSRMLS_CC), - php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0 TSRMLS_CC) TSRMLS_CC), - php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0 TSRMLS_CC) TSRMLS_CC), - NULL, flags - }; - - MAKE_STD_ZVAL(zparams); - array_init(zparams); - php_http_params_parse(Z_ARRVAL_P(zparams), &opts TSRMLS_CC); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); - zval_ptr_dtor(&zparams); - - php_http_params_separator_free(opts.param); - php_http_params_separator_free(opts.arg); - php_http_params_separator_free(opts.val); - } - zval_ptr_dtor(&zcopy); - break; - } - } else { - MAKE_STD_ZVAL(zparams); - array_init(zparams); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); - zval_ptr_dtor(&zparams); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!/z/z/z/l", &zparams, ¶m_sep, &arg_sep, &val_sep, &flags), invalid_arg, return); + + zend_replace_error_handling(EH_THROW, php_http_exception_runtime_class_entry, &zeh TSRMLS_CC); + { + switch (ZEND_NUM_ARGS()) { + case 5: + zend_update_property_long(php_http_params_class_entry, getThis(), ZEND_STRL("flags"), flags TSRMLS_CC); + /* no break */ + case 4: + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep TSRMLS_CC); + /* no break */ + case 3: + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep TSRMLS_CC); + /* no break */ + case 2: + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep TSRMLS_CC); + /* no break */ + } + + if (zparams) { + switch (Z_TYPE_P(zparams)) { + case IS_OBJECT: + case IS_ARRAY: + zcopy = php_http_zsep(1, IS_ARRAY, zparams); + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zcopy TSRMLS_CC); + zval_ptr_dtor(&zcopy); + break; + default: + zcopy = php_http_ztyp(IS_STRING, zparams); + if (Z_STRLEN_P(zcopy)) { + php_http_params_opts_t opts = { + {Z_STRVAL_P(zcopy), Z_STRLEN_P(zcopy)}, + php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0 TSRMLS_CC) TSRMLS_CC), + php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0 TSRMLS_CC) TSRMLS_CC), + php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0 TSRMLS_CC) TSRMLS_CC), + NULL, flags + }; + + MAKE_STD_ZVAL(zparams); + array_init(zparams); + php_http_params_parse(Z_ARRVAL_P(zparams), &opts TSRMLS_CC); + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); + zval_ptr_dtor(&zparams); + + php_http_params_separator_free(opts.param); + php_http_params_separator_free(opts.arg); + php_http_params_separator_free(opts.val); + } + zval_ptr_dtor(&zcopy); + break; } + } else { + MAKE_STD_ZVAL(zparams); + array_init(zparams); + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); + zval_ptr_dtor(&zparams); } - } end_error_handling(); + } + zend_restore_error_handling(&zeh TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_toArray, 0, 0, 0) @@ -851,17 +854,20 @@ PHP_METHOD(HttpParams, offsetExists) { char *name_str; int name_len; + zval **zparam, *zparams; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { - zval **zparam, *zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { + return; + } - if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { - RETVAL_BOOL(Z_TYPE_PP(zparam) != IS_NULL); - } else { - RETVAL_FALSE; - } - zval_ptr_dtor(&zparams); + zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); + + if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { + RETVAL_BOOL(Z_TYPE_PP(zparam) != IS_NULL); + } else { + RETVAL_FALSE; } + zval_ptr_dtor(&zparams); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetGet, 0, 0, 1) @@ -871,16 +877,19 @@ PHP_METHOD(HttpParams, offsetGet) { char *name_str; int name_len; + zval **zparam, *zparams; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { - zval **zparam, *zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { + return; + } - if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { - RETVAL_ZVAL(*zparam, 1, 0); - } + zparams = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); - zval_ptr_dtor(&zparams); + if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { + RETVAL_ZVAL(*zparam, 1, 0); } + + zval_ptr_dtor(&zparams); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetUnset, 0, 0, 1) @@ -890,15 +899,18 @@ PHP_METHOD(HttpParams, offsetUnset) { char *name_str; int name_len; + zval *zparams; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { - zval *zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) { + return; + } - zend_symtable_del(Z_ARRVAL_P(zparams), name_str, name_len + 1); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); + zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); - zval_ptr_dtor(&zparams); - } + zend_symtable_del(Z_ARRVAL_P(zparams), name_str, name_len + 1); + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); + + zval_ptr_dtor(&zparams); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetSet, 0, 0, 2) @@ -910,49 +922,52 @@ PHP_METHOD(HttpParams, offsetSet) zval *nvalue; char *name_str; int name_len; + zval **zparam, *zparams; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name_str, &name_len, &nvalue)) { - zval **zparam, *zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); - - if (name_len) { - if (Z_TYPE_P(nvalue) == IS_ARRAY) { - zval *new_zparam; + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name_str, &name_len, &nvalue)) { + return; + } - if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { - new_zparam = php_http_zsep(1, IS_ARRAY, *zparam); - array_join(Z_ARRVAL_P(nvalue), Z_ARRVAL_P(new_zparam), 0, 0); - } else { - new_zparam = nvalue; - Z_ADDREF_P(new_zparam); - } - add_assoc_zval_ex(zparams, name_str, name_len + 1, new_zparam); - } else { - zval *tmp; + zparams = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0 TSRMLS_CC)); - if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { - tmp = php_http_zsep(1, IS_ARRAY, *zparam); - } else { - MAKE_STD_ZVAL(tmp); - array_init(tmp); - } + if (name_len) { + if (Z_TYPE_P(nvalue) == IS_ARRAY) { + zval *new_zparam; - Z_ADDREF_P(nvalue); - add_assoc_zval_ex(tmp, ZEND_STRS("value"), nvalue); - add_assoc_zval_ex(zparams, name_str, name_len + 1, tmp); + if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { + new_zparam = php_http_zsep(1, IS_ARRAY, *zparam); + array_join(Z_ARRVAL_P(nvalue), Z_ARRVAL_P(new_zparam), 0, 0); + } else { + new_zparam = nvalue; + Z_ADDREF_P(new_zparam); } + add_assoc_zval_ex(zparams, name_str, name_len + 1, new_zparam); } else { - zval *tmp = php_http_ztyp(IS_STRING, nvalue), *arr; + zval *tmp; - MAKE_STD_ZVAL(arr); - array_init(arr); - add_assoc_bool_ex(arr, ZEND_STRS("value"), 1); - add_assoc_zval_ex(zparams, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 1, arr); - zval_ptr_dtor(&tmp); + if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(zparams), name_str, name_len + 1, (void *) &zparam)) { + tmp = php_http_zsep(1, IS_ARRAY, *zparam); + } else { + MAKE_STD_ZVAL(tmp); + array_init(tmp); + } + + Z_ADDREF_P(nvalue); + add_assoc_zval_ex(tmp, ZEND_STRS("value"), nvalue); + add_assoc_zval_ex(zparams, name_str, name_len + 1, tmp); } + } else { + zval *tmp = php_http_ztyp(IS_STRING, nvalue), *arr; - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); - zval_ptr_dtor(&zparams); + MAKE_STD_ZVAL(arr); + array_init(arr); + add_assoc_bool_ex(arr, ZEND_STRS("value"), 1); + add_assoc_zval_ex(zparams, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 1, arr); + zval_ptr_dtor(&tmp); } + + zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams TSRMLS_CC); + zval_ptr_dtor(&zparams); } static zend_function_entry php_http_params_methods[] = { @@ -977,7 +992,8 @@ PHP_MINIT_FUNCTION(http_params) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Params", php_http_params_methods); - php_http_params_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_params_class_entry = zend_register_internal_class(&ce TSRMLS_CC); + php_http_params_class_entry->create_object = php_http_params_object_new; zend_class_implements(php_http_params_class_entry TSRMLS_CC, 1, zend_ce_arrayaccess); zend_declare_class_constant_stringl(php_http_params_class_entry, ZEND_STRL("DEF_PARAM_SEP"), ZEND_STRL(",") TSRMLS_CC); diff --git a/php_http_querystring.c b/php_http_querystring.c index d1b7845..7304d69 100644 --- a/php_http_querystring.c +++ b/php_http_querystring.c @@ -76,7 +76,7 @@ static inline void php_http_querystring_get(zval *this_ptr, int type, char *name } #ifdef PHP_HTTP_HAVE_ICONV -PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char *ie, const char *oe TSRMLS_DC) +STATUS php_http_querystring_xlate(zval *dst, zval *src, const char *ie, const char *oe TSRMLS_DC) { HashPosition pos; zval **entry = NULL; @@ -87,7 +87,7 @@ PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char FOREACH_KEYVAL(pos, src, key, entry) { if (key.type == HASH_KEY_IS_STRING) { if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) { - php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe); return FAILURE; } } @@ -97,7 +97,7 @@ PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char if (key.type == HASH_KEY_IS_STRING) { efree(xkey); } - php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe); return FAILURE; } if (key.type == HASH_KEY_IS_STRING) { @@ -131,7 +131,7 @@ PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char } #endif /* HAVE_ICONV */ -PHP_HTTP_API STATUS php_http_querystring_ctor(zval *instance, zval *params TSRMLS_DC) +STATUS php_http_querystring_ctor(zval *instance, zval *params TSRMLS_DC) { php_http_querystring_set(instance, params, 0 TSRMLS_CC); return SUCCESS; @@ -158,7 +158,7 @@ static int apply_querystring(void *pData TSRMLS_DC) return ZEND_HASH_APPLY_KEEP; } -PHP_HTTP_API STATUS php_http_querystring_parse(HashTable *ht, const char *str, size_t len TSRMLS_DC) +STATUS php_http_querystring_parse(HashTable *ht, const char *str, size_t len TSRMLS_DC) { STATUS rv = FAILURE; php_http_params_opts_t opts; @@ -206,7 +206,7 @@ PHP_HTTP_API STATUS php_http_querystring_parse(HashTable *ht, const char *str, s return rv; } -PHP_HTTP_API STATUS php_http_querystring_update(zval *qarray, zval *params, zval *outstring TSRMLS_DC) +STATUS php_http_querystring_update(zval *qarray, zval *params, zval *outstring TSRMLS_DC) { /* enforce proper type */ if (Z_TYPE_P(qarray) != IS_ARRAY) { @@ -311,7 +311,7 @@ PHP_HTTP_API STATUS php_http_querystring_update(zval *qarray, zval *params, zval zval_dtor(outstring); ZVAL_STRINGL(outstring, s, l, 0); } else { - php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to encode query string"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to encode query string"); return FAILURE; } } @@ -325,69 +325,65 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, __construct) { zval *params = NULL; + zend_error_handling zeh; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", ¶ms)) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_http_querystring_set(getThis(), params, 0 TSRMLS_CC); - } end_error_handling(); - } - } end_error_handling(); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", ¶ms), invalid_arg, return); + + zend_replace_error_handling(EH_THROW, php_http_exception_bad_querystring_class_entry, &zeh TSRMLS_CC); + php_http_querystring_set(getThis(), params, 0 TSRMLS_CC); + zend_restore_error_handling(&zeh TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_getGlobalInstance, 0, 0, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, getGlobalInstance) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *instance = *zend_std_get_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), 0 PHP_HTTP_ZEND_LITERAL_CCN TSRMLS_CC); + zval *instance; - if (Z_TYPE_P(instance) != IS_OBJECT) { - zval **_GET = NULL; + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC); + instance = *zend_std_get_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), 0 PHP_HTTP_ZEND_LITERAL_CCN TSRMLS_CC); - if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET)) - && (Z_TYPE_PP(_GET) == IS_ARRAY) - ) { - MAKE_STD_ZVAL(instance); - ZVAL_OBJVAL(instance, php_http_querystring_object_new(php_http_querystring_class_entry TSRMLS_CC), 0); + if (Z_TYPE_P(instance) != IS_OBJECT) { + zval **_GET = NULL; - SEPARATE_ZVAL_TO_MAKE_IS_REF(_GET); - convert_to_array(*_GET); - zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), *_GET TSRMLS_CC); + zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC); - zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), instance TSRMLS_CC); - zval_ptr_dtor(&instance); - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Could not acquire reference to superglobal GET array"); - } - } - RETVAL_ZVAL(instance, 1, 0); - } end_error_handling(); + if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET)) + && (Z_TYPE_PP(_GET) == IS_ARRAY) + ) { + MAKE_STD_ZVAL(instance); + ZVAL_OBJVAL(instance, php_http_querystring_object_new(php_http_querystring_class_entry TSRMLS_CC), 0); + + SEPARATE_ZVAL_TO_MAKE_IS_REF(_GET); + convert_to_array(*_GET); + zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), *_GET TSRMLS_CC); + + zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), instance TSRMLS_CC); + zval_ptr_dtor(&instance); + } else { + php_http_throw(unexpected_val, "Could not acquire reference to superglobal GET array", NULL); } - } end_error_handling(); + } + + RETVAL_ZVAL(instance, 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_getIterator, 0, 0, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, getIterator) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters_none()) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *retval = NULL, *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); - - object_init_ex(return_value, spl_ce_RecursiveArrayIterator); - zend_call_method_with_1_params(&return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", &retval, qa); - if (retval) { - zval_ptr_dtor(&retval); - } - } end_error_handling(); - } - } end_error_handling(); + zval *retval = NULL, *qa; + + php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); + + qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); + + object_init_ex(return_value, spl_ce_RecursiveArrayIterator); + zend_call_method_with_1_params(&return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", &retval, qa); + if (retval) { + zval_ptr_dtor(&retval); + } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_toString, 0, 0, 0) @@ -404,10 +400,14 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_toArray, 0, 0, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, toArray) { - if (SUCCESS == zend_parse_parameters_none()) { - zval *zqa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); - RETURN_ZVAL(zqa, 1, 0); + zval *zqa; + + if (SUCCESS != zend_parse_parameters_none()) { + return; } + + zqa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); + RETURN_ZVAL(zqa, 1, 0); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_get, 0, 0, 0) @@ -465,7 +465,7 @@ PHP_METHOD(HttpQueryString, set) zval *params; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶ms)) { - RETURN_FALSE; + return; } php_http_querystring_set(getThis(), params, QS_MERGE TSRMLS_CC); @@ -478,15 +478,14 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, mod) { zval *params; + zend_error_handling zeh; + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶ms), invalid_arg, return); - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶ms)) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0); - php_http_querystring_set(return_value, params, QS_MERGE TSRMLS_CC); - } end_error_handling(); - } - } end_error_handling(); + zend_replace_error_handling(EH_THROW, php_http_exception_bad_querystring_class_entry, &zeh TSRMLS_CC); + ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0); + php_http_querystring_set(return_value, params, QS_MERGE TSRMLS_CC); + zend_restore_error_handling(&zeh TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString___getter, 0, 0, 1) @@ -519,28 +518,27 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_xlate, 0, 0, 2) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, xlate) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - char *ie, *oe; - int ie_len, oe_len; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *na, *qa = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC)); - - MAKE_STD_ZVAL(na); - array_init(na); - if (SUCCESS == php_http_querystring_xlate(na, qa, ie, oe TSRMLS_CC)) { - php_http_querystring_set(getThis(), na, 0 TSRMLS_CC); - } + char *ie, *oe; + int ie_len, oe_len; + zval *na, *qa; - zval_ptr_dtor(&na); - zval_ptr_dtor(&qa); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len), invalid_arg, return); - RETVAL_ZVAL(getThis(), 1, 0); - } end_error_handling(); - } - } end_error_handling(); + MAKE_STD_ZVAL(na); + array_init(na); + qa = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC)); + + php_http_expect(SUCCESS == php_http_querystring_xlate(na, qa, ie, oe TSRMLS_CC), bad_conversion, + zval_ptr_dtor(&na); + zval_ptr_dtor(&qa); + return; + ); + + php_http_querystring_set(getThis(), na, 0 TSRMLS_CC); + RETVAL_ZVAL(getThis(), 1, 0); + zval_ptr_dtor(&na); + zval_ptr_dtor(&qa); } #endif /* HAVE_ICONV */ @@ -561,17 +559,15 @@ PHP_METHOD(HttpQueryString, unserialize) { zval *serialized; - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (Z_TYPE_P(serialized) == IS_STRING) { - php_http_querystring_set(getThis(), serialized, 0 TSRMLS_CC); - } else { - php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Expected a string as parameter"); - } - } end_error_handling(); - } - } end_error_handling(); + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) { + return; + } + + if (Z_TYPE_P(serialized) == IS_STRING) { + php_http_querystring_set(getThis(), serialized, 0 TSRMLS_CC); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected a string as parameter"); + } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetGet, 0, 0, 1) @@ -581,14 +577,16 @@ PHP_METHOD(HttpQueryString, offsetGet) { char *offset_str; int offset_len; - zval **value; + zval **value, *qa; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) { + return; + } - if ((SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len))) { - zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); + qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); - if (Z_TYPE_P(qa) == IS_ARRAY - && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value) - ) { + if (Z_TYPE_P(qa) == IS_ARRAY) { + if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)) { RETVAL_ZVAL(*value, 1, 0); } } @@ -602,18 +600,18 @@ PHP_METHOD(HttpQueryString, offsetSet) { char *offset_str; int offset_len; - zval *value; + zval *value, *param; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) { - zval *param; - - MAKE_STD_ZVAL(param); - array_init(param); - Z_ADDREF_P(value); - add_assoc_zval_ex(param, offset_str, offset_len + 1, value); - php_http_querystring_set(getThis(), param, 0 TSRMLS_CC); - zval_ptr_dtor(¶m); + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) { + return; } + + MAKE_STD_ZVAL(param); + array_init(param); + Z_ADDREF_P(value); + add_assoc_zval_ex(param, offset_str, offset_len + 1, value); + php_http_querystring_set(getThis(), param, 0 TSRMLS_CC); + zval_ptr_dtor(¶m); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetExists, 0, 0, 1) @@ -623,19 +621,20 @@ PHP_METHOD(HttpQueryString, offsetExists) { char *offset_str; int offset_len; - zval **value; + zval **value, *qa; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) { + return; + } - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) { - zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); + qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC); - if (Z_TYPE_P(qa) == IS_ARRAY - && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value) - && Z_TYPE_PP(value) != IS_NULL - ) { - RETURN_TRUE; + if (Z_TYPE_P(qa) == IS_ARRAY) { + if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)) { + RETURN_BOOL(Z_TYPE_PP(value) != IS_NULL); } - RETURN_FALSE; } + RETURN_FALSE; } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetUnset, 0, 0, 1) @@ -645,16 +644,17 @@ PHP_METHOD(HttpQueryString, offsetUnset) { char *offset_str; int offset_len; + zval *param; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) { - zval *param; - - MAKE_STD_ZVAL(param); - array_init(param); - add_assoc_null_ex(param, offset_str, offset_len + 1); - php_http_querystring_set(getThis(), param, QS_MERGE TSRMLS_CC); - zval_ptr_dtor(¶m); + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) { + return; } + + MAKE_STD_ZVAL(param); + array_init(param); + add_assoc_null_ex(param, offset_str, offset_len + 1); + php_http_querystring_set(getThis(), param, QS_MERGE TSRMLS_CC); + zval_ptr_dtor(¶m); } zend_class_entry *php_http_querystring_class_entry; @@ -702,7 +702,8 @@ PHP_MINIT_FUNCTION(http_querystring) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "QueryString", php_http_querystring_methods); - php_http_querystring_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_querystring_class_entry = zend_register_internal_class(&ce TSRMLS_CC); + php_http_querystring_class_entry->create_object = php_http_querystring_object_new; zend_class_implements(php_http_querystring_class_entry TSRMLS_CC, 3, zend_ce_serializable, zend_ce_arrayaccess, zend_ce_aggregate); zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC); diff --git a/php_http_strlist.c b/php_http_strlist.c index fa1fd01..4e316db 100644 --- a/php_http_strlist.c +++ b/php_http_strlist.c @@ -12,7 +12,7 @@ #include "php_http_api.h" -PHP_HTTP_API php_http_strlist_iterator_t *php_http_strlist_iterator_init(php_http_strlist_iterator_t *iter, const char list[], unsigned factor) +php_http_strlist_iterator_t *php_http_strlist_iterator_init(php_http_strlist_iterator_t *iter, const char list[], unsigned factor) { if (!iter) { iter = emalloc(sizeof(*iter)); @@ -25,7 +25,7 @@ PHP_HTTP_API php_http_strlist_iterator_t *php_http_strlist_iterator_init(php_htt return iter; } -PHP_HTTP_API const char *php_http_strlist_iterator_this(php_http_strlist_iterator_t *iter, unsigned *id) +const char *php_http_strlist_iterator_this(php_http_strlist_iterator_t *iter, unsigned *id) { if (id) { *id = (iter->major + 1) * iter->factor + iter->minor; @@ -34,7 +34,7 @@ PHP_HTTP_API const char *php_http_strlist_iterator_this(php_http_strlist_iterato return iter->p; } -PHP_HTTP_API const char *php_http_strlist_iterator_next(php_http_strlist_iterator_t *iter) +const char *php_http_strlist_iterator_next(php_http_strlist_iterator_t *iter) { if (*iter->p) { while (*iter->p) { @@ -53,12 +53,12 @@ PHP_HTTP_API const char *php_http_strlist_iterator_next(php_http_strlist_iterato return iter->p; } -PHP_HTTP_API void php_http_strlist_iterator_dtor(php_http_strlist_iterator_t *iter) +void php_http_strlist_iterator_dtor(php_http_strlist_iterator_t *iter) { } -PHP_HTTP_API void php_http_strlist_iterator_free(php_http_strlist_iterator_t **iter) +void php_http_strlist_iterator_free(php_http_strlist_iterator_t **iter) { if (*iter) { efree(*iter); @@ -66,7 +66,7 @@ PHP_HTTP_API void php_http_strlist_iterator_free(php_http_strlist_iterator_t **i } } -PHP_HTTP_API const char *php_http_strlist_find(const char list[], unsigned factor, unsigned item) +const char *php_http_strlist_find(const char list[], unsigned factor, unsigned item) { unsigned M = 0, m = 0, major, minor; const char *p = &list[0]; diff --git a/php_http_url.c b/php_http_url.c index 175886d..eb1d2a3 100644 --- a/php_http_url.c +++ b/php_http_url.c @@ -183,7 +183,7 @@ static php_url *php_http_url_from_env(php_url *url TSRMLS_DC) return url; } -PHP_HTTP_API void php_http_url(int flags, const php_url *old_url, const php_url *new_url, php_url **url_ptr, char **url_str, size_t *url_len TSRMLS_DC) +void php_http_url(int flags, const php_url *old_url, const php_url *new_url, php_url **url_ptr, char **url_str, size_t *url_len TSRMLS_DC) { php_url *url, *tmp_url = NULL; @@ -356,7 +356,7 @@ PHP_HTTP_API void php_http_url(int flags, const php_url *old_url, const php_url } } -PHP_HTTP_API STATUS php_http_url_encode_hash(HashTable *hash, const char *pre_encoded_str, size_t pre_encoded_len, char **encoded_str, size_t *encoded_len TSRMLS_DC) +STATUS php_http_url_encode_hash(HashTable *hash, const char *pre_encoded_str, size_t pre_encoded_len, char **encoded_str, size_t *encoded_len TSRMLS_DC) { const char *arg_sep_str; size_t arg_sep_len; @@ -375,7 +375,7 @@ PHP_HTTP_API STATUS php_http_url_encode_hash(HashTable *hash, const char *pre_en return SUCCESS; } -PHP_HTTP_API STATUS php_http_url_encode_hash_ex(HashTable *hash, php_http_buffer_t *qstr, const char *arg_sep_str, size_t arg_sep_len, const char *val_sep_str, size_t val_sep_len, const char *pre_encoded_str, size_t pre_encoded_len TSRMLS_DC) +STATUS php_http_url_encode_hash_ex(HashTable *hash, php_http_buffer_t *qstr, const char *arg_sep_str, size_t arg_sep_len, const char *val_sep_str, size_t val_sep_len, const char *pre_encoded_str, size_t pre_encoded_len TSRMLS_DC) { if (pre_encoded_len && pre_encoded_str) { php_http_buffer_append(qstr, pre_encoded_str, pre_encoded_len); @@ -395,67 +395,70 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl___construct, 0, 0, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpUrl, __construct) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - zval *new_url = NULL, *old_url = NULL; - long flags = PHP_HTTP_URL_FROM_ENV; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!z!l", &old_url, &new_url, &flags)) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { - php_url *res_purl, *new_purl = NULL, *old_purl = NULL; - - if (new_url) { - switch (Z_TYPE_P(new_url)) { - case IS_OBJECT: - case IS_ARRAY: - new_purl = php_http_url_from_struct(NULL, HASH_OF(new_url) TSRMLS_CC); - break; - default: { - zval *cpy = php_http_ztyp(IS_STRING, new_url); + zval *new_url = NULL, *old_url = NULL; + long flags = PHP_HTTP_URL_FROM_ENV; + zend_error_handling zeh; - new_purl = php_url_parse(Z_STRVAL_P(cpy)); - zval_ptr_dtor(&cpy); - break; - } - } - if (!new_purl) { - return; - } - } - if (old_url) { - switch (Z_TYPE_P(old_url)) { - case IS_OBJECT: - case IS_ARRAY: - old_purl = php_http_url_from_struct(NULL, HASH_OF(old_url) TSRMLS_CC); - break; - default: { - zval *cpy = php_http_ztyp(IS_STRING, old_url); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!z!l", &old_url, &new_url, &flags), invalid_arg, return); - old_purl = php_url_parse(Z_STRVAL_P(cpy)); - zval_ptr_dtor(&cpy); - break; - } - } - if (!old_purl) { - if (new_purl) { - php_url_free(new_purl); - } - return; - } - } + zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh TSRMLS_CC); + { + php_url *res_purl, *new_purl = NULL, *old_purl = NULL; - php_http_url(flags, old_purl, new_purl, &res_purl, NULL, NULL TSRMLS_CC); - php_http_url_to_struct(res_purl, getThis() TSRMLS_CC); + if (new_url) { + switch (Z_TYPE_P(new_url)) { + case IS_OBJECT: + case IS_ARRAY: + new_purl = php_http_url_from_struct(NULL, HASH_OF(new_url) TSRMLS_CC); + break; + default: { + zval *cpy = php_http_ztyp(IS_STRING, new_url); - php_url_free(res_purl); - if (old_purl) { - php_url_free(old_purl); + new_purl = php_url_parse(Z_STRVAL_P(cpy)); + zval_ptr_dtor(&cpy); + break; } + } + if (!new_purl) { + zend_restore_error_handling(&zeh TSRMLS_CC); + return; + } + } + if (old_url) { + switch (Z_TYPE_P(old_url)) { + case IS_OBJECT: + case IS_ARRAY: + old_purl = php_http_url_from_struct(NULL, HASH_OF(old_url) TSRMLS_CC); + break; + default: { + zval *cpy = php_http_ztyp(IS_STRING, old_url); + + old_purl = php_url_parse(Z_STRVAL_P(cpy)); + zval_ptr_dtor(&cpy); + break; + } + } + if (!old_purl) { if (new_purl) { php_url_free(new_purl); } - } end_error_handling(); + zend_restore_error_handling(&zeh TSRMLS_CC); + return; + } + } + + php_http_url(flags, old_purl, new_purl, &res_purl, NULL, NULL TSRMLS_CC); + php_http_url_to_struct(res_purl, getThis() TSRMLS_CC); + + php_url_free(res_purl); + if (old_purl) { + php_url_free(old_purl); } - } end_error_handling(); + if (new_purl) { + php_url_free(new_purl); + } + } + zend_restore_error_handling(&zeh TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl_mod, 0, 0, 1) @@ -466,8 +469,12 @@ PHP_METHOD(HttpUrl, mod) { zval *new_url = NULL; long flags = PHP_HTTP_URL_JOIN_PATH | PHP_HTTP_URL_JOIN_QUERY; + zend_error_handling zeh; + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!|l", &new_url, &flags), invalid_arg, return); - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!|l", &new_url, &flags)) { + zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh TSRMLS_CC); + { php_url *new_purl = NULL, *old_purl = NULL; if (new_url) { @@ -485,6 +492,7 @@ PHP_METHOD(HttpUrl, mod) } } if (!new_purl) { + zend_restore_error_handling(&zeh TSRMLS_CC); return; } } @@ -504,6 +512,7 @@ PHP_METHOD(HttpUrl, mod) php_url_free(new_purl); } } + zend_restore_error_handling(&zeh TSRMLS_CC); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl_toString, 0, 0, 0) @@ -557,7 +566,7 @@ PHP_MINIT_FUNCTION(http_url) zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Url", php_http_url_methods); - php_http_url_class_entry = zend_register_internal_class_ex(&ce, php_http_object_class_entry, NULL TSRMLS_CC); + php_http_url_class_entry = zend_register_internal_class(&ce TSRMLS_CC); zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("scheme"), ZEND_ACC_PUBLIC TSRMLS_CC); zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC); diff --git a/php_http_version.c b/php_http_version.c index 45f7a30..4b80504 100644 --- a/php_http_version.c +++ b/php_http_version.c @@ -12,7 +12,7 @@ #include "php_http_api.h" -PHP_HTTP_API php_http_version_t *php_http_version_init(php_http_version_t *v, unsigned major, unsigned minor TSRMLS_DC) +php_http_version_t *php_http_version_init(php_http_version_t *v, unsigned major, unsigned minor TSRMLS_DC) { if (!v) { v = emalloc(sizeof(*v)); @@ -24,35 +24,35 @@ PHP_HTTP_API php_http_version_t *php_http_version_init(php_http_version_t *v, un return v; } -PHP_HTTP_API php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *str TSRMLS_DC) +php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *str TSRMLS_DC) { php_http_version_t tmp; char separator = 0; if (3 != sscanf(str, "HTTP/%u%c%u", &tmp.major, &separator, &tmp.minor) && 3 != sscanf(str, "%u%c%u", &tmp.major, &separator, &tmp.minor)) { - php_http_error(HE_WARNING, PHP_HTTP_E_MALFORMED_HEADERS, "Could not parse HTTP protocol version '%s'", str); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP protocol version '%s'", str); return NULL; } if (separator && separator != '.' && separator != ',') { - php_http_error(HE_NOTICE, PHP_HTTP_E_MALFORMED_HEADERS, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, str); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, str); } return php_http_version_init(v, tmp.major, tmp.minor TSRMLS_CC); } -PHP_HTTP_API void php_http_version_to_string(php_http_version_t *v, char **str, size_t *len, const char *pre, const char *post TSRMLS_DC) +void php_http_version_to_string(php_http_version_t *v, char **str, size_t *len, const char *pre, const char *post TSRMLS_DC) { *len = spprintf(str, 0, "%s%u.%u%s", pre ? pre : "", v->major, v->minor, post ? post : ""); } -PHP_HTTP_API void php_http_version_dtor(php_http_version_t *v) +void php_http_version_dtor(php_http_version_t *v) { (void) v; } -PHP_HTTP_API void php_http_version_free(php_http_version_t **v) +void php_http_version_free(php_http_version_t **v) { if (*v) { php_http_version_dtor(*v); diff --git a/phpunit/MessageBodyTest.php b/phpunit/MessageBodyTest.php index 253fb55..3aaf3eb 100644 --- a/phpunit/MessageBodyTest.php +++ b/phpunit/MessageBodyTest.php @@ -25,7 +25,7 @@ class MessageBodyTest extends PHPUnit_Framework_TestCase { } function testAppendError() { - $this->setExpectedException("PHPUnit_Framework_Error"); + $this->setExpectedException("http\Exception\RuntimeException"); $this->file->append("nope"); } function testAppend() { diff --git a/tests/envresponsebody002.phpt b/tests/envresponsebody002.phpt index f9b33c5..1421b09 100644 --- a/tests/envresponsebody002.phpt +++ b/tests/envresponsebody002.phpt @@ -20,5 +20,5 @@ try { Done --EXPECTF-- Test -Could not fetch response body, output has already been sent at %senvresponsebody002.php:3 +http\Env\Response::__construct(): Could not fetch response body, output has already been sent at %senvresponsebody002.php:3 Done diff --git a/tests/header007.phpt b/tests/header007.phpt index 7f6f9eb..aa91901 100644 --- a/tests/header007.phpt +++ b/tests/header007.phpt @@ -10,7 +10,6 @@ include "skipif.inc"; echo "Test\n"; $header = "wass\nup"; -/* this generates two warnings because of the LF ;) */ http\Header::parse($header); ?> @@ -18,7 +17,5 @@ Done --EXPECTF-- Test -Warning: http\Header::parse(): Could not parse headers in %s on line %d - Warning: http\Header::parse(): Could not parse headers in %s on line %d Done diff --git a/tests/info_001.phpt b/tests/info_001.phpt index e79abd4..11b83f6 100644 --- a/tests/info_001.phpt +++ b/tests/info_001.phpt @@ -24,27 +24,23 @@ var_dump(new http\Message("GET / HTTP/1.1")); ?> DONE --EXPECTF-- -exception 'http\Exception' with message 'could not parse message: GET HTTP/1.1' in %s +exception 'http\Exception\BadMessageException' with message 'Could not parse message: GET HTTP/1.1' in %s Stack trace: #0 %s: http\Message->__construct('GET HTTP/1.1') #1 {main} -exception 'http\Exception' with message 'could not parse message: GET HTTP/1.123' in %s +exception 'http\Exception\BadMessageException' with message 'Could not parse message: GET HTTP/1.123' in %s Stack trace: #0 %s: http\Message->__construct('GET HTTP/1.123') #1 {main} -exception 'http\Exception' with message 'could not parse message: GETHTTP/1.1' in %s +exception 'http\Exception\BadMessageException' with message 'Could not parse message: GETHTTP/1.1' in %s Stack trace: #0 %s: http\Message->__construct('GETHTTP/1.1') #1 {main} -object(http\Message)#%d (10) { - ["errorHandling":protected]=> - NULL +object(http\Message)#%d (9) { ["type":protected]=> int(1) ["body":protected]=> - object(http\Message\Body)#%d (1) { - ["errorHandling":protected]=> - NULL + object(http\Message\Body)#%d (0) { } ["requestMethod":protected]=> string(3) "GET" diff --git a/tests/message002.phpt b/tests/message002.phpt index f701bc2..06d9e1b 100644 --- a/tests/message002.phpt +++ b/tests/message002.phpt @@ -31,15 +31,11 @@ var_dump(file_get_contents("php://input")); echo "Done\n"; --EXPECTF-- Test -object(%s)#%d (13) { - ["errorHandling":protected]=> - NULL +object(%s)#%d (12) { ["type":protected]=> int(1) ["body":protected]=> - object(%s)#%d (1) { - ["errorHandling":protected]=> - NULL + object(http\Message\Body)#%d (0) { } ["requestMethod":protected]=> string(4) "POST" @@ -65,17 +61,13 @@ object(%s)#%d (13) { ["parentMessage":protected]=> NULL ["query":protected]=> - object(http\QueryString)#2 (2) { - ["errorHandling":protected]=> - NULL + object(http\QueryString)#2 (1) { ["queryArray":"http\QueryString":private]=> array(0) { } } ["form":protected]=> - object(http\QueryString)#3 (2) { - ["errorHandling":protected]=> - NULL + object(http\QueryString)#3 (1) { ["queryArray":"http\QueryString":private]=> array(0) { } diff --git a/tests/message006.phpt b/tests/message006.phpt index 4bb8475..52e534d 100644 --- a/tests/message006.phpt +++ b/tests/message006.phpt @@ -20,20 +20,16 @@ var_dump($m); DONE --EXPECTF-- Test -object(c)#%d (10) { +object(c)#%d (9) { ["headers"]=> array(1) { ["foo"]=> string(3) "bar" } - ["errorHandling":protected]=> - NULL ["type":protected]=> int(0) ["body":protected]=> - object(http\Message\Body)#%d (1) { - ["errorHandling":protected]=> - NULL + object(http\Message\Body)#%d (0) { } ["requestMethod":protected]=> string(0) "" diff --git a/tests/message015.phpt b/tests/message015.phpt index f11efc8..e9bd846 100644 --- a/tests/message015.phpt +++ b/tests/message015.phpt @@ -10,16 +10,24 @@ include "skipif.inc"; echo "Test\n"; $m = new http\Message; -$m->setRequestUrl("/foo"); +try { + $m->setRequestUrl("/foo"); +} catch (http\Exception $e) { + echo $e->getMessage(),"\n"; +} $m->setType(http\Message::TYPE_REQUEST); -$m->setRequestUrl(""); +try { + $m->setRequestUrl(""); +} catch (http\Exception $e) { + echo $e->getMessage(),"\n"; +} $m = new http\Message; try { $m->getParentMessage(); die("unreached"); } catch (http\Exception $e) { - var_dump($e->getMessage()); + echo $e->getMessage(),"\n"; } $m = new http\Message("HTTP/1.1 200\r\nHTTP/1.1 201"); @@ -27,17 +35,15 @@ try { $m->prepend($m->getParentMessage()); die("unreached"); } catch (http\Exception $e) { - var_dump($e->getMessage()); + echo $e->getMessage(),"\n"; } ?> Done --EXPECTF-- Test - -Notice: http\Message::setRequestUrl(): HttpMessage is not of type REQUEST in %s on line %d - -Warning: http\Message::setRequestUrl(): Cannot set HttpMessage::requestUrl to an empty string in %s on line %d -string(42) "HttpMessage does not have a parent message" -string(62) "Cannot prepend a message located within the same message chain" +http\Message is not of type request +Cannot set http\Message's request url to an empty string +http\Message has not parent message +Cannot prepend a message located within the same message chain Done diff --git a/tests/params002.phpt b/tests/params002.phpt index 66e514c..95bc7ac 100644 --- a/tests/params002.phpt +++ b/tests/params002.phpt @@ -14,9 +14,7 @@ echo $p, "\n"; ?> DONE --EXPECTF-- -object(http\Params)#%d (6) { - ["errorHandling":protected]=> - NULL +object(http\Params)#%d (5) { ["params"]=> array(2) { ["foo"]=> diff --git a/tests/version001.phpt b/tests/version001.phpt index 513875d..52acba6 100644 --- a/tests/version001.phpt +++ b/tests/version001.phpt @@ -6,12 +6,16 @@ include "skipif.inc"; ?> --FILE-- setHttpVersion("1-1"); -$m->setHttpVersion("one.one"); +try { + $m->setHttpVersion("1-1"); + $m->setHttpVersion("one.one"); +} catch (http\Exception $e) { + echo $e->getMessage(),"\n"; +} ?> --EXPECTF-- Notice: http\Message::setHttpVersion(): Non-standard version separator '-' in HTTP protocol version '1-1' in %s - -Warning: http\Message::setHttpVersion(): Could not parse HTTP protocol version 'one.one' in %s +http\Message::setHttpVersion(): Could not parse HTTP protocol version 'one.one'