From: Michael Wallner Date: Fri, 2 Jun 2006 19:03:45 +0000 (+0000) Subject: - move some cruft of http_request_api.c to php_http_request_int.h X-Git-Tag: RELEASE_1_0_0~9 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=9676c81efbb8f180fa189d71a7ecb50dde4f5646;p=m6w6%2Fext-http - move some cruft of http_request_api.c to php_http_request_int.h - simplify exception wrapper - check that curl is properly initialized in http_request_{enable|reset}_cookies() --- diff --git a/http.dsp b/http.dsp index 9609ef9..a10817b 100644 --- a/http.dsp +++ b/http.dsp @@ -182,6 +182,10 @@ SOURCE=.\php_http_request_api.h # End Source File # Begin Source File +SOURCE=.\php_http_request_int.h +# End Source File +# Begin Source File + SOURCE=.\php_http_request_body_api.h # End Source File # Begin Source File diff --git a/http_api.c b/http_api.c index a8257fa..acff118 100644 --- a/http_api.c +++ b/http_api.c @@ -96,12 +96,15 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...) va_start(args, format); #ifdef ZEND_ENGINE_2 - if ((type == E_THROW) || (PG(error_handling) == EH_THROW)) { - char *message; - - vspprintf(&message, 0, format, args); - zend_throw_exception(http_exception_get_for_code(code), message, code TSRMLS_CC); - efree(message); + if ((type == E_THROW) || (PG(error_handling) == EH_THROW)) { + char *message; + zend_class_entry *ce = http_exception_get_for_code(code); + + http_try { + vspprintf(&message, 0, format, args); + zend_throw_exception(ce, message, code TSRMLS_CC); + efree(message); + } http_catch(ce); } else #endif php_verror(NULL, "", type, format, args TSRMLS_CC); @@ -109,6 +112,41 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...) } /* }}} */ +#ifdef ZEND_ENGINE_2 +/* {{{ zval *http_exception_wrap(zval *, zval *, zend_class_entry *) */ +zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC) +{ + zval **args, **trace_0, *old_trace_0, *trace = NULL; + + /* create wrapping exception if requested */ + if (!new_exception) { + MAKE_STD_ZVAL(new_exception); + object_init_ex(new_exception, ce); + zend_update_property_string(ce, new_exception, "message", lenof("message"), "Exception caused by inner exception(s)" TSRMLS_CC); + } + + /* copy bt arguments */ + if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), old_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) { + if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) { + old_trace_0 = *trace_0; + if (Z_TYPE_PP(trace_0) == IS_ARRAY && SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) { + if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) { + if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) { + ZVAL_ADDREF(*args); + add_assoc_zval(*trace_0, "args", *args); + } + } + } + } + } + + zend_update_property(Z_OBJCE_P(new_exception), new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC); + zval_ptr_dtor(&old_exception); + return new_exception; +} +/* }}} */ +#endif /* ZEND_ENGINE_2 */ + /* {{{ void http_log(char *, char *, char *) */ void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC) { diff --git a/http_exception_object.c b/http_exception_object.c index 4cb0044..9074005 100644 --- a/http_exception_object.c +++ b/http_exception_object.c @@ -36,6 +36,9 @@ zend_class_entry *HTTP_EX_CE(querystring); PHP_MINIT_FUNCTION(http_exception_object) { HTTP_REGISTER_EXCEPTION(HttpException, http_exception_object_ce, ZEND_EXCEPTION_GET_DEFAULT()); + + zend_declare_property_null(HTTP_EX_DEF_CE, "innerException", lenof("innerException"), ZEND_ACC_PUBLIC TSRMLS_CC); + HTTP_REGISTER_EXCEPTION(HttpRuntimeException, HTTP_EX_CE(runtime), HTTP_EX_DEF_CE); HTTP_REGISTER_EXCEPTION(HttpInvalidParamException, HTTP_EX_CE(invalid_param), HTTP_EX_DEF_CE); HTTP_REGISTER_EXCEPTION(HttpHeaderException, HTTP_EX_CE(header), HTTP_EX_DEF_CE); @@ -50,8 +53,6 @@ PHP_MINIT_FUNCTION(http_exception_object) HTTP_REGISTER_EXCEPTION(HttpUrlException, HTTP_EX_CE(url), HTTP_EX_DEF_CE); HTTP_REGISTER_EXCEPTION(HttpQueryStringException, HTTP_EX_CE(querystring), HTTP_EX_DEF_CE); - zend_declare_property_null(HTTP_EX_CE(request_pool), "exceptionStack", lenof("exceptionStack"), 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); HTTP_LONG_CONSTANT("HTTP_E_HEADER", HTTP_E_HEADER); diff --git a/http_request_api.c b/http_request_api.c index 7bb54a8..b6d7b1e 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -26,41 +26,9 @@ # include "php_http_request_object.h" #endif -/* {{{ cruft for thread safe SSL crypto locks */ -#if defined(ZTS) && defined(HTTP_HAVE_SSL) -# ifdef PHP_WIN32 -# define HTTP_NEED_OPENSSL_TSL -# include -# else /* !PHP_WIN32 */ -# if defined(HTTP_HAVE_OPENSSL) -# if defined(HAVE_OPENSSL_CRYPTO_H) -# define HTTP_NEED_OPENSSL_TSL -# include -# else -# warning \ - "libcurl was compiled with OpenSSL support, but configure could not find " \ - "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \ - "cause random crashes on SSL requests" -# endif -# elif defined(HTTP_HAVE_GNUTLS) -# if defined(HAVE_GCRYPT_H) -# define HTTP_NEED_GNUTLS_TSL -# include -# else -# warning \ - "libcurl was compiled with GnuTLS support, but configure could not find " \ - "gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \ - "cause random crashes on SSL requests" -# endif -# else -# warning \ - "libcurl was compiled with SSL support, but configure could not determine which" \ - "library was used; thus no SSL crypto locking callbacks will be set, which may " \ - "cause random crashes on SSL requests" -# endif /* HTTP_HAVE_OPENSSL || HTTP_HAVE_GNUTLS */ -# endif /* PHP_WIN32 */ -#endif /* ZTS && HTTP_HAVE_SSL */ +#include "php_http_request_int.h" +/* {{{ cruft for thread safe SSL crypto locks */ #ifdef HTTP_NEED_OPENSSL_TSL static MUTEX_T *http_openssl_tsl = NULL; @@ -183,103 +151,6 @@ PHP_MSHUTDOWN_FUNCTION(http_request) } /* }}} */ -/* {{{ MACROS */ -#ifndef HAVE_CURL_EASY_STRERROR -# define curl_easy_strerror(dummy) "unknown error" -#endif - -#define HTTP_CURL_INFO(I) \ - { \ - char *N = #I; \ - HTTP_CURL_INFO_EX(I, N+lenof("CURLINFO_")); \ - } -#define HTTP_CURL_INFO_EX(I, X) \ - switch (I & ~CURLINFO_MASK) \ - { \ - case CURLINFO_STRING: \ - { \ - char *c; \ - if (CURLE_OK == curl_easy_getinfo(request->ch, I, &c)) { \ - char *key = estrndup(X, strlen(X)); \ - add_assoc_string(&array, pretty_key(key, strlen(X), 0, 0), c ? c : "", 1); \ - efree(key); \ - } \ - } \ - break; \ -\ - case CURLINFO_DOUBLE: \ - { \ - double d; \ - if (CURLE_OK == curl_easy_getinfo(request->ch, I, &d)) { \ - char *key = estrndup(X, strlen(X)); \ - add_assoc_double(&array, pretty_key(key, strlen(X), 0, 0), d); \ - efree(key); \ - } \ - } \ - break; \ -\ - case CURLINFO_LONG: \ - { \ - long l; \ - if (CURLE_OK == curl_easy_getinfo(request->ch, I, &l)) { \ - char *key = estrndup(X, strlen(X)); \ - add_assoc_long(&array, pretty_key(key, strlen(X), 0, 0), l); \ - efree(key); \ - } \ - } \ - break; \ -\ - case CURLINFO_SLIST: \ - { \ - struct curl_slist *l, *p; \ - if (CURLE_OK == curl_easy_getinfo(request->ch, I, &l)) { \ - zval *subarray; \ - char *key = estrndup(X, strlen(X)); \ - MAKE_STD_ZVAL(subarray); \ - array_init(subarray); \ - for (p = l; p; p = p->next) { \ - add_next_index_string(subarray, p->data, 1); \ - } \ - add_assoc_zval(&array, pretty_key(key, strlen(X), 0, 0), subarray); \ - curl_slist_free_all(l); \ - efree(key); \ - } \ - } \ - } - -#define HTTP_CURL_OPT(OPTION, p) HTTP_CURL_OPT_EX(request->ch, OPTION, (p)) -#define HTTP_CURL_OPT_EX(ch, OPTION, p) curl_easy_setopt((ch), OPTION, (p)) - -#define HTTP_CURL_OPT_STRING(OPTION, ldiff, obdc) \ - { \ - char *K = #OPTION; \ - HTTP_CURL_OPT_STRING_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION, obdc); \ - } -#define HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \ - if (!strcasecmp(key, keyname)) { \ - zval *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, zval_copy(IS_STRING, *param)); \ - if (obdc) { \ - HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(copy), return FAILURE); \ - } \ - HTTP_CURL_OPT(optname, Z_STRVAL_P(copy)); \ - key = NULL; \ - continue; \ - } -#define HTTP_CURL_OPT_LONG(OPTION, ldiff) \ - { \ - char *K = #OPTION; \ - HTTP_CURL_OPT_LONG_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION); \ - } -#define HTTP_CURL_OPT_LONG_EX(keyname, optname) \ - if (!strcasecmp(key, keyname)) { \ - zval *copy = zval_copy(IS_LONG, *param); \ - HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \ - key = NULL; \ - zval_free(©); \ - continue; \ - } -/* }}} */ - /* {{{ forward declarations */ #define http_request_option(r, o, k, t) _http_request_option_ex((r), (o), (k), sizeof(k), (t) TSRMLS_CC) #define http_request_option_ex(r, o, k, l, t) _http_request_option_ex((r), (o), (k), (l), (t) TSRMLS_CC) @@ -423,8 +294,12 @@ PHP_HTTP_API void _http_request_reset(http_request *request) /* {{{ STATUS http_request_enable_cookies(http_request *) */ PHP_HTTP_API STATUS _http_request_enable_cookies(http_request *request) { + int initialized = 1; TSRMLS_FETCH_FROM_CTX(request->tsrm_ls); - if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, "")) { + + HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0); + if (initialized) { + curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, ""); return SUCCESS; } http_error(HE_WARNING, HTTP_E_REQUEST, "Could not enable cookies for this session"); @@ -435,22 +310,26 @@ PHP_HTTP_API STATUS _http_request_enable_cookies(http_request *request) /* {{{ STATUS http_request_reset_cookies(http_request *, int) */ PHP_HTTP_API STATUS _http_request_reset_cookies(http_request *request, int session_only) { + int initialized = 1; TSRMLS_FETCH_FROM_CTX(request->tsrm_ls); + HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0); if (session_only) { #if HTTP_CURL_VERSION(7,15,4) - curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS"); - return SUCCESS; -#else - http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset session cookies (need libcurl >= v7.15.4)"); + if (initialized) { + curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS"); + return SUCCESS; + } #endif + http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset session cookies (need libcurl >= v7.15.4)"); } else { #if HTTP_CURL_VERSION(7,14,1) - curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL"); - return SUCCESS; -#else - http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset cookies (need libcurl >= v7.14.1)"); + if (initialized) { + curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL"); + return SUCCESS; + } #endif + http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset cookies (need libcurl >= v7.14.1)"); } return FAILURE; } diff --git a/http_request_object.c b/http_request_object.c index 40e36bc..7b15faa 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -325,7 +325,7 @@ zend_function_entry http_request_object_fe[] = { HTTP_REQUEST_ALIAS(methodUnregister, http_request_method_unregister) HTTP_REQUEST_ALIAS(methodName, http_request_method_name) HTTP_REQUEST_ALIAS(methodExists, http_request_method_exists) -#if HAVE_CURL_GETFORMDATA +#ifdef HAVE_CURL_GETFORMDATA HTTP_REQUEST_ALIAS(encodeBody, http_request_body_encode) #endif EMPTY_FUNCTION_ENTRY diff --git a/http_request_pool_api.c b/http_request_pool_api.c index e9473e3..1c67148 100644 --- a/http_request_pool_api.c +++ b/http_request_pool_api.c @@ -284,69 +284,6 @@ void _http_request_pool_responsehandler(zval **req, CURL *ch TSRMLS_DC) } /* }}} */ -static void move_backtrace_args(zval *from, zval *to TSRMLS_DC) -{ - zval **args, **trace_0, *old_trace_0, *trace = NULL; - - if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), from, "trace", lenof("trace"), 0 TSRMLS_CC))) { - if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) { - old_trace_0 = *trace_0; - if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) { - if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), to, "trace", lenof("trace"), 0 TSRMLS_CC))) { - if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) { - ZVAL_ADDREF(*args); - add_assoc_zval(*trace_0, "args", *args); - zend_hash_del(Z_ARRVAL_P(old_trace_0), "args", sizeof("args")); - } - } - } - } - } -} -/* {{{ void http_request_pool_wrap_exception(zval *, zval *) */ -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 (old_exception && Z_OBJCE_P(old_exception) == ce) { - zval *old_exprop, *new_exprop; - - MAKE_STD_ZVAL(new_exprop); - array_init(new_exprop); - old_exprop = zend_read_property(ce, old_exception, "exceptionStack", lenof("exceptionStack"), 0 TSRMLS_CC); - if (Z_TYPE_P(old_exprop) == IS_ARRAY) { - array_copy(old_exprop, new_exprop); - } - add_next_index_zval(new_exprop, new_exception); - zend_update_property(ce, old_exception, "exceptionStack", lenof("exceptionStack"), new_exprop TSRMLS_CC); - zval_ptr_dtor(&new_exprop); - - EG(exception) = old_exception; - } else if (new_exception && Z_OBJCE_P(new_exception) != ce){ - zval *exval, *exprop; - - MAKE_STD_ZVAL(exval); - object_init_ex(exval, ce); - MAKE_STD_ZVAL(exprop); - array_init(exprop); - - if (old_exception) { - add_next_index_zval(exprop, old_exception); - } - move_backtrace_args(new_exception, exval TSRMLS_CC); - zend_update_property_long(ce, exval, "code", lenof("code"), HTTP_E_REQUEST_POOL TSRMLS_CC); - zend_update_property_string(ce, exval, "message", lenof("message"), "See exceptionStack property" TSRMLS_CC); - add_next_index_zval(exprop, new_exception); - zend_update_property(ce, exval, "exceptionStack", lenof("exceptionStack"), exprop TSRMLS_CC); - zval_ptr_dtor(&exprop); - - EG(exception) = exval; - } -} -/* }}} */ - /*#*/ /* {{{ static int http_request_pool_compare_handles(void *, void *) */ diff --git a/package2.xml b/package2.xml index a16f81f..41e2c4f 100644 --- a/package2.xml +++ b/package2.xml @@ -80,6 +80,7 @@ support. Parallel requests are available for PHP 5 and greater. + diff --git a/php_http_api.h b/php_http_api.h index a7349b2..325378c 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -38,6 +38,29 @@ extern char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend #define http_error_ex _http_error_ex extern void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...); + +#ifdef ZEND_ENGINE_2 +#define http_exception_wrap(o, n, ce) _http_exception_wrap((o), (n), (ce) TSRMLS_CC) +extern zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC); + +#define http_try \ +{ \ + zval *old_exception = EG(exception); \ + EG(exception) = NULL; +#define http_catch(ex_ce) \ + if (EG(exception) && old_exception) { \ + EG(exception) = http_exception_wrap(old_exception, EG(exception), ex_ce); \ + } \ +} +#define http_final(ex_ce) \ + if (EG(exception)) { \ + zval *exception = http_exception_wrap(EG(exception), NULL, ex_ce); \ + EG(exception) = NULL; \ + zend_throw_exception_object(exception TSRMLS_CC); \ + } +#endif /* ZEND_ENGINE_2 */ + + #define HTTP_CHECK_CURL_INIT(ch, init, action) \ if ((!(ch)) && (!((ch) = init))) { \ http_error(HE_WARNING, HTTP_E_REQUEST, "Could not initialize curl"); \ diff --git a/php_http_exception_object.h b/php_http_exception_object.h index 241b96c..9cf42cb 100644 --- a/php_http_exception_object.h +++ b/php_http_exception_object.h @@ -24,7 +24,6 @@ PHP_MINIT_FUNCTION(http_exception_object); #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); @@ -37,6 +36,7 @@ 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); +extern zend_function_entry http_exception_object_fe[]; #define http_exception_get_default _http_exception_get_default extern zend_class_entry *_http_exception_get_default(); diff --git a/php_http_request_int.h b/php_http_request_int.h new file mode 100644 index 0000000..5eecf9f --- /dev/null +++ b/php_http_request_int.h @@ -0,0 +1,151 @@ +/* + +--------------------------------------------------------------------+ + | 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-2006, Michael Wallner | + +--------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#if defined(ZTS) && defined(HTTP_HAVE_SSL) +# ifdef PHP_WIN32 +# define HTTP_NEED_OPENSSL_TSL +# include +# else /* !PHP_WIN32 */ +# if defined(HTTP_HAVE_OPENSSL) +# if defined(HAVE_OPENSSL_CRYPTO_H) +# define HTTP_NEED_OPENSSL_TSL +# include +# else +# warning \ + "libcurl was compiled with OpenSSL support, but configure could not find " \ + "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif +# elif defined(HTTP_HAVE_GNUTLS) +# if defined(HAVE_GCRYPT_H) +# define HTTP_NEED_GNUTLS_TSL +# include +# else +# warning \ + "libcurl was compiled with GnuTLS support, but configure could not find " \ + "gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif +# else +# warning \ + "libcurl was compiled with SSL support, but configure could not determine which" \ + "library was used; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif /* HTTP_HAVE_OPENSSL || HTTP_HAVE_GNUTLS */ +# endif /* PHP_WIN32 */ +#endif /* ZTS && HTTP_HAVE_SSL */ + +#ifndef HAVE_CURL_EASY_STRERROR +# define curl_easy_strerror(dummy) "unknown error" +#endif + +#define HTTP_CURL_INFO(I) \ + { \ + char *N = #I; \ + HTTP_CURL_INFO_EX(I, N+lenof("CURLINFO_")); \ + } +#define HTTP_CURL_INFO_EX(I, X) \ + switch (I & ~CURLINFO_MASK) \ + { \ + case CURLINFO_STRING: \ + { \ + char *c; \ + if (CURLE_OK == curl_easy_getinfo(request->ch, I, &c)) { \ + char *key = estrndup(X, strlen(X)); \ + add_assoc_string(&array, pretty_key(key, strlen(X), 0, 0), c ? c : "", 1); \ + efree(key); \ + } \ + } \ + break; \ +\ + case CURLINFO_DOUBLE: \ + { \ + double d; \ + if (CURLE_OK == curl_easy_getinfo(request->ch, I, &d)) { \ + char *key = estrndup(X, strlen(X)); \ + add_assoc_double(&array, pretty_key(key, strlen(X), 0, 0), d); \ + efree(key); \ + } \ + } \ + break; \ +\ + case CURLINFO_LONG: \ + { \ + long l; \ + if (CURLE_OK == curl_easy_getinfo(request->ch, I, &l)) { \ + char *key = estrndup(X, strlen(X)); \ + add_assoc_long(&array, pretty_key(key, strlen(X), 0, 0), l); \ + efree(key); \ + } \ + } \ + break; \ +\ + case CURLINFO_SLIST: \ + { \ + struct curl_slist *l, *p; \ + if (CURLE_OK == curl_easy_getinfo(request->ch, I, &l)) { \ + zval *subarray; \ + char *key = estrndup(X, strlen(X)); \ + MAKE_STD_ZVAL(subarray); \ + array_init(subarray); \ + for (p = l; p; p = p->next) { \ + add_next_index_string(subarray, p->data, 1); \ + } \ + add_assoc_zval(&array, pretty_key(key, strlen(X), 0, 0), subarray); \ + curl_slist_free_all(l); \ + efree(key); \ + } \ + } \ + } + +#define HTTP_CURL_OPT(OPTION, p) HTTP_CURL_OPT_EX(request->ch, OPTION, (p)) +#define HTTP_CURL_OPT_EX(ch, OPTION, p) curl_easy_setopt((ch), OPTION, (p)) + +#define HTTP_CURL_OPT_STRING(OPTION, ldiff, obdc) \ + { \ + char *K = #OPTION; \ + HTTP_CURL_OPT_STRING_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION, obdc); \ + } +#define HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \ + if (!strcasecmp(key, keyname)) { \ + zval *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, zval_copy(IS_STRING, *param)); \ + if (obdc) { \ + HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(copy), return FAILURE); \ + } \ + HTTP_CURL_OPT(optname, Z_STRVAL_P(copy)); \ + key = NULL; \ + continue; \ + } +#define HTTP_CURL_OPT_LONG(OPTION, ldiff) \ + { \ + char *K = #OPTION; \ + HTTP_CURL_OPT_LONG_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION); \ + } +#define HTTP_CURL_OPT_LONG_EX(keyname, optname) \ + if (!strcasecmp(key, keyname)) { \ + zval *copy = zval_copy(IS_LONG, *param); \ + HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \ + key = NULL; \ + zval_free(©); \ + continue; \ + } + +/* + * 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_request_pool_api.h b/php_http_request_pool_api.h index 79a3e4e..19d9eb8 100644 --- a/php_http_request_pool_api.h +++ b/php_http_request_pool_api.h @@ -26,29 +26,9 @@ typedef struct _http_request_pool_t { #define http_request_pool_responsehandler _http_request_pool_responsehandler extern void _http_request_pool_responsehandler(zval **req, CURL *ch TSRMLS_DC); -#define http_request_pool_try \ - { \ - zval *old_exception = EG(exception); \ - EG(exception) = NULL; -#define http_request_pool_catch() \ - if (EG(exception)) { \ - http_request_pool_wrap_exception(old_exception, EG(exception)); \ - } else { \ - EG(exception) = old_exception; \ - } \ - } -#define http_request_pool_final() \ - if (EG(exception)) { \ - zval *exception; \ - http_request_pool_wrap_exception(NULL, EG(exception)); \ - exception = EG(exception); \ - EG(exception) = NULL; \ - zend_throw_exception_object(exception TSRMLS_CC); \ - } - -#define http_request_pool_wrap_exception(o, n) _http_request_pool_wrap_exception((o), (n) TSRMLS_CC) -extern void _http_request_pool_wrap_exception(zval *old_exception, zval *new_exception TSRMLS_DC); - +#define http_request_pool_try http_try +#define http_request_pool_catch() http_catch(HTTP_EX_CE(request_pool)) +#define http_request_pool_final() http_final(HTTP_EX_CE(request_pool)) #define http_request_pool_init(p) _http_request_pool_init((p) TSRMLS_CC) PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool TSRMLS_DC); diff --git a/tests/HttpRequestPool_005.phpt b/tests/HttpRequestPool_005.phpt index 79c3b0d..80a6c64 100644 --- a/tests/HttpRequestPool_005.phpt +++ b/tests/HttpRequestPool_005.phpt @@ -14,19 +14,33 @@ $p = new HttpRequestPool(new HttpRequest('http://_____')); try { $p->send(); } catch (HttpRequestPoolException $x) { - var_dump(count($x->exceptionStack)); + for ($i=0; $x; ++$i, $x = @$x->innerException) { + printf("%s%s: %s\n", str_repeat("\t", $i), get_class($x), $x->getMessage()); + } + var_dump($i); } $p = new HttpRequestPool(new HttpRequest('http://_____'), new HttpRequest('http://_____')); try { $p->send(); } catch (HttpRequestPoolException $x) { - var_dump(count($x->exceptionStack)); + for ($i=0; $x; ++$i, $x = @$x->innerException) { + printf("%s%s: %s\n", str_repeat("\t", $i), get_class($x), $x->getMessage()); + } + var_dump($i); } echo "Done\n"; ?> --EXPECTF-- %sTEST -int(2) -int(4) +HttpRequestPoolException: Exception caused by inner exception(s) + HttpInvalidParamException: Empty or too short HTTP message: '' + HttpRequestException: couldn't resolve host name; Couldn't resolve host '_____' (http://_____/) +int(3) +HttpRequestPoolException: Exception caused by inner exception(s) + HttpInvalidParamException: Empty or too short HTTP message: '' + HttpRequestException: couldn't resolve host name; Couldn't resolve host '_____' (http://_____/) + HttpInvalidParamException: Empty or too short HTTP message: '' + HttpRequestException: couldn't resolve host name; Couldn't resolve host '_____' (http://_____/) +int(5) Done