diff options
author | Rich Trott <rtrott@gmail.com> | 2019-11-28 23:42:12 -0800 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-12-01 02:42:27 -0800 |
commit | 5b52a62ab153ad2b06164b8b7904581869c3c96c (patch) | |
tree | e5e311809eb6414499adaa53defe87b37e46f33e /test/parallel/test-http-max-http-headers.js | |
parent | 05c5ebbe12db965bcf3fa0f652352fb337b09723 (diff) | |
download | android-node-v8-5b52a62ab153ad2b06164b8b7904581869c3c96c.tar.gz android-node-v8-5b52a62ab153ad2b06164b8b7904581869c3c96c.tar.bz2 android-node-v8-5b52a62ab153ad2b06164b8b7904581869c3c96c.zip |
test: move test-http-max-http-headers to parallel
test-http-max-http-headers seems to run fine in parallel, even with
`tools/test.py -j 96 --repeat 192
test/parallel/test-http-max-http-headers.js`.
The same applies to `test-set-http-max-http-headers.js` which (as
written) depends on `test-http-max-http-headers.js` being in the same
directory. So that is being moved too.
PR-URL: https://github.com/nodejs/node/pull/30712
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Diffstat (limited to 'test/parallel/test-http-max-http-headers.js')
-rw-r--r-- | test/parallel/test-http-max-http-headers.js | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/test/parallel/test-http-max-http-headers.js b/test/parallel/test-http-max-http-headers.js new file mode 100644 index 0000000000..04fdebd48c --- /dev/null +++ b/test/parallel/test-http-max-http-headers.js @@ -0,0 +1,180 @@ +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const net = require('net'); +const MAX = +(process.argv[2] || 8 * 1024); // Command line option, or 8KB. + +const { getOptionValue } = require('internal/options'); + +console.log('pid is', process.pid); +console.log('max header size is', getOptionValue('--max-http-header-size')); + +// Verify that we cannot receive more than 8KB of headers. + +function once(cb) { + let called = false; + return () => { + if (!called) { + called = true; + cb(); + } + }; +} + +function finished(client, callback) { + ['abort', 'error', 'end'].forEach((e) => { + client.on(e, once(() => setImmediate(callback))); + }); +} + +function fillHeaders(headers, currentSize, valid = false) { + // `llhttp` counts actual header name/value sizes, excluding the whitespace + // and stripped chars. + // OK, Content-Length, 0, X-CRASH, aaa... + headers += 'a'.repeat(MAX - currentSize); + + // Generate valid headers + if (valid) { + headers = headers.slice(0, -1); + } + return headers + '\r\n\r\n'; +} + +function writeHeaders(socket, headers) { + const array = []; + const chunkSize = 100; + let last = 0; + + for (let i = 0; i < headers.length / chunkSize; i++) { + const current = (i + 1) * chunkSize; + array.push(headers.slice(last, current)); + last = current; + } + + // Safety check we are chunking correctly + assert.strictEqual(array.join(''), headers); + + next(); + + function next() { + if (socket.destroyed) { + console.log('socket was destroyed early, data left to write:', + array.join('').length); + return; + } + + const chunk = array.shift(); + + if (chunk) { + console.log('writing chunk of size', chunk.length); + socket.write(chunk, next); + } else { + socket.end(); + } + } +} + +function test1() { + console.log('test1'); + let headers = + 'HTTP/1.1 200 OK\r\n' + + 'Content-Length: 0\r\n' + + 'X-CRASH: '; + + // OK, Content-Length, 0, X-CRASH, aaa... + const currentSize = 2 + 14 + 1 + 7; + headers = fillHeaders(headers, currentSize); + + const server = net.createServer((sock) => { + sock.once('data', () => { + writeHeaders(sock, headers); + sock.resume(); + }); + + // The socket might error but that's ok + sock.on('error', () => {}); + }); + + server.listen(0, common.mustCall(() => { + const port = server.address().port; + const client = http.get({ port: port }, common.mustNotCall()); + + client.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'HPE_HEADER_OVERFLOW'); + server.close(test2); + })); + })); +} + +const test2 = common.mustCall(() => { + console.log('test2'); + let headers = + 'GET / HTTP/1.1\r\n' + + 'Host: localhost\r\n' + + 'Agent: nod2\r\n' + + 'X-CRASH: '; + + // /, Host, localhost, Agent, node, X-CRASH, a... + const currentSize = 1 + 4 + 9 + 5 + 4 + 7; + headers = fillHeaders(headers, currentSize); + + const server = http.createServer(common.mustNotCall()); + + server.once('clientError', common.mustCall((err) => { + assert.strictEqual(err.code, 'HPE_HEADER_OVERFLOW'); + })); + + server.listen(0, common.mustCall(() => { + const client = net.connect(server.address().port); + client.on('connect', () => { + writeHeaders(client, headers); + client.resume(); + }); + + finished(client, common.mustCall(() => { + server.close(test3); + })); + })); +}); + +const test3 = common.mustCall(() => { + console.log('test3'); + let headers = + 'GET / HTTP/1.1\r\n' + + 'Host: localhost\r\n' + + 'Agent: nod3\r\n' + + 'X-CRASH: '; + + // /, Host, localhost, Agent, node, X-CRASH, a... + const currentSize = 1 + 4 + 9 + 5 + 4 + 7; + headers = fillHeaders(headers, currentSize, true); + + console.log('writing', headers.length); + + const server = http.createServer(common.mustCall((req, res) => { + res.end('hello from test3 server'); + server.close(); + })); + + server.on('clientError', (err) => { + console.log(err.code); + if (err.code === 'HPE_HEADER_OVERFLOW') { + console.log(err.rawPacket.toString('hex')); + } + }); + server.on('clientError', common.mustNotCall()); + + server.listen(0, common.mustCall(() => { + const client = net.connect(server.address().port); + client.on('connect', () => { + writeHeaders(client, headers); + client.resume(); + }); + + client.pipe(process.stdout); + })); +}); + +test1(); |