add CURLINFO_RETRY_AFTER
[m6w6/ext-http] / src / php_http_client_curl.c
index 8f5b2d5b7275057200f0812cf56db34d5486584c..82db05332944a140b01dc2e54af6d5fce296915c 100644 (file)
@@ -330,6 +330,7 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info)
        char *c = NULL;
        long l = 0;
        double d = 0;
+       curl_off_t o = 0;
        struct curl_slist *s = NULL, *p = NULL;
        zval tmp;
 
@@ -510,6 +511,12 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info)
                zend_hash_str_update(info, "scheme", lenof("scheme"), &tmp);
        }
 #endif
+#if PHP_HTTP_CURL_VERSION(7,66,0)
+       if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_RETRY_AFTER, &o)) {
+               ZVAL_LONG(&tmp, o);
+               zend_hash_str_update(info, "retry_after", lenof("retry_after"), &tmp);
+       }
+#endif
 #if PHP_HTTP_CURL_VERSION(7,72,0)
        if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_EFFECTIVE_METHOD, &c)) {
                ZVAL_STRING(&tmp, STR_PTR(c));
@@ -811,7 +818,7 @@ static ZEND_RESULT_CODE php_http_curle_option_set_ssl_verifyhost(php_http_option
        php_http_client_curl_handler_t *curl = userdata;
        CURL *ch = curl->handle;
 
-       if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, Z_TYPE_P(val) == IS_TRUE ? 2 : 0)) {
+       if (CURLE_OK != curl_easy_setopt(ch, opt->option, Z_TYPE_P(val) == IS_TRUE ? 2 : 0)) {
                return FAILURE;
        }
        return SUCCESS;
@@ -942,6 +949,21 @@ static ZEND_RESULT_CODE php_http_curle_option_set_lastmodified(php_http_option_t
        return SUCCESS;
 }
 
+#if PHP_HTTP_CURL_VERSION(7,64,1)
+static ZEND_RESULT_CODE php_http_curle_option_set_altsvc_ctrl(php_http_option_t *opt, zval *val, void *userdata)
+{
+       php_http_client_curl_handler_t *curl = userdata;
+       CURL *ch = curl->handle;
+
+       if (Z_LVAL_P(val)) {
+               if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_ALTSVC_CTRL, Z_LVAL_P(val))) {
+                       return FAILURE;
+               }
+       }
+       return SUCCESS;
+}
+#endif
+
 static ZEND_RESULT_CODE php_http_curle_option_set_compress(php_http_option_t *opt, zval *val, void *userdata)
 {
        php_http_client_curl_handler_t *curl = userdata;
@@ -1165,7 +1187,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_LIBCURL_TLSAUTH_SRP)) {
+                       if (CURLE_OK == curl_easy_setopt(ch, opt->option, PHP_HTTP_LIBCURL_TLSAUTH_SRP)) {
                                return SUCCESS;
                        }
                        /* no break */
@@ -1173,7 +1195,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_LIBCURL_TLSAUTH_DEF)) {
+       if (CURLE_OK != curl_easy_setopt(ch, opt->option, PHP_HTTP_LIBCURL_TLSAUTH_DEF)) {
                return FAILURE;
        }
        return SUCCESS;
@@ -1266,6 +1288,13 @@ static void php_http_curle_options_init(php_http_options_t *registry)
        }
 # endif
 #endif
+#if PHP_HTTP_CURL_VERSION(7,60,0)
+       php_http_option_register(registry, ZEND_STRL("dns_shuffle_addresses"), CURLOPT_DNS_SHUFFLE_ADDRESSES, _IS_BOOL);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,62,0)
+       php_http_option_register(registry, ZEND_STRL("doh_url"), CURLOPT_DOH_URL, IS_STRING);
+#endif
+
 
        /* limits */
        php_http_option_register(registry, ZEND_STRL("low_speed_limit"), CURLOPT_LOW_SPEED_LIMIT, IS_LONG);
@@ -1284,6 +1313,11 @@ static void php_http_curle_options_init(php_http_options_t *registry)
        */
        php_http_option_register(registry, ZEND_STRL("fresh_connect"), CURLOPT_FRESH_CONNECT, _IS_BOOL);
        php_http_option_register(registry, ZEND_STRL("forbid_reuse"), CURLOPT_FORBID_REUSE, _IS_BOOL);
+#if PHP_HTTP_CURL_VERSION(7,65,0)
+       if ((opt = php_http_option_register(registry, ZEND_STRL("maxage_conn"), CURLOPT_MAXAGE_CONN, IS_LONG))) {
+               ZVAL_LONG(&opt->defval, 118);
+       }
+#endif
 
        /* outgoing interface */
        php_http_option_register(registry, ZEND_STRL("interface"), CURLOPT_INTERFACE, IS_STRING);
@@ -1312,6 +1346,11 @@ 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,61,0)
+       if ((opt = php_http_option_register(registry, ZEND_STRL("xoauth2_bearer"), CURLOPT_XOAUTH2_BEARER, IS_STRING))) {
+               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+       }
+#endif
 
        /* redirects */
        if ((opt = php_http_option_register(registry, ZEND_STRL("redirect"), CURLOPT_FOLLOWLOCATION, IS_LONG))) {
@@ -1397,6 +1436,9 @@ static void php_http_curle_options_init(php_http_options_t *registry)
 
        /* http protocol version */
        php_http_option_register(registry, ZEND_STRL("protocol"), CURLOPT_HTTP_VERSION, IS_LONG);
+#if PHP_HTTP_CURL_VERSION(7,64,0)
+       php_http_option_register(registry, ZEND_STRL("http09_allowed"), CURLOPT_HTTP09_ALLOWED, _IS_BOOL);
+#endif
 
        /* timeouts */
        if ((opt = php_http_option_register(registry, ZEND_STRL("timeout"), CURLOPT_TIMEOUT_MS, IS_DOUBLE))) {
@@ -1430,115 +1472,215 @@ static void php_http_curle_options_init(php_http_options_t *registry)
 
        /* ssl */
        if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_SSL)) {
-               if ((opt = php_http_option_register(registry, ZEND_STRL("ssl"), 0, IS_ARRAY))) {
-                       registry = &opt->suboptions;
+               php_http_option_t *ssl_opt, *proxy_opt;
+
+               if ((ssl_opt = php_http_option_register(registry, ZEND_STRL("ssl"), 0, IS_ARRAY))) {
+                       php_http_options_t *ssl_registry = &ssl_opt->suboptions;
 
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("cert"), CURLOPT_SSLCERT, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("cert"), CURLOPT_SSLCERT, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                ZVAL_PSTRING(&opt->defval, "PEM");
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("keytype"), CURLOPT_SSLKEYTYPE, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("keytype"), CURLOPT_SSLKEYTYPE, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                ZVAL_PSTRING(&opt->defval, "PEM");
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("keypasswd"), CURLOPT_SSLKEYPASSWD, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("keypasswd"), CURLOPT_SSLKEYPASSWD, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                        }
-                       php_http_option_register(registry, ZEND_STRL("engine"), CURLOPT_SSLENGINE, IS_STRING);
-                       php_http_option_register(registry, ZEND_STRL("version"), CURLOPT_SSLVERSION, IS_LONG);
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("verifypeer"), CURLOPT_SSL_VERIFYPEER, _IS_BOOL))) {
+                       php_http_option_register(ssl_registry, ZEND_STRL("engine"), CURLOPT_SSLENGINE, IS_STRING);
+                       php_http_option_register(ssl_registry, ZEND_STRL("version"), CURLOPT_SSLVERSION, IS_LONG);
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("verifypeer"), CURLOPT_SSL_VERIFYPEER, _IS_BOOL))) {
                                ZVAL_BOOL(&opt->defval, 1);
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("verifyhost"), CURLOPT_SSL_VERIFYHOST, _IS_BOOL))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("verifyhost"), CURLOPT_SSL_VERIFYHOST, _IS_BOOL))) {
                                ZVAL_BOOL(&opt->defval, 1);
                                opt->setter = php_http_curle_option_set_ssl_verifyhost;
                        }
 #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);
+                       php_http_option_register(ssl_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);
+                       php_http_option_register(ssl_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))) {
+                       if ((opt = php_http_option_register(ssl_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_CAINFO
-                       ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAINFO);
-#endif
+# 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))) {
+                       if ((opt = php_http_option_register(ssl_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_CAPATH
-                       ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAPATH);
-#endif
+# 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))) {
+                       if ((opt = php_http_option_register(ssl_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;
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("egdsocket"), CURLOPT_EGDSOCKET, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("egdsocket"), CURLOPT_EGDSOCKET, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
 #if PHP_HTTP_CURL_VERSION(7,19,0)
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("issuercert"), CURLOPT_ISSUERCERT, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("issuercert"), CURLOPT_ISSUERCERT, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
 #      if PHP_HTTP_HAVE_LIBCURL_OPENSSL
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("crlfile"), CURLOPT_CRLFILE, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_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) && 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))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) {
                                ZVAL_FALSE(&opt->defval);
                        }
 #endif
 #if PHP_HTTP_CURL_VERSION(7,36,0)
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, _IS_BOOL))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, _IS_BOOL))) {
                                ZVAL_BOOL(&opt->defval, 1);
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, _IS_BOOL))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, _IS_BOOL))) {
                                ZVAL_BOOL(&opt->defval, 1);
                        }
 #endif
 #if PHP_HTTP_CURL_VERSION(7,39,0)
                        /* FIXME: see http://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html#AVAILABILITY */
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("pinned_publickey"), CURLOPT_PINNEDPUBLICKEY, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("pinned_publickey"), CURLOPT_PINNEDPUBLICKEY, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
                        }
 #endif
 #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))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tlsauthtype"), CURLOPT_TLSAUTH_TYPE, IS_LONG))) {
                                opt->setter = php_http_curle_option_set_ssl_tlsauthtype;
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthuser"), CURLOPT_TLSAUTH_USERNAME, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tlsauthuser"), CURLOPT_TLSAUTH_USERNAME, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                        }
-                       if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthpass"), CURLOPT_TLSAUTH_PASSWORD, IS_STRING))) {
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tlsauthpass"), CURLOPT_TLSAUTH_PASSWORD, IS_STRING))) {
                                opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
                        }
 #endif
 #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);
+                       php_http_option_register(ssl_registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,61,0)
+                       if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tls13_ciphers"), CURLOPT_TLS13_CIPHERS, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                       }
 #endif
                }
+
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+               /* proxy_ssl */
+               if ((proxy_opt = php_http_option_register(registry, ZEND_STRL("proxy_ssl"), 0, IS_ARRAY))) {
+                       php_http_options_t *proxy_registry = &proxy_opt->suboptions;
+
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("cert"), CURLOPT_PROXY_SSLCERT, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("certtype"), CURLOPT_PROXY_SSLCERTTYPE, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               ZVAL_PSTRING(&opt->defval, "PEM");
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("key"), CURLOPT_PROXY_SSLKEY, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("keytype"), CURLOPT_PROXY_SSLKEYTYPE, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               ZVAL_PSTRING(&opt->defval, "PEM");
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("keypasswd"), CURLOPT_PROXY_KEYPASSWD, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                       }
+                       php_http_option_register(proxy_registry, ZEND_STRL("version"), CURLOPT_PROXY_SSLVERSION, IS_LONG);
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("verifypeer"), CURLOPT_PROXY_SSL_VERIFYPEER, _IS_BOOL))) {
+                               ZVAL_BOOL(&opt->defval, 1);
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("verifyhost"), CURLOPT_PROXY_SSL_VERIFYHOST, _IS_BOOL))) {
+                               ZVAL_BOOL(&opt->defval, 1);
+                               opt->setter = php_http_curle_option_set_ssl_verifyhost;
+                       }
+                       php_http_option_register(proxy_registry, ZEND_STRL("cipher_list"), CURLOPT_PROXY_SSL_CIPHER_LIST, IS_STRING);
+#  if PHP_HTTP_HAVE_LIBCURL_OPENSSL
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("crlfile"), CURLOPT_PROXY_CRLFILE, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+                       }
+#  endif
+# if PHP_HTTP_HAVE_LIBCURL_CAINFO
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("cainfo"), CURLOPT_PROXY_CAINFO, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+#  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(proxy_registry, ZEND_STRL("capath"), CURLOPT_PROXY_CAPATH, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+#  ifdef PHP_HTTP_CAPATH
+                               ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAPATH);
+#  endif
+                       }
+# endif
+
+# if PHP_HTTP_HAVE_LIBCURL_TLSAUTH_TYPE
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tlsauthtype"), CURLOPT_PROXY_TLSAUTH_TYPE, IS_LONG))) {
+                               opt->setter = php_http_curle_option_set_ssl_tlsauthtype;
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tlsauthuser"), CURLOPT_PROXY_TLSAUTH_USERNAME, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                       }
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tlsauthpass"), CURLOPT_PROXY_TLSAUTH_PASSWORD, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                       }
+# endif
+# if PHP_HTTP_CURL_VERSION(7,59,0)
+                       /* FIXME: see http://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html#AVAILABILITY */
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("pinned_publickey"), CURLOPT_PROXY_PINNEDPUBLICKEY, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+                       }
+# endif
+# if PHP_HTTP_CURL_VERSION(7,61,0)
+                       if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tls13_ciphers"), CURLOPT_PROXY_TLS13_CIPHERS, IS_STRING))) {
+                               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+                       }
+# endif
+               }
+#endif
+       }
+
+#if PHP_HTTP_CURL_VERSION(7,64,1)
+       if ((opt = php_http_option_register(registry, ZEND_STRL("altsvc_ctrl"), CURLOPT_ALTSVC_CTRL, IS_LONG))) {
+               opt->setter = php_http_curle_option_set_altsvc_ctrl;
        }
+       if ((opt = php_http_option_register(registry, ZEND_STRL("altsvc"), CURLOPT_ALTSVC, IS_STRING))) {
+               opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+       }
+#endif
 }
 
 static zval *php_http_curle_get_option(php_http_option_t *opt, HashTable *options, void *userdata)
@@ -1641,7 +1783,7 @@ static ZEND_RESULT_CODE php_http_curle_set_option(php_http_option_t *opt, zval *
        return rv;
 }
 
-#if PHP_HTTP_CURL_VERSION(7,30,0)
+#if PHP_HTTP_CURL_VERSION(7,30,0) && !PHP_HTTP_CURL_VERSION(7,62,0)
 static ZEND_RESULT_CODE php_http_curlm_option_set_pipelining_bl(php_http_option_t *opt, zval *value, void *userdata)
 {
        php_http_client_t *client = userdata;
@@ -1776,38 +1918,32 @@ static void php_http_curlm_options_init(php_http_options_t *registry)
        /* set max number of connections to a single host */
 #if PHP_HTTP_CURL_VERSION(7,30,0)
        php_http_option_register(registry, ZEND_STRL("max_host_connections"), CURLMOPT_MAX_HOST_CONNECTIONS, IS_LONG);
-#endif
-       /* maximum number of requests in a pipeline */
-#if PHP_HTTP_CURL_VERSION(7,30,0)
-       if ((opt = php_http_option_register(registry, ZEND_STRL("max_pipeline_length"), CURLMOPT_MAX_PIPELINE_LENGTH, IS_LONG))) {
-               ZVAL_LONG(&opt->defval, 5);
-       }
 #endif
        /* max simultaneously open connections */
 #if PHP_HTTP_CURL_VERSION(7,30,0)
        php_http_option_register(registry, ZEND_STRL("max_total_connections"), CURLMOPT_MAX_TOTAL_CONNECTIONS, IS_LONG);
 #endif
+#if !PHP_HTTP_CURL_VERSION(7,62,0)
        /* enable/disable HTTP pipelining */
        php_http_option_register(registry, ZEND_STRL("pipelining"), CURLMOPT_PIPELINING, _IS_BOOL);
+# if PHP_HTTP_CURL_VERSION(7,30,0)
+       /* maximum number of requests in a pipeline */
+       if ((opt = php_http_option_register(registry, ZEND_STRL("max_pipeline_length"), CURLMOPT_MAX_PIPELINE_LENGTH, IS_LONG))) {
+               ZVAL_LONG(&opt->defval, 5);
+       }
        /* chunk length threshold for pipelining */
-#if PHP_HTTP_CURL_VERSION(7,30,0)
        php_http_option_register(registry, ZEND_STRL("chunk_length_penalty_size"), CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, IS_LONG);
-#endif
        /* size threshold for pipelining penalty */
-#if PHP_HTTP_CURL_VERSION(7,30,0)
        php_http_option_register(registry, ZEND_STRL("content_length_penalty_size"), CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, IS_LONG);
-#endif
        /* pipelining server blacklist */
-#if PHP_HTTP_CURL_VERSION(7,30,0)
        if ((opt = php_http_option_register(registry, ZEND_STRL("pipelining_server_bl"), CURLMOPT_PIPELINING_SERVER_BL, IS_ARRAY))) {
                opt->setter = php_http_curlm_option_set_pipelining_bl;
        }
-#endif
        /* pipelining host blacklist */
-#if PHP_HTTP_CURL_VERSION(7,30,0)
        if ((opt = php_http_option_register(registry, ZEND_STRL("pipelining_site_bl"), CURLMOPT_PIPELINING_SITE_BL, IS_ARRAY))) {
                opt->setter = php_http_curlm_option_set_pipelining_bl;
        }
+# endif
 #endif
        /* events */
        if ((opt = php_http_option_register(registry, ZEND_STRL("use_eventloop"), 0, 0))) {
@@ -2394,13 +2530,13 @@ static ZEND_RESULT_CODE php_http_client_curl_setopt(php_http_client_t *h, php_ht
                case PHP_HTTP_CLIENT_OPT_CONFIGURATION:
                        return php_http_options_apply(&php_http_curlm_options, (HashTable *) arg,  h);
                        break;
-
+#if !PHP_HTTP_CURL_VERSION(7,62,0)
                case PHP_HTTP_CLIENT_OPT_ENABLE_PIPELINING:
                        if (CURLM_OK != curl_multi_setopt(curl->handle->multi, CURLMOPT_PIPELINING, (long) *((zend_bool *) arg))) {
                                return FAILURE;
                        }
                        break;
-
+#endif
                case PHP_HTTP_CLIENT_OPT_USE_EVENTS:
 #if PHP_HTTP_HAVE_LIBEVENT
                        return php_http_curlm_use_eventloop(h, (*(zend_bool *) arg)
@@ -2547,6 +2683,13 @@ PHP_MINIT_FUNCTION(http_client_curl)
        }
 
        if ((info = curl_version_info(CURLVERSION_NOW))) {
+               char tmp_ver[0x20], *tmp_ptr, *tmp_end;
+#define tmp_ver_init() do {\
+       tmp_ver[0] = 0; \
+       tmp_ptr = &tmp_ver[0]; \
+       tmp_end = &tmp_ver[sizeof(tmp_ver) - 1]; \
+} while (0)
+
                /*
                 * Feature constants
                 */
@@ -2554,9 +2697,6 @@ PHP_MINIT_FUNCTION(http_client_curl)
 
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "IPV6", CURL_VERSION_IPV6, CONST_CS|CONST_PERSISTENT);
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "KERBEROS4", CURL_VERSION_KERBEROS4, CONST_CS|CONST_PERSISTENT);
-#if PHP_HTTP_CURL_VERSION(7,40,0)
-               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "KERBEROS5", CURL_VERSION_KERBEROS5, CONST_CS|CONST_PERSISTENT);
-#endif
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "SSL", CURL_VERSION_SSL, CONST_CS|CONST_PERSISTENT);
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "LIBZ", CURL_VERSION_LIBZ, CONST_CS|CONST_PERSISTENT);
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "NTLM", CURL_VERSION_NTLM, CONST_CS|CONST_PERSISTENT);
@@ -2566,9 +2706,6 @@ PHP_MINIT_FUNCTION(http_client_curl)
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "LARGEFILE", CURL_VERSION_LARGEFILE, CONST_CS|CONST_PERSISTENT);
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "IDN", CURL_VERSION_IDN, CONST_CS|CONST_PERSISTENT);
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "SSPI", CURL_VERSION_SSPI, CONST_CS|CONST_PERSISTENT);
-#if PHP_HTTP_CURL_VERSION(7,38,0)
-               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "GSSAPI", CURL_VERSION_GSSAPI, CONST_CS|CONST_PERSISTENT);
-#endif
 #if PHP_HTTP_CURL_VERSION(7,21,4)
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "TLSAUTH_SRP", CURL_VERSION_TLSAUTH_SRP, CONST_CS|CONST_PERSISTENT);
 #endif
@@ -2578,28 +2715,73 @@ PHP_MINIT_FUNCTION(http_client_curl)
 #if PHP_HTTP_CURL_VERSION(7,33,0)
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HTTP2", CURL_VERSION_HTTP2, CONST_CS|CONST_PERSISTENT);
 #endif
+#if PHP_HTTP_CURL_VERSION(7,38,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "GSSAPI", CURL_VERSION_GSSAPI, CONST_CS|CONST_PERSISTENT);
+#endif
 #if PHP_HTTP_CURL_VERSION(7,40,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "KERBEROS5", CURL_VERSION_KERBEROS5, CONST_CS|CONST_PERSISTENT);
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "UNIX_SOCKETS", CURL_VERSION_UNIX_SOCKETS, CONST_CS|CONST_PERSISTENT);
 #endif
 #if PHP_HTTP_CURL_VERSION(7,47,0)
                REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "PSL", CURL_VERSION_PSL, CONST_CS|CONST_PERSISTENT);
 #endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HTTPS_PROXY", CURL_VERSION_HTTPS_PROXY, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,56,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "MULTI_SSL", CURL_VERSION_MULTI_SSL, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,57,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "BROTLI", CURL_VERSION_BROTLI, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,64,1)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "ALTSVC", CURL_VERSION_ALTSVC, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,66,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HTTP3", CURL_VERSION_HTTP3, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,72,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "ZSTD", CURL_VERSION_ZSTD, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "UNICODE", CURL_VERSION_UNICODE, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,74,0)
+               REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HSTS", CURL_VERSION_HSTS, CONST_CS|CONST_PERSISTENT);
+#endif
+
 
                /*
                 * Version constants
                 */
                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_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_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ARES", (char *) info->ares, CONST_CS|CONST_PERSISTENT);
-#  if CURLVERSION_NOW >= 2
-               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "IDN", (char *) info->libidn, CONST_CS|CONST_PERSISTENT);
-#  endif
-# endif
+               REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "CURL", info->version, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "SSL", info->ssl_version, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "LIBZ", info->libz_version, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ARES", info->ares, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "IDN", info->libidn, CONST_CS|CONST_PERSISTENT);
+               tmp_ver_init();
+               tmp_ptr = zend_print_ulong_to_buf(tmp_end, info->iconv_ver_num & 0xf);
+               tmp_end = tmp_ptr - 1;
+               tmp_ptr = zend_print_ulong_to_buf(tmp_end, info->iconv_ver_num >> 8);
+               *tmp_end = '.';
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ICONV", tmp_ptr, CONST_CS|CONST_PERSISTENT);
+#if PHP_HTTP_CURL_VERSION(7,57,0)
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "BROTLI", info->brotli_version, CONST_CS|CONST_PERSISTENT);
 #endif
+#if PHP_HTTP_CURL_VERSION(7,66,0)
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "NGHTTP2", info->nghttp2_version, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "QUIC", info->quic_version, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,70,0)
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "CAINFO", info->cainfo, CONST_CS|CONST_PERSISTENT);
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "CAPATH", info->capath, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,72,0)
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ZSTD", info->zstd_version, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,75,0)
+               REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "HYPER", info->hyper_version, CONST_CS|CONST_PERSISTENT);
+#endif
+
        }
 
        /*
@@ -2668,6 +2850,9 @@ PHP_MINIT_FUNCTION(http_client_curl)
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_GSSNEG", CURLAUTH_GSSNEGOTIATE, CONST_CS|CONST_PERSISTENT);
 #if PHP_HTTP_CURL_VERSION(7,38,0)
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_SPNEGO", CURLAUTH_NEGOTIATE, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,61,0)
+       REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_BEARER", CURLAUTH_BEARER, CONST_CS|CONST_PERSISTENT);
 #endif
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_ANY", CURLAUTH_ANY, CONST_CS|CONST_PERSISTENT);
 
@@ -2695,6 +2880,12 @@ PHP_MINIT_FUNCTION(http_client_curl)
        REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "POSTREDIR_ALL", CURL_REDIR_POST_ALL, CONST_CS|CONST_PERSISTENT);
 #endif
 
+#if PHP_HTTP_CURL_VERSION(7,64,1)
+       REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_READONLYFILE", CURLALTSVC_READONLYFILE, CONST_CS|CONST_PERSISTENT);
+       REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_H1", CURLALTSVC_H1, CONST_CS|CONST_PERSISTENT);
+       REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_H2", CURLALTSVC_H2, CONST_CS|CONST_PERSISTENT);
+       REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_H3", CURLALTSVC_H3, CONST_CS|CONST_PERSISTENT);
+#endif
        return SUCCESS;
 }