# include <gnutls.h>
#endif
+typedef struct php_http_client_curl_handle {
+ CURLM *multi;
+ CURLSH *share;
+} php_http_client_curl_handle_t;
+
typedef struct php_http_client_curl {
- CURLM *handle;
+ php_http_client_curl_handle_t *handle;
int unfinished; /* int because of curl_multi_perform() */
static void *php_http_curlm_ctor(void *opaque, void *init_arg)
{
- return curl_multi_init();
+ php_http_client_curl_handle_t *curl = calloc(1, sizeof(*curl));
+
+ if (!(curl->multi = curl_multi_init())) {
+ free(curl);
+ return NULL;
+ }
+ if (!(curl->share = curl_share_init())) {
+ curl_multi_cleanup(curl->multi);
+ free(curl);
+ return NULL;
+ }
+ curl_share_setopt(curl->share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+ curl_share_setopt(curl->share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
+ return curl;
}
static void php_http_curlm_dtor(void *opaque, void *handle)
{
- curl_multi_cleanup(handle);
+ php_http_client_curl_handle_t *curl = handle;
+
+ curl_share_cleanup(curl->share);
+ curl_multi_cleanup(curl->multi);
+ free(handle);
}
static php_resource_factory_ops_t php_http_curlm_resource_factory_ops = {
php_http_client_curl_t *curl = context->ctx;
do {
- CURLMsg *msg = curl_multi_info_read(curl->handle, &remaining);
+ CURLMsg *msg = curl_multi_info_read(curl->handle->multi, &remaining);
if (msg && CURLMSG_DONE == msg->msg) {
if (CURLE_OK != msg->data.result) {
(void) socket;
(void) action;
- while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle, CURL_SOCKET_TIMEOUT, 0, &curl->unfinished)));
+ while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle->multi, CURL_SOCKET_TIMEOUT, 0, &curl->unfinished)));
if (CURLM_OK != rc) {
php_error_docref(NULL, E_WARNING, "%s", curl_multi_strerror(rc));
if (curl->useevents) {
CURLMcode rc = CURLM_OK;
- while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle, socket, etoca(action), &curl->unfinished)));
+ while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle->multi, socket, etoca(action), &curl->unfinished)));
if (CURLM_OK != rc) {
php_error_docref(NULL, E_WARNING, "%s", curl_multi_strerror(rc));
if (!ev) {
ev = ecalloc(1, sizeof(php_http_curlm_event_t));
ev->context = context;
- curl_multi_assign(curl->handle, sock, ev);
+ curl_multi_assign(curl->handle->multi, sock, ev);
} else {
event_del(&ev->evnt);
}
return SUCCESS;
}
+static ZEND_RESULT_CODE php_http_curle_option_set_cookiesession(php_http_option_t *opt, zval *val, void *userdata)
+{
+ php_http_client_curl_handler_t *curl = userdata;
+ CURL *ch = curl->handle;
+
+ if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIESESSION, (long) (Z_TYPE_P(val) == IS_TRUE))) {
+ return FAILURE;
+ }
+ if (Z_TYPE_P(val) == IS_TRUE) {
+ if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIELIST, "SESS")) {
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
static ZEND_RESULT_CODE php_http_curle_option_set_cookiestore(php_http_option_t *opt, zval *val, void *userdata)
{
php_http_client_curl_handler_t *curl = userdata;
) {
return FAILURE;
}
+
return SUCCESS;
}
#endif
/* proxy */
- if ((opt = php_http_option_register(registry, ZEND_STRL("proxyhost"), CURLOPT_PROXY, IS_STRING))) {
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
- }
+ php_http_option_register(registry, ZEND_STRL("proxyhost"), CURLOPT_PROXY, IS_STRING);
php_http_option_register(registry, ZEND_STRL("proxytype"), CURLOPT_PROXYTYPE, IS_LONG);
php_http_option_register(registry, ZEND_STRL("proxyport"), CURLOPT_PROXYPORT, IS_LONG);
if ((opt = php_http_option_register(registry, ZEND_STRL("proxyauth"), CURLOPT_PROXYUSERPWD, IS_STRING))) {
}
#endif
#if PHP_HTTP_CURL_VERSION(7,43,0)
- if ((opt = php_http_option_register(registry, ZEND_STRL("proxy_service_name"), CURLOPT_PROXY_SERVICE_NAME, IS_STRING))) {
+ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_GSSAPI)
+ && (opt = php_http_option_register(registry, ZEND_STRL("proxy_service_name"), CURLOPT_PROXY_SERVICE_NAME, IS_STRING))
+ ) {
opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
}
#endif
#if PHP_HTTP_CURL_VERSION(7,40,0)
- if ((opt = php_http_option_register(registry, ZEND_STRL("unix_socket_path"), CURLOPT_UNIX_SOCKET_PATH, IS_STRING))) {
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_UNIX_SOCKETS)) {
+ if ((opt = php_http_option_register(registry, ZEND_STRL("unix_socket_path"), CURLOPT_UNIX_SOCKET_PATH, IS_STRING))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+ }
}
#endif
Z_LVAL(opt->defval) = CURLAUTH_ANYSAFE;
}
#if PHP_HTTP_CURL_VERSION(7,43,0)
+ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_SSPI) || PHP_HTTP_CURL_FEATURE(CURL_VERSION_GSSAPI))
if ((opt = php_http_option_register(registry, ZEND_STRL("service_name"), CURLOPT_SERVICE_NAME, IS_STRING))) {
opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
}
}
/* cookiesession, don't load session cookies from cookiestore */
- php_http_option_register(registry, ZEND_STRL("cookiesession"), CURLOPT_COOKIESESSION, _IS_BOOL);
+ if ((opt = php_http_option_register(registry, ZEND_STRL("cookiesession"), CURLOPT_COOKIESESSION, _IS_BOOL))) {
+ opt->setter = php_http_curle_option_set_cookiesession;
+ }
/* cookiestore, read initial cookies from that file and store cookies back into that file */
if ((opt = php_http_option_register(registry, ZEND_STRL("cookiestore"), 0, IS_STRING))) {
opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
#endif
/* ssl */
- if ((opt = php_http_option_register(registry, ZEND_STRL("ssl"), 0, IS_ARRAY))) {
- registry = &opt->suboptions;
+ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_SSL)) {
+ if ((opt = php_http_option_register(registry, ZEND_STRL("ssl"), 0, IS_ARRAY))) {
+ registry = &opt->suboptions;
- if ((opt = php_http_option_register(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))) {
- 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))) {
- 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))) {
- 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))) {
- 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))) {
- ZVAL_BOOL(&opt->defval, 1);
- }
- if ((opt = php_http_option_register(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)
+ if ((opt = php_http_option_register(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))) {
+ 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))) {
+ 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))) {
+ 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))) {
+ 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))) {
+ ZVAL_BOOL(&opt->defval, 1);
+ }
+ if ((opt = php_http_option_register(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) && (defined(PHP_HTTP_HAVE_OPENSSL) || defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_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 ((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;
+ php_http_option_register(registry, ZEND_STRL("cipher_list"), CURLOPT_SSL_CIPHER_LIST, IS_STRING);
+ 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);
+#endif
+ }
+ 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);
#endif
}
- 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;
- }
- 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;
- }
- if ((opt = php_http_option_register(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 ((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;
+ }
+ if ((opt = php_http_option_register(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))) {
- 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("issuercert"), CURLOPT_ISSUERCERT, IS_STRING))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
+ }
# ifdef PHP_HTTP_HAVE_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;
- }
+ 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 ((opt = php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) {
- ZVAL_FALSE(&opt->defval);
- }
+ if ((opt = php_http_option_register(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))) {
- ZVAL_BOOL(&opt->defval, 1);
- }
- if ((opt = php_http_option_register(registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, _IS_BOOL))) {
- ZVAL_BOOL(&opt->defval, 1);
- }
+ if ((opt = php_http_option_register(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))) {
+ 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))) {
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR;
- }
+ /* 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))) {
+ 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) && defined(PHP_HTTP_CURL_TLSAUTH_SRP)
- if ((opt = php_http_option_register(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))) {
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
- }
- if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthpass"), CURLOPT_TLSAUTH_PASSWORD, IS_STRING))) {
- opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
- }
+ if ((opt = php_http_option_register(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))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+ }
+ if ((opt = php_http_option_register(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) && (defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_DARWINSSL))
php_http_option_register(registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL);
#endif
+ }
}
}
php_http_client_curl_handler_t *curl = userdata;
CURL *ch = curl->handle;
zval tmp;
- CURLcode rc = CURLE_OK;
+ CURLcode rc = CURLE_UNKNOWN_OPTION;
ZEND_RESULT_CODE rv = SUCCESS;
if (!val) {
{
php_http_client_t *client = userdata;
php_http_client_curl_t *curl = client->ctx;
- CURLM *ch = curl->handle;
+ CURLM *ch = curl->handle->multi;
HashTable tmp_ht;
char **bl = NULL;
if (!curl->timeout) {
curl->timeout = ecalloc(1, sizeof(struct event));
}
- curl_multi_setopt(curl->handle, CURLMOPT_SOCKETDATA, h);
- curl_multi_setopt(curl->handle, CURLMOPT_SOCKETFUNCTION, php_http_curlm_socket_callback);
- curl_multi_setopt(curl->handle, CURLMOPT_TIMERDATA, h);
- curl_multi_setopt(curl->handle, CURLMOPT_TIMERFUNCTION, php_http_curlm_timer_callback);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_SOCKETDATA, h);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_SOCKETFUNCTION, php_http_curlm_socket_callback);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_TIMERDATA, h);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_TIMERFUNCTION, php_http_curlm_timer_callback);
} else {
- curl_multi_setopt(curl->handle, CURLMOPT_SOCKETDATA, NULL);
- curl_multi_setopt(curl->handle, CURLMOPT_SOCKETFUNCTION, NULL);
- curl_multi_setopt(curl->handle, CURLMOPT_TIMERDATA, NULL);
- curl_multi_setopt(curl->handle, CURLMOPT_TIMERFUNCTION, NULL);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_SOCKETDATA, NULL);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_SOCKETFUNCTION, NULL);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_TIMERDATA, NULL);
+ curl_multi_setopt(curl->handle->multi, CURLMOPT_TIMERFUNCTION, NULL);
}
return SUCCESS;
}
#endif
+static ZEND_RESULT_CODE php_http_curlm_option_set_share_cookies(php_http_option_t *opt, zval *value, void *userdata)
+{
+ php_http_client_t *client = userdata;
+ php_http_client_curl_t *curl = client->ctx;
+ CURLSHcode rc;
+
+ if (Z_TYPE_P(value) == IS_TRUE) {
+ rc = curl_share_setopt(curl->handle->share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+ } else {
+ rc = curl_share_setopt(curl->handle->share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE);
+ }
+
+ if (CURLSHE_OK != rc) {
+ php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_share_strerror(rc));
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+#if PHP_HTTP_CURL_VERSION(7,23,0)
+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;
+ php_http_client_curl_t *curl = client->ctx;
+ CURLSHcode rc;
+
+ if (Z_TYPE_P(value) == IS_TRUE) {
+ rc = curl_share_setopt(curl->handle->share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
+ } else {
+ rc = curl_share_setopt(curl->handle->share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_SSL_SESSION);
+ }
+
+ if (CURLSHE_OK != rc) {
+ php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_share_strerror(rc));
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+#endif
+
static void php_http_curlm_options_init(php_http_options_t *registry)
{
php_http_option_t *opt;
if ((opt = php_http_option_register(registry, ZEND_STRL("use_eventloop"), 0, _IS_BOOL))) {
opt->setter = php_http_curlm_option_set_use_eventloop;
}
+#endif
+ /* share */
+ if ((opt = php_http_option_register(registry, ZEND_STRL("share_cookies"), 0, _IS_BOOL))) {
+ opt->setter = php_http_curlm_option_set_share_cookies;
+ ZVAL_TRUE(&opt->defval);
+ }
+#if PHP_HTTP_CURL_VERSION(7,23,0)
+ 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);
+ }
#endif
}
{
php_http_client_t *client = userdata;
php_http_client_curl_t *curl = client->ctx;
- CURLM *ch = curl->handle;
+ CURLM *ch = curl->handle->multi;
zval *orig = val;
CURLMcode rc = CURLM_UNKNOWN_OPTION;
ZEND_RESULT_CODE rv = SUCCESS;
case _IS_BOOL:
if (CURLM_OK != (rc = curl_multi_setopt(ch, opt->option, (long) zend_is_true(val)))) {
rv = FAILURE;
+ php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_multi_strerror(rc));
}
break;
case IS_LONG:
if (CURLM_OK != (rc = curl_multi_setopt(ch, opt->option, Z_LVAL_P(val)))) {
rv = FAILURE;
+ php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_multi_strerror(rc));
}
break;
default:
rv = FAILURE;
+ php_error_docref(NULL, E_NOTICE, "Could not set option %s", opt->name->val);
break;
}
}
zval_ptr_dtor(val);
}
- if (rv != SUCCESS) {
- php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_easy_strerror(rc));
- }
return rv;
}
st->cookiestore = NULL;
}
st->errorbuffer[0] = '\0';
+ st->errorcode = 0;
}
curl_easy_setopt(ch, CURLOPT_URL, NULL);
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))) {
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);
#endif
curl_easy_setopt(handler->handle, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(handler->handle, CURLOPT_DEBUGFUNCTION, NULL);
+ curl_easy_setopt(handler->handle, CURLOPT_COOKIELIST, "FLUSH");
+ curl_easy_setopt(handler->handle, CURLOPT_SHARE, NULL);
}
static void php_http_client_curl_handler_dtor(php_http_client_curl_handler_t *handler)
size_t id_len;
int port = url->port ? url->port : 80;
zval *zport;
+ php_persistent_handle_factory_t *phf = h->rf->data;
if ((zport = zend_hash_str_find(enqueue->options, ZEND_STRL("port")))) {
zend_long lport = zval_get_long(zport);
}
}
- id_len = spprintf(&id_str, 0, "%s:%d", STR_PTR(url->host), port);
+ 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);
zend_string_release(id);
enqueue->opaque = handler;
enqueue->dtor = queue_dtor;
- if (CURLM_OK == (rs = curl_multi_add_handle(curl->handle, handler->handle))) {
- zend_llist_add_element(&h->requests, enqueue);
- ++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;
- } else {
+ if (CURLM_OK != (rs = curl_multi_add_handle(curl->handle->multi, handler->handle))) {
+ php_http_client_curl_handler_dtor(handler);
php_error_docref(NULL, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs));
return FAILURE;
}
+
+ zend_llist_add_element(&h->requests, enqueue);
+ ++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)
php_http_client_curl_handler_t *handler = enqueue->opaque;
php_http_client_curl_handler_clear(handler);
- if (CURLM_OK == (rs = curl_multi_remove_handle(curl->handle, handler->handle))) {
+ if (CURLM_OK == (rs = curl_multi_remove_handle(curl->handle->multi, handler->handle))) {
zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue);
return SUCCESS;
} else {
static inline void php_http_client_curl_get_timeout(php_http_client_curl_t *curl, long max_tout, struct timeval *timeout)
{
- if ((CURLM_OK == curl_multi_timeout(curl->handle, &max_tout)) && (max_tout > 0)) {
+ if ((CURLM_OK == curl_multi_timeout(curl->handle->multi, &max_tout)) && (max_tout > 0)) {
timeout->tv_sec = max_tout / 1000;
timeout->tv_usec = (max_tout % 1000) * 1000;
} else {
FD_ZERO(&W);
FD_ZERO(&E);
- if (CURLM_OK == curl_multi_fdset(curl->handle, &R, &W, &E, &MAX)) {
+ if (CURLM_OK == curl_multi_fdset(curl->handle->multi, &R, &W, &E, &MAX)) {
if (custom_timeout && timerisset(custom_timeout)) {
timeout = *custom_timeout;
} else {
event_base_loop(curl->evbase, EVLOOP_NONBLOCK);
} else
#endif
- while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curl->handle, &curl->unfinished));
+ while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curl->handle->multi, &curl->unfinished));
php_http_curlm_responsehandler(h);
break;
case PHP_HTTP_CLIENT_OPT_ENABLE_PIPELINING:
- if (CURLM_OK != curl_multi_setopt(curl->handle, CURLMOPT_PIPELINING, (long) *((zend_bool *) arg))) {
+ if (CURLM_OK != curl_multi_setopt(curl->handle->multi, CURLMOPT_PIPELINING, (long) *((zend_bool *) arg))) {
return FAILURE;
}
break;
PHP_MINIT_FUNCTION(http_client_curl)
{
+ curl_version_info_data *info;
php_http_options_t *options;
PHP_HTTP_G->client.curl.driver.driver_name = zend_string_init(ZEND_STRL("curl"), 1);
php_http_curlm_options_init(options);
}
+ if ((info = curl_version_info(CURLVERSION_NOW))) {
+ /*
+ * Feature constants
+ */
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "FEATURES", info->features, CONST_CS|CONST_PERSISTENT);
+
+ 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);
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "GSSNEGOTIATE", CURL_VERSION_GSSNEGOTIATE, CONST_CS|CONST_PERSISTENT);
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "ASYNCHDNS", CURL_VERSION_ASYNCHDNS, CONST_CS|CONST_PERSISTENT);
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "SPNEGO", CURL_VERSION_SPNEGO, CONST_CS|CONST_PERSISTENT);
+ 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
+#if PHP_HTTP_CURL_VERSION(7,22,0)
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "NTLM_WB", CURL_VERSION_NTLM_WB, CONST_CS|CONST_PERSISTENT);
+#endif
+#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,40,0)
+ 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
+
+ /*
+ * 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_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);
+# if CURLVERSION_NOW >= 1
+ REGISTER_NS_STRING_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);
+# endif
+# endif
+#endif
+ }
+
/*
* HTTP Protocol Version Constants
*/
REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_1_1", CURL_HTTP_VERSION_1_1, CONST_CS|CONST_PERSISTENT);
#if PHP_HTTP_CURL_VERSION(7,33,0)
REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_2_0", CURL_HTTP_VERSION_2_0, CONST_CS|CONST_PERSISTENT);
+#endif
+#if PHP_HTTP_CURL_VERSION(7,47,0)
+ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_2TLS", CURL_HTTP_VERSION_2TLS, CONST_CS|CONST_PERSISTENT);
#endif
REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_ANY", CURL_HTTP_VERSION_NONE, CONST_CS|CONST_PERSISTENT);