From c46e1cdcae70254cfc0b7d5781f2c71162a3734d Mon Sep 17 00:00:00 2001 From: Pierrick Charron Date: Wed, 19 Dec 2012 19:40:29 -0500 Subject: [PATCH] Fixed bug #55438 (Curlwapper is not sending http header randomly) Since curl multi is used, it sometime happen that the resource is freed before the curl multi really execute the query. The patch will store the headers slist in the curlstream handle and free it only when the stream will be closed --- NEWS | 4 ++++ ext/curl/php_curl.h | 1 + ext/curl/streams.c | 22 +++++++++------------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index f5b20696908..bb3a7df4704 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed bug #63762 (Sigsegv when Exception::$trace is changed by user). (Johannes) +- cURL extension: + . Fixed bug #55438 (Curlwapper is not sending http header randomly). + (phpnet@lostreality.org, Pierrick) + 20 Dec 2012, PHP 5.3.20 - Zend Engine: diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 05275455e77..af6a965c991 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -181,6 +181,7 @@ typedef struct { CURLMcode mcode; int pending; zval *headers; + struct curl_slist *headers_slist; /* holds custom headers sent out in the request */ } php_curl_stream; diff --git a/ext/curl/streams.c b/ext/curl/streams.c index e317285c311..75a2bd08c10 100644 --- a/ext/curl/streams.c +++ b/ext/curl/streams.c @@ -218,6 +218,10 @@ static int php_curl_stream_close(php_stream *stream, int close_handle TSRMLS_DC) curl_easy_cleanup(curlstream->curl); curl_multi_cleanup(curlstream->multi); + if (curlstream->headers_slist) { + curl_slist_free_all(curlstream->headers_slist); + } + /* we are not closing curlstream->readbuf here, because we export * it as a zval with the wrapperdata - the engine will garbage collect it */ @@ -268,7 +272,6 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, php_stream *stream; php_curl_stream *curlstream; zval *tmp, **ctx_opt = NULL; - struct curl_slist *slist = NULL; curlstream = emalloc(sizeof(php_curl_stream)); memset(curlstream, 0, sizeof(php_curl_stream)); @@ -279,6 +282,7 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, curlstream->curl = curl_easy_init(); curlstream->multi = curl_multi_init(); curlstream->pending = 1; + curlstream->headers_slist = NULL; /* if opening for an include statement, ensure that the local storage will * have a FILE* associated with it. @@ -351,7 +355,7 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, zend_hash_move_forward_ex(Z_ARRVAL_PP(ctx_opt), &pos) ) { if (Z_TYPE_PP(header) == IS_STRING) { - slist = curl_slist_append(slist, Z_STRVAL_PP(header)); + curlstream->headers_slist = curl_slist_append(curlstream->headers_slist, Z_STRVAL_PP(header)); } } } else if (Z_TYPE_PP(ctx_opt) == IS_STRING && Z_STRLEN_PP(ctx_opt)) { @@ -361,14 +365,14 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, p = php_strtok_r(copy_ctx_opt, "\r\n", &token); while (p) { trimmed = php_trim(p, strlen(p), NULL, 0, NULL, 3 TSRMLS_CC); - slist = curl_slist_append(slist, trimmed); + curlstream->headers_slist = curl_slist_append(curlstream->headers_slist, trimmed); efree(trimmed); p = php_strtok_r(NULL, "\r\n", &token); } efree(copy_ctx_opt); } - if (slist) { - curl_easy_setopt(curlstream->curl, CURLOPT_HTTPHEADER, slist); + if (curlstream->headers_slist) { + curl_easy_setopt(curlstream->curl, CURLOPT_HTTPHEADER, curlstream->headers_slist); } } if (SUCCESS == php_stream_context_get_option(context, "http", "method", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) { @@ -500,18 +504,10 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, } } - /* context headers are not needed anymore */ - if (slist) { - curl_easy_setopt(curlstream->curl, CURLOPT_HTTPHEADER, NULL); - curl_slist_free_all(slist); - } return stream; exit_fail: php_stream_close(stream); - if (slist) { - curl_slist_free_all(slist); - } return NULL; }