| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,95 +5,81 @@ const common = require('../common'); | |||
| 5 | 5 | if (!common.hasCrypto) | |
| 6 | 6 | common.skip('missing crypto'); | |
| 7 | 7 | const http2 = require('http2'); | |
| 8 | - const { | ||
| 9 | - constants, | ||
| 10 | - Http2Stream, | ||
| 11 | - nghttp2ErrorString | ||
| 12 | - } = process.binding('http2'); | ||
| 13 | - const { NghttpError } = require('internal/http2/util'); | ||
| 14 | - | ||
| 15 | - // tests error handling within respond | ||
| 16 | - // - every other NGHTTP2 error from binding (should emit stream error) | ||
| 17 | - | ||
| 18 | - const specificTestKeys = []; | ||
| 19 | - | ||
| 20 | - const specificTests = []; | ||
| 21 | - | ||
| 22 | - const genericTests = Object.getOwnPropertyNames(constants) | ||
| 23 | - .filter((key) => ( | ||
| 24 | - key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0 | ||
| 25 | - )) | ||
| 26 | - .map((key) => ({ | ||
| 27 | - ngError: constants[key], | ||
| 28 | - error: { | ||
| 29 | - code: 'ERR_HTTP2_ERROR', | ||
| 30 | - type: NghttpError, | ||
| 31 | - name: 'Error [ERR_HTTP2_ERROR]', | ||
| 32 | - message: nghttp2ErrorString(constants[key]) | ||
| 33 | - }, | ||
| 34 | - type: 'stream' | ||
| 35 | - })); | ||
| 36 | - | ||
| 37 | - | ||
| 38 | - const tests = specificTests.concat(genericTests); | ||
| 39 | - | ||
| 40 | - let currentError; | ||
| 41 | - | ||
| 42 | - // mock submitResponse because we only care about testing error handling | ||
| 43 | - Http2Stream.prototype.respond = () => currentError.ngError; | ||
| 8 | + const { Http2Stream } = process.binding('http2'); | ||
| 9 | + | ||
| 10 | + const types = { | ||
| 11 | + boolean: true, | ||
| 12 | + function: () => {}, | ||
| 13 | + number: 1, | ||
| 14 | + object: {}, | ||
| 15 | + array: [], | ||
| 16 | + null: null, | ||
| 17 | + symbol: Symbol('test') | ||
| 18 | + }; | ||
| 44 | 19 | ||
| 45 | 20 | const server = http2.createServer(); | |
| 46 | - server.on('stream', common.mustCall((stream, headers) => { | ||
| 47 | - const errorMustCall = common.expectsError(currentError.error); | ||
| 48 | - const errorMustNotCall = common.mustNotCall( | ||
| 49 | - `${currentError.error.code} should emit on ${currentError.type}` | ||
| 50 | - ); | ||
| 51 | - | ||
| 52 | - if (currentError.type === 'stream') { | ||
| 53 | - stream.session.on('error', errorMustNotCall); | ||
| 54 | - stream.on('error', errorMustCall); | ||
| 55 | - stream.on('error', common.mustCall(() => { | ||
| 56 | - stream.destroy(); | ||
| 57 | - })); | ||
| 58 | - } else { | ||
| 59 | - stream.session.once('error', errorMustCall); | ||
| 60 | - stream.on('error', errorMustNotCall); | ||
| 61 | - } | ||
| 62 | 21 | ||
| 63 | - stream.respond(); | ||
| 64 | - }, tests.length)); | ||
| 22 | + Http2Stream.prototype.respond = () => 1; | ||
| 23 | + server.on('stream', common.mustCall((stream) => { | ||
| 65 | 24 | ||
| 66 | - server.listen(0, common.mustCall(() => runTest(tests.shift()))); | ||
| 25 | + // Check for all possible TypeError triggers on options.getTrailers | ||
| 26 | + Object.entries(types).forEach(([type, value]) => { | ||
| 27 | + if (type === 'function') { | ||
| 28 | + return; | ||
| 29 | + } | ||
| 67 | 30 | ||
| 68 | - function runTest(test) { | ||
| 69 | - const port = server.address().port; | ||
| 70 | - const url = `http://localhost:${port}`; | ||
| 71 | - const headers = { | ||
| 72 | - ':path': '/', | ||
| 73 | - ':method': 'POST', | ||
| 74 | - ':scheme': 'http', | ||
| 75 | - ':authority': `localhost:${port}` | ||
| 76 | - }; | ||
| 31 | + common.expectsError( | ||
| 32 | + () => stream.respond({ | ||
| 33 | + 'content-type': 'text/plain' | ||
| 34 | + }, { | ||
| 35 | + ['getTrailers']: value | ||
| 36 | + }), | ||
| 37 | + { | ||
| 38 | + type: TypeError, | ||
| 39 | + code: 'ERR_INVALID_OPT_VALUE', | ||
| 40 | + message: `The value "${String(value)}" is invalid ` + | ||
| 41 | + 'for option "getTrailers"' | ||
| 42 | + } | ||
| 43 | + ); | ||
| 44 | + }); | ||
| 45 | + | ||
| 46 | + // Send headers | ||
| 47 | + stream.respond({ | ||
| 48 | + 'content-type': 'text/plain' | ||
| 49 | + }, { | ||
| 50 | + ['getTrailers']: () => common.mustCall() | ||
| 51 | + }); | ||
| 52 | + | ||
| 53 | + // Should throw if headers already sent | ||
| 54 | + common.expectsError( | ||
| 55 | + () => stream.respond(), | ||
| 56 | + { | ||
| 57 | + type: Error, | ||
| 58 | + code: 'ERR_HTTP2_HEADERS_SENT', | ||
| 59 | + message: 'Response has already been initiated.' | ||
| 60 | + } | ||
| 61 | + ); | ||
| 77 | 62 | ||
| 78 | - const client = http2.connect(url); | ||
| 79 | - const req = client.request(headers); | ||
| 80 | - req.on('error', common.expectsError({ | ||
| 81 | - code: 'ERR_HTTP2_STREAM_ERROR', | ||
| 82 | - type: Error, | ||
| 83 | - message: 'Stream closed with error code 2' | ||
| 84 | - })); | ||
| 63 | + // Should throw if stream already destroyed | ||
| 64 | + stream.destroy(); | ||
| 65 | + common.expectsError( | ||
| 66 | + () => stream.respond(), | ||
| 67 | + { | ||
| 68 | + type: Error, | ||
| 69 | + code: 'ERR_HTTP2_INVALID_STREAM', | ||
| 70 | + message: 'The stream has been destroyed' | ||
| 71 | + } | ||
| 72 | + ); | ||
| 73 | + })); | ||
| 85 | 74 | ||
| 86 | - currentError = test; | ||
| 87 | - req.resume(); | ||
| 88 | - req.end(); | ||
| 75 | + server.listen(0, common.mustCall(() => { | ||
| 76 | + const client = http2.connect(`http://localhost:${server.address().port}`); | ||
| 77 | + const req = client.request(); | ||
| 89 | 78 | ||
| 90 | 79 | req.on('end', common.mustCall(() => { | |
| 91 | 80 | client.close(); | |
| 92 | - | ||
| 93 | - if (!tests.length) { | ||
| 94 | - server.close(); | ||
| 95 | - } else { | ||
| 96 | - runTest(tests.shift()); | ||
| 97 | - } | ||
| 81 | + server.close(); | ||
| 98 | 82 | })); | |
| 99 | - } | ||
| 83 | + req.resume(); | ||
| 84 | + req.end(); | ||
| 85 | + })); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,99 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + // Flags: --expose-internals | ||
| 3 | + | ||
| 4 | + const common = require('../common'); | ||
| 5 | + if (!common.hasCrypto) | ||
| 6 | + common.skip('missing crypto'); | ||
| 7 | + const http2 = require('http2'); | ||
| 8 | + const { | ||
| 9 | + constants, | ||
| 10 | + Http2Stream, | ||
| 11 | + nghttp2ErrorString | ||
| 12 | + } = process.binding('http2'); | ||
| 13 | + const { NghttpError } = require('internal/http2/util'); | ||
| 14 | + | ||
| 15 | + // tests error handling within respond | ||
| 16 | + // - every other NGHTTP2 error from binding (should emit stream error) | ||
| 17 | + | ||
| 18 | + const specificTestKeys = []; | ||
| 19 | + | ||
| 20 | + const specificTests = []; | ||
| 21 | + | ||
| 22 | + const genericTests = Object.getOwnPropertyNames(constants) | ||
| 23 | + .filter((key) => ( | ||
| 24 | + key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0 | ||
| 25 | + )) | ||
| 26 | + .map((key) => ({ | ||
| 27 | + ngError: constants[key], | ||
| 28 | + error: { | ||
| 29 | + code: 'ERR_HTTP2_ERROR', | ||
| 30 | + type: NghttpError, | ||
| 31 | + name: 'Error [ERR_HTTP2_ERROR]', | ||
| 32 | + message: nghttp2ErrorString(constants[key]) | ||
| 33 | + }, | ||
| 34 | + type: 'stream' | ||
| 35 | + })); | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + const tests = specificTests.concat(genericTests); | ||
| 39 | + | ||
| 40 | + let currentError; | ||
| 41 | + | ||
| 42 | + // mock submitResponse because we only care about testing error handling | ||
| 43 | + Http2Stream.prototype.respond = () => currentError.ngError; | ||
| 44 | + | ||
| 45 | + const server = http2.createServer(); | ||
| 46 | + server.on('stream', common.mustCall((stream, headers) => { | ||
| 47 | + const errorMustCall = common.expectsError(currentError.error); | ||
| 48 | + const errorMustNotCall = common.mustNotCall( | ||
| 49 | + `${currentError.error.code} should emit on ${currentError.type}` | ||
| 50 | + ); | ||
| 51 | + | ||
| 52 | + if (currentError.type === 'stream') { | ||
| 53 | + stream.session.on('error', errorMustNotCall); | ||
| 54 | + stream.on('error', errorMustCall); | ||
| 55 | + stream.on('error', common.mustCall(() => { | ||
| 56 | + stream.destroy(); | ||
| 57 | + })); | ||
| 58 | + } else { | ||
| 59 | + stream.session.once('error', errorMustCall); | ||
| 60 | + stream.on('error', errorMustNotCall); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + stream.respond(); | ||
| 64 | + }, tests.length)); | ||
| 65 | + | ||
| 66 | + server.listen(0, common.mustCall(() => runTest(tests.shift()))); | ||
| 67 | + | ||
| 68 | + function runTest(test) { | ||
| 69 | + const port = server.address().port; | ||
| 70 | + const url = `http://localhost:${port}`; | ||
| 71 | + const headers = { | ||
| 72 | + ':path': '/', | ||
| 73 | + ':method': 'POST', | ||
| 74 | + ':scheme': 'http', | ||
| 75 | + ':authority': `localhost:${port}` | ||
| 76 | + }; | ||
| 77 | + | ||
| 78 | + const client = http2.connect(url); | ||
| 79 | + const req = client.request(headers); | ||
| 80 | + req.on('error', common.expectsError({ | ||
| 81 | + code: 'ERR_HTTP2_STREAM_ERROR', | ||
| 82 | + type: Error, | ||
| 83 | + message: 'Stream closed with error code 2' | ||
| 84 | + })); | ||
| 85 | + | ||
| 86 | + currentError = test; | ||
| 87 | + req.resume(); | ||
| 88 | + req.end(); | ||
| 89 | + | ||
| 90 | + req.on('end', common.mustCall(() => { | ||
| 91 | + client.close(); | ||
| 92 | + | ||
| 93 | + if (!tests.length) { | ||
| 94 | + server.close(); | ||
| 95 | + } else { | ||
| 96 | + runTest(tests.shift()); | ||
| 97 | + } | ||
| 98 | + })); | ||
| 99 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments