From cc9f67a6e5d50fc0c870a19d98e35e05f03d9b68 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 30 Nov 2005 18:46:53 +0000 Subject: [PATCH] - wrap request exceptions into one request pool exception # I don't know if this is a good idea and it definitly needs some more testing --- http_exception_object.c | 4 +-- http_request_pool_api.c | 54 +++++++++++++++++++++++++++++++++++++ php_http_exception_object.h | 15 +++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/http_exception_object.c b/http_exception_object.c index b6594ba..60966a9 100644 --- a/http_exception_object.c +++ b/http_exception_object.c @@ -23,9 +23,7 @@ #include "php_http_exception_object.h" -#define HTTP_EX_DEF_CE http_exception_object_ce zend_class_entry *http_exception_object_ce; -#define HTTP_EX_CE(name) http_ ##name## _exception_object_ce zend_class_entry *HTTP_EX_CE(runtime); zend_class_entry *HTTP_EX_CE(header); zend_class_entry *HTTP_EX_CE(malformed_headers); @@ -54,6 +52,8 @@ PHP_MINIT_FUNCTION(http_exception_object) HTTP_REGISTER_EXCEPTION(HttpSocketException, HTTP_EX_CE(socket), HTTP_EX_DEF_CE); HTTP_REGISTER_EXCEPTION(HttpResponseException, HTTP_EX_CE(response), HTTP_EX_DEF_CE); HTTP_REGISTER_EXCEPTION(HttpUrlException, HTTP_EX_CE(url), HTTP_EX_DEF_CE); + + zend_declare_property_null(HTTP_EX_CE(request_pool), "requestExceptions", sizeof("requestExceptions")-1, ZEND_ACC_PUBLIC TSRMLS_CC); HTTP_LONG_CONSTANT("HTTP_E_RUNTIME", HTTP_E_RUNTIME); HTTP_LONG_CONSTANT("HTTP_E_INVALID_PARAM", HTTP_E_INVALID_PARAM); diff --git a/http_request_pool_api.c b/http_request_pool_api.c index 48c1cde..6bbde40 100644 --- a/http_request_pool_api.c +++ b/http_request_pool_api.c @@ -22,6 +22,7 @@ #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) #include "php_http_api.h" +#include "php_http_exception_object.h" #include "php_http_request_api.h" #include "php_http_request_object.h" #include "php_http_request_pool_api.h" @@ -37,6 +38,8 @@ ZEND_EXTERN_MODULE_GLOBALS(http); # define curl_multi_strerror(dummy) "unknown error" #endif +#define http_request_pool_wrap_exception(o, n) _http_request_pool_wrap_exception((o), (n) TSRMLS_CC) +static inline void _http_request_pool_wrap_exception(zval *old_exception, zval *new_exception TSRMLS_DC); static void http_request_pool_freebody(http_request_callback_ctx **body); static int http_request_pool_compare_handles(void *h1, void *h2); @@ -272,11 +275,25 @@ PHP_HTTP_API int _http_request_pool_perform(http_request_pool *pool TSRMLS_DC) while ((msg = curl_multi_info_read(pool->ch, &remaining))) { if (CURLMSG_DONE == msg->msg) { if (CURLE_OK != msg->data.result) { + zval *old_exception = EG(exception); + + if (old_exception) { + EG(exception) = NULL; + } http_error(HE_WARNING, HTTP_E_REQUEST, curl_easy_strerror(msg->data.result)); + if (old_exception) { + http_request_pool_wrap_exception(old_exception, EG(exception)); + } } zend_llist_apply_with_argument(&pool->handles, (llist_apply_with_arg_func_t) http_request_pool_responsehandler, msg->easy_handle TSRMLS_CC); } } + if (EG(exception)) { + zval *exception = EG(exception); + + EG(exception) = NULL; + zend_throw_exception_object(exception TSRMLS_CC); + } return pool->unfinished; } @@ -314,6 +331,43 @@ void _http_request_pool_responsehandler(zval **req, CURL *ch TSRMLS_DC) /*#*/ +/* {{{ static void http_request_pool_wrap_exception(zval *, zval *) */ +static inline void _http_request_pool_wrap_exception(zval *old_exception, zval *new_exception TSRMLS_DC) +{ + zend_class_entry *ce = HTTP_EX_CE(request_pool); + + /* if old_exception is already an HttpRequestPoolException append the new one, + else create a new HttpRequestPoolException and append the old and new exceptions */ + if (Z_OBJCE_P(old_exception) == ce) { + zval *exprop; + + exprop = zend_read_property(ce, old_exception, "requestExceptions", sizeof("requestExceptions")-1, 0 TSRMLS_CC); + SEP_PROP(&exprop); + convert_to_array(exprop); + + add_next_index_zval(exprop, new_exception); + zend_update_property(ce, old_exception, "requestExceptions", sizeof("requestExceptions")-1, exprop TSRMLS_CC); + zval_ptr_dtor(&exprop); + + EG(exception) = old_exception; + } else { + zval *exval, *exprop; + + MAKE_STD_ZVAL(exval); + object_init_ex(exval, ce); + MAKE_STD_ZVAL(exprop); + array_init(exprop); + + add_next_index_zval(exprop, old_exception); + add_next_index_zval(exprop, new_exception); + zend_update_property(ce, exval, "requestExceptions", sizeof("requestExceptions")-1, exprop TSRMLS_CC); + zval_ptr_dtor(&exprop); + + EG(exception) = exval; + } +} +/* }}} */ + /* {{{ static void http_request_pool_freebody(http_request_ctx **) */ static void http_request_pool_freebody(http_request_callback_ctx **body) { diff --git a/php_http_exception_object.h b/php_http_exception_object.h index 478aa25..68c462f 100644 --- a/php_http_exception_object.h +++ b/php_http_exception_object.h @@ -20,8 +20,23 @@ PHP_MINIT_FUNCTION(http_exception_object); +#define HTTP_EX_DEF_CE http_exception_object_ce +#define HTTP_EX_CE(name) http_ ##name## _exception_object_ce + extern zend_class_entry *http_exception_object_ce; extern zend_function_entry http_exception_object_fe[]; +extern zend_class_entry *HTTP_EX_CE(runtime); +extern zend_class_entry *HTTP_EX_CE(header); +extern zend_class_entry *HTTP_EX_CE(malformed_headers); +extern zend_class_entry *HTTP_EX_CE(request_method); +extern zend_class_entry *HTTP_EX_CE(message_type); +extern zend_class_entry *HTTP_EX_CE(invalid_param); +extern zend_class_entry *HTTP_EX_CE(encoding); +extern zend_class_entry *HTTP_EX_CE(request); +extern zend_class_entry *HTTP_EX_CE(request_pool); +extern zend_class_entry *HTTP_EX_CE(socket); +extern zend_class_entry *HTTP_EX_CE(response); +extern zend_class_entry *HTTP_EX_CE(url); #define http_exception_get_default _http_exception_get_default extern zend_class_entry *_http_exception_get_default(); -- 2.30.2