1'use strict'; 2const common = require('../common'); 3 4if (!common.hasCrypto) { 5 common.skip('missing crypto'); 6} 7 8const fixtures = require('../common/fixtures'); 9const assert = require('assert'); 10const https = require('https'); 11const http = require('http'); 12const tls = require('tls'); 13const MakeDuplexPair = require('../common/duplexpair'); 14const { finished } = require('stream'); 15 16const certFixture = { 17 key: fixtures.readKey('agent1-key.pem'), 18 cert: fixtures.readKey('agent1-cert.pem'), 19 ca: fixtures.readKey('ca1-cert.pem'), 20}; 21 22 23// Test that setting the `maxHeaderSize` option works on a per-stream-basis. 24 25// Test 1: The server sends larger headers than what would otherwise be allowed. 26{ 27 const { clientSide, serverSide } = MakeDuplexPair(); 28 29 const req = https.request({ 30 createConnection: common.mustCall(() => clientSide), 31 maxHeaderSize: http.maxHeaderSize * 4 32 }, common.mustCall((res) => { 33 assert.strictEqual(res.headers.hello, 'A'.repeat(http.maxHeaderSize * 3)); 34 res.resume(); // We don’t actually care about contents. 35 res.on('end', common.mustCall()); 36 })); 37 req.end(); 38 39 serverSide.resume(); // Dump the request 40 serverSide.end('HTTP/1.1 200 OK\r\n' + 41 'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' + 42 'Content-Length: 0\r\n' + 43 '\r\n\r\n'); 44} 45 46// Test 2: The same as Test 1 except without the option, to make sure it fails. 47{ 48 const { clientSide, serverSide } = MakeDuplexPair(); 49 50 const req = https.request({ 51 createConnection: common.mustCall(() => clientSide) 52 }, common.mustNotCall()); 53 req.end(); 54 req.on('error', common.mustCall()); 55 56 serverSide.resume(); // Dump the request 57 serverSide.end('HTTP/1.1 200 OK\r\n' + 58 'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' + 59 'Content-Length: 0\r\n' + 60 '\r\n\r\n'); 61} 62 63// Test 3: The client sends larger headers than what would otherwise be allowed. 64{ 65 const testData = 'Hello, World!\n'; 66 const server = https.createServer( 67 { maxHeaderSize: http.maxHeaderSize * 4, 68 ...certFixture }, 69 common.mustCall((req, res) => { 70 res.statusCode = 200; 71 res.setHeader('Content-Type', 'text/plain'); 72 res.end(testData); 73 })); 74 75 server.on('clientError', common.mustNotCall()); 76 77 server.listen(0, common.mustCall(() => { 78 const client = tls.connect({ 79 port: server.address().port, 80 rejectUnauthorized: false 81 }); 82 client.write( 83 'GET / HTTP/1.1\r\n' + 84 'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' + 85 '\r\n\r\n'); 86 client.end(); 87 88 client.on('data', () => {}); 89 finished(client, common.mustCall(() => { 90 server.close(); 91 })); 92 })); 93} 94 95// Test 4: The same as Test 3 except without the option, to make sure it fails. 96{ 97 const server = https.createServer({ ...certFixture }, common.mustNotCall()); 98 99 // clientError may be emitted multiple times when header is larger than 100 // maxHeaderSize. 101 server.on('clientError', common.mustCallAtLeast(() => {}, 1)); 102 103 server.listen(0, common.mustCall(() => { 104 const client = tls.connect({ 105 port: server.address().port, 106 rejectUnauthorized: false 107 }); 108 client.write( 109 'GET / HTTP/1.1\r\n' + 110 'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' + 111 '\r\n\r\n'); 112 client.end(); 113 114 client.on('data', () => {}); 115 finished(client, common.mustCall(() => { 116 server.close(); 117 })); 118 })); 119} 120