travis: fix ssl client test
[m6w6/ext-http] / src / php_http_client_curl.c
index 641a9d8d44d1b3de2975eb8ee8dd78dc798ee838..1c84e3dde7940d50d62ea544d3016ad66b1129e9 100644 (file)
 
 #if PHP_HTTP_HAVE_LIBCURL
 
-#ifdef PHP_HTTP_HAVE_OPENSSL
+#if PHP_HTTP_HAVE_LIBCURL_OPENSSL
 #      include <openssl/ssl.h>
 #endif
-#ifdef PHP_HTTP_HAVE_GNUTLS
-#      include <gnutls.h>
+#if PHP_HTTP_HAVE_LIBCURL_GNUTLS
+#      include <gnutls/gnutls.h>
 #endif
 
 typedef struct php_http_client_curl_handler {
@@ -218,6 +218,7 @@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data,
        switch (type) {
                case CURLINFO_TEXT:
                        if (data[0] == '-') {
+                               goto text;
                        } 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)) {
@@ -234,8 +235,16 @@ 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("blacklisted"), data + length)) {
                                h->progress.info = "blacklist check";
+                       } else if (php_memnstr(data, ZEND_STRL("TLS"), data + length)) {
+                               h->progress.info = "ssl negotiation";
                        } else if (php_memnstr(data, ZEND_STRL("SSL"), data + length)) {
                                h->progress.info = "ssl negotiation";
+                       } else if (php_memnstr(data, ZEND_STRL("certificate"), data + length)) {
+                               h->progress.info = "ssl negotiation";
+                       } else if (php_memnstr(data, ZEND_STRL("ALPN"), data + length)) {
+                               h->progress.info = "alpn";
+                       } else if (php_memnstr(data, ZEND_STRL("NPN"), data + length)) {
+                               h->progress.info = "npn";
                        } else if (php_memnstr(data, ZEND_STRL("upload"), data + length)) {
                                h->progress.info = "uploaded";
                        } else if (php_memnstr(data, ZEND_STRL("left intact"), data + length)) {
@@ -247,6 +256,7 @@ 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 {
+                               text:;
 #if 0
                                h->progress.info = data;
                                data[length - 1] = '\0';
@@ -480,6 +490,24 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info)
                zend_hash_str_update(info, "http_version", lenof("http_version"), &tmp);
        }
 #endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+       if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PROXY_SSL_VERIFYRESULT, &l)) {
+               ZVAL_LONG(&tmp, l);
+               zend_hash_str_update(info, "proxy_ssl_verifyresult", lenof("proxy_ssl_verifyresult"), &tmp);
+       }
+#endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+       if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PROTOCOL, &l)) {
+               ZVAL_LONG(&tmp, l);
+               zend_hash_str_update(info, "protocol", lenof("protocol"), &tmp);
+       }
+#endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+       if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SCHEME, &c)) {
+               ZVAL_STRING(&tmp, STR_PTR(c));
+               zend_hash_str_update(info, "scheme", lenof("scheme"), &tmp);
+       }
+#endif
 
        /* END::CURLINFO */
 
@@ -488,7 +516,11 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info)
                zval ti_array, subarray;
                struct curl_tlssessioninfo *ti;
 
+#if PHP_HTTP_CURL_VERSION(7,48,0)
+               if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TLS_SSL_PTR, &ti)) {
+#else
                if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TLS_SESSION, &ti)) {
+#endif
                        char *backend;
 
                        ZVAL_NULL(&subarray);
@@ -500,33 +532,42 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info)
                                break;
                        case CURLSSLBACKEND_OPENSSL:
                                backend = "openssl";
-#ifdef PHP_HTTP_HAVE_OPENSSL
+#if PHP_HTTP_HAVE_LIBCURL_OPENSSL
                                {
+#if PHP_HTTP_CURL_VERSION(7,48,0)
+                                       SSL *ssl = ti->internals;
+                                       SSL_CTX *ctx = ssl ? SSL_get_SSL_CTX(ssl) : NULL;
+#else
                                        SSL_CTX *ctx = ti->internals;
+#endif
 
                                        array_init(&subarray);
-                                       add_assoc_long_ex(&subarray, ZEND_STRL("number"), SSL_CTX_sess_number(ctx));
-                                       add_assoc_long_ex(&subarray, ZEND_STRL("connect"), SSL_CTX_sess_connect(ctx));
-                                       add_assoc_long_ex(&subarray, ZEND_STRL("connect_good"), SSL_CTX_sess_connect_good(ctx));
-                                       add_assoc_long_ex(&subarray, ZEND_STRL("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx));
-                                       add_assoc_long_ex(&subarray, ZEND_STRL("hits"), SSL_CTX_sess_hits(ctx));
-                                       add_assoc_long_ex(&subarray, ZEND_STRL("cache_full"), SSL_CTX_sess_cache_full(ctx));
+                                       if (ctx) {
+                                               add_assoc_long_ex(&subarray, ZEND_STRL("number"), SSL_CTX_sess_number(ctx));
+                                               add_assoc_long_ex(&subarray, ZEND_STRL("connect"), SSL_CTX_sess_connect(ctx));
+                                               add_assoc_long_ex(&subarray, ZEND_STRL("connect_good"), SSL_CTX_sess_connect_good(ctx));
+                                               add_assoc_long_ex(&subarray, ZEND_STRL("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx));
+                                               add_assoc_long_ex(&subarray, ZEND_STRL("hits"), SSL_CTX_sess_hits(ctx));
+                                               add_assoc_long_ex(&subarray, ZEND_STRL("cache_full"), SSL_CTX_sess_cache_full(ctx));
+                                       }
                                }
 #endif
                                break;
                        case CURLSSLBACKEND_GNUTLS:
                                backend = "gnutls";
-#ifdef PHP_HTTP_HAVE_GNUTLS
+#if PHP_HTTP_HAVE_LIBCURL_GNUTLS
                                {
                                        gnutls_session_t sess = ti->internals;
                                        char *desc;
 
                                        array_init(&subarray);
-                                       if ((desc = gnutls_session_get_desc(sess))) {
-                                               add_assoc_string_ex(&subarray, ZEND_STRL("desc"), desc);
-                                               gnutls_free(desc);
+                                       if (sess) {
+                                               if ((desc = gnutls_session_get_desc(sess))) {
+                                                       add_assoc_string_ex(&subarray, ZEND_STRL("desc"), desc);
+                                                       gnutls_free(desc);
+                                               }
+                                               add_assoc_bool_ex(&subarray, ZEND_STRL("resumed"), gnutls_session_is_resumed(sess));
                                        }
-                                       add_assoc_bool_ex(&subarray, ZEND_STRL("resumed"), gnutls_session_is_resumed(sess));
                                }
 #endif
                                break;
@@ -564,7 +605,10 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info)
        }
 #endif
 
-#if (PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)) || (PHP_HTTP_CURL_VERSION(7,34,0) && defined(PHP_HTTP_HAVE_NSS)) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_GSKIT))
+#if (PHP_HTTP_CURL_VERSION(7,19,1) && PHP_HTTP_HAVE_LIBCURL_OPENSSL) || \
+       (PHP_HTTP_CURL_VERSION(7,34,0) && PHP_HTTP_HAVE_LIBCURL_NSS) || \
+       (PHP_HTTP_CURL_VERSION(7,42,0) && PHP_HTTP_HAVE_LIBCURL_GNUTLS) || \
+       (PHP_HTTP_CURL_VERSION(7,39,0) && PHP_HTTP_HAVE_LIBCURL_GSKIT)
        {
                int i;
                zval ci_array, subarray;
@@ -1098,7 +1142,7 @@ static ZEND_RESULT_CODE php_http_curle_option_set_resolve(php_http_option_t *opt
 }
 #endif
 
-#if PHP_HTTP_CURL_VERSION(7,21,4) && defined(PHP_HTTP_CURL_TLSAUTH_SRP)
+#if PHP_HTTP_CURL_VERSION(7,21,4) && PHP_HTTP_HAVE_LIBCURL_TLSAUTH_TYPE
 static ZEND_RESULT_CODE php_http_curle_option_set_ssl_tlsauthtype(php_http_option_t *opt, zval *val, void *userdata)
 {
        php_http_client_curl_handler_t *curl = userdata;
@@ -1107,7 +1151,7 @@ static ZEND_RESULT_CODE php_http_curle_option_set_ssl_tlsauthtype(php_http_optio
        if (val && Z_LVAL_P(val)) {
                switch (Z_LVAL_P(val)) {
                case CURL_TLSAUTH_SRP:
-                       if (CURLE_OK == curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_CURL_TLSAUTH_SRP)) {
+                       if (CURLE_OK == curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_LIBCURL_TLSAUTH_SRP)) {
                                return SUCCESS;
                        }
                        /* no break */
@@ -1115,7 +1159,7 @@ static ZEND_RESULT_CODE php_http_curle_option_set_ssl_tlsauthtype(php_http_optio
                        return FAILURE;
                }
        }
-       if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_CURL_TLSAUTH_DEF)) {
+       if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_LIBCURL_TLSAUTH_DEF)) {
                return FAILURE;
        }
        return SUCCESS;
@@ -1178,7 +1222,7 @@ static void php_http_curle_options_init(php_http_options_t *registry)
                opt->setter = php_http_curle_option_set_resolve;
        }
 #endif
-#if PHP_HTTP_HAVE_ARES
+#if PHP_HTTP_HAVE_LIBCURL_ARES
 # if PHP_HTTP_CURL_VERSION(7,24,0)
        if ((opt = php_http_option_register(registry, ZEND_STRL("dns_servers"), CURLOPT_DNS_SERVERS, IS_STRING))) {
                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
@@ -1388,24 +1432,28 @@ static void php_http_curle_options_init(php_http_options_t *registry)
                                ZVAL_BOOL(&opt->defval, 1);
                                opt->setter = php_http_curle_option_set_ssl_verifyhost;
                        }
-#if PHP_HTTP_CURL_VERSION(7,41,0) && (defined(PHP_HTTP_HAVE_OPENSSL) || defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_GNUTLS))
+#if PHP_HTTP_CURL_VERSION(7,41,0) && (PHP_HTTP_HAVE_LIBCURL_OPENSSL || PHP_HTTP_HAVE_LIBCURL_NSS || PHP_HTTP_HAVE_LIBCURL_GNUTLS)
                php_http_option_register(registry, ZEND_STRL("verifystatus"), CURLOPT_SSL_VERIFYSTATUS, _IS_BOOL);
 #endif
                        php_http_option_register(registry, ZEND_STRL("cipher_list"), CURLOPT_SSL_CIPHER_LIST, IS_STRING);
+#if PHP_HTTP_HAVE_LIBCURL_CAINFO
                        if ((opt = php_http_option_register(registry, ZEND_STRL("cainfo"), CURLOPT_CAINFO, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
-#ifdef PHP_HTTP_CURL_CAINFO
-                       ZVAL_PSTRING(&opt->defval, PHP_HTTP_CURL_CAINFO);
+#ifdef PHP_HTTP_CAINFO
+                       ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAINFO);
 #endif
                        }
+#endif
+#if PHP_HTTP_HAVE_LIBCURL_CAPATH
                        if ((opt = php_http_option_register(registry, ZEND_STRL("capath"), CURLOPT_CAPATH, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
-#ifdef PHP_HTTP_CURL_CAPATH
-                       ZVAL_PSTRING(&opt->defval, PHP_HTTP_CURL_CAPATH);
+#ifdef PHP_HTTP_CAPATH
+                       ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAPATH);
+#endif
+                       }
 #endif
-               }
                        if ((opt = php_http_option_register(registry, ZEND_STRL("random_file"), CURLOPT_RANDOM_FILE, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
@@ -1419,14 +1467,14 @@ static void php_http_curle_options_init(php_http_options_t *registry)
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
-#      ifdef PHP_HTTP_HAVE_OPENSSL
+#      if PHP_HTTP_HAVE_LIBCURL_OPENSSL
                        if ((opt = php_http_option_register(registry, ZEND_STRL("crlfile"), CURLOPT_CRLFILE, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
 #      endif
 #endif
-#if (PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)) || (PHP_HTTP_CURL_VERSION(7,34,0) && defined(PHP_HTTP_HAVE_NSS)) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_GSKIT))
+#if (PHP_HTTP_CURL_VERSION(7,19,1) && PHP_HTTP_HAVE_LIBCURL_OPENSSL) || (PHP_HTTP_CURL_VERSION(7,34,0) && PHP_HTTP_HAVE_LIBCURL_NSS) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_LIBCURL_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_LIBCURL_GSKIT))
                        if ((opt = php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) {
                                ZVAL_FALSE(&opt->defval);
                        }
@@ -1446,7 +1494,7 @@ static void php_http_curle_options_init(php_http_options_t *registry)
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
 #endif
-#if PHP_HTTP_CURL_VERSION(7,21,4) && defined(PHP_HTTP_CURL_TLSAUTH_SRP)
+#if PHP_HTTP_CURL_VERSION(7,21,4) && PHP_HTTP_HAVE_LIBCURL_TLSAUTH_TYPE
                        if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthtype"), CURLOPT_TLSAUTH_TYPE, IS_LONG))) {
                                opt->setter = php_http_curle_option_set_ssl_tlsauthtype;
                        }
@@ -1457,7 +1505,7 @@ static void php_http_curle_options_init(php_http_options_t *registry)
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                        }
 #endif
-#if PHP_HTTP_CURL_VERSION(7,42,0) && (defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_DARWINSSL))
+#if PHP_HTTP_CURL_VERSION(7,42,0) && (PHP_HTTP_HAVE_LIBCURL_NSS || PHP_HTTP_HAVE_LIBCURL_SECURETRANSPORT)
                php_http_option_register(registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL);
 #endif
                }
@@ -1876,7 +1924,7 @@ static php_http_client_curl_handler_t *php_http_client_curl_handler_init(php_htt
        php_http_buffer_init(&handler->options.ranges);
        zend_hash_init(&handler->options.cache, 0, NULL, ZVAL_PTR_DTOR, 0);
 
-#if defined(ZTS)
+#if ZTS
        curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L);
 #endif
        curl_easy_setopt(handle, CURLOPT_HEADER, 0L);
@@ -2199,7 +2247,7 @@ static ZEND_RESULT_CODE php_http_client_curl_dequeue(php_http_client_t *h, php_h
        php_http_client_curl_t *curl = h->ctx;
        php_http_client_curl_handler_t *handler = enqueue->opaque;
 
-       if (h->callback.depth) {
+       if (h->callback.depth && !CG(unclean_shutdown)) {
                php_error_docref(NULL, E_WARNING, "Could not dequeue request while executing callbacks");
                return FAILURE;
        }
@@ -2225,7 +2273,7 @@ static void php_http_client_curl_reset(php_http_client_t *h)
        }
 }
 
-#ifdef PHP_WIN32
+#if PHP_WIN32
 #      define SELECT_ERROR SOCKET_ERROR
 #else
 #      define SELECT_ERROR -1
@@ -2291,7 +2339,7 @@ static ZEND_RESULT_CODE php_http_client_curl_exec(php_http_client_t *h)
 
                while (php_http_client_curl_once(h) && !EG(exception)) {
                        if (SUCCESS != php_http_client_curl_wait(h, NULL)) {
-#ifdef PHP_WIN32
+#if PHP_WIN32
                                /* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */
                                php_error_docref(NULL, E_WARNING, "WinSock error: %d", WSAGetLastError());
 #else
@@ -2422,6 +2470,14 @@ php_http_client_ops_t *php_http_client_curl_get_ops(void)
        return &php_http_client_curl_ops;
 }
 
+#define REGISTER_NS_STRING_OR_NULL_CONSTANT(ns, name, str, flags)                              \
+               do {                                                                           \
+                       if ((str) != NULL) {                                                   \
+                               REGISTER_NS_STRING_CONSTANT(ns, name, str, flags);             \
+                       } else {                                                               \
+                               REGISTER_NS_NULL_CONSTANT(ns, name, flags);                    \
+                       }                                                                      \
+               } while (0)
 
 PHP_MINIT_FUNCTION(http_client_curl)
 {
@@ -2502,12 +2558,12 @@ PHP_MINIT_FUNCTION(http_client_curl)
                REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl", "VERSIONS", curl_version(), CONST_CS|CONST_PERSISTENT);
 #if CURLVERSION_NOW >= 0
                REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "CURL", (char *) info->version, CONST_CS|CONST_PERSISTENT);
-               REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "SSL", (char *) info->ssl_version, CONST_CS|CONST_PERSISTENT);
-               REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "LIBZ", (char *) info->libz_version, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "SSL", (char *) info->ssl_version, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "LIBZ", (char *) info->libz_version, CONST_CS|CONST_PERSISTENT);
 # if CURLVERSION_NOW >= 1
-               REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "ARES", (char *) info->ares, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ARES", (char *) info->ares, CONST_CS|CONST_PERSISTENT);
 #  if CURLVERSION_NOW >= 2
-               REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "IDN", (char *) info->libidn, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "IDN", (char *) info->libidn, CONST_CS|CONST_PERSISTENT);
 #  endif
 # endif
 #endif
@@ -2538,7 +2594,7 @@ PHP_MINIT_FUNCTION(http_client_curl)
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_SSLv2", CURL_SSLVERSION_SSLv2, CONST_CS|CONST_PERSISTENT);
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_SSLv3", CURL_SSLVERSION_SSLv3, CONST_CS|CONST_PERSISTENT);
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_ANY", CURL_SSLVERSION_DEFAULT, CONST_CS|CONST_PERSISTENT);
-#if PHP_HTTP_CURL_VERSION(7,21,4) && defined(PHP_HTTP_CURL_TLSAUTH_SRP)
+#if PHP_HTTP_CURL_VERSION(7,21,4) && PHP_HTTP_HAVE_LIBCURL_TLSAUTH_TYPE
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "TLSAUTH_SRP", CURL_TLSAUTH_SRP, CONST_CS|CONST_PERSISTENT);
 #endif