-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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: add compat trailers, adjust multi-headers #15193
http2: add compat trailers, adjust multi-headers #15193
Conversation
Adds Http2ServerRequest trailers & rawTrailers functionality. Also fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). Adds setter for statusMessage that warns, for backwards compatibility. Refs: expressjs/express#3390 (comment)
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.
Good work, thanks for taking this up! I have left some comments, let me know what you think
lib/internal/http2/compat.js
Outdated
if (trailers === undefined) | ||
return []; | ||
const tuples = Object.entries(trailers); | ||
const flattened = Array.prototype.concat.apply([], tuples); |
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.
Can you use [].concat(tuples)
instead? Why is this needed?
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.
It's a [[name, value], [name, value]] type of structure. [].concat(tuples)
won't flatten it.
That said, I would ideally like to land this without this code and instead with a real solution for rawHeaders
and rawTrailers
(one that actually provides the real raw data to the user). I'm going to create a new commit with that behaviour and would appreciate if you or @jasnell could review.
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.
I think
[].concat(...Object.entries(obj))
would read better.
lib/internal/http2/compat.js
Outdated
@@ -164,7 +172,16 @@ class Http2ServerRequest extends Readable { | |||
} | |||
|
|||
get trailers() { | |||
return this[kTrailers]; | |||
return this[kTrailers] || []; |
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.
this is not the exact behavior. The returned this[kTrailers]
will be editable, while []
will not.
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.
Hmm, good point, thanks! Will update.
lib/internal/http2/compat.js
Outdated
); | ||
statusMessageWarned = true; | ||
} | ||
} |
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.
this same block of code is shown in two other spots, can you refactor it to a single location? It needs a unit test as well.
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.
Definitely. Will update.
@mcollina Incorporated your feedback and also added proper handling of raw headers & trailers, instead of the dummy version we had. Also have tests for everything now. Let me know if you want me to change anything about how the raw stuff works. Thanks! |
07dc4c9
to
52e79ea
Compare
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.
LGTM
Ok, so as mentioned above, there really is an issue with streams not being ended properly. I'm going to add a commit shortly that fixes it and revises how trailers are handled slightly. |
@mcollina new commit added to handle properly ending readable streams when there are trailers or the request has no body. |
CI: https://ci.nodejs.org/job/node-test-pull-request/9951/ (still LGTM) |
Landed as 6416464. |
Adds Http2ServerRequest trailers & rawTrailers functionality. Also fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). Adds setter for statusMessage that warns, for backwards compatibility. End readable side of the stream on trailers or bodyless requests Refs: expressjs/express#3390 (comment) PR-URL: #15193 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
Adds Http2ServerRequest trailers & rawTrailers functionality. Also fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). Adds setter for statusMessage that warns, for backwards compatibility. End readable side of the stream on trailers or bodyless requests Refs: expressjs/express#3390 (comment) PR-URL: #15193 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
Adds Http2ServerRequest trailers & rawTrailers functionality. Also fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). Adds setter for statusMessage that warns, for backwards compatibility. End readable side of the stream on trailers or bodyless requests Refs: expressjs/express#3390 (comment) PR-URL: #15193 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
Adds Http2ServerRequest trailers & rawTrailers functionality. Also fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). Adds setter for statusMessage that warns, for backwards compatibility. End readable side of the stream on trailers or bodyless requests Refs: expressjs/express#3390 (comment) PR-URL: #15193 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
Adds Http2ServerRequest trailers & rawTrailers functionality. Also fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). Adds setter for statusMessage that warns, for backwards compatibility. End readable side of the stream on trailers or bodyless requests Refs: expressjs/express#3390 (comment) PR-URL: nodejs#15193 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
Some changes to compatibility layer to bring it closer to the h1 implementation.
Adds Http2ServerRequest
trailers
&rawTrailers
functionality. Previously didn't work at all and the request would also never end. Which actually makes me wonder, is this even correct or am I compensating for a deeper issue?Fixes behaviour of multi-headers to conform with the spec (all values but set-cookie and cookie should be comma delimited, cookie should be semi-colon delimited and only set-cookie should be an array). I think it's important we conform to the spec and also be backwards compatible, even if arrays are easier to work with for multi-values. (H2 doesn't specify this directly but it links to https://tools.ietf.org/html/rfc7230#section-3.2.2)
Adds setter for statusMessage that warns (same as the getter), for backwards compatibility. See Initial support proposal for http2 expressjs/express#3390 (comment)
@jasnell, @mcollina I would also like to start a discussion re: rawHeaders if possible. The current behaviour doesn't result in true rawHeaders as we have no way of knowing in what format something like cookie was sent to us based on the headers object (could've already been joined or could've been separate). Should we just emit the raw headers object alongside headers & flags from
onSessionHeaders
(and then pass toonServerStream
too)? If we were to add it as the last argument then it wouldn't really interfere with anything but I'm open to alternate suggestions. (We could also hide it on the headers object as non-enumerable property but that seems really dirty.)Thanks in advance for any feedback!
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
http2, test