Description
Symfony version(s) affected
7.1.1
Description
Some pages make Symfony HttpClient crash with PHP Fatal error: Uncaught Error: Typed property Symfony\Component\HttpClient\Chunk\DataChunk::$content must not be accessed before initialization in /var/www/html/vendor/symfony/http-client/Chunk/DataChunk.php:51
I encountered this problem on a URL I cannot disclose and I had a hard time to reproduce it somewhere it can be tested.
I found by chance that the same issue also appears on shop.kahoot.com
(I'm sorry for them, I will use there website as an example here).
How to reproduce
Here is a script that sometimes reproduce this problem:
<?php
use Symfony\Component\HttpClient\HttpClient;
require_once __DIR__.'/vendor/autoload.php';
$url = 'http://shop.kahoot.com/';
$pages = [
'page1',
'page2',
'#page3',
'page4',
];
$client = HttpClient::create();
$requests = [];
foreach ($pages as $page) {
$requests[] = $client->request('GET', $url.$page, [
'headers' => [
'User-Agent' => 'Mozilla Firefox Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0',
],
]);
}
foreach ($requests as $response) {
try {
$response->getContent();
echo "Success";
} catch (\Exception $e) {
var_dump($e->getMessage());
}
}
output (about 5 times out of 10):
$ php test-http-client-2.php
string(57) "HTTP/2 404 returned for "https://shop.kahoot.com/page1"."
string(57) "HTTP/2 404 returned for "https://shop.kahoot.com/page2"."
PHP Fatal error: Uncaught Error: Typed property Symfony\Component\HttpClient\Chunk\DataChunk::$content must not be accessed before initialization in /var/www/html/vendor/symfony/http-client/Chunk/DataChunk.php:51
Stack trace:
#0 /var/www/html/vendor/symfony/http-client/Response/CommonResponseTrait.php(55): Symfony\Component\HttpClient\Chunk\DataChunk->getContent()
#1 /var/www/html/vendor/symfony/http-client/Response/CurlResponse.php(233): Symfony\Component\HttpClient\Response\CurlResponse->doGetContent(true)
#2 /var/www/html/test-http-client-2.php(28): Symfony\Component\HttpClient\Response\CurlResponse->getContent()
#3 {main}
thrown in /var/www/html/vendor/symfony/http-client/Chunk/DataChunk.php on line 51
PHP Fatal error: Uncaught Symfony\Component\HttpClient\Exception\ClientException: HTTP/2 404 returned for "https://shop.kahoot.com/page4". in /var/www/html/vendor/symfony/http-client/Response/CommonResponseTrait.php:170
Stack trace:
#0 /var/www/html/vendor/symfony/http-client/Response/TransportResponseTrait.php(131): Symfony\Component\HttpClient\Response\CurlResponse->checkStatusCode()
#1 /var/www/html/vendor/symfony/http-client/Response/CurlResponse.php(246): Symfony\Component\HttpClient\Response\CurlResponse->doDestruct()
#2 [internal function]: Symfony\Component\HttpClient\Response\CurlResponse->__destruct()
#3 {main}
thrown in /var/www/html/vendor/symfony/http-client/Response/CommonResponseTrait.php on line 170
Possible Solution
I believe but I'm not 100% sure that it is due to the 103 Early Hints
HTTP response returned by the web server:
curl -I 'http://shop.kahoot.com/#page3' -L
HTTP/1.1 301 Moved Permanently
Date: Thu, 27 Jun 2024 21:12:36 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
X-Sorting-Hat-PodId: 157
X-Sorting-Hat-ShopId: 22834877
X-Storefront-Renderer-Rendered: 1
location: https://shop.kahoot.com/
x-redirect-reason: https_required
x-frame-options: DENY
content-security-policy: frame-ancestors 'none';
x-shopid: 22834877
x-shardid: 157
vary: Accept
powered-by: Shopify
server-timing: processing;dur=11, db;dur=2, asn;desc="199524", edge;desc="AMS", country;desc="LU", pageType;desc="index", servedBy;desc="g9tt", requestID;desc="93ab9de5-7d90-44e5-9cf9-34fdb153daab-1719522756"
x-dc: gcp-europe-west4,gcp-europe-west1,gcp-europe-west1
x-request-id: 93ab9de5-7d90-44e5-9cf9-34fdb153daab-1719522756
CF-Cache-Status: DYNAMIC
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=uXH...6qw%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
Server-Timing: cfRequestDuration;dur=54.000139
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Permitted-Cross-Domain-Policies: none
X-Download-Options: noopen
Server: cloudflare
CF-RAY: 89a86fad2f0c0c35-AMS
alt-svc: h3=":443"; ma=86400
HTTP/2 103
link: <https://cdn.shopify.com>; rel=preconnect, <https://cdn.shopify.com>; crossorigin; rel=preconnect
HTTP/2 200
date: Thu, 27 Jun 2024 21:12:36 GMT
content-type: text/html; charset=utf-8
x-sorting-hat-podid: 157
x-sorting-hat-shopid: 22834877
x-storefront-renderer-rendered: 1
etag: W/"cacheable:c1360a6d593e7d7e4d41556ea19a168c"
link: <https://cdn.shopify.com>; rel="preconnect", <https://cdn.shopify.com>; rel="preconnect"; crossorigin
x-shopify-nginx-no-cookies: 0
Additional Context
Also: I can't reproduce this issue when the requests are made sequentially, only when they are in parallel.
Also, I don't understand why the following code gives no error:
<?php
use Symfony\Component\HttpClient\HttpClient;
require_once __DIR__.'/vendor/autoload.php';
$url = 'http://shop.kahoot.com/';
$client = HttpClient::create();
var_dump(strlen($client->request('GET', $url.'#page3', [
'headers' => [
'User-Agent' => 'Mozilla Firefox Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0',
],
])->getContent()));
$ php test-http-client-3.php
int(114495);
Here are my current versions of PHP and Curl, but I had this problem for a few months (older versions of Symfony and PHP) but I couldn't reproduce it easily.
$ php -v
PHP 8.3.8 (cli) (built: Jun 6 2024 19:31:35) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.8, Copyright (c) Zend Technologies
$ curl --version
curl 7.88.1 (x86_64-pc-linux-gnu) libcurl/7.88.1 OpenSSL/3.0.11 zlib/1.2.13 brotli/1.0.9 zstd/1.5.4 libidn2/2.3.3 libpsl/0.21.2 (+libidn2/2.3.3) libssh2/1.10.0 nghttp2/1.52.0 librtmp/2.3 OpenLDAP/2.5.13
Release-Date: 2023-02-20, security patched: 7.88.1-10+deb12u5
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
Thanks for your help