• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2
3'use strict';
4const { expectsError, mustCall } = require('../common');
5const assert = require('assert');
6const { createServer, maxHeaderSize } = require('http');
7const { createConnection } = require('net');
8
9const { getOptionValue } = require('internal/options');
10
11const CRLF = '\r\n';
12const DUMMY_HEADER_NAME = 'Cookie: ';
13const DUMMY_HEADER_VALUE = 'a'.repeat(
14  // Plus one is to make it 1 byte too big
15  maxHeaderSize - DUMMY_HEADER_NAME.length - (2 * CRLF.length) + 1
16);
17const PAYLOAD_GET = 'GET /blah HTTP/1.1';
18const PAYLOAD = PAYLOAD_GET + CRLF +
19  DUMMY_HEADER_NAME + DUMMY_HEADER_VALUE + CRLF.repeat(2);
20
21const server = createServer();
22
23server.on('connection', mustCall((socket) => {
24  // Legacy parser gives sligthly different response.
25  // This discripancy is not fixed on purpose.
26  const legacy = getOptionValue('--http-parser') === 'legacy';
27  socket.on('error', expectsError({
28    name: 'Error',
29    message: 'Parse Error: Header overflow',
30    code: 'HPE_HEADER_OVERFLOW',
31    bytesParsed: maxHeaderSize + PAYLOAD_GET.length - (legacy ? -1 : 0),
32    rawPacket: Buffer.from(PAYLOAD)
33  }));
34}));
35
36server.listen(0, mustCall(() => {
37  const c = createConnection(server.address().port);
38  let received = '';
39
40  c.on('connect', mustCall(() => {
41    c.write(PAYLOAD);
42  }));
43  c.on('data', mustCall((data) => {
44    received += data.toString();
45  }));
46  c.on('end', mustCall(() => {
47    assert.strictEqual(
48      received,
49      'HTTP/1.1 431 Request Header Fields Too Large\r\n' +
50      'Connection: close\r\n\r\n'
51    );
52    c.end();
53  }));
54  c.on('close', mustCall(() => server.close()));
55}));
56