Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9eea677

Browse filesBrowse files
bug #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 abruptly
2 parents 1b7d8b3 + 8c26ace commit 9eea677
Copy full SHA for 9eea677

File tree

1 file changed

+1
-1
lines changed
Filter options

1 file changed

+1
-1
lines changed

‎src/Symfony/Component/HttpClient/Response/CurlResponse.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Response/CurlResponse.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ private static function perform(ClientState $multi, ?array &$responses = null):
327327
}
328328

329329
$multi->handlesActivity[$id][] = null;
330-
$multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL)));
330+
$multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) || (curl_error($ch) === 'OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0' && -1.0 === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) && \in_array('close', array_map('strtolower', $responses[$id]->headers['connection']), true)) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL)));
331331
}
332332
} finally {
333333
$multi->performing = false;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.