-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
Calling stream.end() in callback of stream.write() can leave ClientHttp2Session in an invalid state #49147
Comments
I want to work on this issue, I am a beginner so will need some guidance from the community . Can you please assign me this issue? |
hey @sanket-1305 feel free to work on the issue and submit a PR, there's normally no need to assign issues you can probably find the code relevant to the issue in |
@debadree25 thankyou for the reply, will start working on this but i will need some time, because my exams are going on still i will try my best to solve this asap! |
You say "stream.write(); stream.end() won't reproduce. The end() has to be called in the write() callback." Have you tried enclosing the |
You're looking at Finally, there is a good chance that this problem is not in the http2 code at all. There are indications in the logs in the linked gRPC bug that the underlying TLS socket is reporting incorrect state information to the http2 session. So this is at least in part a tls module bug. It could even be a bug in the C++ code that interfaces with openssl. |
As I beginner i am not able to understand this and will not be able to work on this. I will start working on some basic issues first. |
Both
|
Some observations with a debugger.
During all three of those breakpoints, the debugger shows the same info for the TCP object. This is at (pseudo-code I guess, because of the Symbols) |
Version
v18.16.1
Platform
Linux laptop 6.4.7-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 27 20:01:18 UTC 2023 x86_64 GNU/Linux
Subsystem
http2
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
A server-side timeout of 1ms is never (for me) long enough for the TLS handshake to completely finish.
Once 'connect' is emitted by a session, reproduces every time.
Reproduces with a ':method' header of POST, but not with GET.
What is the expected behavior? Why is that the expected behavior?
Session should be marked as destroyed, which would make subsequent calls to session.request() return an error.
If you change the POST to a GET, the session is destroyed and this example logs
What do you see instead?
The session is not marked as destroyed. Calls to session.request() do not error. Streams can continue to be added to the session. These pile up forever (session.state.outboundQueueSize increases forever) until the process is killed (oom or otherwise).
Additional information
This is a bit involved to set up with the server end and the certificates. I have a docker compose setup available here:
https://github.com/wwilfinger/nodejs-invalid-http2session
This is a stripped-down reproduction of this issue grpc/grpc-node#2502 which also has a docker compose setup available https://github.com/wwilfinger/grpc-pubsub-fake-public/
Several things seem to be required to reproduce:
Some thoughts/feelings:
I don't think the TLS handshake being incomplete is strictly required, but it is a reliable way for the write() to fail with a system error? The handshake is what we were seeing in the wild.
It doesn't really matter what the http/2 server is configured to respond to at the http/2 layer, because from the server's point of view the TLS handshake never finishes.
stream.write(); stream.end() won't reproduce. The end() has to be called in the write() callback.
GET doesn't reproduce. POST does. I haven't tried out other methods.
node v18.16.1 is what I did most of my testing with. It's easy enough to change the base image in the Dockerfile.
node:16-slim
does not reproduce,node:20-slim
does.The text was updated successfully, but these errors were encountered: