struct {
HashTable cache;
+ struct curl_slist *proxyheaders;
struct curl_slist *headers;
struct curl_slist *resolve;
php_http_buffer_t cookies;
static php_http_message_t *php_http_curlm_responseparser(php_http_client_curl_handler_t *h TSRMLS_DC)
{
- php_http_message_t *response = NULL;
+ php_http_message_t *response;
php_http_header_parser_t parser;
+ zval *zh;
response = php_http_message_init(NULL, 0, h->response.body TSRMLS_CC);
php_http_header_parser_init(&parser TSRMLS_CC);
}
php_http_message_body_addref(h->response.body);
+ /* let's update the response headers */
+ if ((zh = php_http_message_header(response, ZEND_STRL("Content-Length"), 1))) {
+ zend_hash_update(&response->hdrs, "X-Original-Content-Length", sizeof("X-Original-Content-Length"), &zh, sizeof(zval *), NULL);
+ }
+ if ((zh = php_http_message_header(response, ZEND_STRL("Transfer-Encoding"), 0))) {
+ zend_hash_update(&response->hdrs, "X-Original-Transfer-Encoding", sizeof("X-Original-Transfer-Encoding"), (void *) &zh, sizeof(zval *), NULL);
+ zend_hash_del(&response->hdrs, "Transfer-Encoding", sizeof("Transfer-Encoding"));
+ }
+ if ((zh = php_http_message_header(response, ZEND_STRL("Content-Range"), 0))) {
+ zend_hash_update(&response->hdrs, "X-Original-Content-Range", sizeof("X-Original-Content-Range"), &zh, sizeof(zval *), NULL);
+ zend_hash_del(&response->hdrs, "Content-Range", sizeof("Content-Range"));
+ }
+ if ((zh = php_http_message_header(response, ZEND_STRL("Content-Encoding"), 0))) {
+ zend_hash_update(&response->hdrs, "X-Original-Content-Encoding", sizeof("X-Original-Content-Encoding"), &zh, sizeof(zval *), NULL);
+ zend_hash_del(&response->hdrs, "Content-Encoding", sizeof("Content-Encoding"));
+ }
php_http_message_update_headers(response);
return response;
php_http_client_curl_handler_t *handler = enqueue->opaque;
php_http_message_t *response = php_http_curlm_responseparser(handler TSRMLS_CC);
- context->callback.response.func(context->callback.response.arg, context, &handler->queue, &response);
- php_http_message_free(&response);
+ if (response) {
+ context->callback.response.func(context->callback.response.arg, context, &handler->queue, &response);
+ php_http_message_free(&response);
+ }
}
}
} while (remaining);
return SUCCESS;
}
+#if PHP_HTTP_CURL_VERSION(7,37,0)
+static STATUS php_http_curle_option_set_proxyheader(php_http_option_t *opt, zval *val, void *userdata)
+{
+ php_http_client_curl_handler_t *curl = userdata;
+ TSRMLS_FETCH_FROM_CTX(curl->client->ts);
+
+ if (val && Z_TYPE_P(val) != IS_NULL) {
+ php_http_array_hashkey_t header_key = php_http_array_hashkey_init(0);
+ zval **header_val, *header_cpy;
+ HashPosition pos;
+ php_http_buffer_t header;
+
+ php_http_buffer_init(&header);
+ FOREACH_KEYVAL(pos, val, header_key, header_val) {
+ if (header_key.type == HASH_KEY_IS_STRING) {
+ header_cpy = php_http_ztyp(IS_STRING, *header_val);
+ php_http_buffer_appendf(&header, "%s: %s", header_key.str, Z_STRVAL_P(header_cpy));
+ php_http_buffer_fix(&header);
+ curl->options.proxyheaders = curl_slist_append(curl->options.proxyheaders, header.data);
+ php_http_buffer_reset(&header);
+
+ zval_ptr_dtor(&header_cpy);
+ }
+ }
+ php_http_buffer_dtor(&header);
+ }
+ if (CURLE_OK != curl_easy_setopt(curl->handle, CURLOPT_PROXYHEADER, curl->options.proxyheaders)) {
+ return FAILURE;
+ }
+ if (CURLE_OK != curl_easy_setopt(curl->handle, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE)) {
+ curl_easy_setopt(curl->handle, CURLOPT_PROXYHEADER, NULL);
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+#endif
+
#if PHP_HTTP_CURL_VERSION(7,21,3)
static STATUS php_http_curle_option_set_resolve(php_http_option_t *opt, zval *val, void *userdata)
{
php_http_option_register(registry, ZEND_STRL("noproxy"), CURLOPT_NOPROXY, IS_STRING);
#endif
+#if PHP_HTTP_CURL_VERSION(7,37,0)
+ if ((opt = php_http_option_register(registry, ZEND_STRL("proxyheader"), CURLOPT_PROXYHEADER, IS_ARRAY))) {
+ opt->setter = php_http_curle_option_set_proxyheader;
+ }
+#endif
+
/* dns */
if ((opt = php_http_option_register(registry, ZEND_STRL("dns_cache_timeout"), CURLOPT_DNS_CACHE_TIMEOUT, IS_LONG))) {
Z_LVAL(opt->defval) = 60;
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)
+ 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
}
}
curl_slist_free_all(curl->options.headers);
curl->options.headers = NULL;
}
+ if (curl->options.proxyheaders) {
+ curl_slist_free_all(curl->options.proxyheaders);
+ curl->options.proxyheaders = NULL;
+ }
php_http_buffer_reset(&curl->options.cookies);
php_http_buffer_reset(&curl->options.ranges);