mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Extend CURLFile to support streams
Due to former restrictions of the libcurl API, curl multipart/formdata
file uploads supported only proper files. However, as of curl 7.56.0
the new `curl_mime_*()` API is available (and already supported by
PHP[1]), which allows us to support arbitrary *seekable* streams, which
is generally desirable, and particularly resolves issues with the
transparent Unicode and long part support on Windows (see bug #77711).
Note that older curl versions are still supported, but CURLFile is
still restricted to proper files in this case.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=a83b68ba56714bfa06737a61af795460caa4a105>
(cherry picked from commit c68dc6b5e3
)
This commit is contained in:
parent
e1202733a5
commit
17a9f1401a
6 changed files with 149 additions and 1 deletions
|
@ -1852,6 +1852,14 @@ static void curl_free_post(void **post)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ curl_free_stream
|
||||
*/
|
||||
static void curl_free_stream(void **post)
|
||||
{
|
||||
php_stream_close((php_stream *)*post);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ curl_free_slist
|
||||
*/
|
||||
static void curl_free_slist(zval *el)
|
||||
|
@ -1943,6 +1951,7 @@ php_curl *alloc_curl_handle()
|
|||
|
||||
zend_llist_init(&ch->to_free->str, sizeof(char *), (llist_dtor_func_t)curl_free_string, 0);
|
||||
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(php_stream *), (llist_dtor_func_t)curl_free_stream, 0);
|
||||
|
||||
ch->to_free->slist = emalloc(sizeof(HashTable));
|
||||
zend_hash_init(ch->to_free->slist, 4, NULL, curl_free_slist, 0);
|
||||
|
@ -2170,6 +2179,32 @@ PHP_FUNCTION(curl_copy_handle)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073800
|
||||
static size_t read_cb(char *buffer, size_t size, size_t nitems, void *arg) /* {{{ */
|
||||
{
|
||||
php_stream *stream = (php_stream *) arg;
|
||||
size_t numread = php_stream_read(stream, buffer, nitems * size);
|
||||
|
||||
if (numread == (size_t)-1) {
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
return numread;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int seek_cb(void *arg, curl_off_t offset, int origin) /* {{{ */
|
||||
{
|
||||
php_stream *stream = (php_stream *) arg;
|
||||
int res = php_stream_seek(stream, offset, origin);
|
||||
|
||||
if (res) {
|
||||
return CURL_SEEKFUNC_CANTSEEK;
|
||||
}
|
||||
return CURL_SEEKFUNC_OK;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ */
|
||||
{
|
||||
CURLcode error = CURLE_OK;
|
||||
|
@ -2805,6 +2840,9 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
|||
/* new-style file upload */
|
||||
zval *prop, rv;
|
||||
char *type = NULL, *filename = NULL;
|
||||
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
|
||||
php_stream *stream;
|
||||
#endif
|
||||
|
||||
prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv);
|
||||
if (Z_TYPE_P(prop) != IS_STRING) {
|
||||
|
@ -2826,17 +2864,24 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
|||
}
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
|
||||
if (!(stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", IGNORE_PATH, NULL))) {
|
||||
zend_string_release_ex(string_key, 0);
|
||||
return FAILURE;
|
||||
}
|
||||
part = curl_mime_addpart(mime);
|
||||
if (part == NULL) {
|
||||
php_stream_close(stream);
|
||||
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_filedata(part, ZSTR_VAL(postval))) != CURLE_OK
|
||||
|| (form_error = curl_mime_data_cb(part, -1, read_cb, seek_cb, NULL, stream)) != CURLE_OK
|
||||
|| (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK
|
||||
|| (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) {
|
||||
php_stream_close(stream);
|
||||
error = form_error;
|
||||
}
|
||||
zend_llist_add_element(&ch->to_free->stream, &stream);
|
||||
#else
|
||||
form_error = curl_formadd(&first, &last,
|
||||
CURLFORM_COPYNAME, ZSTR_VAL(string_key),
|
||||
|
@ -3566,6 +3611,7 @@ static void _php_curl_close_ex(php_curl *ch)
|
|||
if (--(*ch->clone) == 0) {
|
||||
zend_llist_clean(&ch->to_free->str);
|
||||
zend_llist_clean(&ch->to_free->post);
|
||||
zend_llist_clean(&ch->to_free->stream);
|
||||
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