#if PHP_HTTP_HAVE_LIBCURL
+#define DEBUG_COOKIES 0
+
#if PHP_HTTP_HAVE_LIBCURL_OPENSSL
# include <openssl/ssl.h>
#endif
return 0;
}
-static int php_http_curle_header_callback(char *data, size_t n, size_t l, void *arg)
+static size_t php_http_curle_header_callback(char *data, size_t n, size_t l, void *arg)
{
php_http_client_curl_handler_t *h = arg;
return php_http_buffer_append(&h->response.headers, data, n * l);
}
-static int php_http_curle_body_callback(char *data, size_t n, size_t l, void *arg)
+static size_t php_http_curle_body_callback(char *data, size_t n, size_t l, void *arg)
{
php_http_client_curl_handler_t *h = arg;
char *c = NULL;
long l = 0;
double d = 0;
+ curl_off_t o = 0;
struct curl_slist *s = NULL, *p = NULL;
zval tmp;
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));
#define PHP_HTTP_CURLE_OPTION_CHECK_STRLEN 0x0001
#define PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR 0x0002
#define PHP_HTTP_CURLE_OPTION_TRANSFORM_MS 0x0004
+#define PHP_HTTP_CURLE_OPTION_IGNORE_RC 0x0008
static ZEND_RESULT_CODE php_http_curle_option_set_ssl_verifyhost(php_http_option_t *opt, zval *val, void *userdata)
{
return FAILURE;
}
if (Z_TYPE_P(val) == IS_TRUE) {
+#if DEBUG_COOKIES
+ fprintf(stderr, "CURLOPT_COOKIELIST: SESS\n");
+#endif
if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIELIST, "SESS")) {
return FAILURE;
}
} else {
storage->cookiestore = NULL;
}
- if ( CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEFILE, storage->cookiestore)
- || CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEJAR, storage->cookiestore)
- ) {
+
+#if DEBUG_COOKIES
+ fprintf(stderr, "CURLOPT_COOKIEFILE: %s\n", storage->cookiestore);
+#endif
+ // does NOT enable ch->data.cookies until transfer; adds to ch->stsate.cookielist
+ if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEFILE, storage->cookiestore ? storage->cookiestore : "")) {
+ return FAILURE;
+ }
+#if DEBUG_COOKIES
+ fprintf(stderr, "CURLOPT_COOKIEJAR: %s\n", storage->cookiestore);
+#endif
+ // enables ch->data.cookies
+ if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEJAR, storage->cookiestore)) {
return FAILURE;
}
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;
if (val && Z_LVAL_P(val)) {
switch (Z_LVAL_P(val)) {
+ case CURL_TLSAUTH_NONE:
+ break;
case CURL_TLSAUTH_SRP:
- if (CURLE_OK == curl_easy_setopt(ch, opt->option, PHP_HTTP_LIBCURL_TLSAUTH_SRP)) {
+ if (CURLE_OK == curl_easy_setopt(ch, opt->option, "SRP")) {
return SUCCESS;
}
/* no break */
return FAILURE;
}
}
- if (CURLE_OK != curl_easy_setopt(ch, opt->option, PHP_HTTP_LIBCURL_TLSAUTH_DEF)) {
+ if (CURLE_OK != curl_easy_setopt(ch, opt->option, "NONE")) {
return FAILURE;
}
return SUCCESS;
*/
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);
opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
}
#endif
+#if PHP_HTTP_CURL_VERSION(7,75,0)
+ php_http_option_register(registry, ZEND_STRL("aws_sigv4"), CURLOPT_AWS_SIGV4, IS_STRING);
+#endif
/* redirects */
if ((opt = php_http_option_register(registry, ZEND_STRL("redirect"), CURLOPT_FOLLOWLOCATION, IS_LONG))) {
/* 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))) {
}
#endif
#if PHP_HTTP_CURL_VERSION(7,49,0)
+# if defined(linux) || defined(__APPLE__)
+ /* CURLOPT_TCP_FASTOPEN is not supported (yet) on Windows */
php_http_option_register(registry, ZEND_STRL("tcp_fastopen"), CURLOPT_TCP_FASTOPEN, _IS_BOOL);
+# endif
#endif
/* ssl */
}
#endif
#if PHP_HTTP_CURL_VERSION(7,42,0) && (PHP_HTTP_HAVE_LIBCURL_NSS || PHP_HTTP_HAVE_LIBCURL_SECURETRANSPORT)
- php_http_option_register(ssl_registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL);
+ if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_IGNORE_RC;
+ }
#endif
-#if PHP_HTTP_CURL_VERSION(7,61,0)
+#if PHP_HTTP_CURL_VERSION(7,61,0) && PHP_HTTP_HAVE_LIBCURL_TLS13_CIPHERS
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;
}
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_CURL_VERSION(7,71,0)
+ if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("issuercert"), CURLOPT_PROXY_ISSUERCERT, IS_STRING))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+ }
+# endif
# 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_CURL_VERSION(7,61,0)
+# if PHP_HTTP_CURL_VERSION(7,61,0) && PHP_HTTP_HAVE_LIBCURL_TLS13_CIPHERS
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 !PHP_HTTP_HAVE_LIBCURL_ALT_SVC
+ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_ALTSVC)) {
+# endif
+ 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;
+ }
+# if !PHP_HTTP_HAVE_LIBCURL_ALT_SVC
+ }
+# endif
+#endif
+#if PHP_HTTP_CURL_VERSION(7,74,0)
+# if !PHP_HTTP_HAVE_LIBCURL_HSTS
+ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_HSTS)) {
+# endif
+ php_http_option_register(registry, ZEND_STRL("hsts_ctrl"), CURLOPT_HSTS_CTRL, IS_LONG);
+ if ((opt = php_http_option_register(registry, ZEND_STRL("hsts"), CURLOPT_HSTS, IS_STRING))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+ }
+# if !PHP_HTTP_HAVE_LIBCURL_HSTS
+ }
+# endif
+#endif
}
static zval *php_http_curle_get_option(php_http_option_t *opt, HashTable *options, void *userdata)
break;
}
if (rv != SUCCESS) {
- php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_easy_strerror(rc));
+ if (opt->flags & PHP_HTTP_CURLE_OPTION_IGNORE_RC) {
+ rv = SUCCESS;
+ } else {
+ php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_easy_strerror(rc));
+ }
}
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;
return SUCCESS;
}
-#if PHP_HTTP_CURL_VERSION(7,23,0)
+#if PHP_HTTP_HAVE_LIBCURL_SHARE_SSL
static ZEND_RESULT_CODE php_http_curlm_option_set_share_ssl(php_http_option_t *opt, zval *value, void *userdata)
{
php_http_client_t *client = userdata;
/* 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,67,0)
+ if ((opt = php_http_option_register(registry, ZEND_STRL("max_concurrent_streams"), CURLMOPT_MAX_CONCURRENT_STREAMS, IS_LONG))) {
+ ZVAL_LONG(&opt->defval, 100);
+ }
+#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))) {
opt->setter = php_http_curlm_option_set_share_cookies;
ZVAL_TRUE(&opt->defval);
}
-#if PHP_HTTP_CURL_VERSION(7,23,0)
+#if PHP_HTTP_HAVE_LIBCURL_SHARE_SSL
if ((opt = php_http_option_register(registry, ZEND_STRL("share_ssl"), 0, _IS_BOOL))) {
opt->setter = php_http_curlm_option_set_share_ssl;
ZVAL_TRUE(&opt->defval);
/* client ops */
-static ZEND_RESULT_CODE php_http_client_curl_handler_reset(php_http_client_curl_handler_t *curl)
+static ZEND_RESULT_CODE php_http_client_curl_handler_reset(php_http_client_curl_handler_t *handler)
{
- CURL *ch = curl->handle;
+ php_http_client_curl_t *curl = handler->client->ctx;
+ CURL *ch = handler->handle;
php_http_curle_storage_t *st;
if ((st = php_http_curle_get_storage(ch))) {
#endif
#if PHP_HTTP_CURL_VERSION(7,21,3)
- if (curl->options.resolve) {
- curl_slist_free_all(curl->options.resolve);
- curl->options.resolve = NULL;
+ if (handler->options.resolve) {
+ curl_slist_free_all(handler->options.resolve);
+ handler->options.resolve = NULL;
}
#endif
- curl->options.retry.count = 0;
- curl->options.retry.delay = 0;
- curl->options.redirects = 0;
- curl->options.encode_cookies = 1;
+ handler->options.retry.count = 0;
+ handler->options.retry.delay = 0;
+ handler->options.redirects = 0;
+ handler->options.encode_cookies = 1;
- if (curl->options.headers) {
- curl_slist_free_all(curl->options.headers);
- curl->options.headers = NULL;
+ if (handler->options.headers) {
+ curl_slist_free_all(handler->options.headers);
+ handler->options.headers = NULL;
}
- if (curl->options.proxyheaders) {
- curl_slist_free_all(curl->options.proxyheaders);
- curl->options.proxyheaders = NULL;
+ if (handler->options.proxyheaders) {
+ curl_slist_free_all(handler->options.proxyheaders);
+ handler->options.proxyheaders = NULL;
}
- php_http_buffer_reset(&curl->options.cookies);
- php_http_buffer_reset(&curl->options.ranges);
+ php_http_buffer_reset(&handler->options.cookies);
+ php_http_buffer_reset(&handler->options.ranges);
+
+ if (php_http_message_body_size(handler->response.body)) {
+ php_http_message_body_free(&handler->response.body);
+ handler->response.body = php_http_message_body_init(NULL, NULL);
+ }
+ php_http_buffer_reset(&handler->response.headers);
+
+#if ZTS
+ curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
+#endif
+ curl_easy_setopt(ch, CURLOPT_HEADER, 0L);
+ curl_easy_setopt(ch, CURLOPT_FILETIME, 1L);
+ curl_easy_setopt(ch, CURLOPT_AUTOREFERER, 1L);
+ curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 0L);
+ curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, php_http_curle_header_callback);
+ curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, php_http_curle_body_callback);
+ curl_easy_setopt(ch, CURLOPT_DEBUGFUNCTION, php_http_curle_raw_callback);
+ curl_easy_setopt(ch, CURLOPT_READFUNCTION, php_http_curle_read_callback);
+ curl_easy_setopt(ch, CURLOPT_SEEKFUNCTION, php_http_curle_seek_callback);
+#if PHP_HTTP_CURL_VERSION(7,32,0)
+ curl_easy_setopt(ch, CURLOPT_XFERINFOFUNCTION, php_http_curle_xferinfo_callback);
+ curl_easy_setopt(ch, CURLOPT_XFERINFODATA, handler);
+#else
+ curl_easy_setopt(ch, CURLOPT_PROGRESSFUNCTION, php_http_curle_progress_callback);
+ curl_easy_setopt(ch, CURLOPT_PROGRESSDATA, handler);
+#endif
+ curl_easy_setopt(ch, CURLOPT_DEBUGDATA, handler);
+ curl_easy_setopt(ch, CURLOPT_WRITEDATA, handler);
+ curl_easy_setopt(ch, CURLOPT_HEADERDATA, handler);
+#if DEBUG_COOKIES
+ fprintf(stderr, "CURLOPT_SHARE: %p\n", curl->handle->share);
+#endif
+ curl_easy_setopt(ch, CURLOPT_SHARE, curl->handle->share);
return SUCCESS;
}
static php_http_client_curl_handler_t *php_http_client_curl_handler_init(php_http_client_t *h, php_resource_factory_t *rf)
{
void *handle;
- php_http_client_curl_t *curl = h->ctx;
php_http_client_curl_handler_t *handler;
if (!(handle = php_resource_factory_handle_ctor(rf, NULL))) {
php_http_buffer_init(&handler->options.ranges);
zend_hash_init(&handler->options.cache, 0, NULL, ZVAL_PTR_DTOR, 0);
-#if ZTS
- curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L);
-#endif
- curl_easy_setopt(handle, CURLOPT_HEADER, 0L);
- curl_easy_setopt(handle, CURLOPT_FILETIME, 1L);
- curl_easy_setopt(handle, CURLOPT_AUTOREFERER, 1L);
- curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L);
- curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);
- curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, php_http_curle_header_callback);
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, php_http_curle_body_callback);
- curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, php_http_curle_raw_callback);
- curl_easy_setopt(handle, CURLOPT_READFUNCTION, php_http_curle_read_callback);
- curl_easy_setopt(handle, CURLOPT_SEEKFUNCTION, php_http_curle_seek_callback);
-#if PHP_HTTP_CURL_VERSION(7,32,0)
- curl_easy_setopt(handle, CURLOPT_XFERINFOFUNCTION, php_http_curle_xferinfo_callback);
- curl_easy_setopt(handle, CURLOPT_XFERINFODATA, handler);
-#else
- curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, php_http_curle_progress_callback);
- curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, handler);
-#endif
- curl_easy_setopt(handle, CURLOPT_DEBUGDATA, handler);
- curl_easy_setopt(handle, CURLOPT_WRITEDATA, handler);
- curl_easy_setopt(handle, CURLOPT_HEADERDATA, handler);
- curl_easy_setopt(handle, CURLOPT_SHARE, curl->handle->share);
-
php_http_client_curl_handler_reset(handler);
return handler;
curl_easy_setopt(curl->handle, CURLOPT_URL, storage->url);
/* apply options */
- php_http_options_apply(&php_http_curle_options, enqueue->options, curl);
+ if (SUCCESS != php_http_options_apply(&php_http_curle_options, enqueue->options, curl)) {
+ return FAILURE;
+ }
/* request headers */
php_http_message_update_headers(msg);
#endif
curl_easy_setopt(handler->handle, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(handler->handle, CURLOPT_DEBUGFUNCTION, NULL);
+ /* see gh issue #84 */
+#if DEBUG_COOKIES
+ fprintf(stderr, "CURLOPT_COOKIELIST: FLUSH\n");
+ fprintf(stderr, "CURLOPT_SHARE: (null)\n");
+#endif
curl_easy_setopt(handler->handle, CURLOPT_COOKIELIST, "FLUSH");
curl_easy_setopt(handler->handle, CURLOPT_SHARE, NULL);
- /* see gh issue #84 */
#if PHP_HTTP_CURL_VERSION(7,63,0) && !PHP_HTTP_CURL_VERSION(7,65,0)
- curl_easy_setopt(handler->handle, CURLOPT_COOKIEJAR, NULL);
+ {
+ php_http_curle_storage_t *st = php_http_curle_get_storage(handler->handle);
+ curl_easy_setopt(handler->handle, CURLOPT_COOKIEJAR, st ? st->cookiestore : NULL);
+ }
#endif
}
php_http_client_curl_handler_dtor(handler);
}
+static void retire_ch(php_persistent_handle_factory_t *f, void **handle)
+{
+ CURL *ch = *handle;
+ /* erase all cookies */
+ if (ch) {
+ curl_easy_reset(ch);
+ curl_easy_setopt(ch, CURLOPT_COOKIELIST, "ALL");
+ curl_easy_setopt(ch, CURLOPT_COOKIEFILE, NULL);
+ }
+}
+
static php_resource_factory_t *create_rf(php_http_client_t *h, php_http_client_enqueue_t *enqueue)
{
php_persistent_handle_factory_t *pf = NULL;
id_len = spprintf(&id_str, 0, "%.*s:%s:%d", (int) phf->ident->len, phf->ident->val, STR_PTR(url->host), port);
id = php_http_cs2zs(id_str, id_len);
- pf = php_persistent_handle_concede(NULL, PHP_HTTP_G->client.curl.driver.request_name, id, NULL, NULL);
+ pf = php_persistent_handle_concede(NULL, PHP_HTTP_G->client.curl.driver.request_name, id, NULL, retire_ch);
zend_string_release(id);
}
return SUCCESS;
}
+static ZEND_RESULT_CODE php_http_client_curl_requeue(php_http_client_t *h, php_http_client_enqueue_t *enqueue)
+{
+ CURLMcode rs;
+ php_http_client_curl_t *curl = h->ctx;
+ php_http_client_curl_handler_t *handler = enqueue->opaque;
+ php_http_client_progress_state_t *progress;
+
+ if (SUCCESS != php_http_client_curl_handler_reset(handler)) {
+ return FAILURE;
+ }
+
+ if (SUCCESS != php_http_client_curl_handler_prepare(handler, enqueue)) {
+ return FAILURE;
+ }
+
+ if (CURLM_OK != (rs = curl_multi_remove_handle(curl->handle->multi, handler->handle))) {
+ php_error_docref(NULL, E_WARNING, "Could not dequeue request: %s", curl_multi_strerror(rs));
+ return FAILURE;
+ }
+
+ if (CURLM_OK != (rs = curl_multi_add_handle(curl->handle->multi, handler->handle))) {
+ zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue);
+ php_error_docref(NULL, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs));
+ return FAILURE;
+ }
+
+ ++curl->unfinished;
+
+ if (h->callback.progress.func && SUCCESS == php_http_client_getopt(h, PHP_HTTP_CLIENT_OPT_PROGRESS_INFO, enqueue->request, &progress)) {
+ progress->info = "start";
+ h->callback.progress.func(h->callback.progress.arg, h, &handler->queue, progress);
+ progress->started = 1;
+ }
+
+ return SUCCESS;
+}
+
static ZEND_RESULT_CODE php_http_client_curl_dequeue(php_http_client_t *h, php_http_client_enqueue_t *enqueue)
{
CURLMcode rs;
{
php_http_client_curl_t *curl = h->ctx;
+ (void) curl;
+
switch (opt) {
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)
php_http_client_curl_once,
php_http_client_curl_enqueue,
php_http_client_curl_dequeue,
+ php_http_client_curl_requeue,
php_http_client_curl_setopt,
php_http_client_curl_getopt
};
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); \
- } \
+#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)
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 (info->iconv_ver_num) {
+ 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 ? tmp_ptr : NULL, 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
#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
+#if PHP_HTTP_CURL_VERSION(7,75,0)
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AWS_SIGV4", CURLAUTH_AWS_SIGV4, CONST_CS|CONST_PERSISTENT);
#endif
REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_ANY", CURLAUTH_ANY, CONST_CS|CONST_PERSISTENT);
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
+#if PHP_HTTP_CURL_VERSION(7,74,0)
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HSTS_ENABLE", CURLHSTS_ENABLE, CONST_CS|CONST_PERSISTENT);
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HSTS_READONLYFILE", CURLHSTS_READONLYFILE, CONST_CS|CONST_PERSISTENT);
+#endif
return SUCCESS;
}