{
php_curl *ch;
CURL *cp;
+ zval *clone;
zstr url = NULL_ZSTR;
int url_len = 0;
zend_uchar url_type = 0;
ch->uses = 0;
+ MAKE_STD_ZVAL(clone);
+ ch->clone = clone;
+
curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str);
zend_llist_copy(&dupch->to_free.slist, &ch->to_free.slist);
zend_llist_copy(&dupch->to_free.post, &ch->to_free.post);
+ /* Keep track of cloned copies to avoid invoking curl destructors for every clone */
+ Z_ADDREF_P(ch->clone);
+ dupch->clone = ch->clone;
+
ZEND_REGISTER_RESOURCE(return_value, dupch, le_curl);
dupch->id = Z_LVAL_P(return_value);
}
#if LIBCURL_VERSION_NUM < 0x071101
zend_llist_clean(&ch->to_free.str);
#endif
- zend_llist_clean(&ch->to_free.slist);
- zend_llist_clean(&ch->to_free.post);
+
+ /* cURL destructors should be invoked only by last curl handle */
+ if (Z_REFCOUNT_P(ch->clone) <= 1) {
+ zend_llist_clean(&ch->to_free.slist);
+ zend_llist_clean(&ch->to_free.post);
+ zval_ptr_dtor(&ch->clone);
+ } else {
+ Z_DELREF_P(ch->clone);
+ ch->to_free.slist.dtor = NULL;
+ ch->to_free.post.dtor = NULL;
+ zend_llist_clean(&ch->to_free.slist);
+ zend_llist_clean(&ch->to_free.post);
+ }
if (ch->handlers->write->buf.len > 0) {
smart_str_free(&ch->handlers->write->buf);
--- /dev/null
+--TEST--
+Test curl_copy_handle() with simple POST
+--SKIPIF--
+<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?>
+--FILE--
+<?php
+ $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
+
+ echo '*** Testing curl copy handle with simple POST using array as arguments ***' . "\n";
+
+ $url = "{$host}/get.php?test=getpost";
+ $ch = curl_init();
+
+ ob_start(); // start output buffering
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, array("Hello" => "World", "Foo" => "Bar", "Person" => "John Doe"));
+ curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use
+
+ $copy = curl_copy_handle($ch);
+ curl_close($ch);
+
+ $curl_content = curl_exec($copy);
+ curl_close($copy);
+
+ var_dump( $curl_content );
+?>
+===DONE===
+--EXPECTF--
+*** Testing curl copy handle with simple POST using array as arguments ***
+string(163) "array(1) {
+ ["test"]=>
+ string(7) "getpost"
+}
+array(3) {
+ ["Hello"]=>
+ string(5) "World"
+ ["Foo"]=>
+ string(3) "Bar"
+ ["Person"]=>
+ string(8) "John Doe"
+}
+"
+===DONE===