Skip to content

Commit a6d385a

Browse files
committed
Extract function
As suggested by Nikita[1]. [1] <#5045 (comment)>
1 parent 4b860c0 commit a6d385a

File tree

1 file changed

+162
-152
lines changed

1 file changed

+162
-152
lines changed

ext/curl/interface.c

Lines changed: 162 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,167 @@ static int seek_cb(void *arg, curl_off_t offset, int origin) /* {{{ */
21502150
/* }}} */
21512151
#endif
21522152

2153+
static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields) /* {{{ */
2154+
{
2155+
CURLcode error = CURLE_OK;
2156+
zval *current;
2157+
HashTable *postfields;
2158+
zend_string *string_key;
2159+
zend_ulong num_key;
2160+
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2161+
curl_mime *mime = NULL;
2162+
curl_mimepart *part;
2163+
CURLcode form_error;
2164+
#else
2165+
struct HttpPost *first = NULL;
2166+
struct HttpPost *last = NULL;
2167+
CURLFORMcode form_error;
2168+
#endif
2169+
2170+
postfields = HASH_OF(zpostfields);
2171+
if (!postfields) {
2172+
php_error_docref(NULL, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS");
2173+
return FAILURE;
2174+
}
2175+
2176+
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2177+
if (zend_hash_num_elements(postfields) > 0) {
2178+
mime = curl_mime_init(ch->cp);
2179+
if (mime == NULL) {
2180+
return FAILURE;
2181+
}
2182+
}
2183+
#endif
2184+
2185+
ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
2186+
zend_string *postval, *tmp_postval;
2187+
/* Pretend we have a string_key here */
2188+
if (!string_key) {
2189+
string_key = zend_long_to_str(num_key);
2190+
} else {
2191+
zend_string_addref(string_key);
2192+
}
2193+
2194+
ZVAL_DEREF(current);
2195+
if (Z_TYPE_P(current) == IS_OBJECT &&
2196+
instanceof_function(Z_OBJCE_P(current), curl_CURLFile_class)) {
2197+
/* new-style file upload */
2198+
zval *prop, rv;
2199+
char *type = NULL, *filename = NULL;
2200+
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2201+
php_stream *stream;
2202+
#endif
2203+
2204+
prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv);
2205+
if (Z_TYPE_P(prop) != IS_STRING) {
2206+
php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", ZSTR_VAL(string_key));
2207+
} else {
2208+
postval = Z_STR_P(prop);
2209+
2210+
if (php_check_open_basedir(ZSTR_VAL(postval))) {
2211+
return 1;
2212+
}
2213+
2214+
prop = zend_read_property(curl_CURLFile_class, current, "mime", sizeof("mime")-1, 0, &rv);
2215+
if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
2216+
type = Z_STRVAL_P(prop);
2217+
}
2218+
prop = zend_read_property(curl_CURLFile_class, current, "postname", sizeof("postname")-1, 0, &rv);
2219+
if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
2220+
filename = Z_STRVAL_P(prop);
2221+
}
2222+
2223+
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2224+
if (!(stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", IGNORE_PATH, NULL))) {
2225+
zend_string_release_ex(string_key, 0);
2226+
return FAILURE;
2227+
}
2228+
part = curl_mime_addpart(mime);
2229+
if (part == NULL) {
2230+
php_stream_close(stream);
2231+
zend_string_release_ex(string_key, 0);
2232+
return FAILURE;
2233+
}
2234+
if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
2235+
|| (form_error = curl_mime_data_cb(part, -1, read_cb, seek_cb, NULL, stream)) != CURLE_OK
2236+
|| (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK
2237+
|| (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) {
2238+
php_stream_close(stream);
2239+
error = form_error;
2240+
}
2241+
zend_llist_add_element(&ch->to_free->stream, &stream);
2242+
#else
2243+
form_error = curl_formadd(&first, &last,
2244+
CURLFORM_COPYNAME, ZSTR_VAL(string_key),
2245+
CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
2246+
CURLFORM_FILENAME, filename ? filename : ZSTR_VAL(postval),
2247+
CURLFORM_CONTENTTYPE, type ? type : "application/octet-stream",
2248+
CURLFORM_FILE, ZSTR_VAL(postval),
2249+
CURLFORM_END);
2250+
if (form_error != CURL_FORMADD_OK) {
2251+
/* Not nice to convert between enums but we only have place for one error type */
2252+
error = (CURLcode)form_error;
2253+
}
2254+
#endif
2255+
}
2256+
2257+
zend_string_release_ex(string_key, 0);
2258+
continue;
2259+
}
2260+
2261+
postval = zval_get_tmp_string(current, &tmp_postval);
2262+
2263+
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2264+
part = curl_mime_addpart(mime);
2265+
if (part == NULL) {
2266+
zend_tmp_string_release(tmp_postval);
2267+
zend_string_release_ex(string_key, 0);
2268+
return FAILURE;
2269+
}
2270+
if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
2271+
|| (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK) {
2272+
error = form_error;
2273+
}
2274+
#else
2275+
/* The arguments after _NAMELENGTH and _CONTENTSLENGTH
2276+
* must be explicitly cast to long in curl_formadd
2277+
* use since curl needs a long not an int. */
2278+
form_error = curl_formadd(&first, &last,
2279+
CURLFORM_COPYNAME, ZSTR_VAL(string_key),
2280+
CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
2281+
CURLFORM_COPYCONTENTS, ZSTR_VAL(postval),
2282+
CURLFORM_CONTENTSLENGTH, ZSTR_LEN(postval),
2283+
CURLFORM_END);
2284+
2285+
if (form_error != CURL_FORMADD_OK) {
2286+
/* Not nice to convert between enums but we only have place for one error type */
2287+
error = (CURLcode)form_error;
2288+
}
2289+
#endif
2290+
zend_tmp_string_release(tmp_postval);
2291+
zend_string_release_ex(string_key, 0);
2292+
} ZEND_HASH_FOREACH_END();
2293+
2294+
SAVE_CURL_ERROR(ch, error);
2295+
if (error != CURLE_OK) {
2296+
return FAILURE;
2297+
}
2298+
2299+
if ((*ch->clone) == 1) {
2300+
zend_llist_clean(&ch->to_free->post);
2301+
}
2302+
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2303+
zend_llist_add_element(&ch->to_free->post, &mime);
2304+
error = curl_easy_setopt(ch->cp, CURLOPT_MIMEPOST, mime);
2305+
#else
2306+
zend_llist_add_element(&ch->to_free->post, &first);
2307+
error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
2308+
#endif
2309+
SAVE_CURL_ERROR(ch, error);
2310+
return error == CURLE_OK ? SUCCESS : FAILURE;
2311+
}
2312+
/* }}} */
2313+
21532314
static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ */
21542315
{
21552316
CURLcode error = CURLE_OK;
@@ -2744,158 +2905,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
27442905

27452906
case CURLOPT_POSTFIELDS:
27462907
if (Z_TYPE_P(zvalue) == IS_ARRAY || Z_TYPE_P(zvalue) == IS_OBJECT) {
2747-
zval *current;
2748-
HashTable *postfields;
2749-
zend_string *string_key;
2750-
zend_ulong num_key;
2751-
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2752-
curl_mime *mime = NULL;
2753-
curl_mimepart *part;
2754-
CURLcode form_error;
2755-
#else
2756-
struct HttpPost *first = NULL;
2757-
struct HttpPost *last = NULL;
2758-
CURLFORMcode form_error;
2759-
#endif
2760-
postfields = HASH_OF(zvalue);
2761-
if (!postfields) {
2762-
php_error_docref(NULL, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS");
2763-
return FAILURE;
2764-
}
2765-
2766-
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2767-
if (zend_hash_num_elements(postfields) > 0) {
2768-
mime = curl_mime_init(ch->cp);
2769-
if (mime == NULL) {
2770-
return FAILURE;
2771-
}
2772-
}
2773-
#endif
2774-
2775-
ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
2776-
zend_string *postval, *tmp_postval;
2777-
/* Pretend we have a string_key here */
2778-
if (!string_key) {
2779-
string_key = zend_long_to_str(num_key);
2780-
} else {
2781-
zend_string_addref(string_key);
2782-
}
2783-
2784-
ZVAL_DEREF(current);
2785-
if (Z_TYPE_P(current) == IS_OBJECT &&
2786-
instanceof_function(Z_OBJCE_P(current), curl_CURLFile_class)) {
2787-
/* new-style file upload */
2788-
zval *prop, rv;
2789-
char *type = NULL, *filename = NULL;
2790-
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2791-
php_stream *stream;
2792-
#endif
2793-
2794-
prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv);
2795-
if (Z_TYPE_P(prop) != IS_STRING) {
2796-
php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", ZSTR_VAL(string_key));
2797-
} else {
2798-
postval = Z_STR_P(prop);
2799-
2800-
if (php_check_open_basedir(ZSTR_VAL(postval))) {
2801-
return 1;
2802-
}
2803-
2804-
prop = zend_read_property(curl_CURLFile_class, current, "mime", sizeof("mime")-1, 0, &rv);
2805-
if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
2806-
type = Z_STRVAL_P(prop);
2807-
}
2808-
prop = zend_read_property(curl_CURLFile_class, current, "postname", sizeof("postname")-1, 0, &rv);
2809-
if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
2810-
filename = Z_STRVAL_P(prop);
2811-
}
2812-
2813-
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2814-
if (!(stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", IGNORE_PATH, NULL))) {
2815-
zend_string_release_ex(string_key, 0);
2816-
return FAILURE;
2817-
}
2818-
part = curl_mime_addpart(mime);
2819-
if (part == NULL) {
2820-
php_stream_close(stream);
2821-
zend_string_release_ex(string_key, 0);
2822-
return FAILURE;
2823-
}
2824-
if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
2825-
|| (form_error = curl_mime_data_cb(part, -1, read_cb, seek_cb, NULL, stream)) != CURLE_OK
2826-
|| (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK
2827-
|| (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) {
2828-
php_stream_close(stream);
2829-
error = form_error;
2830-
}
2831-
zend_llist_add_element(&ch->to_free->stream, &stream);
2832-
#else
2833-
form_error = curl_formadd(&first, &last,
2834-
CURLFORM_COPYNAME, ZSTR_VAL(string_key),
2835-
CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
2836-
CURLFORM_FILENAME, filename ? filename : ZSTR_VAL(postval),
2837-
CURLFORM_CONTENTTYPE, type ? type : "application/octet-stream",
2838-
CURLFORM_FILE, ZSTR_VAL(postval),
2839-
CURLFORM_END);
2840-
if (form_error != CURL_FORMADD_OK) {
2841-
/* Not nice to convert between enums but we only have place for one error type */
2842-
error = (CURLcode)form_error;
2843-
}
2844-
#endif
2845-
}
2846-
2847-
zend_string_release_ex(string_key, 0);
2848-
continue;
2849-
}
2850-
2851-
postval = zval_get_tmp_string(current, &tmp_postval);
2852-
2853-
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2854-
part = curl_mime_addpart(mime);
2855-
if (part == NULL) {
2856-
zend_tmp_string_release(tmp_postval);
2857-
zend_string_release_ex(string_key, 0);
2858-
return FAILURE;
2859-
}
2860-
if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
2861-
|| (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK) {
2862-
error = form_error;
2863-
}
2864-
#else
2865-
/* The arguments after _NAMELENGTH and _CONTENTSLENGTH
2866-
* must be explicitly cast to long in curl_formadd
2867-
* use since curl needs a long not an int. */
2868-
form_error = curl_formadd(&first, &last,
2869-
CURLFORM_COPYNAME, ZSTR_VAL(string_key),
2870-
CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
2871-
CURLFORM_COPYCONTENTS, ZSTR_VAL(postval),
2872-
CURLFORM_CONTENTSLENGTH, ZSTR_LEN(postval),
2873-
CURLFORM_END);
2874-
2875-
if (form_error != CURL_FORMADD_OK) {
2876-
/* Not nice to convert between enums but we only have place for one error type */
2877-
error = (CURLcode)form_error;
2878-
}
2879-
#endif
2880-
zend_tmp_string_release(tmp_postval);
2881-
zend_string_release_ex(string_key, 0);
2882-
} ZEND_HASH_FOREACH_END();
2883-
2884-
SAVE_CURL_ERROR(ch, error);
2885-
if (error != CURLE_OK) {
2886-
return FAILURE;
2887-
}
2888-
2889-
if ((*ch->clone) == 1) {
2890-
zend_llist_clean(&ch->to_free->post);
2891-
}
2892-
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2893-
zend_llist_add_element(&ch->to_free->post, &mime);
2894-
error = curl_easy_setopt(ch->cp, CURLOPT_MIMEPOST, mime);
2895-
#else
2896-
zend_llist_add_element(&ch->to_free->post, &first);
2897-
error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
2898-
#endif
2908+
return build_mime_structure_from_hash(ch, zvalue);
28992909
} else {
29002910
#if LIBCURL_VERSION_NUM >= 0x071101
29012911
zend_string *tmp_str;

0 commit comments

Comments
 (0)