GeezerVison is showing github.com — quic: convert incoming :status header to number · nodejs/node@88bee43
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/quic.md +3-2Lines changed: 3 additions & 2 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -3962,8 +3962,9 @@ A few things to note: | 3962 | 3962 | the request is `HEADERS` followed by `END_STREAM`. | 3963 | 3963 | * The `onheaders` callback receives the response pseudo-headers and | 3964 | 3964 | regular headers in a single object with lowercase string keys. | 3965 | | - After the callback returns, the same object is also accessible | 3966 | | - via [`stream.headers`][]. | | 3965 | + For incoming headers, the `:status` pseudo-header is converted to | | 3966 | + a `number`, matching HTTP/2 behavior. After the callback returns, | | 3967 | + the same object is also accessible via [`stream.headers`][]. | 3967 | 3968 | * Reading `for await (const chunks of stream)` consumes the response | 3968 | 3969 | body. Each iteration yields a `Uint8Array[]` batch of chunks. | 3969 | 3970 | * HTTP semantic helpers (URL parsing, method/status validation, | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/quic/quic.js +10-5Lines changed: 10 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1285,14 +1285,19 @@ function parseHeaderPairs(pairs) { | 1285 | 1285 | assert(pairs.length % 2 === 0); | 1286 | 1286 | const block = { __proto__: null }; | 1287 | 1287 | for (let n = 0; n + 1 < pairs.length; n += 2) { | 1288 | | - if (block[pairs[n]] !== undefined) { | 1289 | | - if (ArrayIsArray(block[pairs[n]])) { | 1290 | | - ArrayPrototypePush(block[pairs[n]], pairs[n + 1]); | | 1288 | + const name = pairs[n]; | | 1289 | + let value = pairs[n + 1]; | | 1290 | + // Match HTTP/2 behavior: incoming :status is exposed as a number. | | 1291 | + if (name === ':status') | | 1292 | + value |= 0; | | 1293 | + if (block[name] !== undefined) { | | 1294 | + if (ArrayIsArray(block[name])) { | | 1295 | + ArrayPrototypePush(block[name], value); | 1291 | 1296 | } else { | 1292 | | - block[pairs[n]] = [block[pairs[n]], pairs[n + 1]]; | | 1297 | + block[name] = [block[name], value]; | 1293 | 1298 | } | 1294 | 1299 | } else { | 1295 | | - block[pairs[n]] = pairs[n + 1]; | | 1300 | + block[name] = value; | 1296 | 1301 | } | 1297 | 1302 | } | 1298 | 1303 | return block; | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-callback-errors.mjs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -151,7 +151,7 @@ async function makeServer(onheadersHandler, extraOpts = {}) { | 151 | 151 | ':authority': 'localhost', | 152 | 152 | }, | 153 | 153 | onheaders: mustCall(function(headers) { | 154 | | - assert.strictEqual(headers[':status'], '200'); | | 154 | + assert.strictEqual(headers[':status'], 200); | 155 | 155 | }), | 156 | 156 | ontrailers: mustCall(function() { | 157 | 157 | throw new Error('ontrailers sync error'); | @@ -265,7 +265,7 @@ async function makeServer(onheadersHandler, extraOpts = {}) { | 265 | 265 | ':authority': 'localhost', | 266 | 266 | }, | 267 | 267 | onheaders: mustCall(function(headers) { | 268 | | - assert.strictEqual(headers[':status'], '200'); | | 268 | + assert.strictEqual(headers[':status'], 200); | 269 | 269 | }), | 270 | 270 | }); | 271 | 271 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-close-behavior.mjs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -62,7 +62,7 @@ const decoder = new TextDecoder(); | 62 | 62 | ':authority': 'localhost', | 63 | 63 | }, | 64 | 64 | onheaders: mustCall((headers) => { | 65 | | - assert.strictEqual(headers[':status'], '200'); | | 65 | + assert.strictEqual(headers[':status'], 200); | 66 | 66 | }), | 67 | 67 | }); | 68 | 68 |
| @@ -74,7 +74,7 @@ const decoder = new TextDecoder(); | 74 | 74 | ':authority': 'localhost', | 75 | 75 | }, | 76 | 76 | onheaders: mustCall((headers) => { | 77 | | - assert.strictEqual(headers[':status'], '200'); | | 77 | + assert.strictEqual(headers[':status'], 200); | 78 | 78 | }), | 79 | 79 | }); | 80 | 80 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-concurrent-requests.mjs +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -72,7 +72,7 @@ const requests = paths.map(mustCall(async (path) => { | 72 | 72 | ':authority': 'localhost', | 73 | 73 | }, | 74 | 74 | onheaders: mustCall((headers) => { | 75 | | - assert.strictEqual(headers[':status'], '200'); | | 75 | + assert.strictEqual(headers[':status'], 200); | 76 | 76 | headersReceived.resolve(); | 77 | 77 | }), | 78 | 78 | }); | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-datagram.mjs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -87,7 +87,7 @@ const decoder = new TextDecoder(); | 87 | 87 | ':authority': 'localhost', | 88 | 88 | }, | 89 | 89 | onheaders: mustCall(function(headers) { | 90 | | - assert.strictEqual(headers[':status'], '200'); | | 90 | + assert.strictEqual(headers[':status'], 200); | 91 | 91 | }), | 92 | 92 | }); | 93 | 93 |
| @@ -151,7 +151,7 @@ const decoder = new TextDecoder(); | 151 | 151 | ':authority': 'localhost', | 152 | 152 | }, | 153 | 153 | onheaders: mustCall((headers) => { | 154 | | - assert.strictEqual(headers[':status'], '200'); | | 154 | + assert.strictEqual(headers[':status'], 200); | 155 | 155 | }), | 156 | 156 | }); | 157 | 157 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-error-codes.mjs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -55,7 +55,7 @@ const decoder = new TextDecoder(); | 55 | 55 | ':authority': 'localhost', | 56 | 56 | }, | 57 | 57 | onheaders: mustCall(function(headers) { | 58 | | - assert.strictEqual(headers[':status'], '200'); | | 58 | + assert.strictEqual(headers[':status'], 200); | 59 | 59 | }), | 60 | 60 | }); | 61 | 61 |
| @@ -106,7 +106,7 @@ const decoder = new TextDecoder(); | 106 | 106 | ':authority': 'localhost', | 107 | 107 | }, | 108 | 108 | onheaders: mustCall(function(headers) { | 109 | | - assert.strictEqual(headers[':status'], '200'); | | 109 | + assert.strictEqual(headers[':status'], 200); | 110 | 110 | }), | 111 | 111 | }); | 112 | 112 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-goaway.mjs +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -78,7 +78,7 @@ dc.subscribe('quic.session.goaway', mustCall((msg) => { | 78 | 78 | await clientSession.opened; | 79 | 79 |
| 80 | 80 | const onClientHeaders = mustCall(function(headers) { | 81 | | - assert.strictEqual(headers[':status'], '200'); | | 81 | + assert.strictEqual(headers[':status'], 200); | 82 | 82 | if (++clientHeaderCount === 2) { | 83 | 83 | bothHeadersReceived.resolve(); | 84 | 84 | } | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-header-validation.mjs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -91,7 +91,7 @@ const decoder = new TextDecoder(); | 91 | 91 | }, | 92 | 92 | onheaders: mustCall(function(headers) { | 93 | 93 | // Client should also receive lowercased response header names. | 94 | | - assert.strictEqual(headers[':status'], '200'); | | 94 | + assert.strictEqual(headers[':status'], 200); | 95 | 95 | assert.strictEqual(headers['content-type'], 'text/html'); | 96 | 96 | assert.strictEqual(headers['x-response-header'], 'ResponseValue'); | 97 | 97 |
| @@ -148,7 +148,7 @@ const decoder = new TextDecoder(); | 148 | 148 | ':authority': 'localhost', | 149 | 149 | }, | 150 | 150 | onheaders: mustCall((headers) => { | 151 | | - assert.strictEqual(headers[':status'], '204'); | | 151 | + assert.strictEqual(headers[':status'], 204); | 152 | 152 | }), | 153 | 153 | }); | 154 | 154 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-quic-h3-informational-headers.mjs +4-4Lines changed: 4 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -34,7 +34,7 @@ dc.subscribe('quic.stream.info', mustCall((msg) => { | 34 | 34 | assert.ok(msg.stream, 'stream.info should include stream'); | 35 | 35 | assert.ok(msg.session, 'stream.info should include session'); | 36 | 36 | assert.ok(msg.headers, 'stream.info should include headers'); | 37 | | - assert.strictEqual(msg.headers[':status'], '103'); | | 37 | + assert.strictEqual(msg.headers[':status'], 103); | 38 | 38 | })); | 39 | 39 |
| 40 | 40 | // quic.stream.headers also fires for the final response headers. | @@ -89,12 +89,12 @@ const stream = await clientSession.createBidirectionalStream({ | 89 | 89 | ':authority': 'localhost', | 90 | 90 | }, | 91 | 91 | oninfo: mustCall(function(headers) { | 92 | | - assert.strictEqual(headers[':status'], '103'); | | 92 | + assert.strictEqual(headers[':status'], 103); | 93 | 93 | assert.strictEqual(headers.link, '</style.css>; rel=preload; as=style'); | 94 | 94 | clientInfoReceived.resolve(); | 95 | 95 | }), | 96 | 96 | onheaders: mustCall(function(headers) { | 97 | | - assert.strictEqual(headers[':status'], '200'); | | 97 | + assert.strictEqual(headers[':status'], 200); | 98 | 98 | assert.strictEqual(headers['content-type'], 'text/plain'); | 99 | 99 | clientHeadersReceived.resolve(); | 100 | 100 | }), | @@ -107,7 +107,7 @@ const body = await bytes(stream); | 107 | 107 | assert.strictEqual(decoder.decode(body), responseBody); | 108 | 108 |
| 109 | 109 | // stream.headers should return the final (initial) headers, not 1xx. | 110 | | -assert.strictEqual(stream.headers[':status'], '200'); | | 110 | +assert.strictEqual(stream.headers[':status'], 200); | 111 | 111 |
| 112 | 112 | await Promise.all([stream.closed, serverDone.promise]); | 113 | 113 | await clientSession.close(); | |
|