| modification, are permitted provided that the conditions mentioned |
| in the accompanying LICENSE file are met. |
+--------------------------------------------------------------------+
- | Copyright (c) 2004-2013, Michael Wallner <mike@php.net> |
+ | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
+--------------------------------------------------------------------+
*/
#if PHP_HTTP_HAVE_CURL
#if PHP_HTTP_HAVE_EVENT
-# include <event.h>
# if !PHP_HTTP_HAVE_EVENT2 && /* just be really sure */ !(LIBEVENT_VERSION_NUMBER >= 0x02000000)
+# include <event.h>
# define event_base_new event_init
# define event_assign(e, b, s, a, cb, d) do {\
event_set(e, s, a, cb, d); \
event_base_set(b, e); \
} while(0)
+# else
+# if PHP_HTTP_HAVE_EVENT2
+# include <event2/event.h>
+# include <event2/event_struct.h>
+# else
+# error "libevent presence is unknown"
+# endif
# endif
# ifndef DBG_EVENTS
# define DBG_EVENTS 0
# endif
#endif
+#ifdef PHP_HTTP_HAVE_OPENSSL
+# include <openssl/ssl.h>
+#endif
+#ifdef PHP_HTTP_HAVE_GNUTLS
+# include <gnutls.h>
+#endif
+
typedef struct php_http_client_curl {
CURLM *handle;
{
php_http_message_body_t *body = ctx;
- if (body) {
- TSRMLS_FETCH_FROM_CTX(body->ts);
- return php_stream_read(php_http_message_body_stream(body), data, len * n);
+ if (body && body->stream_id) {
+ php_stream *s = php_http_message_body_stream(body);
+
+ if (s) {
+ TSRMLS_FETCH_FROM_CTX(body->ts);
+ return php_stream_read(s, data, len * n);
+ } else abort();
}
return 0;
}
+#if PHP_HTTP_CURL_VERSION(7,32,0)
+static int php_http_curle_xferinfo_callback(void *ctx, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
+#else
static int php_http_curle_progress_callback(void *ctx, double dltotal, double dlnow, double ultotal, double ulnow)
+#endif
{
php_http_client_curl_handler_t *h = ctx;
zend_bool update = 0;
h->progress.info = "blacklist check";
} else if (php_memnstr(data, ZEND_STRL("SSL"), data + length)) {
h->progress.info = "ssl negotiation";
+ } else if (php_memnstr(data, ZEND_STRL("upload"), data + length)) {
+ h->progress.info = "uploaded";
} else if (php_memnstr(data, ZEND_STRL("left intact"), data + length)) {
h->progress.info = "not disconnected";
} else if (php_memnstr(data, ZEND_STRL("closed"), data + length)) {
} else {
#if PHP_DEBUG
h->progress.info = data;
+ data[length - 1] = '\0';
#endif
}
if (h->client->callback.progress.func) {
/* END::CURLINFO */
+#if PHP_HTTP_CURL_VERSION(7,34,0)
+ {
+ int i;
+ zval *ti_array;
+ struct curl_tlssessioninfo *ti;
+
+ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TLS_SESSION, &ti)) {
+ const char *backend;
+
+ MAKE_STD_ZVAL(subarray);
+ ZVAL_NULL(subarray);
+ MAKE_STD_ZVAL(ti_array);
+ array_init(ti_array);
+
+ switch (ti->backend) {
+ case CURLSSLBACKEND_NONE:
+ backend = "none";
+ break;
+ case CURLSSLBACKEND_OPENSSL:
+ backend = "openssl";
+#ifdef PHP_HTTP_HAVE_OPENSSL
+ {
+ SSL_CTX *ctx = ti->internals;
+
+ array_init(subarray);
+ add_assoc_long_ex(subarray, ZEND_STRS("number"), SSL_CTX_sess_number(ctx));
+ add_assoc_long_ex(subarray, ZEND_STRS("connect"), SSL_CTX_sess_connect(ctx));
+ add_assoc_long_ex(subarray, ZEND_STRS("connect_good"), SSL_CTX_sess_connect_good(ctx));
+ add_assoc_long_ex(subarray, ZEND_STRS("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx));
+ add_assoc_long_ex(subarray, ZEND_STRS("hits"), SSL_CTX_sess_hits(ctx));
+ add_assoc_long_ex(subarray, ZEND_STRS("cache_full"), SSL_CTX_sess_cache_full(ctx));
+ }
+#endif
+ break;
+ case CURLSSLBACKEND_GNUTLS:
+ backend = "gnutls";
+#ifdef PHP_HTTP_HAVE_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_STRS("desc"), desc, 1);
+ gnutls_free(desc);
+ }
+ add_assoc_bool_ex(subarray, ZEND_STRS("resumed"), gnutls_session_is_resumed(sess));
+ }
+#endif
+ break;
+ case CURLSSLBACKEND_NSS:
+ backend = "nss";
+ break;
+ case CURLSSLBACKEND_QSOSSL:
+ backend = "qsossl";
+ break;
+ case CURLSSLBACKEND_GSKIT:
+ backend = "gskit";
+ break;
+ case CURLSSLBACKEND_POLARSSL:
+ backend = "polarssl";
+ break;
+ case CURLSSLBACKEND_CYASSL:
+ backend = "cyassl";
+ break;
+ case CURLSSLBACKEND_SCHANNEL:
+ backend = "schannel";
+ break;
+ case CURLSSLBACKEND_DARWINSSL:
+ backend = "darwinssl";
+ break;
+ default:
+ backend = "unknown";
+ }
+ add_assoc_string_ex(ti_array, ZEND_STRS("backend"), estrdup(backend), 0);
+ add_assoc_zval_ex(ti_array, ZEND_STRS("internals"), subarray);
+ add_assoc_zval_ex(&array, "tls_session", sizeof("tls_session"), ti_array);
+ }
+ }
+#endif
+
#if PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)
{
int i;
/* useragent */
if ((opt = php_http_option_register(registry, ZEND_STRL("useragent"), CURLOPT_USERAGENT, IS_STRING))) {
/* don't check strlen, to allow sending no useragent at all */
- ZVAL_STRING(&opt->defval, "PECL::HTTP/" PHP_PECL_HTTP_VERSION " (PHP/" PHP_VERSION ")", 0);
+ ZVAL_STRING(&opt->defval,
+ "PECL_HTTP/" PHP_PECL_HTTP_VERSION " "
+ "PHP/" PHP_VERSION " "
+ "libcurl/" LIBCURL_VERSION
+ , 0);
}
/* resume */
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_IOCTLFUNCTION, php_http_curle_ioctl_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_DEBUGDATA, handler);
curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, handler);
+#endif
+ curl_easy_setopt(handle, CURLOPT_DEBUGDATA, handler);
php_http_client_curl_handler_reset(handler);
}
}
php_http_buffer_dtor(&header);
- curl_easy_setopt(curl->handle, CURLOPT_HTTPHEADER, curl->options.headers);
}
+ curl_easy_setopt(curl->handle, CURLOPT_HTTPHEADER, curl->options.headers);
/* attach request body */
if ((body_size = php_http_message_body_size(msg->body))) {
curl_easy_setopt(curl->handle, CURLOPT_READDATA, msg->body);
curl_easy_setopt(curl->handle, CURLOPT_INFILESIZE, body_size);
curl_easy_setopt(curl->handle, CURLOPT_POSTFIELDSIZE, body_size);
+ } else {
+ curl_easy_setopt(curl->handle, CURLOPT_IOCTLDATA, NULL);
+ curl_easy_setopt(curl->handle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(curl->handle, CURLOPT_INFILESIZE, 0L);
+ curl_easy_setopt(curl->handle, CURLOPT_POSTFIELDSIZE, 0L);
}
php_http_options_apply(&php_http_curle_options, enqueue->options, curl);
TSRMLS_FETCH_FROM_CTX(handler->client->ts);
curl_easy_setopt(handler->handle, CURLOPT_NOPROGRESS, 1L);
+#if PHP_HTTP_CURL_VERSION(7,32,0)
+ curl_easy_setopt(handler->handle, CURLOPT_XFERINFOFUNCTION, NULL);
+#else
curl_easy_setopt(handler->handle, CURLOPT_PROGRESSFUNCTION, NULL);
+#endif
curl_easy_setopt(handler->handle, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(handler->handle, CURLOPT_DEBUGFUNCTION, NULL);
static STATUS php_http_client_curl_exec(php_http_client_t *h)
{
- TSRMLS_FETCH_FROM_CTX(h->ts);
-
#if PHP_HTTP_HAVE_EVENT
php_http_client_curl_t *curl = h->ctx;
+#endif
+ TSRMLS_FETCH_FROM_CTX(h->ts);
+#if PHP_HTTP_HAVE_EVENT
if (curl->useevents) {
php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, h);
do {
/* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "WinSock error: %d", WSAGetLastError());
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, strerror(errno));
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
#endif
return FAILURE;
}
PHP_MSHUTDOWN_FUNCTION(http_client_curl)
{
+ php_persistent_handle_cleanup(ZEND_STRL("http\\Client\\Curl"), NULL, 0 TSRMLS_CC);
+ php_persistent_handle_cleanup(ZEND_STRL("http\\Client\\Curl\\Request"), NULL, 0 TSRMLS_CC);
+
php_http_options_dtor(&php_http_curle_options);
+
return SUCCESS;
}