Commit 9eea677
committed
bug symfony#58562 [HttpClient] Close gracefull when the server closes the connection abruptly (discordier)
This PR was squashed before being merged into the 5.4 branch.
Discussion
----------
[HttpClient] Close gracefull when the server closes the connection abruptly
| Q | A
| ------------- | ---
| Branch? | 5.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| License | MIT
curl will return `-1.0` for `CURLINFO_CONTENT_LENGTH_DOWNLOAD` since [7.19.4](https://curl.se/libcurl/c/CURLINFO_CONTENT_LENGTH_DOWNLOAD.html) if not known (means not specified by the server response).
When handling data for empty responses, this will cause us to compare `0.0` (`CURLINFO_SIZE_DOWNLOAD`) with `-1.0` (`CURLINFO_CONTENT_LENGTH_DOWNLOAD`) and thus error out with SSL error 0 then (which means normal close).
We therefore now explicitly allow to download 0 bytes, when no size has been indicated.
I'm unsure how to add tests here and also unsure what's the lowest version to be affected.
I don't think this affects BC, as the usecase to expect to get an error for an empty response seems very unlikely.
I tried to come up with a reproducer but failed as I can only reproduce it via HTTPS in my application.
Stacktrace:
```
In Stream.php line 266:
[RuntimeException]
Unable to read stream contents: OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0 for "https://[redacted]/api".
Exception trace:
at /project/vendor/nyholm/psr7/src/Stream.php:266
Nyholm\Psr7\Stream::Nyholm\Psr7\{closure}() at n/a:n/a
trigger_error() at /project/vendor/symfony/http-client/Response/StreamWrapper.php:129
Symfony\Component\HttpClient\Response\StreamWrapper->stream_read() at n/a:n/a
stream_get_contents() at /project/vendor/nyholm/psr7/src/Stream.php:270
Nyholm\Psr7\Stream->getContents() at /project/vendor/nyholm/psr7/src/StreamTrait.php:23
Nyholm\Psr7\Stream->__toString() at /project/src/ApiClient823/Generated/Endpoint/VersionVersion.php:57
[...]
```
The same request via `curl -v`:
```
curl -v https://[redacted]/api
* Trying [redacted]...
* Connected to [redacted] ([redacted]) port 8006 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=[redacted]
* start date: Aug 22 00:39:02 2024 GMT
* expire date: Nov 20 00:39:01 2024 GMT
* subjectAltName: host "[redacted]" matched cert's "[redacted]"
* issuer: C=US; O=Let's Encrypt; CN=R10
* SSL certificate verify ok.
* using HTTP/1.x
> GET /api HTTP/1.1
> Host: [redacted]
> User-Agent: curl/7.88.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 401 No ticket
< Cache-Control: max-age=0
< Connection: close
< Date: Mon, 14 Oct 2024 13:52:18 GMT
< Pragma: no-cache
< Server: [redacted]
< Expires: Mon, 14 Oct 2024 13:52:18 GMT
<
* Closing connection 0
* TLSv1.3 (OUT), TLS alert, close notify (256):
```
Commits
-------
8c26ace [HttpClient] Close gracefull when the server closes the connection abruptly1 file changed
+1
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
327 | 327 | | |
328 | 328 | | |
329 | 329 | | |
330 | | - | |
| 330 | + | |
331 | 331 | | |
332 | 332 | | |
333 | 333 | | |
| |||
0 commit comments