- move some cruft of http_request_api.c to php_http_request_int.h
authorMichael Wallner <mike@php.net>
Fri, 2 Jun 2006 19:03:45 +0000 (19:03 +0000)
committerMichael Wallner <mike@php.net>
Fri, 2 Jun 2006 19:03:45 +0000 (19:03 +0000)
- simplify exception wrapper
- check that curl is properly initialized in http_request_{enable|reset}_cookies()

12 files changed:
http.dsp
http_api.c
http_exception_object.c
http_request_api.c
http_request_object.c
http_request_pool_api.c
package2.xml
php_http_api.h
php_http_exception_object.h
php_http_request_int.h [new file with mode: 0644]
php_http_request_pool_api.h
tests/HttpRequestPool_005.phpt

index 9609ef9..a10817b 100644 (file)
--- a/http.dsp
+++ b/http.dsp
@@ -182,6 +182,10 @@ SOURCE=.\php_http_request_api.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\php_http_request_int.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\php_http_request_body_api.h\r
 # End Source File\r
 # Begin Source File\r
index a8257fa..acff118 100644 (file)
@@ -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)
 {
index 4cb0044..9074005 100644 (file)
@@ -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);
index 7bb54a8..b6d7b1e 100644 (file)
 #      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 <openssl/crypto.h>
-#      else /* !PHP_WIN32 */
-#              if defined(HTTP_HAVE_OPENSSL)
-#                      if defined(HAVE_OPENSSL_CRYPTO_H)
-#                              define HTTP_NEED_OPENSSL_TSL
-#                              include <openssl/crypto.h>
-#                      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 <gcrypt.h>
-#                      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(&copy); \
-               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;
 }
index 40e36bc..7b15faa 100644 (file)
@@ -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
index e9473e3..1c67148 100644 (file)
@@ -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 *) */
index a16f81f..41e2c4f 100644 (file)
@@ -80,6 +80,7 @@ support. Parallel requests are available for PHP 5 and greater.
    <file role="src" name="php_http_message_api.h"/>
    <file role="src" name="php_http_querystring_api.h"/>
    <file role="src" name="php_http_request_api.h"/>
+   <file role="src" name="php_http_request_int.h"/>
    <file role="src" name="php_http_request_body_api.h"/>
    <file role="src" name="php_http_request_method_api.h"/>
    <file role="src" name="php_http_request_pool_api.h"/>
index a7349b2..325378c 100644 (file)
@@ -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"); \
index 241b96c..9cf42cb 100644 (file)
@@ -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 (file)
index 0000000..5eecf9f
--- /dev/null
@@ -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 <mike@php.net>            |
+    +--------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#if defined(ZTS) && defined(HTTP_HAVE_SSL)
+#      ifdef PHP_WIN32
+#              define HTTP_NEED_OPENSSL_TSL
+#              include <openssl/crypto.h>
+#      else /* !PHP_WIN32 */
+#              if defined(HTTP_HAVE_OPENSSL)
+#                      if defined(HAVE_OPENSSL_CRYPTO_H)
+#                              define HTTP_NEED_OPENSSL_TSL
+#                              include <openssl/crypto.h>
+#                      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 <gcrypt.h>
+#                      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(&copy); \
+               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
+ */
index 79a3e4e..19d9eb8 100644 (file)
@@ -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);
index 79c3b0d..80a6c64 100644 (file)
@@ -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