summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierrick Charron <pierrick@php.net>2012-12-19 19:40:29 -0500
committerPierrick Charron <pierrick@php.net>2012-12-19 19:40:29 -0500
commitc46e1cdcae70254cfc0b7d5781f2c71162a3734d (patch)
tree2e3c23195a41370c2e2cd8477b11ba7ba9911ebc
parente01fe5315c5fd03231641f7bb0819dbfaaadf935 (diff)
downloadphp-git-c46e1cdcae70254cfc0b7d5781f2c71162a3734d.tar.gz
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
-rw-r--r--NEWS4
-rw-r--r--ext/curl/php_curl.h1
-rw-r--r--ext/curl/streams.c22
3 files changed, 14 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index f5b2069690..bb3a7df470 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 05275455e7..af6a965c99 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 e317285c31..75a2bd08c1 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;
}