Skip to content

Commit f2cc479

Browse files
committed
Add clone support for Curl object
1 parent abb4182 commit f2cc479

File tree

5 files changed

+71
-10
lines changed

5 files changed

+71
-10
lines changed

ext/curl/interface.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ static zend_object *curl_create_object(zend_class_entry *class_type);
239239
static void curl_free_obj(zend_object *object);
240240
static HashTable *curl_get_gc(zend_object *object, zval **table, int *n);
241241
static zend_function *curl_get_constructor(zend_object *object);
242+
static zend_object *curl_clone_obj(zend_object *object);
243+
php_curl *alloc_curl_handle(php_curl *ch);
244+
static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields);
242245

243246
static const zend_function_entry curl_object_methods[] = {
244247
PHP_FE_END
@@ -1203,7 +1206,7 @@ PHP_MINIT_FUNCTION(curl)
12031206
curl_object_handlers.free_obj = curl_free_obj;
12041207
curl_object_handlers.get_gc = curl_get_gc;
12051208
curl_object_handlers.get_constructor = curl_get_constructor;
1206-
curl_object_handlers.clone_obj = NULL;
1209+
curl_object_handlers.clone_obj = curl_clone_obj;
12071210

12081211
curl_multi_register_class();
12091212
curl_share_register_class();
@@ -1230,6 +1233,35 @@ static zend_function *curl_get_constructor(zend_object *object) {
12301233
return NULL;
12311234
}
12321235

1236+
static zend_object *curl_clone_obj(zend_object *object) {
1237+
php_curl *ch;
1238+
CURL *cp;
1239+
php_curl *dupch;
1240+
zval *postfields;
1241+
1242+
ch = curl_from_obj(object);
1243+
1244+
cp = curl_easy_duphandle(ch->cp);
1245+
if (!cp) {
1246+
return NULL;
1247+
}
1248+
1249+
dupch = ecalloc(1, sizeof(php_curl));
1250+
dupch = alloc_curl_handle(dupch);
1251+
dupch->cp = cp;
1252+
1253+
_php_setup_easy_copy_handlers(dupch, ch);
1254+
1255+
postfields = &ch->postfields;
1256+
if (Z_TYPE_P(postfields) != IS_UNDEF) {
1257+
if (build_mime_structure_from_hash(dupch, postfields) != SUCCESS) {
1258+
return NULL;
1259+
}
1260+
}
1261+
1262+
return &ch->std;
1263+
}
1264+
12331265
static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
12341266
{
12351267
php_curl *curl = curl_from_obj(object);
@@ -1692,15 +1724,18 @@ PHP_FUNCTION(curl_version)
16921724
}
16931725
/* }}} */
16941726

1695-
/* {{{ alloc_curl_handle
1696-
*/
1697-
php_curl *alloc_curl_handle(zval *curl)
1727+
php_curl *alloc_curl_handle_from_zval(zval *curl)
16981728
{
16991729
php_curl *ch;
17001730

17011731
object_init_ex(curl, curl_ce);
17021732
ch = Z_CURL_P(curl);
17031733

1734+
return alloc_curl_handle(ch);
1735+
}
1736+
1737+
php_curl *alloc_curl_handle(php_curl *ch)
1738+
{
17041739
ch->to_free = ecalloc(1, sizeof(struct _php_curl_free));
17051740
ch->handlers = ecalloc(1, sizeof(php_curl_handlers));
17061741
ch->handlers->write = ecalloc(1, sizeof(php_curl_write));
@@ -1813,7 +1848,7 @@ PHP_FUNCTION(curl_init)
18131848
RETURN_FALSE;
18141849
}
18151850

1816-
ch = alloc_curl_handle(return_value);
1851+
ch = alloc_curl_handle_from_zval(return_value);
18171852

18181853
ch->cp = cp;
18191854

@@ -2123,7 +2158,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
21232158
Copy a cURL handle along with all of it's preferences */
21242159
PHP_FUNCTION(curl_copy_handle)
21252160
{
2126-
php_curl *ch;
2161+
php_curl *ch;
21272162
CURL *cp;
21282163
zval *zid;
21292164
php_curl *dupch;
@@ -2141,7 +2176,7 @@ PHP_FUNCTION(curl_copy_handle)
21412176
RETURN_FALSE;
21422177
}
21432178

2144-
dupch = alloc_curl_handle(return_value);
2179+
dupch = alloc_curl_handle_from_zval(return_value);
21452180
dupch->cp = cp;
21462181

21472182
_php_setup_easy_copy_handlers(dupch, ch);

ext/curl/multi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
401401

402402
parent = Z_CURL_P(pz_parent_ch);
403403

404-
ch = alloc_curl_handle(&pz_ch);
404+
ch = alloc_curl_handle_from_zval(&pz_ch);
405405
ch->cp = easy;
406406
_php_setup_easy_copy_handlers(ch, parent);
407407

ext/curl/php_curl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ typedef struct {
151151
zend_object std;
152152
} php_curlsh;
153153

154-
php_curl *alloc_curl_handle(zval *curl);
154+
php_curl *alloc_curl_handle_from_zval(zval *curl);
155155
void _php_curl_cleanup_handle(php_curl *);
156156
void _php_curl_multi_cleanup_list(void *data);
157157
void _php_curl_verify_handlers(php_curl *ch, int reporterror);

ext/curl/tests/curl_handle_clone.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Test that cloning of Curl objects is supported
3+
--SKIPIF--
4+
<?php include 'skipif.inc'; ?>
5+
--FILE--
6+
<?php
7+
8+
include 'server.inc';
9+
$host = curl_cli_server_start();
10+
11+
$ch1 = curl_init();
12+
curl_setopt($ch1, CURLOPT_URL, $host);
13+
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
14+
curl_exec($ch1);
15+
16+
$ch2 = clone $ch1;
17+
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 0);
18+
19+
var_dump(curl_getinfo($ch1, CURLINFO_EFFECTIVE_URL) === curl_getinfo($ch2, CURLINFO_EFFECTIVE_URL));
20+
curl_exec($ch2);
21+
22+
?>
23+
--EXPECT--
24+
bool(true)
25+
Hello World!
26+
Hello World!

ext/posix/tests/posix_ttyname_error_wrongparams.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PHP Testfest Berlin 2009-05-10
2121
<?php
2222
var_dump(posix_ttyname(0)); // param not a resource
2323
try {
24-
var_dump(posix_ttyname(curl_init())); // wrong resource type
24+
var_dump(posix_ttyname(fopen(__FILE__))); // wrong resource type
2525
} catch (TypeError $e) {
2626
echo $e->getMessage(), "\n";
2727
}

0 commit comments

Comments
 (0)