summaryrefslogtreecommitdiff
path: root/test/parallel/test-http-max-http-headers.js
diff options
context:
space:
mode:
authorRich Trott <rtrott@gmail.com>2019-11-28 23:42:12 -0800
committerRich Trott <rtrott@gmail.com>2019-12-01 02:42:27 -0800
commit5b52a62ab153ad2b06164b8b7904581869c3c96c (patch)
treee5e311809eb6414499adaa53defe87b37e46f33e /test/parallel/test-http-max-http-headers.js
parent05c5ebbe12db965bcf3fa0f652352fb337b09723 (diff)
downloadandroid-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.js180
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();