@@ -1795,11 +1795,20 @@ static void curl_free_post(void **post)
1795
1795
}
1796
1796
/* }}} */
1797
1797
1798
- /* {{{ curl_free_stream
1798
+ struct mime_data_cb_arg {
1799
+ zend_string * filename ;
1800
+ php_stream * stream ;
1801
+ };
1802
+
1803
+ /* {{{ curl_free_cb_arg
1799
1804
*/
1800
- static void curl_free_stream (void * * post )
1805
+ static void curl_free_cb_arg (void * * cb_arg_p )
1801
1806
{
1802
- php_stream_close ((php_stream * )* post );
1807
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) * cb_arg_p ;
1808
+
1809
+ ZEND_ASSERT (cb_arg -> stream == NULL );
1810
+ zend_string_release (cb_arg -> filename );
1811
+ efree (cb_arg );
1803
1812
}
1804
1813
/* }}} */
1805
1814
@@ -1900,11 +1909,13 @@ php_curl *alloc_curl_handle()
1900
1909
1901
1910
zend_llist_init (& ch -> to_free -> str , sizeof (char * ), (llist_dtor_func_t )curl_free_string , 0 );
1902
1911
zend_llist_init (& ch -> to_free -> post , sizeof (struct HttpPost * ), (llist_dtor_func_t )curl_free_post , 0 );
1903
- zend_llist_init (& ch -> to_free -> stream , sizeof (php_stream * ), (llist_dtor_func_t )curl_free_stream , 0 );
1912
+ zend_llist_init (& ch -> to_free -> stream , sizeof (struct mime_data_cb_arg * ), (llist_dtor_func_t )curl_free_cb_arg , 0 );
1904
1913
1905
1914
ch -> to_free -> slist = emalloc (sizeof (HashTable ));
1906
1915
zend_hash_init (ch -> to_free -> slist , 4 , NULL , curl_free_slist , 0 );
1907
-
1916
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
1917
+ ZVAL_UNDEF (& ch -> postfields );
1918
+ #endif
1908
1919
return ch ;
1909
1920
}
1910
1921
/* }}} */
@@ -2094,62 +2105,48 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
2094
2105
(* source -> clone )++ ;
2095
2106
}
2096
2107
2097
- /* {{{ proto resource curl_copy_handle(resource ch)
2098
- Copy a cURL handle along with all of it's preferences */
2099
- PHP_FUNCTION (curl_copy_handle )
2108
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2109
+ static size_t read_cb (char * buffer , size_t size , size_t nitems , void * arg ) /* {{{ */
2100
2110
{
2101
- CURL * cp ;
2102
- zval * zid ;
2103
- php_curl * ch , * dupch ;
2104
-
2105
- ZEND_PARSE_PARAMETERS_START (1 ,1 )
2106
- Z_PARAM_RESOURCE (zid )
2107
- ZEND_PARSE_PARAMETERS_END ();
2111
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) arg ;
2112
+ ssize_t numread ;
2108
2113
2109
- if ((ch = (php_curl * )zend_fetch_resource (Z_RES_P (zid ), le_curl_name , le_curl )) == NULL ) {
2110
- RETURN_FALSE ;
2114
+ if (cb_arg -> stream == NULL ) {
2115
+ if (!(cb_arg -> stream = php_stream_open_wrapper (ZSTR_VAL (cb_arg -> filename ), "rb" , IGNORE_PATH , NULL ))) {
2116
+ return CURL_READFUNC_ABORT ;
2117
+ }
2111
2118
}
2112
-
2113
- cp = curl_easy_duphandle ( ch -> cp );
2114
- if (! cp ) {
2115
- php_error_docref ( NULL , E_WARNING , "Cannot duplicate cURL handle" ) ;
2116
- RETURN_FALSE ;
2119
+ numread = php_stream_read ( cb_arg -> stream , buffer , nitems * size );
2120
+ if ( numread < 0 ) {
2121
+ php_stream_close ( cb_arg -> stream );
2122
+ cb_arg -> stream = NULL ;
2123
+ return CURL_READFUNC_ABORT ;
2117
2124
}
2118
-
2119
- dupch = alloc_curl_handle ();
2120
- dupch -> cp = cp ;
2121
-
2122
- _php_setup_easy_copy_handlers (dupch , ch );
2123
-
2124
- Z_ADDREF_P (zid );
2125
-
2126
- ZVAL_RES (return_value , zend_register_resource (dupch , le_curl ));
2127
- dupch -> res = Z_RES_P (return_value );
2125
+ return numread ;
2128
2126
}
2129
2127
/* }}} */
2130
2128
2131
- #if LIBCURL_VERSION_NUM >= 0x073800
2132
- static size_t read_cb (char * buffer , size_t size , size_t nitems , void * arg ) /* {{{ */
2129
+ static int seek_cb (void * arg , curl_off_t offset , int origin ) /* {{{ */
2133
2130
{
2134
- php_stream * stream = (php_stream * ) arg ;
2135
- ssize_t numread = php_stream_read ( stream , buffer , nitems * size ) ;
2131
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) arg ;
2132
+ int res ;
2136
2133
2137
- if (numread < 0 ) {
2138
- return CURL_READFUNC_ABORT ;
2134
+ if (cb_arg -> stream == NULL ) {
2135
+ return CURL_SEEKFUNC_CANTSEEK ;
2139
2136
}
2140
- return numread ;
2137
+ res = php_stream_seek (cb_arg -> stream , offset , origin );
2138
+ return res == SUCCESS ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK ;
2141
2139
}
2142
2140
/* }}} */
2143
2141
2144
- static int seek_cb (void * arg , curl_off_t offset , int origin ) /* {{{ */
2142
+ static void free_cb (void * arg ) /* {{{ */
2145
2143
{
2146
- php_stream * stream = (php_stream * ) arg ;
2147
- int res = php_stream_seek (stream , offset , origin );
2144
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) arg ;
2148
2145
2149
- if (res ) {
2150
- return CURL_SEEKFUNC_CANTSEEK ;
2146
+ if (cb_arg -> stream != NULL ) {
2147
+ php_stream_close (cb_arg -> stream );
2148
+ cb_arg -> stream = NULL ;
2151
2149
}
2152
- return CURL_SEEKFUNC_OK ;
2153
2150
}
2154
2151
/* }}} */
2155
2152
#endif
@@ -2160,7 +2157,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
2160
2157
zval * current ;
2161
2158
HashTable * postfields ;
2162
2159
zend_string * string_key ;
2163
- zend_ulong num_key ;
2160
+ zend_ulong num_key ;
2164
2161
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2165
2162
curl_mime * mime = NULL ;
2166
2163
curl_mimepart * part ;
@@ -2202,7 +2199,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
2202
2199
zval * prop , rv ;
2203
2200
char * type = NULL , * filename = NULL ;
2204
2201
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2205
- php_stream * stream ;
2202
+ struct mime_data_cb_arg * cb_arg ;
2206
2203
#endif
2207
2204
2208
2205
prop = zend_read_property (curl_CURLFile_class , current , "name" , sizeof ("name" )- 1 , 0 , & rv );
@@ -2225,24 +2222,25 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
2225
2222
}
2226
2223
2227
2224
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2228
- if (!(stream = php_stream_open_wrapper (ZSTR_VAL (postval ), "rb" , IGNORE_PATH , NULL ))) {
2229
- zend_string_release_ex (string_key , 0 );
2230
- return FAILURE ;
2231
- }
2225
+ zval_ptr_dtor (& ch -> postfields );
2226
+ ZVAL_COPY (& ch -> postfields , zpostfields );
2227
+
2228
+ cb_arg = emalloc (sizeof * cb_arg );
2229
+ cb_arg -> filename = zend_string_copy (postval );
2230
+ cb_arg -> stream = NULL ;
2231
+
2232
2232
part = curl_mime_addpart (mime );
2233
2233
if (part == NULL ) {
2234
- php_stream_close (stream );
2235
2234
zend_string_release_ex (string_key , 0 );
2236
2235
return FAILURE ;
2237
2236
}
2238
2237
if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2239
- || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , NULL , stream )) != CURLE_OK
2238
+ || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , free_cb , cb_arg )) != CURLE_OK
2240
2239
|| (form_error = curl_mime_filename (part , filename ? filename : ZSTR_VAL (postval ))) != CURLE_OK
2241
2240
|| (form_error = curl_mime_type (part , type ? type : "application/octet-stream" )) != CURLE_OK ) {
2242
- php_stream_close (stream );
2243
2241
error = form_error ;
2244
2242
}
2245
- zend_llist_add_element (& ch -> to_free -> stream , & stream );
2243
+ zend_llist_add_element (& ch -> to_free -> stream , & cb_arg );
2246
2244
#else
2247
2245
form_error = curl_formadd (& first , & last ,
2248
2246
CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
@@ -2310,11 +2308,60 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
2310
2308
zend_llist_add_element (& ch -> to_free -> post , & first );
2311
2309
error = curl_easy_setopt (ch -> cp , CURLOPT_HTTPPOST , first );
2312
2310
#endif
2311
+
2313
2312
SAVE_CURL_ERROR (ch , error );
2314
2313
return error == CURLE_OK ? SUCCESS : FAILURE ;
2315
2314
}
2316
2315
/* }}} */
2317
2316
2317
+ /* {{{ proto resource curl_copy_handle(resource ch)
2318
+ Copy a cURL handle along with all of it's preferences */
2319
+ PHP_FUNCTION (curl_copy_handle )
2320
+ {
2321
+ CURL * cp ;
2322
+ zval * zid ;
2323
+ php_curl * ch , * dupch ;
2324
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2325
+ zval * postfields ;
2326
+ #endif
2327
+
2328
+ ZEND_PARSE_PARAMETERS_START (1 ,1 )
2329
+ Z_PARAM_RESOURCE (zid )
2330
+ ZEND_PARSE_PARAMETERS_END ();
2331
+
2332
+ if ((ch = (php_curl * )zend_fetch_resource (Z_RES_P (zid ), le_curl_name , le_curl )) == NULL ) {
2333
+ RETURN_FALSE ;
2334
+ }
2335
+
2336
+ cp = curl_easy_duphandle (ch -> cp );
2337
+ if (!cp ) {
2338
+ php_error_docref (NULL , E_WARNING , "Cannot duplicate cURL handle" );
2339
+ RETURN_FALSE ;
2340
+ }
2341
+
2342
+ dupch = alloc_curl_handle ();
2343
+ dupch -> cp = cp ;
2344
+
2345
+ _php_setup_easy_copy_handlers (dupch , ch );
2346
+
2347
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2348
+ postfields = & ch -> postfields ;
2349
+ if (Z_TYPE_P (postfields ) != IS_UNDEF ) {
2350
+ if (build_mime_structure_from_hash (dupch , postfields ) != SUCCESS ) {
2351
+ _php_curl_close_ex (dupch );
2352
+ php_error_docref (NULL , E_WARNING , "Cannot rebuild mime structure" );
2353
+ RETURN_FALSE ;
2354
+ }
2355
+ }
2356
+ #endif
2357
+
2358
+ Z_ADDREF_P (zid );
2359
+
2360
+ ZVAL_RES (return_value , zend_register_resource (dupch , le_curl ));
2361
+ dupch -> res = Z_RES_P (return_value );
2362
+ }
2363
+ /* }}} */
2364
+
2318
2365
static int _php_curl_setopt (php_curl * ch , zend_long option , zval * zvalue ) /* {{{ */
2319
2366
{
2320
2367
CURLcode error = CURLE_OK ;
@@ -3613,6 +3660,9 @@ static void _php_curl_close_ex(php_curl *ch)
3613
3660
#endif
3614
3661
3615
3662
efree (ch -> handlers );
3663
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
3664
+ zval_ptr_dtor (& ch -> postfields );
3665
+ #endif
3616
3666
efree (ch );
3617
3667
}
3618
3668
/* }}} */
0 commit comments