-
Notifications
You must be signed in to change notification settings - Fork 30k
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
HTTP2: API for checking if http2ServerRequest had body frame. #22497
Comments
@nodejs/http2 |
If the |
@jasnell It's true, but I concerned following case.
|
Sounds like Express will go down the route to reaching into the Node.js internals since there doesn't seem to be a solution here. |
@dougwilson We can probably add something if that's the trade-off. Let me think about a good API and get back to you. |
I don’t understand this issue. If we are missing an API we can add it, but I do not understand what is missing and what you need. What code are you trying to make work on both? |
@mcollina Checking if the incoming request has or had a body ( |
At this point, there's really nothing to reach in to. Let's step back and examine how the code works... In the method From that point on, the JS code will not know if there are any data frames until the underlying app.use((req, res, next) => {
// We really don't know if there's going to be a body or not unless the `Stream` is closed
}); The most we can do at this point is provide a flag that says whether or not any |
In the OP I think @sogaani describes the use case pretty well. He found that |
By the time the middleware is invoked, we might not be able to reliably know if a DATA frame is going to arrive at all for a given request. All we would know for sure is whether it's possible for DATA frame to arrive. For instance, a client could send the request HEADERS frame followed immediately by a trailing HEADERS frame, without any DATA frames at all. Or, the stream could be closed with an RST_STREAM at any time. Or, the client can send an empty DATA frame with no payload and the end-stream flag set... and could do so well after the middleware is invoked. |
We'll just accept the PR using .sync for now, then 👍 |
btw, I'm not saying that we shouldn't add an API here, I'm trying to figure out what kind of API we can add that will be useful for the actual use case. Specifically, there are two things that I absolutely know we can do:
What we cannot do reliably is reliably determine if DATA frames will or will not arrive for any given stream. |
Right, that's what was said we wanted to know in the middleware. |
We need both (1) and (2). |
We need to equiv of what you can do in http1 to know if the request will have a body (it doesn't matter if the client craps out and never sends it) in a way we can check even after the data stream has been fully read. It's just a flag on the last http2 header frame that indicates if there can be data frames or not. All header frames arrive before the compat api invokes your function so we will have that info. |
I do not think I think we really need to surface this info from the lower layers. |
excellent, that's the clarification I was hoping for. For 2, the easy way to determine if DATA frames can still be received is to just check if the readable side is still open. For 1, I'm thinking that a generic |
We don't need both (1) and (2), it can just be one signal. Maybe having both will be useful to others. The data we need is just a flag on the last headers frame. |
Ex this is the exact question the code is trying to answer: For a given http2 compact api request object at any part of it's life cycle after it was emitted to a request listener, did the HEADER (or last CONTINUATION frame) have the END_STREAM flag set or not? I hope that is specific enough. |
You can already determine that by checking the readable state of the stream. If the end stream flag is set on the header, the readable side of the |
You can't tell in certain cases ex #22497 (comment) |
i.e if a middleware fully read the stream before my code, it it then always have the readable false. This is the OP issue. |
Remember my example said "object at any part of it's life cycle after it was emitted to a request listener" |
How can I clarify further so we can stop talking in circles? |
I think we're on the same page now. This really isn't an HTTP2 specific issue. It's a readable streams issue. There needs to be a better way of determining after the fact that a readable ended with or without data. There doesn't need to be a http2 specific API here. I think @mcollina is going to work on a PR. |
Even if streams did that, we'd still have to look into that private The other thing to keep in mind is we need the exact answer to the question the code is trying to ask as defined above. That means that it's important to know if there was a zero-length DATA frame or not as the only DATA frame. If the readable doesn't consider that emitted data, then the readable streams fix wouldn't work in that case, either. |
So, basically you need to know: a. is data in the buffer
If that is the question, I do not understand how checking for |
What I need to know is #22497 (comment) |
PR: #22843 |
Indicates is the END_STREAM flag was set on the received HEADERS frame PR-URL: #22843 Fixes: #22497 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Indicates is the END_STREAM flag was set on the received HEADERS frame PR-URL: #22843 Fixes: #22497 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Indicates is the END_STREAM flag was set on the received HEADERS frame PR-URL: #22843 Fixes: #22497 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Indicates is the END_STREAM flag was set on the received HEADERS frame PR-URL: nodejs#22843 Fixes: nodejs#22497 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Indicates is the END_STREAM flag was set on the received HEADERS frame PR-URL: nodejs#22843 Fixes: nodejs#22497 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Indicates is the END_STREAM flag was set on the received HEADERS frame Backport-PR-URL: #22850 PR-URL: #22843 Fixes: #22497 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Is your feature request related to a problem? Please describe.
Some express middleware check if
httpRequest
has/had body. e.g body-parser.And it depends on
content-length
header.Although a http request with body in http/1 must contain content-length header, http2 request with body can have no
content-length
header.We can use
http2ServerRequest.stream.readable
only before readable stream ended to check if request might have body frame. I'm not sure how to check it after readable stream ended with current http2 compatibility APIs.Describe the solution you'd like
I'd like to add new API to check if request had body, or readable stream had been read data after readable stream ended.
Describe alternatives you've considered
I notice that
http2ServerRequest.stream._readableState.sync
can be used. However we should not use_readableState
.The text was updated successfully, but these errors were encountered: