mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
cURL: make possible to send file from buffer string
Add CURLStringFile class which works similarly to CURLFile, but uploads a file from a string rather than a file. This avoids the need to create a temporary file, or use of a data:// stream. Basic usage: $file = new CURLStringFile($data, 'filename.txt', 'text/plain'); curl_setopt($curl, CURLOPT_POSTFIELDS, ['file' => $file]); Closes GH-6456.
This commit is contained in:
parent
d16341dabe
commit
e727919b97
9 changed files with 271 additions and 1 deletions
|
@ -1654,6 +1654,15 @@ static void curl_free_cb_arg(void **cb_arg_p)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x073800 /* 7.56.0 */
|
||||
/* {{{ curl_free_buffers */
|
||||
static void curl_free_buffers(void **buffer)
|
||||
{
|
||||
zend_string_release((zend_string *) *buffer);
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
/* {{{ curl_free_slist */
|
||||
static void curl_free_slist(zval *el)
|
||||
{
|
||||
|
@ -1744,6 +1753,10 @@ void init_curl_handle(php_curl *ch)
|
|||
zend_llist_init(&ch->to_free->post, sizeof(struct HttpPost *), (llist_dtor_func_t)curl_free_post, 0);
|
||||
zend_llist_init(&ch->to_free->stream, sizeof(struct mime_data_cb_arg *), (llist_dtor_func_t)curl_free_cb_arg, 0);
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x073800 /* 7.56.0 */
|
||||
zend_llist_init(&ch->to_free->buffers, sizeof(zend_string *), (llist_dtor_func_t)curl_free_buffers, 0);
|
||||
#endif
|
||||
|
||||
ch->to_free->slist = emalloc(sizeof(HashTable));
|
||||
zend_hash_init(ch->to_free->slist, 4, NULL, curl_free_slist, 0);
|
||||
ZVAL_UNDEF(&ch->postfields);
|
||||
|
@ -2086,6 +2099,78 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
|
|||
continue;
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(current) == IS_OBJECT && instanceof_function(Z_OBJCE_P(current), curl_CURLStringFile_class)) {
|
||||
/* new-style file upload from string */
|
||||
zval *prop, rv;
|
||||
char *type = NULL, *filename = NULL;
|
||||
|
||||
prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "postname", sizeof("postname")-1, 0, &rv);
|
||||
if (EG(exception)) {
|
||||
zend_string_release_ex(string_key, 0);
|
||||
return FAILURE;
|
||||
}
|
||||
ZVAL_DEREF(prop);
|
||||
ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING);
|
||||
|
||||
filename = Z_STRVAL_P(prop);
|
||||
|
||||
prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "mime", sizeof("mime")-1, 0, &rv);
|
||||
if (EG(exception)) {
|
||||
zend_string_release_ex(string_key, 0);
|
||||
return FAILURE;
|
||||
}
|
||||
ZVAL_DEREF(prop);
|
||||
ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING);
|
||||
|
||||
type = Z_STRVAL_P(prop);
|
||||
|
||||
prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "data", sizeof("data")-1, 0, &rv);
|
||||
if (EG(exception)) {
|
||||
zend_string_release_ex(string_key, 0);
|
||||
return FAILURE;
|
||||
}
|
||||
ZVAL_DEREF(prop);
|
||||
ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING);
|
||||
|
||||
postval = Z_STR_P(prop);
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
|
||||
zval_ptr_dtor(&ch->postfields);
|
||||
ZVAL_COPY(&ch->postfields, zpostfields);
|
||||
|
||||
part = curl_mime_addpart(mime);
|
||||
if (part == NULL) {
|
||||
zend_string_release_ex(string_key, 0);
|
||||
return FAILURE;
|
||||
}
|
||||
if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
|
||||
|| (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK
|
||||
|| (form_error = curl_mime_filename(part, filename)) != CURLE_OK
|
||||
|| (form_error = curl_mime_type(part, type)) != CURLE_OK) {
|
||||
error = form_error;
|
||||
}
|
||||
#else
|
||||
postval = zend_string_copy(postval);
|
||||
zend_llist_add_element(&ch->to_free->buffers, &postval);
|
||||
|
||||
form_error = curl_formadd(&first, &last,
|
||||
CURLFORM_COPYNAME, ZSTR_VAL(string_key),
|
||||
CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
|
||||
CURLFORM_BUFFER, filename,
|
||||
CURLFORM_CONTENTTYPE, type,
|
||||
CURLFORM_BUFFERPTR, ZSTR_VAL(postval),
|
||||
CURLFORM_BUFFERLENGTH, ZSTR_LEN(postval),
|
||||
CURLFORM_END);
|
||||
if (form_error != CURL_FORMADD_OK) {
|
||||
/* Not nice to convert between enums but we only have place for one error type */
|
||||
error = (CURLcode)form_error;
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_string_release_ex(string_key, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
postval = zval_get_tmp_string(current, &tmp_postval);
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
|
||||
|
@ -3330,6 +3415,11 @@ static void curl_free_obj(zend_object *object)
|
|||
if (--(*ch->clone) == 0) {
|
||||
zend_llist_clean(&ch->to_free->post);
|
||||
zend_llist_clean(&ch->to_free->stream);
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x073800 /* 7.56.0 */
|
||||
zend_llist_clean(&ch->to_free->buffers);
|
||||
#endif
|
||||
|
||||
zend_hash_destroy(ch->to_free->slist);
|
||||
efree(ch->to_free->slist);
|
||||
efree(ch->to_free);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue