* use the resource factory
authorMichael Wallner <mike@php.net>
Sat, 21 May 2011 15:46:12 +0000 (15:46 +0000)
committerMichael Wallner <mike@php.net>
Sat, 21 May 2011 15:46:12 +0000 (15:46 +0000)
* use the separator where applicable

15 files changed:
config9.m4
php_http_curl.c
php_http_curl.h
php_http_encoding.c
php_http_neon.c
php_http_neon.h
php_http_persistent_handle.c
php_http_persistent_handle.h
php_http_request.c
php_http_request.h
php_http_request_datashare.c
php_http_request_datashare.h
php_http_request_factory.c
php_http_request_pool.c
php_http_request_pool.h

index c59c53f..c4486df 100644 (file)
@@ -444,6 +444,7 @@ dnl ----
                php_http_negotiate.c \
                php_http_object.c \
                php_http_params.c \
+               php_http_resource_factory.c \
                php_http_persistent_handle.c \
                php_http_property_proxy.c \
                php_http_querystring.c \
@@ -486,6 +487,7 @@ dnl ----
                php_http_negotiate.h \
                php_http_object.h \
                php_http_params.h \
+               php_http_resource_factory.h \
                php_http_persistent_handle.h \
                php_http_property_proxy.h \
                php_http_querystring.h \
index 307d488..71365dc 100644 (file)
@@ -76,7 +76,7 @@ typedef struct php_http_curl_request_datashare {
        }
 #define PHP_HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \
        if (!strcasecmp(key.str, keyname)) { \
-               zval *copy = cache_option(&curl->options.cache, keyname, strlen(keyname)+1, 0, php_http_zsep(IS_STRING, *param)); \
+               zval *copy = cache_option(&curl->options.cache, keyname, strlen(keyname)+1, 0, php_http_ztyp(IS_STRING, *param)); \
                if (obdc) { \
                        if (SUCCESS != php_check_open_basedir(Z_STRVAL_P(copy) TSRMLS_CC)) { \
                                return FAILURE; \
@@ -93,7 +93,7 @@ typedef struct php_http_curl_request_datashare {
        }
 #define PHP_HTTP_CURL_OPT_LONG_EX(keyname, optname) \
        if (!strcasecmp(key.str, keyname)) { \
-               zval *copy = php_http_zsep(IS_LONG, *param); \
+               zval *copy = php_http_ztyp(IS_LONG, *param); \
                curl_easy_setopt(ch, optname, Z_LVAL_P(copy)); \
                zval_ptr_dtor(&copy); \
                continue; \
@@ -113,6 +113,69 @@ static inline php_http_curl_request_storage_t *get_storage(CURL *ch) {
        return st;
 }
 
+/* resource_factory ops */
+
+static void *php_http_curl_ctor(void *opaque TSRMLS_DC)
+{
+       void *ch;
+
+       if ((ch = curl_easy_init())) {
+               get_storage(ch);
+               return ch;
+       }
+       return NULL;
+}
+
+static void *php_http_curl_copy(void *opaque, void *handle TSRMLS_DC)
+{
+       void *ch;
+
+       if ((ch = curl_easy_duphandle(handle))) {
+               get_storage(ch);
+               return ch;
+       }
+       return NULL;
+}
+
+static void php_http_curl_dtor(void *opaque, void *handle TSRMLS_DC)
+{
+       php_http_curl_request_storage_t *st = get_storage(handle);
+
+       curl_easy_cleanup(handle);
+
+       if (st) {
+               if (st->url) {
+                       pefree(st->url, 1);
+               }
+               if (st->cookiestore) {
+                       pefree(st->cookiestore, 1);
+               }
+               pefree(st, 1);
+       }
+}
+
+static void *php_http_curlm_ctor(void *opaque TSRMLS_DC)
+{
+       return curl_multi_init();
+}
+
+static void php_http_curlm_dtor(void *opaque, void *handle TSRMLS_DC)
+{
+       curl_multi_cleanup(handle);
+}
+
+static void *php_http_curlsh_ctor(void *opaque TSRMLS_DC)
+{
+       return curl_share_init();
+}
+
+static void php_http_curlsh_dtor(void *opaque, void *handle TSRMLS_DC)
+{
+       curl_share_cleanup(handle);
+}
+
+/* callbacks */
+
 static size_t php_http_curl_read_callback(void *data, size_t len, size_t n, void *ctx)
 {
        php_http_message_body_t *body = ctx;
@@ -165,6 +228,35 @@ static int php_http_curl_raw_callback(CURL *ch, curl_infotype type, char *data,
        php_http_curl_request_t *curl = h->ctx;
        unsigned flags = 0;
 
+       /* catch progress */
+       switch (type) {
+               case CURLINFO_TEXT:
+                       if (php_memnstr(data, ZEND_STRL("About to connect"), data + length)) {
+                               curl->progress.state.info = "resolve";
+                       } else if (php_memnstr(data, ZEND_STRL("Trying"), data + length)) {
+                               curl->progress.state.info = "connect";
+                       } else if (php_memnstr(data, ZEND_STRL("Connected"), data + length)) {
+                               curl->progress.state.info = "connected";
+                       } else if (php_memnstr(data, ZEND_STRL("left intact"), data + length)) {
+                               curl->progress.state.info = "not disconnected";
+                       } else if (php_memnstr(data, ZEND_STRL("closed"), data + length)) {
+                               curl->progress.state.info = "disconnected";
+                       }
+                       php_http_request_progress_notify(&curl->progress TSRMLS_CC);
+                       break;
+               case CURLINFO_HEADER_OUT:
+               case CURLINFO_DATA_OUT:
+               case CURLINFO_SSL_DATA_OUT:
+                       curl->progress.state.info = "send";
+                       break;
+               case CURLINFO_HEADER_IN:
+               case CURLINFO_DATA_IN:
+               case CURLINFO_SSL_DATA_IN:
+                       curl->progress.state.info = "receive";
+                       break;
+               default:
+                       break;
+       }
        /* process data */
        switch (type) {
                case CURLINFO_HEADER_IN:
@@ -478,7 +570,7 @@ static inline zval *get_option(HashTable *cache, HashTable *options, char *key,
                ulong h = zend_hash_func(key, keylen);
 
                if (SUCCESS == zend_hash_quick_find(options, key, keylen, h, (void *) &zoption)) {
-                       zval *option = php_http_zsep(type, *zoption);
+                       zval *option = php_http_ztyp(type, *zoption);
 
                        if (cache) {
                                zval *cached = cache_option(cache, key, keylen, h, option);
@@ -575,8 +667,8 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                        if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void *) &prs)) {
                                zend_hash_move_forward(Z_ARRVAL_P(zoption));
                                if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void *) &pre)) {
-                                       zval *prs_cpy = php_http_zsep(IS_LONG, *prs);
-                                       zval *pre_cpy = php_http_zsep(IS_LONG, *pre);
+                                       zval *prs_cpy = php_http_ztyp(IS_LONG, *prs);
+                                       zval *pre_cpy = php_http_ztyp(IS_LONG, *pre);
 
                                        if (Z_LVAL_P(prs_cpy) && Z_LVAL_P(pre_cpy)) {
                                                curl_easy_setopt(ch, CURLOPT_LOCALPORT, MIN(Z_LVAL_P(prs_cpy), Z_LVAL_P(pre_cpy)));
@@ -674,8 +766,8 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                                        if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(rr), (void *) &re, &pos2)) {
                                                if (    ((Z_TYPE_PP(rb) == IS_LONG) || ((Z_TYPE_PP(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(rb), Z_STRLEN_PP(rb), NULL, NULL, 1))) &&
                                                                ((Z_TYPE_PP(re) == IS_LONG) || ((Z_TYPE_PP(re) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(re), Z_STRLEN_PP(re), NULL, NULL, 1)))) {
-                                                       zval *rbl = php_http_zsep(IS_LONG, *rb);
-                                                       zval *rel = php_http_zsep(IS_LONG, *re);
+                                                       zval *rbl = php_http_ztyp(IS_LONG, *rb);
+                                                       zval *rel = php_http_ztyp(IS_LONG, *re);
 
                                                        if ((Z_LVAL_P(rbl) >= 0) && (Z_LVAL_P(rel) >= 0)) {
                                                                php_http_buffer_appendf(&rs, "%ld-%ld,", Z_LVAL_P(rbl), Z_LVAL_P(rel));
@@ -715,7 +807,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                php_http_buffer_init(&header);
                FOREACH_KEYVAL(pos, zoption, header_key, header_val) {
                        if (header_key.type == HASH_KEY_IS_STRING) {
-                               zval *header_cpy = php_http_zsep(IS_STRING, *header_val);
+                               zval *header_cpy = php_http_ztyp(IS_STRING, *header_val);
 
                                if (!strcasecmp(header_key.str, "range")) {
                                        range_req = 1;
@@ -780,7 +872,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                                FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) {
                                        if (cookie_key.type == HASH_KEY_IS_STRING) {
-                                               zval *val = php_http_zsep(IS_STRING, *cookie_val);
+                                               zval *val = php_http_ztyp(IS_STRING, *cookie_val);
                                                php_http_buffer_appendf(&curl->options.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val));
                                                zval_ptr_dtor(&val);
                                        }
@@ -1099,7 +1191,8 @@ static php_http_request_datashare_t *php_http_curl_request_datashare_init(php_ht
 {
        php_http_curl_request_datashare_t *curl;
 
-       if (!handle && (SUCCESS != php_http_persistent_handle_acquire(ZEND_STRL("http_request_datashare.curl"), &handle TSRMLS_CC))) {
+       if (!handle && !(handle = php_http_resource_factory_handle_ctor(h->rf TSRMLS_CC))) {
+               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_DATASHARE, "could not initialize curl share handle");
                return NULL;
        }
 
@@ -1107,7 +1200,8 @@ static php_http_request_datashare_t *php_http_curl_request_datashare_init(php_ht
        curl->handle = handle;
 #ifdef ZTS
        if (h->persistent) {
-               if (SUCCESS == php_http_persistent_handle_acquire(ZEND_STRL("http_request_datashare_lock.curl"), (void *) &curl->locks)) {
+               curl->locks = php_http_request_datashare_locks_init();
+               if (curl->locks) {
                        curl_share_setopt(share->ch, CURLSHOPT_LOCKFUNC, php_http_curl_request_datashare_lock_func);
                        curl_share_setopt(share->ch, CURLSHOPT_UNLOCKFUNC, php_http_curl_request_datashare_unlock_func);
                        curl_share_setopt(share->ch, CURLSHOPT_USERDATA, curl->locks);
@@ -1124,14 +1218,16 @@ static void php_http_curl_request_datashare_dtor(php_http_request_datashare_t *h
        php_http_curl_request_datashare_t *curl = h->ctx;
        TSRMLS_FETCH_FROM_CTX(h->ts);
 
-       php_http_persistent_handle_release(ZEND_STRL("http_request_datashare.curl"), &curl->handle TSRMLS_CC);
+       php_http_resource_factory_handle_dtor(h->rf, curl->handle TSRMLS_CC);
 
 #ifdef ZTS
        if (h->persistent) {
-               php_http_persistent_handle_release(ZEND_STRL("http_request_datashare_lock.curl"), (void *) &curl->locks TSRMLS_CC);
+               http_request_datashare_locks_dtor(curl->locks);
        }
 #endif
 
+       pefree(curl, h->persistent);
+       h->ctx = NULL;
 }
 
 static STATUS php_http_curl_request_datashare_attach(php_http_request_datashare_t *h, php_http_request_t *r)
@@ -1193,7 +1289,14 @@ static STATUS php_http_curl_request_datashare_setopt(php_http_request_datashare_
        return SUCCESS;
 }
 
+static php_http_resource_factory_ops_t php_http_curlsh_resource_factory_ops = {
+       php_http_curlsh_ctor,
+       NULL,
+       php_http_curlsh_dtor
+};
+
 static php_http_request_datashare_ops_t php_http_curl_request_datashare_ops = {
+               &php_http_curlsh_resource_factory_ops,
                php_http_curl_request_datashare_init,
                NULL /* copy */,
                php_http_curl_request_datashare_dtor,
@@ -1215,7 +1318,8 @@ static php_http_request_pool_t *php_http_curl_request_pool_init(php_http_request
 {
        php_http_curl_request_pool_t *curl;
 
-       if (!handle && (SUCCESS != php_http_persistent_handle_acquire(ZEND_STRL("http_request_pool.curl"), &handle TSRMLS_CC))) {
+       if (!handle && !(handle = php_http_resource_factory_handle_ctor(h->rf TSRMLS_CC))) {
+               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_POOL, "could not initialize curl pool handle");
                return NULL;
        }
 
@@ -1240,7 +1344,8 @@ static void php_http_curl_request_pool_dtor(php_http_request_pool_t *h)
 #endif
        curl->unfinished = 0;
        php_http_request_pool_reset(h);
-       php_http_persistent_handle_release(ZEND_STRL("http_request_pool.curl"), &curl->handle TSRMLS_CC);
+
+       php_http_resource_factory_handle_dtor(h->rf, curl->handle);
 
        efree(curl);
        h->ctx = NULL;
@@ -1349,14 +1454,16 @@ static int php_http_curl_request_pool_once(php_http_request_pool_t *h)
        return curl->unfinished;
 
 }
+#ifdef PHP_HTTP_HAVE_EVENT
 static void dolog(int i, const char *m) {
        fprintf(stderr, "%d: %s\n", i, m);
 }
+#endif
 static STATUS php_http_curl_request_pool_exec(php_http_request_pool_t *h)
 {
+#ifdef PHP_HTTP_HAVE_EVENT
        php_http_curl_request_pool_t *curl = h->ctx;
 
-#ifdef PHP_HTTP_HAVE_EVENT
        if (curl->useevents) {
                event_set_log_callback(dolog);
                do {
@@ -1420,7 +1527,14 @@ static STATUS php_http_curl_request_pool_setopt(php_http_request_pool_t *h, php_
        return SUCCESS;
 }
 
+static php_http_resource_factory_ops_t php_http_curlm_resource_factory_ops = {
+       php_http_curlm_ctor,
+       NULL,
+       php_http_curlm_dtor
+};
+
 static php_http_request_pool_ops_t php_http_curl_request_pool_ops = {
+               &php_http_curlm_resource_factory_ops,
                php_http_curl_request_pool_init,
                NULL /* copy */,
                php_http_curl_request_pool_dtor,
@@ -1447,7 +1561,8 @@ static php_http_request_t *php_http_curl_request_init(php_http_request_t *h, voi
        php_http_curl_request_t *ctx;
        TSRMLS_FETCH_FROM_CTX(h->ts);
 
-       if (!handle && (SUCCESS != php_http_persistent_handle_acquire(ZEND_STRL("http_request.curl"), &handle TSRMLS_CC))) {
+       if (!handle && !(handle = php_http_resource_factory_handle_ctor(h->rf TSRMLS_CC))) {
+               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "could not initialize curl handle");
                return NULL;
        }
 
@@ -1485,14 +1600,14 @@ static php_http_request_t *php_http_curl_request_copy(php_http_request_t *from,
        void *copy;
        TSRMLS_FETCH_FROM_CTX(from->ts);
 
-       if (SUCCESS != php_http_persistent_handle_accrete(ZEND_STRL("http_request.curl"), ctx->handle, &copy TSRMLS_CC)) {
+       if (!(copy = php_http_resource_factory_handle_copy(from->rf, ctx->handle TSRMLS_CC))) {
                return NULL;
        }
 
        if (to) {
                return php_http_curl_request_init(to, copy);
        } else {
-               return php_http_request_init(NULL, from->ops, copy TSRMLS_CC);
+               return php_http_request_init(NULL, from->ops, from->rf, copy TSRMLS_CC);
        }
 }
 
@@ -1505,7 +1620,7 @@ static void php_http_curl_request_dtor(php_http_request_t *h)
        curl_easy_setopt(ctx->handle, CURLOPT_VERBOSE, 0L);
        curl_easy_setopt(ctx->handle, CURLOPT_DEBUGFUNCTION, NULL);
 
-       php_http_persistent_handle_release(ZEND_STRL("http_request.curl"), &ctx->handle TSRMLS_CC);
+       php_http_resource_factory_handle_dtor(h->rf, ctx->handle TSRMLS_CC);
 
        php_http_buffer_dtor(&ctx->options.cookies);
        zend_hash_destroy(&ctx->options.cache);
@@ -1514,11 +1629,7 @@ static void php_http_curl_request_dtor(php_http_request_t *h)
                curl_slist_free_all(ctx->options.headers);
                ctx->options.headers = NULL;
        }
-
-       if (ctx->progress.callback) {
-               zval_ptr_dtor(&ctx->progress.callback);
-               ctx->progress.callback = NULL;
-       }
+       php_http_request_progress_dtor(&ctx->progress);
 
        efree(ctx);
        h->ctx = NULL;
@@ -1714,19 +1825,12 @@ static STATUS php_http_curl_request_setopt(php_http_request_t *h, php_http_reque
                                php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "Cannot change progress callback while executing it");
                                return FAILURE;
                        }
-                       if (arg) {
-                               Z_ADDREF_P(arg);
-                       }
                        if (curl->progress.callback) {
-                               zval_ptr_dtor(&curl->progress.callback);
+                               php_http_request_progress_dtor(&curl->progress TSRMLS_CC);
                        }
                        curl->progress.callback = arg;
                        break;
 
-               case PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK_WANTS_STATE:
-                       curl->progress.pass_state = *((int *)arg);
-                       break;
-
                case PHP_HTTP_REQUEST_OPT_COOKIES_ENABLE:
                        /* are cookies already enabled anyway? */
                        if (!get_storage(curl->handle)->cookiestore) {
@@ -1781,7 +1885,14 @@ static STATUS php_http_curl_request_getopt(php_http_request_t *h, php_http_reque
        return SUCCESS;
 }
 
+static php_http_resource_factory_ops_t php_http_curl_resource_factory_ops = {
+       php_http_curl_ctor,
+       php_http_curl_copy,
+       php_http_curl_dtor
+};
+
 static php_http_request_ops_t php_http_curl_request_ops = {
+       &php_http_curl_resource_factory_ops,
        php_http_curl_request_init,
        php_http_curl_request_copy,
        php_http_curl_request_dtor,
@@ -1796,45 +1907,6 @@ PHP_HTTP_API php_http_request_ops_t *php_http_curl_get_request_ops(void)
        return &php_http_curl_request_ops;
 }
 
-/* safe curl wrappers */
-static void *safe_curl_init(void)
-{
-       void *ch;
-
-       if ((ch = curl_easy_init())) {
-               get_storage(ch);
-               return ch;
-       }
-       return NULL;
-}
-
-static void *safe_curl_copy(void *p)
-{
-       void *ch;
-
-       if ((ch = curl_easy_duphandle(p))) {
-               get_storage(ch);
-               return ch;
-       }
-       return NULL;
-}
-
-static void safe_curl_dtor(void *p) {
-       php_http_curl_request_storage_t *st = get_storage(p);
-
-       curl_easy_cleanup(p);
-
-       if (st) {
-               if (st->url) {
-                       pefree(st->url, 1);
-               }
-               if (st->cookiestore) {
-                       pefree(st->cookiestore, 1);
-               }
-               pefree(st, 1);
-       }
-}
-
 #if defined(ZTS) && defined(PHP_HTTP_HAVE_SSL)
 #      ifdef PHP_WIN32
 #              define PHP_HTTP_NEED_OPENSSL_TSL
@@ -1909,7 +1981,23 @@ static struct gcry_thread_cbs php_http_gnutls_tsl = {
 };
 #endif
 
+#define PHP_HTTP_BEGIN_ARGS(method, req_args)  PHP_HTTP_BEGIN_ARGS_EX(HttpCURL, method, 0, req_args)
+#define PHP_HTTP_EMPTY_ARGS(method)                            PHP_HTTP_EMPTY_ARGS_EX(HttpCURL, method, 0)
+#define PHP_HTTP_CURL_ME(method, visibility)   PHP_ME(HttpCURL, method, PHP_HTTP_ARGS(HttpCURL, method), visibility)
+#define PHP_HTTP_CURL_ALIAS(method, func)      PHP_HTTP_STATIC_ME_ALIAS(method, func, PHP_HTTP_ARGS(HttpCURL, method))
+#define PHP_HTTP_CURL_MALIAS(me, al, vis)      ZEND_FENTRY(me, ZEND_MN(HttpCURL_##al), PHP_HTTP_ARGS(HttpCURL, al), vis)
+
+PHP_HTTP_EMPTY_ARGS(__construct);
 
+zend_class_entry *php_http_curl_class_entry;
+zend_function_entry php_http_curl_method_entry[] = {
+       PHP_HTTP_CURL_ME(__construct, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+
+       EMPTY_FUNCTION_ENTRY
+};
+
+PHP_METHOD(HttpCURL, __construct) {
+}
 
 PHP_MINIT_FUNCTION(http_curl)
 {
@@ -1942,15 +2030,15 @@ PHP_MINIT_FUNCTION(http_curl)
                return FAILURE;
        }
 
-       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request_datashare.curl"), curl_share_init, (php_http_persistent_handle_dtor_t) curl_share_cleanup, NULL TSRMLS_CC)) {
+       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request_datashare.curl"), &php_http_curlsh_resource_factory_ops, NULL, NULL)) {
                return FAILURE;
        }
 
-       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request_pool.curl"), curl_multi_init, (php_http_persistent_handle_dtor_t) curl_multi_cleanup, NULL TSRMLS_CC)) {
+       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request_pool.curl"), &php_http_curlm_resource_factory_ops, NULL, NULL)) {
                return FAILURE;
        }
 
-       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request.curl"), safe_curl_init, safe_curl_dtor, safe_curl_copy)) {
+       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request.curl"), &php_http_curl_resource_factory_ops, NULL, NULL)) {
                return FAILURE;
        }
 
@@ -1958,60 +2046,62 @@ PHP_MINIT_FUNCTION(http_curl)
                return FAILURE;
        }
 
+       PHP_HTTP_REGISTER_CLASS(http, CURL, http_curl, php_http_curl_class_entry, 0);
+
        /*
        * HTTP Protocol Version Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("VERSION_1_0"), CURL_HTTP_VERSION_1_0 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("VERSION_1_1"), CURL_HTTP_VERSION_1_1 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("VERSION_NONE"), CURL_HTTP_VERSION_NONE TSRMLS_CC); /* to be removed */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("VERSION_ANY"), CURL_HTTP_VERSION_NONE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("HTTP_VERSION_1_0"), CURL_HTTP_VERSION_1_0 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("HTTP_VERSION_1_1"), CURL_HTTP_VERSION_1_1 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("HTTP_VERSION_NONE"), CURL_HTTP_VERSION_NONE TSRMLS_CC); /* to be removed */
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("HTTP_VERSION_ANY"), CURL_HTTP_VERSION_NONE TSRMLS_CC);
 
        /*
        * SSL Version Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("SSL_VERSION_TLSv1"), CURL_SSLVERSION_TLSv1 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("SSL_VERSION_SSLv2"), CURL_SSLVERSION_SSLv2 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("SSL_VERSION_SSLv3"), CURL_SSLVERSION_SSLv3 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("SSL_VERSION_ANY"), CURL_SSLVERSION_DEFAULT TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("SSL_VERSION_TLSv1"), CURL_SSLVERSION_TLSv1 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("SSL_VERSION_SSLv2"), CURL_SSLVERSION_SSLv2 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("SSL_VERSION_SSLv3"), CURL_SSLVERSION_SSLv3 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("SSL_VERSION_ANY"), CURL_SSLVERSION_DEFAULT TSRMLS_CC);
 
        /*
        * DNS IPvX resolving
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("IPRESOLVE_V4"), CURL_IPRESOLVE_V4 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("IPRESOLVE_V6"), CURL_IPRESOLVE_V6 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("IPRESOLVE_ANY"), CURL_IPRESOLVE_WHATEVER TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("IPRESOLVE_V4"), CURL_IPRESOLVE_V4 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("IPRESOLVE_V6"), CURL_IPRESOLVE_V6 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("IPRESOLVE_ANY"), CURL_IPRESOLVE_WHATEVER TSRMLS_CC);
 
        /*
        * Auth Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_BASIC"), CURLAUTH_BASIC TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_DIGEST"), CURLAUTH_DIGEST TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("AUTH_BASIC"), CURLAUTH_BASIC TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("AUTH_DIGEST"), CURLAUTH_DIGEST TSRMLS_CC);
 #if PHP_HTTP_CURL_VERSION(7,19,3)
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_DIGEST_IE"), CURLAUTH_DIGEST_IE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("AUTH_DIGEST_IE"), CURLAUTH_DIGEST_IE TSRMLS_CC);
 #endif
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_NTLM"), CURLAUTH_NTLM TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_GSSNEG"), CURLAUTH_GSSNEGOTIATE TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_ANY"), CURLAUTH_ANY TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("AUTH_NTLM"), CURLAUTH_NTLM TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("AUTH_GSSNEG"), CURLAUTH_GSSNEGOTIATE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("AUTH_ANY"), CURLAUTH_ANY TSRMLS_CC);
 
        /*
        * Proxy Type Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS4"), CURLPROXY_SOCKS4 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS4A"), CURLPROXY_SOCKS5 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS5_HOSTNAME"), CURLPROXY_SOCKS5 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS5"), CURLPROXY_SOCKS5 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_HTTP"), CURLPROXY_HTTP TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("PROXY_SOCKS4"), CURLPROXY_SOCKS4 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("PROXY_SOCKS4A"), CURLPROXY_SOCKS5 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("PROXY_SOCKS5_HOSTNAME"), CURLPROXY_SOCKS5 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("PROXY_SOCKS5"), CURLPROXY_SOCKS5 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("PROXY_HTTP"), CURLPROXY_HTTP TSRMLS_CC);
 #      if PHP_HTTP_CURL_VERSION(7,19,4)
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_HTTP_1_0"), CURLPROXY_HTTP_1_0 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("PROXY_HTTP_1_0"), CURLPROXY_HTTP_1_0 TSRMLS_CC);
 #      endif
 
        /*
        * Post Redirection Constants
        */
 #if PHP_HTTP_CURL_VERSION(7,19,1)
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("POSTREDIR_301"), CURL_REDIR_POST_301 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("POSTREDIR_302"), CURL_REDIR_POST_302 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("POSTREDIR_ALL"), CURL_REDIR_POST_ALL TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("POSTREDIR_301"), CURL_REDIR_POST_301 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("POSTREDIR_302"), CURL_REDIR_POST_302 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_curl_class_entry, ZEND_STRL("POSTREDIR_ALL"), CURL_REDIR_POST_ALL TSRMLS_CC);
 #endif
 
        return SUCCESS;
index 89f1948..6e9cc16 100644 (file)
@@ -15,4 +15,11 @@ struct php_http_request_pool_globals {
 };
 #endif
 
+extern zend_class_entry *php_http_curl_class_entry;
+extern zend_function_entry php_http_curl_method_entry[];
+
+#define php_http_curl_new php_http_object_new
+
+PHP_METHOD(HttpCURL, __construct);
+
 #endif
index 93712c7..b7c994b 100644 (file)
@@ -950,11 +950,11 @@ void php_http_encoding_stream_object_free(void *object TSRMLS_DC)
 
 PHP_METHOD(HttpEncodingStream, __construct)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       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_EX_CE(encoding)) {
+                       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) {
index 5b26dfc..11117d3 100644 (file)
@@ -143,58 +143,34 @@ static void php_http_neon_progress_callback(void *ctx, ne_session_status status,
 {
        php_http_request_t *h = ctx;
        php_http_neon_request_t *neon = h->ctx;
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
        switch (status) {
                case ne_status_lookup:
+                       neon->progress.state.info = "resolve";
                        break;
                case ne_status_connecting:
+                       neon->progress.state.info = "connect";
                        break;
                case ne_status_connected:
+                       neon->progress.state.info = "connected";
                        break;
                case ne_status_sending:
+                       neon->progress.state.info = "send";
                        neon->progress.state.ul.total = info->sr.total;
                        neon->progress.state.ul.now = info->sr.progress;
                        break;
                case ne_status_recving:
+                       neon->progress.state.info = "receive";
                        neon->progress.state.dl.total = info->sr.total;
                        neon->progress.state.dl.now = info->sr.progress;
                        break;
                case ne_status_disconnected:
+                       neon->progress.state.info = "disconnected";
                        break;
        }
 
-       if (neon->progress.callback) {
-               zval retval;
-               TSRMLS_FETCH_FROM_CTX(h->ts);
-
-               INIT_PZVAL(&retval);
-               ZVAL_NULL(&retval);
-
-               with_error_handling(EH_NORMAL, NULL) {
-                       if (neon->progress.pass_state) {
-                               zval *param;
-
-                               MAKE_STD_ZVAL(param);
-                               array_init(param);
-                               add_assoc_double(param, "dltotal", neon->progress.state.dl.total);
-                               add_assoc_double(param, "dlnow", neon->progress.state.dl.now);
-                               add_assoc_double(param, "ultotal", neon->progress.state.ul.total);
-                               add_assoc_double(param, "ulnow", neon->progress.state.ul.now);
-
-                               neon->progress.in_cb = 1;
-                               call_user_function(EG(function_table), NULL, neon->progress.callback, &retval, 1, &param TSRMLS_CC);
-                               neon->progress.in_cb = 0;
-
-                               zval_ptr_dtor(&param);
-                       } else {
-                               neon->progress.in_cb = 1;
-                               call_user_function(EG(function_table), NULL, neon->progress.callback, &retval, 0, NULL TSRMLS_CC);
-                               neon->progress.in_cb = 0;
-                       }
-               } end_error_handling();
-
-               zval_dtor(&retval);
-       }
+       php_http_request_progress_notify(&neon->progress TSRMLS_CC);
 }
 
 /* helpers */
@@ -219,7 +195,7 @@ static inline zval *get_option(HashTable *cache, HashTable *options, char *key,
                ulong h = zend_hash_func(key, keylen);
 
                if (SUCCESS == zend_hash_quick_find(options, key, keylen, h, (void *) &zoption)) {
-                       zval *option = php_http_zsep(type, *zoption);
+                       zval *option = php_http_ztyp(type, *zoption);
 
                        if (cache) {
                                zval *cached = cache_option(cache, key, keylen, h, option);
@@ -361,8 +337,8 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                                        if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(rr), (void *) &re, &pos2)) {
                                                if (    ((Z_TYPE_PP(rb) == IS_LONG) || ((Z_TYPE_PP(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(rb), Z_STRLEN_PP(rb), NULL, NULL, 1))) &&
                                                                ((Z_TYPE_PP(re) == IS_LONG) || ((Z_TYPE_PP(re) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(re), Z_STRLEN_PP(re), NULL, NULL, 1)))) {
-                                                       zval *rbl = php_http_zsep(IS_LONG, *rb);
-                                                       zval *rel = php_http_zsep(IS_LONG, *re);
+                                                       zval *rbl = php_http_ztyp(IS_LONG, *rb);
+                                                       zval *rel = php_http_ztyp(IS_LONG, *re);
 
                                                        if ((Z_LVAL_P(rbl) >= 0) && (Z_LVAL_P(rel) >= 0)) {
                                                                php_http_buffer_appendf(&rs, "%ld-%ld,", Z_LVAL_P(rbl), Z_LVAL_P(rel));
@@ -391,7 +367,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                FOREACH_KEYVAL(pos, zoption, header_key, header_val) {
                        if (header_key.type == HASH_KEY_IS_STRING) {
-                               zval *header_cpy = php_http_zsep(IS_STRING, *header_val);
+                               zval *header_cpy = php_http_ztyp(IS_STRING, *header_val);
 
                                if (!strcasecmp(header_key.str, "range")) {
                                        range_req = 1;
@@ -455,7 +431,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                                FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) {
                                        if (cookie_key.type == HASH_KEY_IS_STRING) {
-                                               zval *val = php_http_zsep(IS_STRING, *cookie_val);
+                                               zval *val = php_http_ztyp(IS_STRING, *cookie_val);
                                                php_http_buffer_appendf(&neon->options.headers, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val));
                                                zval_ptr_dtor(&val);
                                        }
@@ -494,13 +470,13 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                        }
                }
                if (SUCCESS == zend_hash_find(Z_ARRVAL_P(zoption), ZEND_STRS("key"), (void *) &zssl)) {
-                       zval *cpy = php_http_zsep(IS_STRING, *zssl);
+                       zval *cpy = php_http_ztyp(IS_STRING, *zssl);
                        ne_ssl_client_cert *cc = ne_ssl_clicert_read(Z_STRVAL_P(cpy));
 
                        if (cc) {
                                if (ne_ssl_clicert_encrypted(cc)) {
                                        if (SUCCESS == zend_hash_find(Z_ARRVAL_P(zoption), ZEND_STRS("keypasswd"), (void *) &zssl)) {
-                                               zval *cpy = php_http_zsep(IS_STRING, *zssl);
+                                               zval *cpy = php_http_ztyp(IS_STRING, *zssl);
 
                                                if (NE_OK == ne_ssl_clicert_decrypt(cc, Z_STRVAL_P(cpy))) {
                                                        neon->options.ssl.clicert = cc;
@@ -517,7 +493,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                        zval_ptr_dtor(&cpy);
                }
                if (SUCCESS == zend_hash_find(Z_ARRVAL_P(zoption), ZEND_STRS("cert"), (void *) &zssl)) {
-                       zval *cpy = php_http_zsep(IS_STRING, *zssl);
+                       zval *cpy = php_http_ztyp(IS_STRING, *zssl);
                        ne_ssl_certificate *tc = ne_ssl_cert_read(Z_STRVAL_P(cpy));
 
                        if (tc) {
@@ -553,7 +529,7 @@ static php_http_request_t *php_http_neon_request_copy(php_http_request_t *from,
        if (to) {
                return php_http_neon_request_init(to, NULL);
        } else {
-               return php_http_request_init(NULL, from->ops, NULL TSRMLS_CC);
+               return php_http_request_init(NULL, from->ops, from->rf, NULL TSRMLS_CC);
        }
 }
 
@@ -565,6 +541,8 @@ static void php_http_neon_request_dtor(php_http_request_t *h)
        php_http_buffer_dtor(&ctx->options.headers);
        zend_hash_destroy(&ctx->options.cache);
 
+       php_http_request_progress_dtor(&ctx->progress);
+
        efree(ctx);
        h->ctx = NULL;
 }
@@ -607,15 +585,7 @@ static STATUS php_http_neon_request_reset(php_http_request_t *h)
        neon->options.timeout.read = 0;
        neon->options.timeout.connect = 0;
 
-       if (neon->progress.callback) {
-               zval_ptr_dtor(&neon->progress.callback);
-               neon->progress.callback = NULL;
-       }
-       neon->progress.pass_state = 0;
-       neon->progress.state.dl.now = 0;
-       neon->progress.state.dl.total = 0;
-       neon->progress.state.ul.now = 0;
-       neon->progress.state.ul.total = 0;
+       php_http_request_progress_dtor(&neon->progress);
 
        return SUCCESS;
 }
@@ -645,20 +615,21 @@ static STATUS php_http_neon_request_exec(php_http_request_t *h, php_http_request
        if (neon->options.port) {
                purl->port = neon->options.port;
        } else if (!purl->port) {
+               purl->port = 80;
+               if (strncascmp(purl->scheme, "http", 4)) {
 #ifdef HAVE_GETSERVBYNAME
-               struct servent *se;
+                       struct servent *se;
 
-               if ((se = getservbyname(purl->scheme, "tcp")) && se->s_port) {
-                       purl->port = ntohs(se->s_port);
-               } else
+                       if ((se = getservbyname(purl->scheme, "tcp")) && se->s_port) {
+                               purl->port = ntohs(se->s_port);
+                       }
 #endif
-               if (!strcasecmp(purl->scheme, "https")) {
+               } else if (purl->scheme[4] == 's') {
                        purl->port = 443;
-               } else {
-                       purl->port = 80;
                }
        }
 
+       /* never returns NULL */
        session = ne_session_create(purl->scheme, purl->host, purl->port);
        if (neon->options.proxy.host) {
                switch (neon->options.proxy.type) {
@@ -793,16 +764,14 @@ static STATUS php_http_neon_request_setopt(php_http_request_t *h, php_http_reque
                        break;
 
                case PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK:
-                       if (neon->progress.callback) {
-                               zval_ptr_dtor(&neon->progress.callback);
+                       if (neon->progress.in_cb) {
+                               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "Cannot change progress callback while executing it");
+                               return FAILURE;
                        }
-                       if ((neon->progress.callback = arg)) {
-                               Z_ADDREF_P(neon->progress.callback);
+                       if (neon->progress.callback) {
+                               php_http_request_progress_dtor(&neon->progress TSRMLS_CC);
                        }
-                       break;
-
-               case PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK_WANTS_STATE:
-                       neon->progress.pass_state = *((int *)arg);
+                       neon->progress.callback = arg;
                        break;
 
                case PHP_HTTP_REQUEST_OPT_COOKIES_ENABLE:
@@ -825,7 +794,7 @@ static STATUS php_http_neon_request_getopt(php_http_request_t *h, php_http_reque
 
        switch (opt) {
                case PHP_HTTP_REQUEST_OPT_PROGRESS_INFO:
-                       memcpy(arg, &neon->progress, sizeof(neon->progress));
+                       *((php_http_request_progress_t **) arg) = &neon->progress;
                        break;
 
                case PHP_HTTP_REQUEST_OPT_TRANSFER_INFO:
@@ -838,7 +807,14 @@ static STATUS php_http_neon_request_getopt(php_http_request_t *h, php_http_reque
        return SUCCESS;
 }
 
+static php_http_resource_factory_ops_t php_http_neon_resource_factory_ops = {
+               NULL,
+               NULL,
+               NULL
+};
+
 static php_http_request_ops_t php_http_neon_request_ops = {
+       &php_http_neon_resource_factory_ops,
        php_http_neon_request_init,
        php_http_neon_request_copy,
        php_http_neon_request_dtor,
@@ -853,6 +829,25 @@ PHP_HTTP_API php_http_request_ops_t *php_http_neon_get_request_ops(void)
        return &php_http_neon_request_ops;
 }
 
+#define PHP_HTTP_BEGIN_ARGS(method, req_args)  PHP_HTTP_BEGIN_ARGS_EX(HttpNEON, method, 0, req_args)
+#define PHP_HTTP_EMPTY_ARGS(method)                            PHP_HTTP_EMPTY_ARGS_EX(HttpNEON, method, 0)
+#define PHP_HTTP_NEON_ME(method, visibility)   PHP_ME(HttpNEON, method, PHP_HTTP_ARGS(HttpNEON, method), visibility)
+#define PHP_HTTP_NEON_ALIAS(method, func)      PHP_HTTP_STATIC_ME_ALIAS(method, func, PHP_HTTP_ARGS(HttpNEON, method))
+#define PHP_HTTP_NEON_MALIAS(me, al, vis)      ZEND_FENTRY(me, ZEND_MN(HttpNEON_##al), PHP_HTTP_ARGS(HttpNEON, al), vis)
+
+PHP_HTTP_EMPTY_ARGS(__construct);
+
+zend_class_entry *php_http_neon_class_entry;
+zend_function_entry php_http_neon_method_entry[] = {
+       PHP_HTTP_NEON_ME(__construct, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+
+       EMPTY_FUNCTION_ENTRY
+};
+
+PHP_METHOD(HttpNEON, __construct) {
+}
+
+
 PHP_MINIT_FUNCTION(http_neon)
 {
        php_http_request_factory_driver_t driver = {
@@ -863,22 +858,25 @@ PHP_MINIT_FUNCTION(http_neon)
                return FAILURE;
        }
 
+       PHP_HTTP_REGISTER_CLASS(http, NEON, http_neon, php_http_neon_class_entry, 0);
+
        /*
        * Auth Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_BASIC"), NE_AUTH_BASIC TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_DIGEST"), NE_AUTH_DIGEST TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_NTLM"), NE_AUTH_NTLM TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_GSSNEG"), NE_AUTH_GSSAPI TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_ANY"), NE_AUTH_ALL TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_BASIC"), NE_AUTH_BASIC TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_DIGEST"), NE_AUTH_DIGEST TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_NTLM"), NE_AUTH_NTLM TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_GSSAPI"), NE_AUTH_GSSAPI TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_GSSNEG"), NE_AUTH_NEGOTIATE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_ANY"), NE_AUTH_ALL TSRMLS_CC);
 
        /*
        * Proxy Type Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS4"), NE_SOCK_SOCKSV4 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS4A"), NE_SOCK_SOCKSV4A TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS5"), NE_SOCK_SOCKSV5 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_HTTP"), -1 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_SOCKS4"), NE_SOCK_SOCKSV4 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_SOCKS4A"), NE_SOCK_SOCKSV4A TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_SOCKS5"), NE_SOCK_SOCKSV5 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_HTTP"), -1 TSRMLS_CC);
 
        if (NE_OK != ne_sock_init()) {
                return FAILURE;
index 96b7d0d..dd4ff98 100644 (file)
@@ -6,4 +6,11 @@ php_http_request_ops_t *php_http_neon_get_request_ops(void);
 PHP_MINIT_FUNCTION(http_neon);
 PHP_MSHUTDOWN_FUNCTION(http_neon);
 
+extern zend_class_entry *php_http_neon_class_entry;
+extern zend_function_entry php_http_neon_method_entry[];
+
+#define php_http_neon_new php_http_object_new
+
+PHP_METHOD(HttpNEON, __construct);
+
 #endif /* PHP_HTTP_NEON_H */
index a5f9689..55d53d0 100644 (file)
@@ -39,9 +39,7 @@ typedef struct php_http_persistent_handle_list {
 
 typedef struct php_http_persistent_handle_provider {
        php_http_persistent_handle_list_t list; /* "ident" => array(handles) entries */
-       php_http_persistent_handle_ctor_t ctor;
-       php_http_persistent_handle_dtor_t dtor;
-       php_http_persistent_handle_copy_t copy;
+       php_http_resource_factory_t rf;
 } php_http_persistent_handle_provider_t;
 
 static inline php_http_persistent_handle_list_t *php_http_persistent_handle_list_init(php_http_persistent_handle_list_t *list)
@@ -64,7 +62,7 @@ static inline php_http_persistent_handle_list_t *php_http_persistent_handle_list
        return list;
 }
 
-static inline void php_http_persistent_handle_list_dtor(php_http_persistent_handle_list_t *list, php_http_persistent_handle_dtor_t dtor)
+static inline void php_http_persistent_handle_list_dtor(php_http_persistent_handle_list_t *list, php_http_persistent_handle_provider_t *provider TSRMLS_DC)
 {
        HashPosition pos;
        void **handle;
@@ -77,14 +75,14 @@ static inline void php_http_persistent_handle_list_dtor(php_http_persistent_hand
                fprintf(stderr, "DESTROY: %p\n", *handle);
 #endif
                
-               dtor(*handle);
+               provider->rf.fops.dtor(provider->rf.data, *handle TSRMLS_CC);
        }
        zend_hash_destroy(&list->free);
 }
 
-static inline void php_http_persistent_handle_list_free(php_http_persistent_handle_list_t **list, php_http_persistent_handle_dtor_t dtor)
+static inline void php_http_persistent_handle_list_free(php_http_persistent_handle_list_t **list, php_http_persistent_handle_provider_t *provider TSRMLS_DC)
 {
-       php_http_persistent_handle_list_dtor(*list, dtor);
+       php_http_persistent_handle_list_dtor(*list, provider TSRMLS_CC);
 #if PHP_HTTP_DEBUG_PHANDLES
        fprintf(stderr, "LSTFREE: %p\n", *list);
 #endif
@@ -92,11 +90,11 @@ static inline void php_http_persistent_handle_list_free(php_http_persistent_hand
        *list = NULL;
 }
 
-static inline php_http_persistent_handle_list_t *php_http_persistent_handle_list_find(php_http_persistent_handle_provider_t *provider TSRMLS_DC)
+static inline php_http_persistent_handle_list_t *php_http_persistent_handle_list_find(php_http_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len TSRMLS_DC)
 {
        php_http_persistent_handle_list_t **list, *new_list;
        
-       if (SUCCESS == zend_hash_quick_find(&provider->list.free, PHP_HTTP_G->persistent_handle.ident.s, PHP_HTTP_G->persistent_handle.ident.l, PHP_HTTP_G->persistent_handle.ident.h, (void *) &list)) {
+       if (SUCCESS == zend_hash_find(&provider->list.free, ident_str, ident_len + 1, (void *) &list)) {
 #if PHP_HTTP_DEBUG_PHANDLES
                fprintf(stderr, "LSTFIND: %p\n", *list);
 #endif
@@ -104,31 +102,31 @@ static inline php_http_persistent_handle_list_t *php_http_persistent_handle_list
        }
        
        if ((new_list = php_http_persistent_handle_list_init(NULL))) {
-               if (SUCCESS == zend_hash_quick_add(&provider->list.free, PHP_HTTP_G->persistent_handle.ident.s, PHP_HTTP_G->persistent_handle.ident.l, PHP_HTTP_G->persistent_handle.ident.h, (void *) &new_list, sizeof(php_http_persistent_handle_list_t *), (void *) &list)) {
+               if (SUCCESS == zend_hash_add(&provider->list.free, ident_str, ident_len + 1, (void *) &new_list, sizeof(php_http_persistent_handle_list_t *), (void *) &list)) {
 #if PHP_HTTP_DEBUG_PHANDLES
                        fprintf(stderr, "LSTFIND: %p (new)\n", *list);
 #endif
                        return *list;
                }
-               php_http_persistent_handle_list_free(&new_list, provider->dtor);
+               php_http_persistent_handle_list_free(&new_list, provider TSRMLS_CC);
        }
        
        return NULL;
 }
 
-static inline STATUS php_http_persistent_handle_do_acquire(php_http_persistent_handle_provider_t *provider, void **handle TSRMLS_DC)
+static inline STATUS php_http_persistent_handle_do_acquire(php_http_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC)
 {
        ulong index;
        void **handle_ptr;
        php_http_persistent_handle_list_t *list;
        
-       if ((list = php_http_persistent_handle_list_find(provider TSRMLS_CC))) {
+       if ((list = php_http_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
                zend_hash_internal_pointer_end(&list->free);
                if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&list->free, NULL, &index, 0) && SUCCESS == zend_hash_get_current_data(&list->free, (void *) &handle_ptr)) {
                        *handle = *handle_ptr;
                        zend_hash_index_del(&list->free, index);
                } else {
-                       *handle = provider->ctor();
+                       *handle = provider->rf.fops.ctor(provider->rf.data TSRMLS_CC);
                }
                
                if (*handle) {
@@ -143,13 +141,13 @@ static inline STATUS php_http_persistent_handle_do_acquire(php_http_persistent_h
        return FAILURE;
 }
 
-static inline STATUS php_http_persistent_handle_do_release(php_http_persistent_handle_provider_t *provider, void **handle TSRMLS_DC)
+static inline STATUS php_http_persistent_handle_do_release(php_http_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC)
 {
        php_http_persistent_handle_list_t *list;
        
-       if ((list = php_http_persistent_handle_list_find(provider TSRMLS_CC))) {
+       if ((list = php_http_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
                if (provider->list.used >= PHP_HTTP_G->persistent_handle.limit) {
-                       provider->dtor(*handle);
+                       provider->rf.fops.dtor(provider->rf.data, *handle TSRMLS_CC);
                } else {
                        if (SUCCESS != zend_hash_next_index_insert(&list->free, (void *) handle, sizeof(void *), NULL)) {
                                return FAILURE;
@@ -165,12 +163,12 @@ static inline STATUS php_http_persistent_handle_do_release(php_http_persistent_h
        return FAILURE;
 }
 
-static inline STATUS php_http_persistent_handle_do_accrete(php_http_persistent_handle_provider_t *provider, void *old_handle, void **new_handle TSRMLS_DC)
+static inline STATUS php_http_persistent_handle_do_accrete(php_http_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len, void *old_handle, void **new_handle TSRMLS_DC)
 {
        php_http_persistent_handle_list_t *list;
        
-       if (provider->copy && (*new_handle = provider->copy(old_handle))) {
-               if ((list = php_http_persistent_handle_list_find(provider TSRMLS_CC))) {
+       if (provider->rf.fops.copy && (*new_handle = provider->rf.fops.copy(provider->rf.data, old_handle TSRMLS_CC))) {
+               if ((list = php_http_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
                        ++list->used;
                }
                ++provider->list.used;
@@ -188,10 +186,11 @@ static void php_http_persistent_handles_hash_dtor(void *p)
        FOREACH_HASH_VAL(pos, &provider->list.free, list) {
                /* fix shutdown crash in PHP4 */
                list_tmp = *list;
-               php_http_persistent_handle_list_free(&list_tmp, provider->dtor);
+               php_http_persistent_handle_list_free(&list_tmp, provider TSRMLS_CC);
        }
        
        zend_hash_destroy(&provider->list.free);
+       php_http_resource_factory_dtor(&provider->rf);
 }
 
 PHP_MINIT_FUNCTION(http_persistent_handle)
@@ -212,23 +211,23 @@ PHP_MSHUTDOWN_FUNCTION(http_persistent_handle)
        return SUCCESS;
 }
 
-PHP_HTTP_API STATUS php_http_persistent_handle_provide(const char *name_str, size_t name_len, php_http_persistent_handle_ctor_t ctor, php_http_persistent_handle_dtor_t dtor, php_http_persistent_handle_copy_t copy)
+PHP_HTTP_API STATUS php_http_persistent_handle_provide(const char *name_str, size_t name_len, php_http_resource_factory_ops_t *fops, void *data, void (*dtor)(void *))
 {
        STATUS status = FAILURE;
        php_http_persistent_handle_provider_t provider;
        
        LOCK();
        if (php_http_persistent_handle_list_init(&provider.list)) {
-               provider.ctor = ctor;
-               provider.dtor = dtor;
-               provider.copy = copy;
-               
+               if (php_http_resource_factory_init(&provider.rf, fops, data, dtor)) {
 #if PHP_HTTP_DEBUG_PHANDLES
-               fprintf(stderr, "PROVIDE: %s\n", name_str);
+                       fprintf(stderr, "PROVIDE: %s\n", name_str);
 #endif
                
-               if (SUCCESS == zend_hash_add(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &provider, sizeof(php_http_persistent_handle_provider_t), NULL)) {
-                       status = SUCCESS;
+                       if (SUCCESS == zend_hash_add(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &provider, sizeof(php_http_persistent_handle_provider_t), NULL)) {
+                               status = SUCCESS;
+                       } else {
+                               php_http_resource_factory_dtor(&provider.rf);
+                       }
                }
        }
        UNLOCK();
@@ -236,7 +235,80 @@ PHP_HTTP_API STATUS php_http_persistent_handle_provide(const char *name_str, siz
        return status;
 }
 
-PHP_HTTP_API STATUS php_http_persistent_handle_acquire(const char *name_str, size_t name_len, void **handle TSRMLS_DC)
+PHP_HTTP_API php_http_persistent_handle_factory_t *php_http_persistent_handle_concede(php_http_persistent_handle_factory_t *a, const char *name_str, size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC)
+{
+       STATUS status = FAILURE;
+       php_http_persistent_handle_factory_t *free_a = NULL;
+
+       if (!a) {
+               free_a = a = emalloc(sizeof(*a));
+       }
+       memset(a, 0, sizeof(*a));
+
+       LOCK();
+       status = zend_hash_find(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &a->provider);
+       UNLOCK();
+
+       if (SUCCESS == status) {
+               a->ident.str = estrndup(ident_str, a->ident.len = ident_len);
+               if (free_a) {
+                       a->free_on_abandon = 1;
+               }
+       } else {
+               if (free_a) {
+                       efree(a);
+               }
+               a = NULL;
+       }
+
+#if PHP_HTTP_DEBUG_PHANDLES
+       fprintf(stderr, "CONCETE: %p (%s) (%s)\n", a ? a->provider : NULL, name_str, ident_str);
+#endif
+
+       return a;
+}
+
+PHP_HTTP_API void php_http_persistent_handle_abandon(php_http_persistent_handle_factory_t *a)
+{
+       zend_bool f = a->free_on_abandon;
+
+       STR_FREE(a->ident.str);
+       memset(a, 0, sizeof(*a));
+       if (f) {
+               efree(a);
+       }
+}
+
+PHP_HTTP_API void *php_http_persistent_handle_acquire(php_http_persistent_handle_factory_t *a TSRMLS_DC)
+{
+       void *handle = NULL;
+
+       LOCK();
+       php_http_persistent_handle_do_acquire(a->provider, a->ident.str, a->ident.len, &handle TSRMLS_CC);
+       UNLOCK();
+
+       return handle;
+}
+
+PHP_HTTP_API void *php_http_persistent_handle_accrete(php_http_persistent_handle_factory_t *a, void *handle TSRMLS_DC)
+{
+       void *new_handle;
+
+       LOCK();
+       php_http_persistent_handle_do_accrete(a->provider, a->ident.str, a->ident.len, handle, &new_handle TSRMLS_CC);
+       UNLOCK();
+
+       return new_handle;
+}
+
+PHP_HTTP_API void php_http_persistent_handle_release(php_http_persistent_handle_factory_t *a, void *handle TSRMLS_DC)
+{
+       LOCK();
+       php_http_persistent_handle_do_release(a->provider, a->ident.str, a->ident.len, &handle);
+       UNLOCK();
+}
+
+PHP_HTTP_API STATUS php_http_persistent_handle_acquire2(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC)
 {
        STATUS status = FAILURE;
        php_http_persistent_handle_provider_t *provider;
@@ -244,7 +316,7 @@ PHP_HTTP_API STATUS php_http_persistent_handle_acquire(const char *name_str, siz
        *handle = NULL;
        LOCK();
        if (SUCCESS == zend_hash_find(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &provider)) {
-               status = php_http_persistent_handle_do_acquire(provider, handle TSRMLS_CC);
+               status = php_http_persistent_handle_do_acquire(provider, ident_str, ident_len, handle TSRMLS_CC);
        }
        UNLOCK();
        
@@ -255,7 +327,7 @@ PHP_HTTP_API STATUS php_http_persistent_handle_acquire(const char *name_str, siz
        return status;
 }
 
-PHP_HTTP_API STATUS php_http_persistent_handle_release(const char *name_str, size_t name_len, void **handle TSRMLS_DC)
+PHP_HTTP_API STATUS php_http_persistent_handle_release2(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC)
 {
        STATUS status = FAILURE;
        php_http_persistent_handle_provider_t *provider;
@@ -265,7 +337,7 @@ PHP_HTTP_API STATUS php_http_persistent_handle_release(const char *name_str, siz
        
        LOCK();
        if (SUCCESS == zend_hash_find(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &provider)) {
-               status = php_http_persistent_handle_do_release(provider, handle TSRMLS_CC);
+               status = php_http_persistent_handle_do_release(provider, ident_str, ident_len, handle TSRMLS_CC);
        }
        UNLOCK();
        
@@ -276,7 +348,7 @@ PHP_HTTP_API STATUS php_http_persistent_handle_release(const char *name_str, siz
        return status;
 }
 
-PHP_HTTP_API STATUS php_http_persistent_handle_accrete(const char *name_str, size_t name_len, void *old_handle, void **new_handle TSRMLS_DC)
+PHP_HTTP_API STATUS php_http_persistent_handle_accrete2(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, void *old_handle, void **new_handle TSRMLS_DC)
 {
        STATUS status = FAILURE;
        php_http_persistent_handle_provider_t *provider;
@@ -284,7 +356,7 @@ PHP_HTTP_API STATUS php_http_persistent_handle_accrete(const char *name_str, siz
        *new_handle = NULL;
        LOCK();
        if (SUCCESS == zend_hash_find(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &provider)) {
-               status = php_http_persistent_handle_do_accrete(provider, old_handle, new_handle TSRMLS_CC);
+               status = php_http_persistent_handle_do_accrete(provider, ident_str, ident_len, old_handle, new_handle TSRMLS_CC);
        }
        UNLOCK();
        
@@ -295,7 +367,7 @@ PHP_HTTP_API STATUS php_http_persistent_handle_accrete(const char *name_str, siz
        return status;
 }
 
-PHP_HTTP_API void php_http_persistent_handle_cleanup(const char *name_str, size_t name_len, int current_ident_only TSRMLS_DC)
+PHP_HTTP_API void php_http_persistent_handle_cleanup(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC)
 {
        php_http_persistent_handle_provider_t *provider;
        php_http_persistent_handle_list_t *list, **listp;
@@ -304,28 +376,28 @@ PHP_HTTP_API void php_http_persistent_handle_cleanup(const char *name_str, size_
        LOCK();
        if (name_str && name_len) {
                if (SUCCESS == zend_hash_find(&php_http_persistent_handles_hash, name_str, name_len+1, (void *) &provider)) {
-                       if (current_ident_only) {
-                               if ((list = php_http_persistent_handle_list_find(provider TSRMLS_CC))) {
-                                       php_http_persistent_handle_list_dtor(list, provider->dtor);
+                       if (ident_str && ident_len) {
+                               if ((list = php_http_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
+                                       php_http_persistent_handle_list_dtor(list, provider TSRMLS_CC);
                                        php_http_persistent_handle_list_init(list);
                                }
                        } else {
                                FOREACH_HASH_VAL(pos1, &provider->list.free, listp) {
-                                       php_http_persistent_handle_list_dtor(*listp, provider->dtor);
+                                       php_http_persistent_handle_list_dtor(*listp, provider TSRMLS_CC);
                                        php_http_persistent_handle_list_init(*listp);
                                }
                        }
                }
        } else {
                FOREACH_HASH_VAL(pos1, &php_http_persistent_handles_hash, provider) {
-                       if (current_ident_only) {
-                               if ((list = php_http_persistent_handle_list_find(provider TSRMLS_CC))) {
-                                       php_http_persistent_handle_list_dtor(list, provider->dtor);
+                       if (ident_str && ident_len) {
+                               if ((list = php_http_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
+                                       php_http_persistent_handle_list_dtor(list, provider TSRMLS_CC);
                                        php_http_persistent_handle_list_init(list);
                                }
                        } else {
                                FOREACH_HASH_VAL(pos2, &provider->list.free, listp) {
-                                       php_http_persistent_handle_list_dtor(*listp, provider->dtor);
+                                       php_http_persistent_handle_list_dtor(*listp, provider TSRMLS_CC);
                                        php_http_persistent_handle_list_init(*listp);
                                }
                        }
index 075fe92..07aa796 100644 (file)
 #ifndef PHP_HTTP_PERSISTENT_HANDLE_H
 #define PHP_HTTP_PERSISTENT_HANDLE_H
 
-typedef void *(*php_http_persistent_handle_ctor_t)(void);
-typedef void (*php_http_persistent_handle_dtor_t)(void *handle);
-typedef void *(*php_http_persistent_handle_copy_t)(void *handle);
+#include "php_http_resource_factory.h"
+
+typedef struct php_http_persistent_handle_factory {
+       void *provider;
+
+       struct {
+               char *str;
+               size_t len;
+       } ident;
+
+       unsigned free_on_abandon:1;
+} php_http_persistent_handle_factory_t;
 
 struct php_http_persistent_handle_globals {
        ulong limit;
@@ -31,12 +40,21 @@ struct php_http_persistent_handle_globals {
 PHP_MINIT_FUNCTION(http_persistent_handle);
 PHP_MSHUTDOWN_FUNCTION(http_persistent_handle);
 
-PHP_HTTP_API STATUS php_http_persistent_handle_provide(const char *name_str, size_t name_len, php_http_persistent_handle_ctor_t ctor, php_http_persistent_handle_dtor_t dtor, php_http_persistent_handle_copy_t copy);
-PHP_HTTP_API void php_http_persistent_handle_cleanup(const char *name_str, size_t name_len, int current_ident_only TSRMLS_DC);
+PHP_HTTP_API STATUS php_http_persistent_handle_provide(const char *name_str, size_t name_len, php_http_resource_factory_ops_t *fops, void *data, void (*dtor)(void *));
+PHP_HTTP_API php_http_persistent_handle_factory_t *php_http_persistent_handle_concede(php_http_persistent_handle_factory_t *a, const char *name_str, size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC);
+PHP_HTTP_API void php_http_persistent_handle_abandon(php_http_persistent_handle_factory_t *a);
+PHP_HTTP_API void *php_http_persistent_handle_acquire(php_http_persistent_handle_factory_t *a TSRMLS_DC);
+PHP_HTTP_API void php_http_persistent_handle_release(php_http_persistent_handle_factory_t *a, void *handle TSRMLS_DC);
+PHP_HTTP_API void *php_http_persistent_handle_accrete(php_http_persistent_handle_factory_t *a, void *handle TSRMLS_DC);
+
+PHP_HTTP_API php_http_resource_factory_ops_t *php_http_persistnet_handle_factory_ops(void);
+
+PHP_HTTP_API void php_http_persistent_handle_cleanup(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC);
 PHP_HTTP_API HashTable *php_http_persistent_handle_statall(HashTable *ht TSRMLS_DC);
-PHP_HTTP_API STATUS php_http_persistent_handle_acquire(const char *name_str, size_t name_len, void **handle TSRMLS_DC);
-PHP_HTTP_API STATUS php_http_persistent_handle_release(const char *name_str, size_t name_len, void **handle TSRMLS_DC);
-PHP_HTTP_API STATUS php_http_persistent_handle_accrete(const char *name_str, size_t name_len, void *old_handle, void **new_handle TSRMLS_DC);
+
+PHP_HTTP_API STATUS php_http_persistent_handle_acquire2(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC);
+PHP_HTTP_API STATUS php_http_persistent_handle_release2(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC);
+PHP_HTTP_API STATUS php_http_persistent_handle_accrete2(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, void *old_handle, void **new_handle TSRMLS_DC);
 
 #endif /* PHP_HTTP_PERSISTENT_HANDLE_H */
 
index 63d68db..6b8d444 100644 (file)
@@ -19,7 +19,7 @@
 #include <Zend/zend_interfaces.h>
 
 
-PHP_HTTP_API php_http_request_t *php_http_request_init(php_http_request_t *h, php_http_request_ops_t *ops, void *init_arg TSRMLS_DC)
+PHP_HTTP_API php_http_request_t *php_http_request_init(php_http_request_t *h, php_http_request_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg TSRMLS_DC)
 {
        php_http_request_t *free_h = NULL;
 
@@ -29,6 +29,7 @@ PHP_HTTP_API php_http_request_t *php_http_request_init(php_http_request_t *h, ph
        memset(h, 0, sizeof(*h));
 
        h->ops = ops;
+       h->rf = rf ? rf : php_http_resource_factory_init(NULL, h->ops->rsrc, NULL, NULL TSRMLS_CC);
        h->buffer = php_http_buffer_init(NULL TSRMLS_CC);
        h->parser = php_http_message_parser_init(NULL TSRMLS_CC);
        h->message = php_http_message_init(NULL, 0 TSRMLS_CC);
@@ -53,6 +54,12 @@ PHP_HTTP_API void php_http_request_dtor(php_http_request_t *h)
                h->ops->dtor(h);
        }
 
+       php_http_resource_factory_free(&h->rf);
+
+       if (h->persistent_handle_id) {
+               zval_ptr_dtor(&h->persistent_handle_id);
+       }
+
        php_http_message_parser_free(&h->parser);
        php_http_message_free(&h->message);
        php_http_buffer_free(&h->buffer);
@@ -306,7 +313,7 @@ zend_object_value php_http_request_object_new_ex(zend_class_entry *ce, php_http_
        object_properties_init((zend_object *) o, ce);
 
        if (!(o->request = r)) {
-               o->request = php_http_request_init(NULL, NULL, NULL TSRMLS_CC);
+               o->request = php_http_request_init(NULL, NULL, NULL, NULL TSRMLS_CC);
        }
 
        if (ptr) {
@@ -439,19 +446,19 @@ STATUS php_http_request_object_requesthandler(php_http_request_object_t *obj, zv
 
        if (SUCCESS == php_http_request_getopt(obj->request, PHP_HTTP_REQUEST_OPT_PROGRESS_INFO, &progress)) {
                if (!progress->callback) {
-                       zval *pcb;
-                       int no = 0;
+                       php_http_request_progress_callback_t *callback = emalloc(sizeof(*callback));
 
-                       MAKE_STD_ZVAL(pcb);
-                       array_init(pcb);
+                       callback->type = PHP_HTTP_REQUEST_PROGRESS_CALLBACK_USER;
+                       callback->pass_state = 0;
+                       MAKE_STD_ZVAL(callback->func.user);
+                       array_init(callback->func.user);
                        Z_ADDREF_P(getThis());
-                       add_next_index_zval(pcb, getThis());
-                       add_next_index_stringl(pcb, ZEND_STRL("notify"), 1);
+                       add_next_index_zval(callback->func.user, getThis());
+                       add_next_index_stringl(callback->func.user, ZEND_STRL("notify"), 1);
 
-                       php_http_request_setopt(obj->request, PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK, pcb);
-                       php_http_request_setopt(obj->request, PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK_WANTS_STATE, &no);
-                       zval_ptr_dtor(&pcb);
+                       php_http_request_setopt(obj->request, PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK, callback);
                }
+               progress->state.info = "start";
                php_http_request_progress_notify(progress TSRMLS_CC);
                progress->state.started = 1;
        }
@@ -523,6 +530,7 @@ STATUS php_http_request_object_responsehandler(php_http_request_object_t *obj, z
        }
 
        if (SUCCESS == php_http_request_getopt(obj->request, PHP_HTTP_REQUEST_OPT_PROGRESS_INFO, &progress)) {
+               progress->state.info = "finished";
                progress->state.finished = 1;
                php_http_request_progress_notify(progress TSRMLS_CC);
        }
@@ -595,14 +603,14 @@ static inline void php_http_request_object_get_options_subr(INTERNAL_FUNCTION_PA
 
 PHP_METHOD(HttpRequest, __construct)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                zend_parse_parameters_none();
        } end_error_handling();
 }
 
 PHP_METHOD(HttpRequest, getObservers)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
                        RETVAL_PROP(php_http_request_class_entry, "observers");
                }
@@ -675,6 +683,7 @@ PHP_METHOD(HttpRequest, getProgress)
                object_init(return_value);
                add_property_bool(return_value, "started", progress->state.started);
                add_property_bool(return_value, "finished", progress->state.finished);
+               add_property_string(return_value, "info", STR_PTR(progress->state.info), 1);
                add_property_double(return_value, "dltotal", progress->state.dl.total);
                add_property_double(return_value, "dlnow", progress->state.dl.now);
                add_property_double(return_value, "ultotal", progress->state.ul.total);
@@ -965,7 +974,7 @@ PHP_METHOD(HttpRequest, setQueryData)
                                efree(query_data_str);
                        }
                } else {
-                       zval *data = php_http_zsep(IS_STRING, qdata);
+                       zval *data = php_http_ztyp(IS_STRING, qdata);
 
                        zend_update_property_stringl(php_http_request_class_entry, getThis(), ZEND_STRL("queryData"), Z_STRVAL_P(data), Z_STRLEN_P(data) TSRMLS_CC);
                        zval_ptr_dtor(&data);
@@ -1087,7 +1096,7 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                        if (allowed_extras_array) {
                                allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *));
                                FOREACH_VAL(pos, allowed_extras_array, entry) {
-                                       zval *data = php_http_zsep(IS_STRING, *entry);
+                                       zval *data = php_http_ztyp(IS_STRING, *entry);
                                        allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
                                        zval_ptr_dtor(&data);
                                }
@@ -1101,7 +1110,7 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                zval **single_header;
 
                                                FOREACH_VAL(pos2, *header, single_header) {
-                                                       zval *data = php_http_zsep(IS_STRING, *single_header);
+                                                       zval *data = php_http_ztyp(IS_STRING, *single_header);
 
                                                        if ((list = php_http_cookie_list_parse(NULL, Z_STRVAL_P(data), flags, allowed_extras TSRMLS_CC))) {
                                                                zval *cookie;
@@ -1113,7 +1122,7 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                        zval_ptr_dtor(&data);
                                                }
                                        } else {
-                                               zval *data = php_http_zsep(IS_STRING, *header);
+                                               zval *data = php_http_ztyp(IS_STRING, *header);
                                                if ((list = php_http_cookie_list_parse(NULL, Z_STRVAL_P(data), flags, allowed_extras TSRMLS_CC))) {
                                                        zval *cookie;
 
@@ -1167,7 +1176,7 @@ PHP_METHOD(HttpRequest, getResponseStatus)
 
 PHP_METHOD(HttpRequest, getResponseMessage)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
                        zval *message = zend_read_property(php_http_request_class_entry, getThis(), ZEND_STRL("responseMessage"), 0 TSRMLS_CC);
 
@@ -1182,7 +1191,7 @@ PHP_METHOD(HttpRequest, getResponseMessage)
 
 PHP_METHOD(HttpRequest, getRequestMessage)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
                        zval *message = zend_read_property(php_http_request_class_entry, getThis(), ZEND_STRL("requestMessage"), 0 TSRMLS_CC);
 
@@ -1197,7 +1206,7 @@ PHP_METHOD(HttpRequest, getRequestMessage)
 
 PHP_METHOD(HttpRequest, getHistory)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
                        zval *hist = zend_read_property(php_http_request_class_entry, getThis(), ZEND_STRL("history"), 0 TSRMLS_CC);
 
@@ -1241,7 +1250,7 @@ PHP_METHOD(HttpRequest, send)
 {
        RETVAL_FALSE;
 
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
                        php_http_request_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
                        php_http_request_method_t meth = PHP_HTTP_NO_REQUEST_METHOD;
index b848612..96baa36 100644 (file)
@@ -28,17 +28,39 @@ typedef struct php_http_request_progress_state {
                double now;
                double total;
        } dl;
+       const char *info;
        unsigned started:1;
        unsigned finished:1;
 } php_http_request_progress_state_t;
 
+#define PHP_HTTP_REQUEST_PROGRESS_CALLBACK_USER 0
+#define PHP_HTTP_REQUEST_PROGRESS_CALLBACK_INTERN 1
+typedef struct php_http_request_progress_callback {
+       union {
+               zval *user;
+               void (*intern)(php_http_request_progress_state_t* TSRMLS_DC);
+       } func;
+       unsigned type:1;
+       unsigned pass_state:1;
+} php_http_request_progress_callback_t;
+
 typedef struct php_http_request_progress {
        php_http_request_progress_state_t state;
-       zval *callback;
+       php_http_request_progress_callback_t *callback;
        unsigned in_cb:1;
-       unsigned pass_state:1;
 } php_http_request_progress_t;
 
+static inline void php_http_request_progress_dtor(php_http_request_progress_t *progress TSRMLS_DC)
+{
+       if (progress->callback) {
+               if (progress->callback->type == PHP_HTTP_REQUEST_PROGRESS_CALLBACK_USER) {
+                       zval_ptr_dtor(&progress->callback->func.user);
+               }
+               efree(progress->callback);
+       }
+       memset(progress, 0, sizeof(*progress));
+}
+
 static inline void php_http_request_progress_notify(php_http_request_progress_t *progress TSRMLS_DC)
 {
        if (progress->callback) {
@@ -48,27 +70,37 @@ static inline void php_http_request_progress_notify(php_http_request_progress_t
                ZVAL_NULL(&retval);
 
                with_error_handling(EH_NORMAL, NULL) {
-                       if (progress->pass_state) {
-                               zval *param;
-
-                               MAKE_STD_ZVAL(param);
-                               array_init(param);
-                               add_assoc_bool(param, "started", progress->state.started);
-                               add_assoc_bool(param, "finished", progress->state.finished);
-                               add_assoc_double(param, "dltotal", progress->state.dl.total);
-                               add_assoc_double(param, "dlnow", progress->state.dl.now);
-                               add_assoc_double(param, "ultotal", progress->state.ul.total);
-                               add_assoc_double(param, "ulnow", progress->state.ul.now);
-
-                               progress->in_cb = 1;
-                               call_user_function(EG(function_table), NULL, progress->callback, &retval, 1, &param TSRMLS_CC);
-                               progress->in_cb = 0;
-
-                               zval_ptr_dtor(&param);
-                       } else {
-                               progress->in_cb = 1;
-                               call_user_function(EG(function_table), NULL, progress->callback, &retval, 0, NULL TSRMLS_CC);
-                               progress->in_cb = 0;
+                       switch (progress->callback->type) {
+                               case PHP_HTTP_REQUEST_PROGRESS_CALLBACK_USER:
+                                       if (progress->callback->pass_state) {
+                                               zval *param;
+
+                                               MAKE_STD_ZVAL(param);
+                                               array_init(param);
+                                               add_assoc_bool(param, "started", progress->state.started);
+                                               add_assoc_bool(param, "finished", progress->state.finished);
+                                               add_assoc_string(param, "info", estrdup(progress->state.info), 0);
+                                               add_assoc_double(param, "dltotal", progress->state.dl.total);
+                                               add_assoc_double(param, "dlnow", progress->state.dl.now);
+                                               add_assoc_double(param, "ultotal", progress->state.ul.total);
+                                               add_assoc_double(param, "ulnow", progress->state.ul.now);
+
+                                               progress->in_cb = 1;
+                                               call_user_function(EG(function_table), NULL, progress->callback->func.user, &retval, 1, &param TSRMLS_CC);
+                                               progress->in_cb = 0;
+
+                                               zval_ptr_dtor(&param);
+                                       } else {
+                                               progress->in_cb = 1;
+                                               call_user_function(EG(function_table), NULL, progress->callback->func.user, &retval, 0, NULL TSRMLS_CC);
+                                               progress->in_cb = 0;
+                                       }
+                                       break;
+                               case PHP_HTTP_REQUEST_PROGRESS_CALLBACK_INTERN:
+                                       progress->callback->func.intern(progress->callback->pass_state ? &progress->state : NULL TSRMLS_CC);
+                                       break;
+                               default:
+                                       break;
                        }
                } end_error_handling();
 
@@ -78,8 +110,7 @@ static inline void php_http_request_progress_notify(php_http_request_progress_t
 
 typedef enum php_http_request_setopt_opt {
        PHP_HTTP_REQUEST_OPT_SETTINGS,                                          /* HashTable* */
-       PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK,                         /* zval* */
-       PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK_WANTS_STATE,     /* int* */
+       PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK,                         /* php_http_request_progress_callback_t* */
        PHP_HTTP_REQUEST_OPT_COOKIES_ENABLE,                            /* - */
        PHP_HTTP_REQUEST_OPT_COOKIES_RESET,                                     /* - */
        PHP_HTTP_REQUEST_OPT_COOKIES_RESET_SESSION,                     /* - */
@@ -102,6 +133,7 @@ typedef STATUS (*php_http_request_setopt_func_t)(php_http_request_t *h, php_http
 typedef STATUS (*php_http_request_getopt_func_t)(php_http_request_t *h, php_http_request_getopt_opt_t opt, void *arg);
 
 typedef struct php_http_request_ops {
+       php_http_resource_factory_ops_t *rsrc;
        php_http_request_init_func_t init;
        php_http_request_copy_func_t copy;
        php_http_request_dtor_func_t dtor;
@@ -115,16 +147,18 @@ PHP_HTTP_API php_http_request_ops_t *php_http_request_get_default_ops(TSRMLS_D);
 
 struct php_http_request {
        void *ctx;
+       php_http_resource_factory_t *rf;
        php_http_request_ops_t *ops;
        php_http_message_parser_t *parser;
        php_http_message_t *message;
        php_http_buffer_t *buffer;
+       zval *persistent_handle_id;
 #ifdef ZTS
        void ***ts;
 #endif
 };
 
-PHP_HTTP_API php_http_request_t *php_http_request_init(php_http_request_t *h, php_http_request_ops_t *ops, void *init_arg TSRMLS_DC);
+PHP_HTTP_API php_http_request_t *php_http_request_init(php_http_request_t *h, php_http_request_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg TSRMLS_DC);
 PHP_HTTP_API php_http_request_t *php_http_request_copy(php_http_request_t *from, php_http_request_t *to);
 PHP_HTTP_API STATUS php_http_request_exec(php_http_request_t *h, php_http_request_method_t meth, const char *url, php_http_message_body_t *body);
 PHP_HTTP_API STATUS php_http_request_reset(php_http_request_t *h);
index 68e4c07..f44d5b0 100644 (file)
@@ -28,7 +28,7 @@ php_http_request_datashare_t *php_http_request_datashare_global_get(const char *
                php_http_request_factory_driver_t driver;
 
                if ((SUCCESS == php_http_request_factory_get_driver(driver_str, driver_len, &driver)) && driver.request_datashare_ops) {
-                       s = php_http_request_datashare_init(NULL, driver.request_datashare_ops, NULL, 1 TSRMLS_CC);
+                       s = php_http_request_datashare_init(NULL, driver.request_datashare_ops, NULL, NULL, 1 TSRMLS_CC);
                        zend_hash_add(&php_http_request_datashare_global_shares, lower_str, driver_len + 1, &s, sizeof(php_http_request_datashare_t *), NULL);
                }
        }
@@ -40,9 +40,9 @@ php_http_request_datashare_t *php_http_request_datashare_global_get(const char *
        return s;
 }
 
-PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_http_request_datashare_t *h, php_http_request_datashare_ops_t *ops, void *init_arg, zend_bool persistent TSRMLS_DC)
+PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_http_request_datashare_t *h, php_http_request_datashare_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg, zend_bool persistent TSRMLS_DC)
 {
-       php_http_request_datashare_t *free_h;
+       php_http_request_datashare_t *free_h = NULL;
 
        if (!h) {
                free_h = h = pemalloc(sizeof(*h), persistent);
@@ -55,6 +55,7 @@ PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_h
                TSRMLS_SET_CTX(h->ts);
        }
        h->ops = ops;
+       h->rf = rf ? rf : php_http_resource_factory_init(NULL, h->ops->rsrc, NULL, NULL TSRMLS_CC);
 
        if (h->ops->init) {
                if (!(h = h->ops->init(h, init_arg))) {
@@ -86,6 +87,10 @@ PHP_HTTP_API void php_http_request_datashare_dtor(php_http_request_datashare_t *
                pefree(h->requests, h->persistent);
                h->requests = NULL;
        }
+
+       if (h->persistent_handle_id) {
+               zval_ptr_dtor(&h->persistent_handle_id);
+       }
 }
 
 PHP_HTTP_API void php_http_request_datashare_free(php_http_request_datashare_t **h)
@@ -212,7 +217,7 @@ zend_object_value php_http_request_datashare_object_new_ex(zend_class_entry *ce,
        if (share) {
                o->share = share;
        } else {
-               o->share = php_http_request_datashare_init(NULL, NULL, NULL, 0 TSRMLS_CC);
+               o->share = php_http_request_datashare_init(NULL, NULL, NULL, NULL, 0 TSRMLS_CC);
        }
 
        if (ptr) {
@@ -275,7 +280,7 @@ static zval **php_http_request_datashare_object_get_prop_ptr(zval *object, zval
 
 PHP_METHOD(HttpRequestDataShare, __construct)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                zend_parse_parameters_none();
        } end_error_handling();
 }
index cdc4142..3b71962 100644 (file)
@@ -19,6 +19,7 @@ typedef STATUS (*php_http_request_datashare_detach_func_t)(php_http_request_data
 typedef STATUS (*php_http_request_datashare_setopt_func_t)(php_http_request_datashare_t *h, php_http_request_datashare_setopt_opt_t opt, void *arg);
 
 typedef struct php_http_request_datashare_ops {
+       php_http_resource_factory_ops_t *rsrc;
        php_http_request_datashare_init_func_t init;
        php_http_request_datashare_copy_func_t copy;
        php_http_request_datashare_dtor_func_t dtor;
@@ -31,9 +32,11 @@ typedef struct php_http_request_datashare_ops {
 #define PHP_HTTP_REQUEST_DATASHARE_REQUESTS(s) ((s)->persistent ? &PHP_HTTP_G->request_datashare.requests : (s)->requests)
 struct php_http_request_datashare {
        void *ctx;
+       php_http_resource_factory_t *rf;
        php_http_request_datashare_ops_t *ops;
        zend_llist *requests; /* NULL if persistent, use PHP_HTTP_REQUEST_DATASHARE_REQUESTS */
        unsigned persistent:1;
+       zval *persistent_handle_id;
 #ifdef ZTS
        void ***ts;
 #endif
@@ -54,7 +57,7 @@ extern PHP_MSHUTDOWN_FUNCTION(http_request_datashare);
 extern PHP_RINIT_FUNCTION(http_request_datashare);
 extern PHP_RSHUTDOWN_FUNCTION(http_request_datashare);
 
-PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_http_request_datashare_t *h, php_http_request_datashare_ops_t *ops, void *init_arg, zend_bool persistent TSRMLS_DC);
+PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_http_request_datashare_t *h, php_http_request_datashare_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg, zend_bool persistent TSRMLS_DC);
 PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_copy(php_http_request_datashare_t *from, php_http_request_datashare_t *to);
 PHP_HTTP_API void php_http_request_datashare_dtor(php_http_request_datashare_t *h);
 PHP_HTTP_API void php_http_request_datashare_free(php_http_request_datashare_t **h);
index 16352ee..a4ac4f0 100644 (file)
@@ -47,7 +47,6 @@ static zend_class_entry *php_http_request_factory_get_class_entry(zval *this_ptr
 #define PHP_HTTP_REQUEST_FACTORY_MALIAS(me, al, vis)   ZEND_FENTRY(me, ZEND_MN(HttpRequestFactory_##al), PHP_HTTP_ARGS(HttpRequestFactory, al), vis)
 
 PHP_HTTP_BEGIN_ARGS(__construct, 1)
-       PHP_HTTP_ARG_VAL(driver, 0)
        PHP_HTTP_ARG_VAL(options, 0)
 PHP_HTTP_END_ARGS;
 PHP_HTTP_BEGIN_ARGS(createRequest, 0)
@@ -78,34 +77,23 @@ zend_function_entry php_http_request_factory_method_entry[] = {
 
 PHP_METHOD(HttpRequestFactory, __construct)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
-               char *driver_str;
-               int driver_len;
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                HashTable *options = NULL;
 
-               if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|h", &driver_str, &driver_len, &options)) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_factory)) {
-                               char *lower_str = php_strtolower(estrdup(driver_str), driver_len);
-
-                               if (zend_hash_exists(&php_http_request_factory_drivers, lower_str, driver_len + 1)) {
-                                       zend_update_property_stringl(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), lower_str, driver_len TSRMLS_CC);
-
-                                       if (options) {
-                                               zval **val;
-                                               HashPosition pos;
-                                               php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
-
-                                               FOREACH_HASH_KEYVAL(pos, options, key, val) {
-                                                       if (key.type == HASH_KEY_IS_STRING) {
-                                                               zend_update_property(php_http_request_factory_class_entry, getThis(), key.str, key.len - 1, *val);
-                                                       }
-                                               }
+               if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &options)) {
+                       if (options) {
+                               zval **val;
+                               HashPosition pos;
+                               php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
+
+                               FOREACH_HASH_KEYVAL(pos, options, key, val) {
+                                       if (key.type == HASH_KEY_IS_STRING) {
+                                               zval *newval = php_http_zsep(1, Z_TYPE_PP(val), *val);
+                                               zend_update_property(php_http_request_factory_class_entry, getThis(), key.str, key.len - 1, newval);
+                                               zval_ptr_dtor(&newval);
                                        }
-                               } else {
-                                       php_http_error(HE_THROW, PHP_HTTP_E_REQUEST_FACTORY, "unknown request driver: '%s'", driver_str);
                                }
-                               efree(lower_str);
-                       } end_error_handling();
+                       }
                }
        } end_error_handling();
 }
@@ -117,48 +105,74 @@ PHP_METHOD(HttpRequestFactory, createRequest)
        long meth = -1;
        zval *options = NULL;
 
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!la!", &url_str, &url_len, &meth, &options)) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_factory)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                zval *zdriver, *os;
                                zend_object_value ov;
                                zend_class_entry *class_entry = NULL;
                                php_http_request_t *req = NULL;
                                php_http_request_factory_driver_t driver;
 
-                               if (!(class_entry = php_http_request_factory_get_class_entry(getThis(), ZEND_STRL("requestClass") TSRMLS_CC))) {
+                               class_entry = php_http_request_factory_get_class_entry(getThis(), ZEND_STRL("requestClass") TSRMLS_CC);
+
+                               if (!class_entry) {
                                        class_entry = php_http_request_class_entry;
                                }
 
-                               if ((zdriver = zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), 0 TSRMLS_CC))
-                               &&      (IS_STRING == Z_TYPE_P(zdriver))
-                               &&      (SUCCESS == php_http_request_factory_get_driver(Z_STRVAL_P(zdriver), Z_STRLEN_P(zdriver), &driver))
-                               &&      (driver.request_ops)
-                               &&      (req = php_http_request_init(NULL, driver.request_ops, NULL TSRMLS_CC))
-                               &&      (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_request_object_new_ex, php_http_request_class_entry, req, NULL TSRMLS_CC))
-                               ) {
-                                       ZVAL_OBJVAL(return_value, ov, 0);
-
-                                       MAKE_STD_ZVAL(os);
-                                       object_init_ex(os, spl_ce_SplObjectStorage);
-                                       zend_update_property(php_http_request_class_entry, return_value, ZEND_STRL("observers"), os TSRMLS_CC);
-                                       zval_ptr_dtor(&os);
-
-                                       if (url_str) {
-                                               zend_update_property_stringl(php_http_request_class_entry, return_value, ZEND_STRL("url"), url_str, url_len TSRMLS_CC);
-                                       }
-                                       if (meth > 0) {
-                                               zend_update_property_long(php_http_request_class_entry, return_value, ZEND_STRL("method"), meth TSRMLS_CC);
-                                       }
-                                       if (options) {
-                                               zend_call_method_with_1_params(&return_value, Z_OBJCE_P(return_value), NULL, "setoptions", NULL, options);
+                               zdriver = zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), 0 TSRMLS_CC);
+
+                               if ((IS_STRING == Z_TYPE_P(zdriver)) && (SUCCESS == php_http_request_factory_get_driver(Z_STRVAL_P(zdriver), Z_STRLEN_P(zdriver), &driver)) && driver.request_ops) {
+                                       zval *phi = php_http_zsep(1, IS_STRING, zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("persistentHandleId"), 0 TSRMLS_CC));
+                                       php_http_resource_factory_t *rf = NULL;
+
+                                       if (Z_STRLEN_P(phi)) {
+                                               char *name_str;
+                                               size_t name_len;
+                                               php_http_persistent_handle_factory_t *pf;
+
+                                               name_len = spprintf(&name_str, 0, "http_request.%s", Z_STRVAL_P(zdriver));
+
+                                               if ((pf = php_http_persistent_handle_concede(NULL , name_str, name_len, Z_STRVAL_P(phi), Z_STRLEN_P(phi) TSRMLS_CC))) {
+                                                       php_http_resource_factory_ops_t ops = {
+                                                                       php_http_persistent_handle_acquire,
+                                                                       php_http_persistent_handle_accrete,
+                                                                       php_http_persistent_handle_release
+                                                       };
+
+                                                       rf = php_http_resource_factory_init(NULL, &ops, pf, php_http_persistent_handle_abandon TSRMLS_CC);
+                                               }
+
+                                               efree(name_str);
                                        }
-                               } else {
+
+                                       req = php_http_request_init(NULL, driver.request_ops, rf, NULL TSRMLS_CC);
                                        if (req) {
-                                               php_http_request_free(&req);
-                                       } else {
-                                               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_FACTORY, "requests are not supported by this driver");
+                                               if (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_request_object_new_ex, php_http_request_class_entry, req, NULL TSRMLS_CC)) {
+                                                       ZVAL_OBJVAL(return_value, ov, 0);
+
+                                                       MAKE_STD_ZVAL(os);
+                                                       object_init_ex(os, spl_ce_SplObjectStorage);
+                                                       zend_update_property(php_http_request_class_entry, return_value, ZEND_STRL("observers"), os TSRMLS_CC);
+                                                       zval_ptr_dtor(&os);
+
+                                                       if (url_str) {
+                                                               zend_update_property_stringl(php_http_request_class_entry, return_value, ZEND_STRL("url"), url_str, url_len TSRMLS_CC);
+                                                       }
+                                                       if (meth > 0) {
+                                                               zend_update_property_long(php_http_request_class_entry, return_value, ZEND_STRL("method"), meth TSRMLS_CC);
+                                                       }
+                                                       if (options) {
+                                                               zend_call_method_with_1_params(&return_value, Z_OBJCE_P(return_value), NULL, "setoptions", NULL, options);
+                                                       }
+                                               } else {
+                                                       php_http_request_free(&req);
+                                               }
                                        }
+
+                                       zval_ptr_dtor(&phi);
+                               } else {
+                                       php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_FACTORY, "requests are not supported by this driver");
                                }
                        } end_error_handling();
                }
@@ -170,41 +184,62 @@ PHP_METHOD(HttpRequestFactory, createPool)
        int argc = 0;
        zval ***argv;
 
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|*", &argv, &argc)) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_factory)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                int i;
                                zval *zdriver;
                                zend_object_value ov;
                                zend_class_entry *class_entry = NULL;
                                php_http_request_pool_t *pool = NULL;
-                               php_http_request_pool_object_t *obj;
                                php_http_request_factory_driver_t driver;
 
                                if (!(class_entry = php_http_request_factory_get_class_entry(getThis(), ZEND_STRL("requestPoolClass") TSRMLS_CC))) {
                                        class_entry = php_http_request_pool_class_entry;
                                }
 
-                               if ((zdriver = zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), 0 TSRMLS_CC))
-                               &&      (IS_STRING == Z_TYPE_P(zdriver))
-                               &&      (SUCCESS == php_http_request_factory_get_driver(Z_STRVAL_P(zdriver), Z_STRLEN_P(zdriver), &driver))
-                               &&      (driver.request_pool_ops)
-                               &&      (pool = php_http_request_pool_init(NULL, driver.request_pool_ops, NULL TSRMLS_CC))
-                               &&      (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_request_pool_object_new_ex, php_http_request_pool_class_entry, pool, (void *) &obj TSRMLS_CC))
-                               ) {
-                                       ZVAL_OBJVAL(return_value, ov, 0);
-
-                                       for (i = 0; i < argc; ++i) {
-                                               if (Z_TYPE_PP(argv[i]) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(argv[i]), php_http_request_class_entry TSRMLS_CC)) {
-                                                       php_http_request_pool_attach(obj->pool, *(argv[i]));
+                               zdriver = zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), 0 TSRMLS_CC);
+                               if ((IS_STRING == Z_TYPE_P(zdriver)) && (SUCCESS == php_http_request_factory_get_driver(Z_STRVAL_P(zdriver), Z_STRLEN_P(zdriver), &driver)) && driver.request_pool_ops) {
+                                       zval *phi = php_http_zsep(1, IS_STRING, zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("persistentHandleId"), 0 TSRMLS_CC));
+                                       php_http_resource_factory_t *rf = NULL;
+
+                                       if (Z_STRLEN_P(phi)) {
+                                               char *name_str;
+                                               size_t name_len;
+                                               php_http_persistent_handle_factory_t *pf;
+
+                                               name_len = spprintf(&name_str, 0, "http_request_pool.%s", Z_STRVAL_P(zdriver));
+
+                                               if ((pf = php_http_persistent_handle_concede(NULL , name_str, name_len, Z_STRVAL_P(phi), Z_STRLEN_P(phi) TSRMLS_CC))) {
+                                                       php_http_resource_factory_ops_t ops = {
+                                                                       php_http_persistent_handle_acquire,
+                                                                       php_http_persistent_handle_accrete,
+                                                                       php_http_persistent_handle_release
+                                                       };
+
+                                                       rf = php_http_resource_factory_init(NULL, &ops, pf, php_http_persistent_handle_abandon TSRMLS_CC);
                                                }
+
+                                               efree(name_str);
                                        }
-                               } else {
+
+                                       pool = php_http_request_pool_init(NULL, driver.request_pool_ops, rf, NULL TSRMLS_CC);
                                        if (pool) {
-                                               php_http_request_pool_free(&pool);
-                                       } else {
-                                               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_FACTORY, "pools are not supported by this driver");
+                                               if (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_request_pool_object_new_ex, php_http_request_pool_class_entry, pool, NULL TSRMLS_CC)) {
+                                                       ZVAL_OBJVAL(return_value, ov, 0);
+                                                       for (i = 0; i < argc; ++i) {
+                                                               if (Z_TYPE_PP(argv[i]) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(argv[i]), php_http_request_class_entry TSRMLS_CC)) {
+                                                                       php_http_request_pool_attach(pool, *(argv[i]));
+                                                               }
+                                                       }
+                                               } else {
+                                                       php_http_request_pool_free(&pool);
+                                               }
                                        }
+
+                                       zval_ptr_dtor(&phi);
+                               } else {
+                                       php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_FACTORY, "pools are not supported by this driver");
                                }
                        } end_error_handling();
                }
@@ -216,41 +251,62 @@ PHP_METHOD(HttpRequestFactory, createDataShare)
        int argc = 0;
        zval ***argv;
 
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|*", &argv, &argc)) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_factory)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                int i;
                                zval *zdriver;
                                zend_object_value ov;
                                zend_class_entry *class_entry;
                                php_http_request_datashare_t *share = NULL;
-                               php_http_request_datashare_object_t *obj;
                                php_http_request_factory_driver_t driver;
 
                                if (!(class_entry = php_http_request_factory_get_class_entry(getThis(), ZEND_STRL("requestDataShareClass") TSRMLS_CC))) {
                                        class_entry = php_http_request_datashare_class_entry;
                                }
 
-                               if ((zdriver = zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), 0 TSRMLS_CC))
-                               &&      (IS_STRING == Z_TYPE_P(zdriver))
-                               &&      (SUCCESS == php_http_request_factory_get_driver(Z_STRVAL_P(zdriver), Z_STRLEN_P(zdriver), &driver))
-                               &&      (driver.request_datashare_ops)
-                               &&      (share = php_http_request_datashare_init(NULL, driver.request_datashare_ops, NULL, 0 TSRMLS_CC))
-                               &&      (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_request_datashare_object_new_ex, php_http_request_datashare_class_entry, share, (void *) &obj TSRMLS_CC))
-                               ) {
-                                       ZVAL_OBJVAL(return_value, ov, 0);
-
-                                       for (i = 0; i < argc; ++i) {
-                                               if (Z_TYPE_PP(argv[i]) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(argv[i]), php_http_request_class_entry TSRMLS_CC)) {
-                                                       php_http_request_datashare_attach(obj->share, *(argv[i]));
+                               zdriver = zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("driver"), 0 TSRMLS_CC);
+                               if ((IS_STRING == Z_TYPE_P(zdriver)) && (SUCCESS == php_http_request_factory_get_driver(Z_STRVAL_P(zdriver), Z_STRLEN_P(zdriver), &driver)) && driver.request_datashare_ops) {
+                                       zval *phi = php_http_zsep(1, IS_STRING, zend_read_property(php_http_request_factory_class_entry, getThis(), ZEND_STRL("persistentHandleId"), 0 TSRMLS_CC));
+                                       php_http_resource_factory_t *rf = NULL;
+
+                                       if (Z_STRLEN_P(phi)) {
+                                               char *name_str;
+                                               size_t name_len;
+                                               php_http_persistent_handle_factory_t *pf;
+
+                                               name_len = spprintf(&name_str, 0, "http_request_datashare.%s", Z_STRVAL_P(zdriver));
+
+                                               if ((pf = php_http_persistent_handle_concede(NULL , name_str, name_len, Z_STRVAL_P(phi), Z_STRLEN_P(phi) TSRMLS_CC))) {
+                                                       php_http_resource_factory_ops_t ops = {
+                                                                       php_http_persistent_handle_acquire,
+                                                                       php_http_persistent_handle_accrete,
+                                                                       php_http_persistent_handle_release
+                                                       };
+
+                                                       rf = php_http_resource_factory_init(NULL, &ops, pf, php_http_persistent_handle_abandon TSRMLS_CC);
                                                }
+
+                                               efree(name_str);
                                        }
-                               } else {
+
+                                       share = php_http_request_datashare_init(NULL, driver.request_datashare_ops, rf, NULL, 0 TSRMLS_CC);
                                        if (share) {
-                                               php_http_request_datashare_free(&share);
-                                       } else {
-                                               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_FACTORY, "datashares are not supported by this driver");
+                                               if (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_request_datashare_object_new_ex, php_http_request_datashare_class_entry, share, NULL TSRMLS_CC)) {
+                                                       ZVAL_OBJVAL(return_value, ov, 0);
+                                                       for (i = 0; i < argc; ++i) {
+                                                               if (Z_TYPE_PP(argv[i]) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(argv[i]), php_http_request_class_entry TSRMLS_CC)) {
+                                                                       php_http_request_datashare_attach(share, *(argv[i]));
+                                                               }
+                                                       }
+                                               } else {
+                                                       php_http_request_datashare_free(&share);
+                                               }
                                        }
+
+                                       zval_ptr_dtor(&phi);
+                               } else {
+                                       php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_FACTORY, "datashares are not supported by this driver");
                                }
                        } end_error_handling();
                }
@@ -259,9 +315,9 @@ PHP_METHOD(HttpRequestFactory, createDataShare)
 
 PHP_METHOD(HttpRequestFactory, getGlobalDataShareInstance)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_datashare)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                zval *instance = *zend_std_get_static_property(php_http_request_datashare_class_entry, ZEND_STRL("instance"), 0, NULL TSRMLS_CC);
 
                                if (Z_TYPE_P(instance) != IS_OBJECT) {
@@ -327,10 +383,13 @@ PHP_MINIT_FUNCTION(http_request_factory)
        zend_hash_init(&php_http_request_factory_drivers, 0, NULL, NULL, 1);
 
        PHP_HTTP_REGISTER_CLASS(http\\request, Factory, http_request_factory, php_http_object_class_entry, 0);
-       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("driver"), ZEND_ACC_PRIVATE TSRMLS_CC);
-       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("requestClass"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("requestPoolClass"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("requestDataShareClass"), ZEND_ACC_PUBLIC TSRMLS_CC);
+       php_http_request_factory_class_entry->create_object = php_http_request_factory_new;
+
+       zend_declare_property_stringl(php_http_request_factory_class_entry, ZEND_STRL("driver"), ZEND_STRL("curl"), ZEND_ACC_PROTECTED TSRMLS_CC);
+       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("persistentHandleId"), ZEND_ACC_PROTECTED TSRMLS_CC);
+       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("requestClass"), ZEND_ACC_PROTECTED TSRMLS_CC);
+       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("requestPoolClass"), ZEND_ACC_PROTECTED TSRMLS_CC);
+       zend_declare_property_null(php_http_request_factory_class_entry, ZEND_STRL("requestDataShareClass"), ZEND_ACC_PROTECTED TSRMLS_CC);
 
        return SUCCESS;
 }
index 7f081b8..379e3b1 100644 (file)
@@ -4,7 +4,7 @@
 #include <Zend/zend_interfaces.h>
 #include <ext/spl/spl_iterators.h>
 
-PHP_HTTP_API php_http_request_pool_t *php_http_request_pool_init(php_http_request_pool_t *h, php_http_request_pool_ops_t *ops, void *init_arg TSRMLS_DC)
+PHP_HTTP_API php_http_request_pool_t *php_http_request_pool_init(php_http_request_pool_t *h, php_http_request_pool_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg TSRMLS_DC)
 {
        php_http_request_pool_t *free_h = NULL;
 
@@ -14,6 +14,7 @@ PHP_HTTP_API php_http_request_pool_t *php_http_request_pool_init(php_http_reques
        memset(h, 0, sizeof(*h));
 
        h->ops = ops;
+       h->rf = rf ? rf : php_http_resource_factory_init(NULL, h->ops->rsrc, NULL, NULL TSRMLS_CC);
        zend_llist_init(&h->requests.attached, sizeof(zval *), (llist_dtor_func_t) ZVAL_PTR_DTOR, 0);
        zend_llist_init(&h->requests.finished, sizeof(zval *), (llist_dtor_func_t) ZVAL_PTR_DTOR, 0);
        TSRMLS_SET_CTX(h->ts);
@@ -47,6 +48,10 @@ PHP_HTTP_API void php_http_request_pool_dtor(php_http_request_pool_t *h)
 
        zend_llist_clean(&h->requests.finished);
        zend_llist_clean(&h->requests.attached);
+
+       if (h->persistent_handle_id) {
+               zval_ptr_dtor(&h->persistent_handle_id);
+       }
 }
 
 PHP_HTTP_API void php_http_request_pool_free(php_http_request_pool_t **h) {
@@ -285,7 +290,7 @@ zend_object_value php_http_request_pool_object_new_ex(zend_class_entry *ce, php_
        object_properties_init((zend_object *) o, ce);
 
        if (!(o->pool = p)) {
-               o->pool = php_http_request_pool_init(NULL, NULL, NULL TSRMLS_CC);
+               o->pool = php_http_request_pool_init(NULL, NULL, NULL, NULL TSRMLS_CC);
        }
 
        if (ptr) {
@@ -316,7 +321,7 @@ static void php_http_request_pool_object_llist2array(zval **req, zval *array TSR
 
 PHP_METHOD(HttpRequestPool, __construct)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                zend_parse_parameters_none();
        } end_error_handling();
 }
@@ -345,11 +350,11 @@ PHP_METHOD(HttpRequestPool, reset)
 
 PHP_METHOD(HttpRequestPool, attach)
 {
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                zval *request;
 
                if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_request_class_entry)) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                php_http_request_pool_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
                                if (obj->iterator.pos > 0 && obj->iterator.pos < zend_llist_count(&obj->pool->requests.attached)) {
@@ -368,11 +373,11 @@ PHP_METHOD(HttpRequestPool, detach)
 {
        RETVAL_FALSE;
 
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                zval *request;
 
                if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_request_class_entry)) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_pool)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                php_http_request_pool_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
                                obj->iterator.pos = -1;
@@ -388,9 +393,9 @@ PHP_METHOD(HttpRequestPool, send)
 {
        RETVAL_FALSE;
 
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                if (SUCCESS == zend_parse_parameters_none()) {
-                       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_pool)) {
+                       with_error_handling(EH_THROW, php_http_exception_class_entry) {
                                php_http_request_pool_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
                                php_http_request_pool_exec(obj->pool);
index f75c01d..221292d 100644 (file)
@@ -23,6 +23,7 @@ typedef STATUS (*php_http_request_pool_detach_func_t)(php_http_request_pool_t *p
 typedef STATUS (*php_http_request_pool_setopt_func_t)(php_http_request_pool_t *p, php_http_request_pool_setopt_opt_t opt, void *arg);
 
 typedef struct php_http_request_pool_ops {
+       php_http_resource_factory_ops_t *rsrc;
        php_http_request_pool_init_func_t init;
        php_http_request_pool_copy_func_t copy;
        php_http_request_pool_dtor_func_t dtor;
@@ -37,6 +38,7 @@ typedef struct php_http_request_pool_ops {
 
 struct php_http_request_pool {
        void *ctx;
+       php_http_resource_factory_t *rf;
        php_http_request_pool_ops_t *ops;
 
        struct {
@@ -44,12 +46,14 @@ struct php_http_request_pool {
                zend_llist finished;
        } requests;
 
+       zval *persistent_handle_id;
+
 #ifdef ZTS
        void ***ts;
 #endif
 };
 
-PHP_HTTP_API php_http_request_pool_t *php_http_request_pool_init(php_http_request_pool_t *pool, php_http_request_pool_ops_t *ops, void *init_arg TSRMLS_DC);
+PHP_HTTP_API php_http_request_pool_t *php_http_request_pool_init(php_http_request_pool_t *pool, php_http_request_pool_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg TSRMLS_DC);
 PHP_HTTP_API php_http_request_pool_t *php_http_request_pool_copy(php_http_request_pool_t *from, php_http_request_pool_t *to);
 PHP_HTTP_API void php_http_request_pool_dtor(php_http_request_pool_t *pool);
 PHP_HTTP_API void php_http_request_pool_free(php_http_request_pool_t **pool);
@@ -65,6 +69,7 @@ PHP_HTTP_API void php_http_request_pool_requests(php_http_request_pool_t *h, zva
 typedef struct php_http_request_pool_object {
        zend_object zo;
        php_http_request_pool_t *pool;
+       zend_object_value factory;
        struct {
                long pos;
        } iterator;