From c930230e8622f9120de603ac520a4a04874fe965 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 3 Feb 2023 00:00:42 +0100 Subject: [PATCH 1/2] Fix GH-10031: [Stream] STREAM_NOTIFY_PROGRESS over HTTP emitted irregularly for last chunk of data Fixes GH-10031 It's possible that the server already sent in more data than just the headers. Since the stream only accepts progress increments after the headers are processed, the already read data is never added to the process. We account for this by adjusting the progress counter by the difference of already read header data and the body. --- ext/standard/http_fopen_wrapper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 5964efd2f9a1c..fa0dcb5e6890a 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -955,6 +955,13 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (transfer_encoding) { php_stream_filter_append(&stream->readfilters, transfer_encoding); } + + /* It's possible that the server already sent in more data than just the headers. + * We account for this by adjusting the progress counter by the difference of + * already read header data and the body. */ + if (stream->writepos > stream->readpos) { + php_stream_notify_progress_increment(context, stream->writepos - stream->readpos, 0); + } } return stream; From fae78d8149bdf8742f808ae6e467a7d2fdce0909 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 3 Feb 2023 00:03:26 +0100 Subject: [PATCH 2/2] Add a regression test for GH-10031 Co-authored-by: aetonsi <18366087+aetonsi@users.noreply.github.com> --- ext/standard/tests/streams/gh10031.phpt | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 ext/standard/tests/streams/gh10031.phpt diff --git a/ext/standard/tests/streams/gh10031.phpt b/ext/standard/tests/streams/gh10031.phpt new file mode 100644 index 0000000000000..aa3576dab51ad --- /dev/null +++ b/ext/standard/tests/streams/gh10031.phpt @@ -0,0 +1,52 @@ +--TEST-- +GH-10031 ([Stream] STREAM_NOTIFY_PROGRESS over HTTP emitted irregularly for last chunk of data) +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--CONFLICTS-- +server +--FILE-- + ['ignore_errors' => true,]]); +$lastBytesTransferred = 0; +stream_context_set_params($context, ['notification' => function ($code, $s, $m, $mc, $bytes_transferred, $bytes_max) +use (&$lastBytesTransferred) { + if ($code === STREAM_NOTIFY_FILE_SIZE_IS) echo "expected filesize=$bytes_max".PHP_EOL; + $lastBytesTransferred = $bytes_transferred; + @ob_flush(); +}]); + +$get = file_get_contents("http://".PHP_CLI_SERVER_ADDRESS, false, $context); + +echo "got filesize=" . strlen($get) . PHP_EOL; +var_dump($lastBytesTransferred); + +?> +--EXPECT-- +expected filesize=1000 +got filesize=1000 +int(1000)