diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-03-02 18:45:12 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-03-02 19:11:33 +0100 |
commit | fc8b3ab7cbb4f5e77584babeaf25b9bf16f524cd (patch) | |
tree | 95c01fc4473ead1707bc27b17cc33c9f71ace6ff /ext/curl/interface.c | |
parent | a0377021c5640cd6e6ad719a76dd38f91f7c367b (diff) | |
download | php-git-fc8b3ab7cbb4f5e77584babeaf25b9bf16f524cd.tar.gz |
Fix #79013: Content-Length missing when posting a curlFile with curl
Unfortunately, some Webservers (e.g. IIS) do not implement the (F)CGI
specifications correctly wrt. chunked uploads (i.e. Transfer-encoding:
chunked), but instead pass -1 as CONTENT_LENGTH to the CGI
application. However, our (F)CFI SAPIs (i.e. cgi and cgi-fcgi) do not
support this.
Therefore we try to retrieve the stream size in advance and pass it to
`curl_mime_data_cb()` to prevent libcurl from doing chunked uploads.
This is basically the same approach that `curl_mime_filedata()`
implements, except that we are keeping already opened streams open for
the `read_cb()`.
Diffstat (limited to 'ext/curl/interface.c')
-rw-r--r-- | ext/curl/interface.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 668f7a71d9..45e41ba49e 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2200,6 +2200,10 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields char *type = NULL, *filename = NULL; #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ struct mime_data_cb_arg *cb_arg; + php_stream *stream; + php_stream_statbuf ssb; + size_t filesize = -1; + curl_seek_callback seekfunc = seek_cb; #endif prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv); @@ -2225,9 +2229,17 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields zval_ptr_dtor(&ch->postfields); ZVAL_COPY(&ch->postfields, zpostfields); + if ((stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", STREAM_MUST_SEEK, NULL))) { + if (!stream->readfilters.head && !php_stream_stat(stream, &ssb)) { + filesize = ssb.sb.st_size; + } + } else { + seekfunc = NULL; + } + cb_arg = emalloc(sizeof *cb_arg); cb_arg->filename = zend_string_copy(postval); - cb_arg->stream = NULL; + cb_arg->stream = stream; part = curl_mime_addpart(mime); if (part == NULL) { @@ -2235,7 +2247,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields return FAILURE; } if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK - || (form_error = curl_mime_data_cb(part, -1, read_cb, seek_cb, free_cb, cb_arg)) != CURLE_OK + || (form_error = curl_mime_data_cb(part, filesize, read_cb, seekfunc, free_cb, cb_arg)) != 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) { error = form_error; |