fix sovereignty of clients when using events
authorMichael Wallner <mike@php.net>
Mon, 1 Sep 2014 09:02:39 +0000 (11:02 +0200)
committerMichael Wallner <mike@php.net>
Mon, 1 Sep 2014 09:02:39 +0000 (11:02 +0200)
php_http.c
php_http_api.h
php_http_client_curl.c
php_http_client_curl.h
tests/client015.phpt [new file with mode: 0644]

index 2101f0b..3200a16 100644 (file)
@@ -187,9 +187,6 @@ PHP_RINIT_FUNCTION(http)
 {
        if (0
        || SUCCESS != PHP_RINIT_CALL(http_env)
 {
        if (0
        || SUCCESS != PHP_RINIT_CALL(http_env)
-#if PHP_HTTP_HAVE_CURL && PHP_HTTP_HAVE_EVENT
-       || SUCCESS != PHP_RINIT_CALL(http_client_curl)
-#endif
        ) {
                return FAILURE;
        }
        ) {
                return FAILURE;
        }
@@ -200,9 +197,6 @@ PHP_RINIT_FUNCTION(http)
 PHP_RSHUTDOWN_FUNCTION(http)
 {
        if (0
 PHP_RSHUTDOWN_FUNCTION(http)
 {
        if (0
-#if PHP_HTTP_HAVE_CURL && PHP_HTTP_HAVE_EVENT
-       || SUCCESS != PHP_RSHUTDOWN_CALL(http_client_curl)
-#endif
        || SUCCESS != PHP_RSHUTDOWN_CALL(http_env)
        ) {
                return FAILURE;
        || SUCCESS != PHP_RSHUTDOWN_CALL(http_env)
        ) {
                return FAILURE;
index 091fd65..0e65ccb 100644 (file)
@@ -108,9 +108,6 @@ typedef int STATUS;
 
 ZEND_BEGIN_MODULE_GLOBALS(php_http)
        struct php_http_env_globals env;
 
 ZEND_BEGIN_MODULE_GLOBALS(php_http)
        struct php_http_env_globals env;
-#if PHP_HTTP_HAVE_CURL && PHP_HTTP_HAVE_EVENT
-       struct php_http_curl_globals curl;
-#endif
 ZEND_END_MODULE_GLOBALS(php_http)
 
 ZEND_EXTERN_MODULE_GLOBALS(php_http);
 ZEND_END_MODULE_GLOBALS(php_http)
 
 ZEND_EXTERN_MODULE_GLOBALS(php_http);
index 37f255b..db73a31 100644 (file)
@@ -49,6 +49,7 @@ typedef struct php_http_client_curl {
        int unfinished;  /* int because of curl_multi_perform() */
 
 #if PHP_HTTP_HAVE_EVENT
        int unfinished;  /* int because of curl_multi_perform() */
 
 #if PHP_HTTP_HAVE_EVENT
+       struct event_base *evbase;
        struct event *timeout;
        unsigned useevents:1;
 #endif
        struct event *timeout;
        unsigned useevents:1;
 #endif
@@ -758,7 +759,7 @@ static int php_http_curlm_socket_callback(CURL *easy, curl_socket_t sock, int ac
                                return -1;
                }
 
                                return -1;
                }
 
-               event_assign(&ev->evnt, PHP_HTTP_G->curl.event_base, sock, events, php_http_curlm_event_callback, context);
+               event_assign(&ev->evnt, curl->evbase, sock, events, php_http_curlm_event_callback, context);
                event_add(&ev->evnt, NULL);
        }
 
                event_add(&ev->evnt, NULL);
        }
 
@@ -779,10 +780,9 @@ static void php_http_curlm_timer_callback(CURLM *multi, long timeout_ms, void *t
                        php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, context);
                } else if (timeout_ms > 0 || !event_initialized(curl->timeout) || !event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
                        struct timeval timeout;
                        php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, context);
                } else if (timeout_ms > 0 || !event_initialized(curl->timeout) || !event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
                        struct timeval timeout;
-                       TSRMLS_FETCH_FROM_CTX(context->ts);
 
                        if (!event_initialized(curl->timeout)) {
 
                        if (!event_initialized(curl->timeout)) {
-                               event_assign(curl->timeout, PHP_HTTP_G->curl.event_base, CURL_SOCKET_TIMEOUT, 0, php_http_curlm_timeout_callback, context);
+                               event_assign(curl->timeout, curl->evbase, CURL_SOCKET_TIMEOUT, 0, php_http_curlm_timeout_callback, context);
                        } else if (event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
                                event_del(curl->timeout);
                        }
                        } else if (event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
                                event_del(curl->timeout);
                        }
@@ -1742,6 +1742,10 @@ static void php_http_client_curl_dtor(php_http_client_t *h)
                efree(curl->timeout);
                curl->timeout = NULL;
        }
                efree(curl->timeout);
                curl->timeout = NULL;
        }
+       if (curl->evbase) {
+               event_base_free(curl->evbase);
+               curl->evbase = NULL;
+       }
 #endif
        curl->unfinished = 0;
 
 #endif
        curl->unfinished = 0;
 
@@ -1951,7 +1955,7 @@ static STATUS php_http_client_curl_exec(php_http_client_t *h)
        if (curl->useevents) {
                php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, h);
                do {
        if (curl->useevents) {
                php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, h);
                do {
-                       int ev_rc = event_base_dispatch(PHP_HTTP_G->curl.event_base);
+                       int ev_rc = event_base_dispatch(curl->evbase);
 
 #if DBG_EVENTS
                        fprintf(stderr, "%c", "X.0"[ev_rc+1]);
 
 #if DBG_EVENTS
                        fprintf(stderr, "%c", "X.0"[ev_rc+1]);
@@ -1995,6 +1999,9 @@ static STATUS php_http_client_curl_setopt(php_http_client_t *h, php_http_client_
                case PHP_HTTP_CLIENT_OPT_USE_EVENTS:
 #if PHP_HTTP_HAVE_EVENT
                        if ((curl->useevents = *((zend_bool *) arg))) {
                case PHP_HTTP_CLIENT_OPT_USE_EVENTS:
 #if PHP_HTTP_HAVE_EVENT
                        if ((curl->useevents = *((zend_bool *) arg))) {
+                               if (!curl->evbase) {
+                                       curl->evbase = event_base_new();
+                               }
                                if (!curl->timeout) {
                                        curl->timeout = ecalloc(1, sizeof(struct event));
                                }
                                if (!curl->timeout) {
                                        curl->timeout = ecalloc(1, sizeof(struct event));
                                }
@@ -2161,24 +2168,6 @@ PHP_MSHUTDOWN_FUNCTION(http_client_curl)
        return SUCCESS;
 }
 
        return SUCCESS;
 }
 
-#if PHP_HTTP_HAVE_EVENT
-PHP_RINIT_FUNCTION(http_client_curl)
-{
-       if (!PHP_HTTP_G->curl.event_base && !(PHP_HTTP_G->curl.event_base = event_base_new())) {
-               return FAILURE;
-       }
-       return SUCCESS;
-}
-PHP_RSHUTDOWN_FUNCTION(http_client_curl)
-{
-       if (PHP_HTTP_G->curl.event_base) {
-               event_base_free(PHP_HTTP_G->curl.event_base);
-               PHP_HTTP_G->curl.event_base = NULL;
-       }
-       return SUCCESS;
-}
-#endif /* PHP_HTTP_HAVE_EVENT */
-
 #endif /* PHP_HTTP_HAVE_CURL */
 
 /*
 #endif /* PHP_HTTP_HAVE_CURL */
 
 /*
index 03b9b6f..c82a09c 100644 (file)
 
 #if PHP_HTTP_HAVE_CURL
 
 
 #if PHP_HTTP_HAVE_CURL
 
-#if PHP_HTTP_HAVE_EVENT
-struct php_http_curl_globals {
-       void *event_base;
-};
-
-PHP_RINIT_FUNCTION(http_client_curl);
-PHP_RSHUTDOWN_FUNCTION(http_client_curl);
-#endif /* PHP_HTTP_HAVE_EVENT */
-
 PHP_MINIT_FUNCTION(http_client_curl);
 PHP_MSHUTDOWN_FUNCTION(http_client_curl);
 #endif /* PHP_HTTP_HAVE_CURL */
 PHP_MINIT_FUNCTION(http_client_curl);
 PHP_MSHUTDOWN_FUNCTION(http_client_curl);
 #endif /* PHP_HTTP_HAVE_CURL */
diff --git a/tests/client015.phpt b/tests/client015.phpt
new file mode 100644 (file)
index 0000000..35981a5
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+http client event base
+--SKIPIF--
+<?php 
+include "skipif.inc";
+try {
+       $client = new http\Client;
+       if (!$client->enableEvents())
+               throw new Exception("need events support"); 
+} catch (Exception $e) {
+       die("skip ".$e->getMessage()); 
+}
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$client1 = new http\Client;
+$client2 = new http\Client;
+
+$client1->enableEvents();
+$client2->enableEvents();
+
+$client1->enqueue(new http\Client\Request("GET", "http://www.google.ca/"));
+$client2->enqueue(new http\Client\Request("GET", "http://www.google.co.uk/"));
+
+$client1->send();
+
+if (($r = $client1->getResponse())) {
+       var_dump($r->getTransferInfo("response_code"));
+}
+if (($r = $client2->getResponse())) {
+       var_dump($r->getTransferInfo("response_code"));
+}
+
+?>
+DONE
+--EXPECT--
+Test
+int(200)
+DONE