@@ -1591,11 +1591,20 @@ static void curl_free_post(void **post)
1591
1591
}
1592
1592
/* }}} */
1593
1593
1594
- /* {{{ curl_free_stream
1594
+ struct mime_data_cb_arg {
1595
+ zend_string * filename ;
1596
+ php_stream * stream ;
1597
+ };
1598
+
1599
+ /* {{{ curl_free_cb_arg
1595
1600
*/
1596
- static void curl_free_stream (void * * post )
1601
+ static void curl_free_cb_arg (void * * cb_arg_p )
1597
1602
{
1598
- php_stream_close ((php_stream * )* post );
1603
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) * cb_arg_p ;
1604
+
1605
+ ZEND_ASSERT (cb_arg -> stream == NULL );
1606
+ zend_string_release (cb_arg -> filename );
1607
+ efree (cb_arg );
1599
1608
}
1600
1609
/* }}} */
1601
1610
@@ -1692,11 +1701,13 @@ php_curl *alloc_curl_handle()
1692
1701
1693
1702
zend_llist_init (& ch -> to_free -> str , sizeof (char * ), (llist_dtor_func_t )curl_free_string , 0 );
1694
1703
zend_llist_init (& ch -> to_free -> post , sizeof (struct HttpPost * ), (llist_dtor_func_t )curl_free_post , 0 );
1695
- zend_llist_init (& ch -> to_free -> stream , sizeof (php_stream * ), (llist_dtor_func_t )curl_free_stream , 0 );
1704
+ zend_llist_init (& ch -> to_free -> stream , sizeof (struct mime_data_cb_arg * ), (llist_dtor_func_t )curl_free_cb_arg , 0 );
1696
1705
1697
1706
ch -> to_free -> slist = emalloc (sizeof (HashTable ));
1698
1707
zend_hash_init (ch -> to_free -> slist , 4 , NULL , curl_free_slist , 0 );
1699
-
1708
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
1709
+ ZVAL_UNDEF (& ch -> postfields );
1710
+ #endif
1700
1711
return ch ;
1701
1712
}
1702
1713
/* }}} */
@@ -1882,62 +1893,48 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1882
1893
(* source -> clone )++ ;
1883
1894
}
1884
1895
1885
- /* {{{ proto resource curl_copy_handle(resource ch)
1886
- Copy a cURL handle along with all of it's preferences */
1887
- PHP_FUNCTION (curl_copy_handle )
1896
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
1897
+ static size_t read_cb (char * buffer , size_t size , size_t nitems , void * arg ) /* {{{ */
1888
1898
{
1889
- CURL * cp ;
1890
- zval * zid ;
1891
- php_curl * ch , * dupch ;
1892
-
1893
- ZEND_PARSE_PARAMETERS_START (1 ,1 )
1894
- Z_PARAM_RESOURCE (zid )
1895
- ZEND_PARSE_PARAMETERS_END ();
1899
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) arg ;
1900
+ ssize_t numread ;
1896
1901
1897
- if ((ch = (php_curl * )zend_fetch_resource (Z_RES_P (zid ), le_curl_name , le_curl )) == NULL ) {
1898
- RETURN_THROWS ();
1902
+ if (cb_arg -> stream == NULL ) {
1903
+ if (!(cb_arg -> stream = php_stream_open_wrapper (ZSTR_VAL (cb_arg -> filename ), "rb" , IGNORE_PATH , NULL ))) {
1904
+ return CURL_READFUNC_ABORT ;
1905
+ }
1899
1906
}
1900
-
1901
- cp = curl_easy_duphandle ( ch -> cp );
1902
- if (! cp ) {
1903
- php_error_docref ( NULL , E_WARNING , "Cannot duplicate cURL handle" ) ;
1904
- RETURN_FALSE ;
1907
+ numread = php_stream_read ( cb_arg -> stream , buffer , nitems * size );
1908
+ if ( numread < 0 ) {
1909
+ php_stream_close ( cb_arg -> stream );
1910
+ cb_arg -> stream = NULL ;
1911
+ return CURL_READFUNC_ABORT ;
1905
1912
}
1906
-
1907
- dupch = alloc_curl_handle ();
1908
- dupch -> cp = cp ;
1909
-
1910
- _php_setup_easy_copy_handlers (dupch , ch );
1911
-
1912
- Z_ADDREF_P (zid );
1913
-
1914
- ZVAL_RES (return_value , zend_register_resource (dupch , le_curl ));
1915
- dupch -> res = Z_RES_P (return_value );
1913
+ return numread ;
1916
1914
}
1917
1915
/* }}} */
1918
1916
1919
- #if LIBCURL_VERSION_NUM >= 0x073800
1920
- static size_t read_cb (char * buffer , size_t size , size_t nitems , void * arg ) /* {{{ */
1917
+ static int seek_cb (void * arg , curl_off_t offset , int origin ) /* {{{ */
1921
1918
{
1922
- php_stream * stream = (php_stream * ) arg ;
1923
- ssize_t numread = php_stream_read ( stream , buffer , nitems * size ) ;
1919
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) arg ;
1920
+ int res ;
1924
1921
1925
- if (numread < 0 ) {
1926
- return CURL_READFUNC_ABORT ;
1922
+ if (cb_arg -> stream == NULL ) {
1923
+ return CURL_SEEKFUNC_CANTSEEK ;
1927
1924
}
1928
- return numread ;
1925
+ res = php_stream_seek (cb_arg -> stream , offset , origin );
1926
+ return res == SUCCESS ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK ;
1929
1927
}
1930
1928
/* }}} */
1931
1929
1932
- static int seek_cb (void * arg , curl_off_t offset , int origin ) /* {{{ */
1930
+ static void free_cb (void * arg ) /* {{{ */
1933
1931
{
1934
- php_stream * stream = (php_stream * ) arg ;
1935
- int res = php_stream_seek (stream , offset , origin );
1932
+ struct mime_data_cb_arg * cb_arg = (struct mime_data_cb_arg * ) arg ;
1936
1933
1937
- if (res ) {
1938
- return CURL_SEEKFUNC_CANTSEEK ;
1934
+ if (cb_arg -> stream != NULL ) {
1935
+ php_stream_close (cb_arg -> stream );
1936
+ cb_arg -> stream = NULL ;
1939
1937
}
1940
- return CURL_SEEKFUNC_OK ;
1941
1938
}
1942
1939
/* }}} */
1943
1940
#endif
@@ -1948,7 +1945,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
1948
1945
zval * current ;
1949
1946
HashTable * postfields ;
1950
1947
zend_string * string_key ;
1951
- zend_ulong num_key ;
1948
+ zend_ulong num_key ;
1952
1949
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
1953
1950
curl_mime * mime = NULL ;
1954
1951
curl_mimepart * part ;
@@ -1990,7 +1987,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
1990
1987
zval * prop , rv ;
1991
1988
char * type = NULL , * filename = NULL ;
1992
1989
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
1993
- php_stream * stream ;
1990
+ struct mime_data_cb_arg * cb_arg ;
1994
1991
#endif
1995
1992
1996
1993
prop = zend_read_property (curl_CURLFile_class , current , "name" , sizeof ("name" )- 1 , 0 , & rv );
@@ -2013,24 +2010,25 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
2013
2010
}
2014
2011
2015
2012
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2016
- if (!(stream = php_stream_open_wrapper (ZSTR_VAL (postval ), "rb" , IGNORE_PATH , NULL ))) {
2017
- zend_string_release_ex (string_key , 0 );
2018
- return FAILURE ;
2019
- }
2013
+ zval_ptr_dtor (& ch -> postfields );
2014
+ ZVAL_COPY (& ch -> postfields , zpostfields );
2015
+
2016
+ cb_arg = emalloc (sizeof * cb_arg );
2017
+ cb_arg -> filename = zend_string_copy (postval );
2018
+ cb_arg -> stream = NULL ;
2019
+
2020
2020
part = curl_mime_addpart (mime );
2021
2021
if (part == NULL ) {
2022
- php_stream_close (stream );
2023
2022
zend_string_release_ex (string_key , 0 );
2024
2023
return FAILURE ;
2025
2024
}
2026
2025
if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2027
- || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , NULL , stream )) != CURLE_OK
2026
+ || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , free_cb , cb_arg )) != CURLE_OK
2028
2027
|| (form_error = curl_mime_filename (part , filename ? filename : ZSTR_VAL (postval ))) != CURLE_OK
2029
2028
|| (form_error = curl_mime_type (part , type ? type : "application/octet-stream" )) != CURLE_OK ) {
2030
- php_stream_close (stream );
2031
2029
error = form_error ;
2032
2030
}
2033
- zend_llist_add_element (& ch -> to_free -> stream , & stream );
2031
+ zend_llist_add_element (& ch -> to_free -> stream , & cb_arg );
2034
2032
#else
2035
2033
form_error = curl_formadd (& first , & last ,
2036
2034
CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
@@ -2098,11 +2096,60 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
2098
2096
zend_llist_add_element (& ch -> to_free -> post , & first );
2099
2097
error = curl_easy_setopt (ch -> cp , CURLOPT_HTTPPOST , first );
2100
2098
#endif
2099
+
2101
2100
SAVE_CURL_ERROR (ch , error );
2102
2101
return error == CURLE_OK ? SUCCESS : FAILURE ;
2103
2102
}
2104
2103
/* }}} */
2105
2104
2105
+ /* {{{ proto resource curl_copy_handle(resource ch)
2106
+ Copy a cURL handle along with all of it's preferences */
2107
+ PHP_FUNCTION (curl_copy_handle )
2108
+ {
2109
+ CURL * cp ;
2110
+ zval * zid ;
2111
+ php_curl * ch , * dupch ;
2112
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2113
+ zval * postfields ;
2114
+ #endif
2115
+
2116
+ ZEND_PARSE_PARAMETERS_START (1 ,1 )
2117
+ Z_PARAM_RESOURCE (zid )
2118
+ ZEND_PARSE_PARAMETERS_END ();
2119
+
2120
+ if ((ch = (php_curl * )zend_fetch_resource (Z_RES_P (zid ), le_curl_name , le_curl )) == NULL ) {
2121
+ RETURN_FALSE ;
2122
+ }
2123
+
2124
+ cp = curl_easy_duphandle (ch -> cp );
2125
+ if (!cp ) {
2126
+ php_error_docref (NULL , E_WARNING , "Cannot duplicate cURL handle" );
2127
+ RETURN_FALSE ;
2128
+ }
2129
+
2130
+ dupch = alloc_curl_handle ();
2131
+ dupch -> cp = cp ;
2132
+
2133
+ _php_setup_easy_copy_handlers (dupch , ch );
2134
+
2135
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2136
+ postfields = & ch -> postfields ;
2137
+ if (Z_TYPE_P (postfields ) != IS_UNDEF ) {
2138
+ if (build_mime_structure_from_hash (dupch , postfields ) != SUCCESS ) {
2139
+ _php_curl_close_ex (dupch );
2140
+ php_error_docref (NULL , E_WARNING , "Cannot rebuild mime structure" );
2141
+ RETURN_FALSE ;
2142
+ }
2143
+ }
2144
+ #endif
2145
+
2146
+ Z_ADDREF_P (zid );
2147
+
2148
+ ZVAL_RES (return_value , zend_register_resource (dupch , le_curl ));
2149
+ dupch -> res = Z_RES_P (return_value );
2150
+ }
2151
+ /* }}} */
2152
+
2106
2153
static int _php_curl_setopt (php_curl * ch , zend_long option , zval * zvalue ) /* {{{ */
2107
2154
{
2108
2155
CURLcode error = CURLE_OK ;
@@ -3286,6 +3333,9 @@ static void _php_curl_close_ex(php_curl *ch)
3286
3333
}
3287
3334
3288
3335
efree (ch -> handlers );
3336
+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
3337
+ zval_ptr_dtor (& ch -> postfields );
3338
+ #endif
3289
3339
efree (ch );
3290
3340
}
3291
3341
/* }}} */
0 commit comments