removed awkward custom error handling and http\Object base class
[m6w6/ext-http] / php_http_client_curl.c
index fb8ecf678f3e5e07366f7e772fd18d6551704b2a..fbb950ac276eb4a059a4494746601dea236c3fa1 100644 (file)
@@ -6,7 +6,7 @@
     | modification, are permitted provided that the conditions mentioned |
     | in the accompanying LICENSE file are met.                          |
     +--------------------------------------------------------------------+
-    | Copyright (c) 2004-2011, Michael Wallner <mike@php.net>            |
+    | Copyright (c) 2004-2013, Michael Wallner <mike@php.net>            |
     +--------------------------------------------------------------------+
 */
 
@@ -228,7 +228,12 @@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data,
        /* catch progress */
        switch (type) {
                case CURLINFO_TEXT:
-                       if (php_memnstr(data, ZEND_STRL("About to connect"), data + length)) {
+                       if (data[0] == '-') {
+                       } else if (php_memnstr(data, ZEND_STRL("Adding handle:"), data + length)) {
+                               h->progress.info = "setup";
+                       } else if (php_memnstr(data, ZEND_STRL("addHandle"), data + length)) {
+                               h->progress.info = "setup";
+                       } else if (php_memnstr(data, ZEND_STRL("About to connect"), data + length)) {
                                h->progress.info = "resolve";
                        } else if (php_memnstr(data, ZEND_STRL("Trying"), data + length)) {
                                h->progress.info = "connect";
@@ -238,6 +243,10 @@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data,
                                h->progress.info = "connected";
                        } else if (php_memnstr(data, ZEND_STRL("Re-using existing connection!"), data + length)) {
                                h->progress.info = "connected";
+                       } else if (php_memnstr(data, ZEND_STRL("blacklisted"), data + length)) {
+                               h->progress.info = "blacklist check";
+                       } else if (php_memnstr(data, ZEND_STRL("SSL"), data + length)) {
+                               h->progress.info = "ssl negotiation";
                        } else if (php_memnstr(data, ZEND_STRL("left intact"), data + length)) {
                                h->progress.info = "not disconnected";
                        } else if (php_memnstr(data, ZEND_STRL("closed"), data + length)) {
@@ -247,7 +256,9 @@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data,
                        } else if (php_memnstr(data, ZEND_STRL("Operation timed out"), data + length)) {
                                h->progress.info = "timeout";
                        } else {
+#if PHP_DEBUG
                                h->progress.info = data;
+#endif
                        }
                        if (h->client->callback.progress.func) {
                                h->client->callback.progress.func(h->client->callback.progress.arg, h->client, &h->queue, &h->progress);
@@ -505,7 +516,7 @@ static void php_http_curlm_responsehandler(php_http_client_t *context)
                if (msg && CURLMSG_DONE == msg->msg) {
                        if (CURLE_OK != msg->data.result) {
                                php_http_curle_storage_t *st = php_http_curle_get_storage(msg->easy_handle);
-                               php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "%s; %s (%s)", curl_easy_strerror(msg->data.result), STR_PTR(st->errorbuffer), STR_PTR(st->url));
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s; %s (%s)", curl_easy_strerror(msg->data.result), STR_PTR(st->errorbuffer), STR_PTR(st->url));
                        }
 
                        if ((enqueue = php_http_client_enqueued(context, msg->easy_handle, compare_queue))) {
@@ -559,7 +570,7 @@ static void php_http_curlm_timeout_callback(int socket, short action, void *even
                while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle, CURL_SOCKET_TIMEOUT, 0, &curl->unfinished)));
 
                if (CURLM_OK != rc) {
-                       php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "%s",  curl_multi_strerror(rc));
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s",  curl_multi_strerror(rc));
                }
 
                php_http_curlm_responsehandler(context);
@@ -575,13 +586,13 @@ static void php_http_curlm_event_callback(int socket, short action, void *event_
        fprintf(stderr, "E");
 #endif
        if (curl->useevents) {
-               CURLMcode rc = CURLE_OK;
+               CURLMcode rc = CURLM_OK;
                TSRMLS_FETCH_FROM_CTX(context->ts);
 
                while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle, socket, etoca(action), &curl->unfinished)));
 
                if (CURLM_OK != rc) {
-                       php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "%s", curl_multi_strerror(rc));
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc));
                }
 
                php_http_curlm_responsehandler(context);
@@ -632,7 +643,7 @@ static int php_http_curlm_socket_callback(CURL *easy, curl_socket_t sock, int ac
                                return 0;
 
                        default:
-                               php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "Unknown socket action %d", action);
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown socket action %d", action);
                                return -1;
                }
 
@@ -986,7 +997,9 @@ static void php_http_curle_options_init(php_http_options_t *registry TSRMLS_DC)
        if ((opt = php_http_option_register(registry, ZEND_STRL("proxyauth"), CURLOPT_PROXYUSERPWD, IS_STRING))) {
                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
        }
-       php_http_option_register(registry, ZEND_STRL("proxyauthtype"), CURLOPT_PROXYAUTH, IS_LONG);
+       if ((opt = php_http_option_register(registry, ZEND_STRL("proxyauthtype"), CURLOPT_PROXYAUTH, IS_LONG))) {
+               Z_LVAL(opt->defval) = CURLAUTH_ANYSAFE;
+       }
        php_http_option_register(registry, ZEND_STRL("proxytunnel"), CURLOPT_HTTPPROXYTUNNEL, IS_BOOL);
 #if PHP_HTTP_CURL_VERSION(7,19,4)
        php_http_option_register(registry, ZEND_STRL("noproxy"), CURLOPT_NOPROXY, IS_STRING);
@@ -1044,17 +1057,17 @@ static void php_http_curle_options_init(php_http_options_t *registry TSRMLS_DC)
        if ((opt = php_http_option_register(registry, ZEND_STRL("httpauth"), CURLOPT_USERPWD, IS_STRING))) {
                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
        }
-       php_http_option_register(registry, ZEND_STRL("httpauthtype"), CURLOPT_HTTPAUTH, IS_LONG);
+       if ((opt = php_http_option_register(registry, ZEND_STRL("httpauthtype"), CURLOPT_HTTPAUTH, IS_LONG))) {
+               Z_LVAL(opt->defval) = CURLAUTH_ANYSAFE;
+       }
 
        /* redirects */
        if ((opt = php_http_option_register(registry, ZEND_STRL("redirect"), CURLOPT_FOLLOWLOCATION, IS_LONG))) {
                opt->setter = php_http_curle_option_set_redirect;
        }
-       php_http_option_register(registry, ZEND_STRL("unrestrictedauth"), CURLOPT_UNRESTRICTED_AUTH, IS_BOOL);
+       php_http_option_register(registry, ZEND_STRL("unrestricted_auth"), CURLOPT_UNRESTRICTED_AUTH, IS_BOOL);
 #if PHP_HTTP_CURL_VERSION(7,19,1)
-       php_http_option_register(registry, ZEND_STRL("postredir"), CURLOPT_POSTREDIR, IS_BOOL);
-#else
-       php_http_option_register(registry, ZEND_STRL("postredir"), CURLOPT_POST301, IS_BOOL);
+       php_http_option_register(registry, ZEND_STRL("postredir"), CURLOPT_POSTREDIR, IS_LONG);
 #endif
 
        /* retries */
@@ -1157,7 +1170,6 @@ static void php_http_curle_options_init(php_http_options_t *registry TSRMLS_DC)
                        opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                }
                php_http_option_register(registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING);
-               php_http_option_register(registry, ZEND_STRL("certpasswd"), CURLOPT_SSLCERTPASSWD, IS_STRING);
 
                if ((opt = php_http_option_register(registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) {
                        opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
@@ -1295,7 +1307,7 @@ static STATUS php_http_curle_set_option(php_http_option_t *opt, zval *val, void
                break;
        }
        if (rv != SUCCESS) {
-               php_http_error(HE_NOTICE, PHP_HTTP_E_CLIENT, "Could not set option %s", opt->name.s);
+               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s", opt->name.s);
        }
        return rv;
 }
@@ -1358,7 +1370,7 @@ static php_http_client_curl_handler_t *php_http_client_curl_handler_init(php_htt
        TSRMLS_FETCH_FROM_CTX(h->ts);
 
        if (!(handle = php_resource_factory_handle_ctor(rf, NULL TSRMLS_CC))) {
-               php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Failed to initialize curl handle");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize curl handle");
                return NULL;
        }
 
@@ -1408,7 +1420,7 @@ static STATUS php_http_client_curl_handler_prepare(php_http_client_curl_handler_
 
        /* request url */
        if (!PHP_HTTP_INFO(msg).request.url) {
-               php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Cannot request empty URL");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot request empty URL");
                return FAILURE;
        }
        storage->errorbuffer[0] = '\0';
@@ -1440,7 +1452,7 @@ static STATUS php_http_client_curl_handler_prepare(php_http_client_curl_handler_
                        if (PHP_HTTP_INFO(msg).request.method) {
                                curl_easy_setopt(curl->handle, CURLOPT_CUSTOMREQUEST, PHP_HTTP_INFO(msg).request.method);
                        } else {
-                               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_METHOD, "Cannot use empty request method");
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot use empty request method");
                                return FAILURE;
                        }
                        break;
@@ -1528,7 +1540,7 @@ static php_http_client_t *php_http_client_curl_init(php_http_client_t *h, void *
        TSRMLS_FETCH_FROM_CTX(h->ts);
 
        if (!handle && !(handle = php_resource_factory_handle_ctor(h->rf, NULL TSRMLS_CC))) {
-               php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_POOL, "Failed to initialize curl handle");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize curl handle");
                return NULL;
        }
 
@@ -1575,7 +1587,17 @@ static php_resource_factory_t *create_rf(const char *url TSRMLS_DC)
        php_url *purl;
        php_resource_factory_t *rf = NULL;
 
-       if ((purl = php_url_parse(url))) {
+       if (!url || !*url) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot request empty URL");
+               return NULL;
+       }
+
+       purl = php_url_parse(url);
+
+       if (!purl) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse URL '%s'", url);
+               return NULL;
+       } else {
                char *id_str = NULL;
                size_t id_len = spprintf(&id_str, 0, "%s:%d", STR_PTR(purl->host), purl->port ? purl->port : 80);
                php_persistent_handle_factory_t *pf = php_persistent_handle_concede(NULL, ZEND_STRL("http\\Client\\Curl\\Request"), id_str, id_len, NULL, NULL TSRMLS_CC);
@@ -1601,9 +1623,15 @@ static STATUS php_http_client_curl_enqueue(php_http_client_t *h, php_http_client
        php_http_client_curl_t *curl = h->ctx;
        php_http_client_curl_handler_t *handler;
        php_http_client_progress_state_t *progress;
+       php_resource_factory_t *rf;
        TSRMLS_FETCH_FROM_CTX(h->ts);
 
-       handler = php_http_client_curl_handler_init(h, create_rf(enqueue->request->http.info.request.url TSRMLS_CC));
+       rf = create_rf(enqueue->request->http.info.request.url TSRMLS_CC);
+       if (!rf) {
+               return FAILURE;
+       }
+
+       handler = php_http_client_curl_handler_init(h, rf);
        if (!handler) {
                return FAILURE;
        }
@@ -1629,7 +1657,7 @@ static STATUS php_http_client_curl_enqueue(php_http_client_t *h, php_http_client
 
                return SUCCESS;
        } else {
-               php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_POOL, "Could not enqueue request: %s", curl_multi_strerror(rs));
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs));
                return FAILURE;
        }
 }
@@ -1645,7 +1673,7 @@ static STATUS php_http_client_curl_dequeue(php_http_client_t *h, php_http_client
                zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue);
                return SUCCESS;
        } else {
-               php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "Could not dequeue request: %s", curl_multi_strerror(rs));
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not dequeue request: %s", curl_multi_strerror(rs));
        }
 
        return FAILURE;
@@ -1678,7 +1706,7 @@ static STATUS php_http_client_curl_wait(php_http_client_t *h, struct timeval *cu
        if (curl->useevents) {
                TSRMLS_FETCH_FROM_CTX(h->ts);
 
-               php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "not implemented");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "not implemented");
                return FAILURE;
        }
 #endif
@@ -1719,7 +1747,7 @@ static int php_http_client_curl_once(php_http_client_t *h)
 #if PHP_HTTP_HAVE_EVENT
        if (curl->useevents) {
                TSRMLS_FETCH_FROM_CTX(h->ts);
-               php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "not implemented");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "not implemented");
                return FAILURE;
        }
 #endif
@@ -1749,7 +1777,7 @@ static STATUS php_http_client_curl_exec(php_http_client_t *h)
 #endif
 
                        if (ev_rc < 0) {
-                               php_http_error(HE_ERROR, PHP_HTTP_E_RUNTIME, "Error in event_base_dispatch()");
+                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in event_base_dispatch()");
                                return FAILURE;
                        }
                } while (curl->unfinished);
@@ -1760,9 +1788,9 @@ static STATUS php_http_client_curl_exec(php_http_client_t *h)
                        if (SUCCESS != php_http_client_curl_wait(h, NULL)) {
 #ifdef PHP_WIN32
                                /* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */
-                               php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, "WinSock error: %d", WSAGetLastError());
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "WinSock error: %d", WSAGetLastError());
 #else
-                               php_http_error(HE_WARNING, PHP_HTTP_E_SOCKET, strerror(errno));
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, strerror(errno));
 #endif
                                return FAILURE;
                        }
@@ -1853,7 +1881,7 @@ static php_http_client_ops_t php_http_client_curl_ops = {
        php_http_client_curl_getopt
 };
 
-PHP_HTTP_API php_http_client_ops_t *php_http_client_curl_get_ops(void)
+php_http_client_ops_t *php_http_client_curl_get_ops(void)
 {
        return &php_http_client_curl_ops;
 }
@@ -1862,10 +1890,11 @@ PHP_MINIT_FUNCTION(http_client_curl)
 {
        php_http_options_t *options;
        php_http_client_driver_t driver = {
+               ZEND_STRL("curl"),
                &php_http_client_curl_ops
        };
 
-       if (SUCCESS != php_http_client_driver_add(ZEND_STRL("curl"), &driver)) {
+       if (SUCCESS != php_http_client_driver_add(&driver)) {
                        return FAILURE;
                }