-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HttpClient] Close gracefull when the server closes the connection abruptly #58562
Conversation
I rebased against 5.4, as this seems to be the first affected version. |
|
Are you in control of the server sending these responses? The change you propose here will accept broken responses that should have sent some bytes but didn't before closing. This might make the client less robust. |
HTTP/1.1 actually allows the server to close the connection to tell about the end of the response: |
(and yes, a test case would be great, to confirm the behavior of all implementations, not only curl) |
Somewhat, it's a standard proxmox server API endpoint (
I am puzzled as well - furthermore, it works fine on command line (see transcript in OP). Maybe the "TLSv1.3 (OUT), TLS alert, close notify (256):" hints an exit code of 256 despite the shell exit code is 0? I wonder how we can ensure that it is specific enough... I mean it's pretty easy for me to validate that it's working like this but how to determine the side effects are minimized? Regarding a test, I tried to come up with one but failed except when testing against a real server. Any advisory on how to proceed here is greatly appreciated. |
See curl/curl#4624 It looks like curl ignores this error unless it's built with the debug flag. |
I'm not sure I understand what you mean by making this specific for the SSL_ERROR_SYSCALL. Regarding an unit test, I have written a socket server which gets used in By trying to implement a test, I found that the Sidenote: carsonbot tagged this as 7.2 wheras I currently target 5.4 - do I have to rebase against 7.2 now or will you change the milestone? |
carsonbot probably failed to identify the milestone (and so used the default one) because of your answer being |
yes
nope, that'd be wrong
yes (but as the PR is now, it contains nothing but tentative tests) Let forget about tests if this cannot be tested without complex setup 🤷 |
Changed.
Removed
Kept
Yes, I tried to put a reproducer here but as I said, I did not succeed for this problem (it is pretty hard to create an "improper" ssl shutdown in PHP). I now dropped the test stuff and fixed the initial problem - I kept the fix in the |
@@ -320,7 +320,7 @@ private static function perform(ClientState $multi, ?array &$responses = null): | |||
} | |||
|
|||
$multi->handlesActivity[$id][] = null; | |||
$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))); | |||
$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)) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-reading https://www.rfc-editor.org/rfc/rfc2616#section-4.4, we might want to also check that no content-length / transfer-encoding header have been sent
Maybe we should be even stricter and do this only when the server sends Connection: close
, WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, had not time to work on this the past days.
I added the check at the end so the calls to in_array
and array_map
are minimized.
Tested it against my server.
Is this now ok?
d53781d
to
8c26ace
Compare
Thank you @discordier. |
Sorry to be the bearer of bad news :) #59039 |
curl will return
-1.0
forCURLINFO_CONTENT_LENGTH_DOWNLOAD
since 7.19.4 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:
The same request via
curl -v
: