-
-
Notifications
You must be signed in to change notification settings - Fork 35k
http2: add compat trailers, adjust multi-headers #15193
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,6 +51,13 @@ function onStreamData(chunk) { | |
| this.pause(); | ||
| } | ||
|
|
||
| function onStreamTrailers(trailers) { | ||
| const request = this[kRequest]; | ||
| request[kTrailers] = trailers; | ||
| // also causes the request stream to end | ||
| request.push(null); | ||
| } | ||
|
|
||
| function onStreamEnd() { | ||
| // Cause the request stream to end as well. | ||
| const request = this[kRequest]; | ||
|
|
@@ -120,6 +127,7 @@ class Http2ServerRequest extends Readable { | |
| // Pause the stream.. | ||
| stream.pause(); | ||
| stream.on('data', onStreamData); | ||
| stream.on('trailers', onStreamTrailers); | ||
| stream.on('end', onStreamEnd); | ||
| stream.on('error', onStreamError); | ||
| stream.on('close', onStreamClosedRequest); | ||
|
|
@@ -164,7 +172,16 @@ class Http2ServerRequest extends Readable { | |
| } | ||
|
|
||
| get trailers() { | ||
| return this[kTrailers]; | ||
| return this[kTrailers] || []; | ||
| } | ||
|
|
||
| get rawTrailers() { | ||
| const trailers = this[kTrailers]; | ||
| if (trailers === undefined) | ||
| return []; | ||
| const tuples = Object.entries(trailers); | ||
| const flattened = Array.prototype.concat.apply([], tuples); | ||
|
||
| return flattened.map(String); | ||
| } | ||
|
|
||
| get httpVersionMajor() { | ||
|
|
@@ -392,6 +409,16 @@ class Http2ServerResponse extends Stream { | |
| return ''; | ||
| } | ||
|
|
||
| set statusMessage(msg) { | ||
| if (statusMessageWarned === false) { | ||
| process.emitWarning( | ||
| 'Status message is not supported by HTTP/2 (RFC7540 8.1.2.4)', | ||
| 'UnsupportedWarning' | ||
| ); | ||
| statusMessageWarned = true; | ||
| } | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely. Will update. |
||
|
|
||
| flushHeaders() { | ||
| if (this[kStream].headersSent === false) | ||
| this[kBeginSend](); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| // Flags: --expose-http2 | ||
| 'use strict'; | ||
|
|
||
| const common = require('../common'); | ||
| if (!common.hasCrypto) | ||
| common.skip('missing crypto'); | ||
| const assert = require('assert'); | ||
| const h2 = require('http2'); | ||
|
|
||
| // Http2ServerRequest should have getter for trailers & rawTrailers | ||
|
|
||
| const expectedTrailers = { | ||
| 'x-foo': 'xOxOxOx, OxOxOxO, xOxOxOx, OxOxOxO' | ||
| }; | ||
|
|
||
| const server = h2.createServer(); | ||
| server.listen(0, common.mustCall(function() { | ||
| const port = server.address().port; | ||
| server.once('request', common.mustCall(function(request, response) { | ||
| let data = ''; | ||
| request.setEncoding('utf8'); | ||
| request.on('data', common.mustCall((chunk) => data += chunk)); | ||
| request.on('end', common.mustCall(() => { | ||
| const trailers = request.trailers; | ||
| for (const [name, value] of Object.entries(expectedTrailers)) { | ||
| assert.strictEqual(trailers[name], value); | ||
| } | ||
| assert.strictEqual(data, 'test\ntest'); | ||
| response.end(); | ||
| })); | ||
| })); | ||
|
|
||
| const url = `http://localhost:${port}`; | ||
| const client = h2.connect(url, common.mustCall(function() { | ||
| const headers = { | ||
| ':path': '/foobar', | ||
| ':method': 'POST', | ||
| ':scheme': 'http', | ||
| ':authority': `localhost:${port}` | ||
| }; | ||
| const request = client.request(headers, { | ||
| getTrailers(trailers) { | ||
| trailers['x-fOo'] = 'xOxOxOx'; | ||
| trailers['x-foO'] = 'OxOxOxO'; | ||
| trailers['X-fOo'] = 'xOxOxOx'; | ||
| trailers['X-foO'] = 'OxOxOxO'; | ||
| } | ||
| }); | ||
| request.resume(); | ||
| request.on('end', common.mustCall(function() { | ||
| server.close(); | ||
| client.destroy(); | ||
| })); | ||
| request.write('test\n'); | ||
| request.end('test'); | ||
| })); | ||
| })); |
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.