http: server check Host header, to meet RFC 7230 5.4 requirement

PR-URL: https://github.com/nodejs/node/pull/45597
Fixes: https://github.com/nodejs/node/issues/39033
Co-authored-by: Luigi Pinca <luigipinca@gmail.com>
Co-authored-by: mscdex <mscdex@users.noreply.github.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
wwwzbwcom 2021-07-09 15:59:35 +08:00 committed by Paolo Insogna
parent 71ff89f929
commit ed3604cd64
46 changed files with 156 additions and 42 deletions

View File

@ -3185,6 +3185,10 @@ changes:
* `uniqueHeaders` {Array} A list of response headers that should be sent only
once. If the header's value is an array, the items will be joined
using `; `.
* `requireHostHeader` {boolean} It forces the server to respond with
a 400 (Bad Request) status code to any HTTP/1.1 request message
that lacks a Host header (as mandated by the specification).
**Default:** `true`.
* `requestListener` {Function}

View File

@ -473,6 +473,14 @@ function storeHTTPOptions(options) {
} else {
this.connectionsCheckingInterval = 30_000; // 30 seconds
}
const requireHostHeader = options.requireHostHeader;
if (requireHostHeader !== undefined) {
validateBoolean(requireHostHeader, 'options.requireHostHeader');
this.requireHostHeader = requireHostHeader;
} else {
this.requireHostHeader = true;
}
}
function setupConnectionsTracking(server) {
@ -1022,7 +1030,18 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
let handled = false;
if (req.httpVersionMajor === 1 && req.httpVersionMinor === 1) {
// From RFC 7230 5.4 https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
// A server MUST respond with a 400 (Bad Request) status code to any
// HTTP/1.1 request message that lacks a Host header field
if (server.requireHostHeader && req.headers.host === undefined) {
res.writeHead(400, ['Connection', 'close']);
res.end();
return 0;
}
const isRequestsLimitSet = (
typeof server.maxRequestsPerSocket === 'number' &&
server.maxRequestsPerSocket > 0
@ -1045,7 +1064,6 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
if (RegExpPrototypeExec(continueExpression, req.headers.expect) !== null) {
res._expect_continue = true;
if (server.listenerCount('checkContinue') > 0) {
server.emit('checkContinue', req, res);
} else {

View File

@ -52,6 +52,7 @@ let maxHeaderSize;
* ServerResponse?: ServerResponse;
* insecureHTTPParser?: boolean;
* maxHeaderSize?: number;
* requireHostHeader?: boolean
* }} [opts]
* @param {Function} [requestListener]
* @returns {Server}

View File

@ -47,7 +47,7 @@ function test(statusCode) {
const conn = net.createConnection(
server.address().port,
common.mustCall(() => {
conn.write('GET / HTTP/1.1\r\n\r\n');
conn.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
let resp = '';
conn.setEncoding('utf8');

View File

@ -10,7 +10,8 @@ function execute(options) {
const expectHeaders = {
'x-foo': 'boom',
'cookie': 'a=1; b=2; c=3',
'connection': 'keep-alive'
'connection': 'keep-alive',
'host': 'example.com',
};
// no Host header when you set headers an array
@ -43,13 +44,20 @@ function execute(options) {
// Should be the same except for implicit Host header on the first two
execute({ headers: { 'x-foo': 'boom', 'cookie': 'a=1; b=2; c=3' } });
execute({ headers: { 'x-foo': 'boom', 'cookie': [ 'a=1', 'b=2', 'c=3' ] } });
execute({ headers: [[ 'x-foo', 'boom' ], [ 'cookie', 'a=1; b=2; c=3' ]] });
execute({ headers: [
[ 'x-foo', 'boom' ], [ 'cookie', [ 'a=1', 'b=2', 'c=3' ]],
[ 'x-foo', 'boom' ],
[ 'cookie', 'a=1; b=2; c=3' ],
[ 'Host', 'example.com' ],
] });
execute({ headers: [
[ 'x-foo', 'boom' ],
[ 'cookie', [ 'a=1', 'b=2', 'c=3' ]],
[ 'Host', 'example.com' ],
] });
execute({ headers: [
[ 'x-foo', 'boom' ], [ 'cookie', 'a=1' ],
[ 'cookie', 'b=2' ], [ 'cookie', 'c=3'],
[ 'cookie', 'b=2' ], [ 'cookie', 'c=3' ],
[ 'Host', 'example.com'],
] });
// Authorization and Host header both missing from the second
@ -58,4 +66,5 @@ execute({ auth: 'foo:bar', headers:
execute({ auth: 'foo:bar', headers: [
[ 'x-foo', 'boom' ], [ 'cookie', 'a=1' ],
[ 'cookie', 'b=2' ], [ 'cookie', 'c=3'],
[ 'Host', 'example.com'],
] });

View File

@ -28,15 +28,18 @@ const server = http.createServer(function(req, res) {
switch (req.url.substr(1)) {
case 'multiple-writes':
delete req.headers.host;
assert.deepStrictEqual(req.headers, expectedHeadersMultipleWrites);
res.write('hello');
res.end('world');
break;
case 'end-with-data':
delete req.headers.host;
assert.deepStrictEqual(req.headers, expectedHeadersEndWithData);
res.end('hello world');
break;
case 'empty':
delete req.headers.host;
assert.deepStrictEqual(req.headers, expectedHeadersEndNoData);
res.end();
break;
@ -56,7 +59,6 @@ server.listen(0, function() {
path: '/multiple-writes'
});
req.removeHeader('Date');
req.removeHeader('Host');
req.write('hello ');
req.end('world');
req.on('response', function(res) {
@ -70,7 +72,6 @@ server.listen(0, function() {
path: '/end-with-data'
});
req.removeHeader('Date');
req.removeHeader('Host');
req.end('hello world');
req.on('response', function(res) {
assert.deepStrictEqual(res.headers, { ...expectedHeadersEndWithData, 'keep-alive': 'timeout=1' });
@ -83,7 +84,6 @@ server.listen(0, function() {
path: '/empty'
});
req.removeHeader('Date');
req.removeHeader('Host');
req.end();
req.on('response', function(res) {
assert.deepStrictEqual(res.headers, { ...expectedHeadersEndNoData, 'keep-alive': 'timeout=1' });

View File

@ -17,7 +17,7 @@ server.listen(0, mustCall(() => {
let received = '';
c.on('connect', mustCall(() => {
c.write('GET /blah HTTP/1.1\r\n\r\n');
c.write('GET /blah HTTP/1.1\r\nHost: example.com\r\n\r\n');
}));
c.on('data', mustCall((data) => {
received += data.toString();

View File

@ -22,6 +22,7 @@ const MakeDuplexPair = require('../common/duplexpair');
serverSide.resume(); // Dump the request
serverSide.end('HTTP/1.1 200 OK\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'Content-Length: 0\r\n' +
'\r\n\r\n');
@ -39,6 +40,7 @@ const MakeDuplexPair = require('../common/duplexpair');
serverSide.resume(); // Dump the request
serverSide.end('HTTP/1.1 200 OK\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'Content-Length: 0\r\n' +
'\r\n\r\n');
@ -62,6 +64,7 @@ const MakeDuplexPair = require('../common/duplexpair');
server.emit('connection', serverSide);
clientSide.write('GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'\r\n\r\n');
}
@ -77,6 +80,7 @@ const MakeDuplexPair = require('../common/duplexpair');
server.emit('connection', serverSide);
clientSide.write('GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'\r\n\r\n');
}

View File

@ -19,6 +19,7 @@ server.listen(0, common.mustCall(function() {
client.write(
'GET / HTTP/1.1\r\n' +
'Content-Type: text/te\x08t\r\n' +
'Host: example.com' +
'Connection: close\r\n\r\n');
}
);

View File

@ -8,6 +8,7 @@ const assert = require('assert');
function request(socket) {
socket.write('GET / HTTP/1.1\r\n');
socket.write('Connection: keep-alive\r\n');
socket.write('Host: localhost\r\n');
socket.write('\r\n\r\n');
}

View File

@ -24,12 +24,14 @@ function writeRequest(socket, withBody) {
socket.write('POST / HTTP/1.1\r\n');
socket.write('Connection: keep-alive\r\n');
socket.write('Content-Type: text/plain\r\n');
socket.write('Host: localhost\r\n');
socket.write(`Content-Length: ${bodySent.length}\r\n\r\n`);
socket.write(`${bodySent}\r\n`);
socket.write('\r\n\r\n');
} else {
socket.write('GET / HTTP/1.1\r\n');
socket.write('Connection: keep-alive\r\n');
socket.write('Host: localhost\r\n');
socket.write('\r\n\r\n');
}
}

View File

@ -21,6 +21,7 @@ function assertResponse(headers, body, expectClosed) {
function writeRequest(socket) {
socket.write('POST / HTTP/1.1\r\n');
socket.write('Host: localhost\r\n');
socket.write('Connection: keep-alive\r\n');
socket.write('Content-Type: text/plain\r\n');
socket.write(`Content-Length: ${bodySent.length}\r\n\r\n`);

View File

@ -41,7 +41,7 @@ server.listen(0);
server.on('listening', function() {
const c = net.createConnection(this.address().port);
c.on('connect', function() {
c.write('GET /hello?foo=%99bar HTTP/1.1\r\n\r\n');
c.write('GET /hello?foo=%99bar HTTP/1.1\r\nHost: example.com\r\n\r\n');
c.end();
});
});

View File

@ -62,6 +62,7 @@ const MakeDuplexPair = require('../common/duplexpair');
server.emit('connection', serverSide);
clientSide.write('GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' +
'\r\n\r\n');
}

View File

@ -27,7 +27,9 @@ const http = require('http');
let requests = 0;
let responses = 0;
const headers = {};
const headers = {
host: 'example.com'
};
const N = 100;
for (let i = 0; i < N; ++i) {
headers[`key${i}`] = i;
@ -56,8 +58,8 @@ server.maxHeadersCount = max;
server.listen(0, function() {
const maxAndExpected = [ // for client
[20, 20],
[1200, 103],
[0, N + 3], // Connection, Date and Transfer-Encoding
[1200, 104],
[0, N + 4], // Host and Connection
];
doRequest();

View File

@ -27,7 +27,7 @@ const server = http
.listen(0, function() {
const s = net.connect(this.address().port);
const big = 'GET / HTTP/1.1\r\n\r\n'.repeat(COUNT);
const big = 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'.repeat(COUNT);
s.write(big);
s.resume();

View File

@ -26,7 +26,7 @@ const server = http
});
})
.listen(0, function() {
const req = 'GET / HTTP/1.1\r\n\r\n'.repeat(COUNT);
const req = 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'.repeat(COUNT);
client = net.connect(this.address().port, function() {
client.write(req);
});

View File

@ -50,7 +50,7 @@ const server = http
.listen(0, () => {
const s = net.connect(server.address().port);
more = () => {
s.write('GET / HTTP/1.1\r\n\r\n');
s.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
};
done = () => {
s.write(

View File

@ -17,6 +17,7 @@ server.listen(0, common.mustCall(() => {
const req = [
'POST / HTTP/1.1',
'Host: example.com',
'Content-Length: 11',
'',
'hello world',

View File

@ -0,0 +1,41 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
{
const server = http.createServer(common.mustNotCall((req, res) => {
res.writeHead(200);
res.end();
}));
// From RFC 7230 5.4 https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
// A server MUST respond with a 400 (Bad Request) status code to any
// HTTP/1.1 request message that lacks a Host header field
server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port, headers: [] }, (res) => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(res.headers.connection, 'close');
res.resume().on('end', common.mustCall(() => {
server.close();
}));
});
}));
}
{
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
res.writeHead(200, ['test', '1']);
res.end();
}));
server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port, headers: [] }, (res) => {
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(res.headers.test, '1');
res.resume().on('end', common.mustCall(() => {
server.close();
}));
});
}));
}

View File

@ -53,7 +53,7 @@ const server = http.createServer((req, res) => {
res.end('ok');
});
server.listen(0, () => {
const end = 'HTTP/1.1\r\n\r\n';
const end = 'HTTP/1.1\r\nHost: example.com\r\n\r\n';
const client = net.connect({ port: server.address().port }, () => {
client.write(`GET ${str} ${end}`);
client.write(`GET / ${end}`);

View File

@ -50,7 +50,7 @@ server.listen(0, function() {
client2.on('close', common.mustCall());
client2.write('GET / HTTP/1.1\r\n\r\n');
client2.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
}));
client1.on('close', common.mustCall());

View File

@ -60,7 +60,7 @@ server.listen(0, function() {
client2Closed = true;
}));
client2.write('GET / HTTP/1.1\r\n\r\n');
client2.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
}));
client1.on('close', common.mustCall(() => {

View File

@ -12,7 +12,7 @@ const { connect } = require('net');
function performRequestWithDelay(client, firstDelay, secondDelay, closeAfter) {
client.resume();
client.write('GET / HTTP/1.1\r\n');
client.write('GET / HTTP/1.1\r\nHost: example.com\r\n');
setTimeout(() => {
client.write('Connection: ');

View File

@ -66,7 +66,8 @@ server.listen(0, common.mustCall(() => {
// Send two requests using pipelining. Delay before finishing the second one
client.resume();
client.write('GET / HTTP/1.1\r\nConnection: keep-alive\r\n\r\nGET / HTTP/1.1\r\nConnection: ');
client.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n' +
'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: ');
// Complete the request
setTimeout(() => {

View File

@ -16,6 +16,7 @@ function assertResponse(headers, body, expectClosed) {
function writeRequest(socket) {
socket.write('POST / HTTP/1.1\r\n');
socket.write('Connection: keep-alive\r\n');
socket.write('Host: localhost\r\n');
socket.write('Content-Type: text/plain\r\n');
socket.write(`Content-Length: ${bodySent.length}\r\n\r\n`);
socket.write(`${bodySent}\r\n`);

View File

@ -16,6 +16,7 @@ function assertResponse(headers, body, expectClosed) {
function writeRequest(socket) {
socket.write('POST / HTTP/1.1\r\n');
socket.write('Connection: keep-alive\r\n');
socket.write('Host: localhost\r\n');
socket.write('Content-Type: text/plain\r\n');
socket.write(`Content-Length: ${bodySent.length}\r\n\r\n`);
socket.write(`${bodySent}\r\n`);

View File

@ -47,6 +47,7 @@ server.listen(0, common.mustCall(() => {
client.resume();
client.write('POST / HTTP/1.1\r\n');
client.write('Host: example.com\r\n');
client.write('Content-Length: 20\r\n');
client.write('Connection: close\r\n');
client.write('\r\n');

View File

@ -58,6 +58,7 @@ server.listen(0, common.mustCall(() => {
client.resume();
client.write('POST / HTTP/1.1\r\n');
client.write('Host: example.com\r\n');
client.write('Content-Length: 20\r\n');
client.write('Connection: close\r\n');
client.write('\r\n');

View File

@ -12,7 +12,7 @@ const { connect } = require('net');
function performRequestWithDelay(client, firstDelay, secondDelay, closeAfter) {
client.resume();
client.write('GET / HTTP/1.1\r\n');
client.write('GET / HTTP/1.1\r\nHost: example.com\r\n');
setTimeout(() => {
client.write('Connection: ');

View File

@ -60,7 +60,8 @@ server.listen(0, common.mustCall(() => {
// Send two requests using pipelining. Delay before finishing the second one
client.resume();
client.write('GET / HTTP/1.1\r\nConnection: keep-alive\r\n\r\nGET / HTTP/1.1\r\nConnection: ');
client.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n' +
'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: ');
// Complete the request
setTimeout(() => {

View File

@ -7,7 +7,7 @@ const { connect } = require('net');
// This test validates that request are correct checked for both requests and headers timeout in various situations.
const requestBodyPart1 = 'POST / HTTP/1.1\r\nContent-Length: 20\r\n';
const requestBodyPart1 = 'POST / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 20\r\n';
const requestBodyPart2 = 'Connection: close\r\n\r\n1234567890';
const requestBodyPart3 = '1234567890';

View File

@ -18,7 +18,7 @@ const net = require('net');
server.close();
}).listen(0, function() {
const socket = net.connect(this.address().port, function() {
socket.write('PUT / HTTP/1.1\r\n\r\n');
socket.write('PUT / HTTP/1.1\r\nHost: example.com\r\n\r\n');
socket.once('data', function() {
socket.end('hello world');

View File

@ -89,7 +89,9 @@ server.on('listening', function() {
c.setEncoding('utf8');
c.on('connect', function() {
c.write('GET /hello?hello=world&foo=b==ar HTTP/1.1\r\n\r\n');
c.write(
'GET /hello?hello=world&foo=b==ar HTTP/1.1\r\n' +
'Host: example.com\r\n\r\n');
requests_sent += 1;
});
@ -97,13 +99,16 @@ server.on('listening', function() {
server_response += chunk;
if (requests_sent === 1) {
c.write('POST /quit HTTP/1.1\r\n\r\n');
c.write(
'POST /quit HTTP/1.1\r\n' +
'Host: example.com\r\n\r\n'
);
requests_sent += 1;
}
if (requests_sent === 2) {
c.write('GET / HTTP/1.1\r\nX-X: foo\r\n\r\n' +
'GET / HTTP/1.1\r\nX-X: bar\r\n\r\n');
c.write('GET / HTTP/1.1\r\nX-X: foo\r\nHost: example.com\r\n\r\n' +
'GET / HTTP/1.1\r\nX-X: bar\r\nHost: example.com\r\n\r\n');
// Note: we are making the connection half-closed here
// before we've gotten the response from the server. This
// is a pretty bad thing to do and not really supported

View File

@ -59,7 +59,7 @@ function testHttp11(port, callback) {
let tid;
c.on('connect', function() {
c.write('GET / HTTP/1.1\r\n\r\n');
c.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
tid = setTimeout(common.mustNotCall(), 2000, 'Couldn\'t find last chunk.');
});

View File

@ -38,7 +38,10 @@ function test() {
const client = net.connect(
this.address().port,
function() {
client.write('GET / HTTP/1.1\r\nConnection: close\r\n\r\n');
client.write(
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Connection: close\r\n\r\n');
}
);
client.on('data', function(chunk) {

View File

@ -87,6 +87,7 @@ function test_upgrade_with_listener() {
conn.on('connect', function() {
writeReq(conn,
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n' +
@ -124,6 +125,7 @@ function test_upgrade_no_listener() {
conn.on('connect', function() {
writeReq(conn,
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
@ -146,7 +148,7 @@ function test_standard_http() {
conn.setEncoding('utf8');
conn.on('connect', function() {
writeReq(conn, 'GET / HTTP/1.1\r\n\r\n');
writeReq(conn, 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
});
conn.once('data', function(data) {

View File

@ -113,7 +113,9 @@ server.on('listening', () => {
path: '/world',
headers: [ ['Cookie', 'abc=123'],
['Cookie', 'def=456'],
['Cookie', 'ghi=789'] ],
['Cookie', 'ghi=789'],
['Host', 'example.com'],
],
agent: agent
}, common.mustCall((res) => {
const cookieHeaders = req._header.match(/^Cookie: .+$/img);

View File

@ -22,7 +22,7 @@ const expectCertError = /^Error: unable to verify the first certificate$/;
const checkRequest = (socket, server) => {
let result = '';
socket.on('connect', common.mustCall((data) => {
socket.write('GET / HTTP/1.1\r\n\r\n');
socket.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
socket.end();
}));
socket.on('data', common.mustCall((chunk) => {

View File

@ -25,7 +25,7 @@ const httpsServer = https.createServer({
}
res.writeHead(200, {});
res.end('ok');
}, 9)).listen(0, common.mustCall(function(err) {
}, 6)).listen(0, common.mustCall(function(err) {
debug(`test https server listening on port ${this.address().port}`);
assert.ifError(err);
https.get({

View File

@ -37,6 +37,7 @@ const certFixture = {
serverSide.resume(); // Dump the request
serverSide.end('HTTP/1.1 200 OK\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'Content-Length: 0\r\n' +
'\r\n\r\n');
@ -55,6 +56,7 @@ const certFixture = {
serverSide.resume(); // Dump the request
serverSide.end('HTTP/1.1 200 OK\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'Content-Length: 0\r\n' +
'\r\n\r\n');
@ -81,6 +83,7 @@ const certFixture = {
});
client.write(
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'\r\n\r\n');
client.end();
@ -107,6 +110,7 @@ const certFixture = {
});
client.write(
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: foo\x08foo\r\n' +
'\r\n\r\n');
client.end();

View File

@ -13,7 +13,7 @@ const tls = require('tls');
const { readKey } = require('../common/fixtures');
function request(socket) {
socket.write('GET / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n\r\n');
socket.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n\r\n');
}
// https options

View File

@ -38,6 +38,7 @@ const certFixture = {
serverSide.resume(); // Dump the request
serverSide.end('HTTP/1.1 200 OK\r\n' +
'Host: example.com\r\n' +
'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' +
'Content-Length: 0\r\n' +
'\r\n\r\n');
@ -55,6 +56,7 @@ const certFixture = {
serverSide.resume(); // Dump the request
serverSide.end('HTTP/1.1 200 OK\r\n' +
'Host: example.com\r\n' +
'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' +
'Content-Length: 0\r\n' +
'\r\n\r\n');
@ -81,6 +83,7 @@ const certFixture = {
});
client.write(
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' +
'\r\n\r\n');
client.end();
@ -107,6 +110,7 @@ const certFixture = {
});
client.write(
'GET / HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'Hello: ' + 'A'.repeat(http.maxHeaderSize * 3) + '\r\n' +
'\r\n\r\n');
client.end();

View File

@ -16,7 +16,9 @@ const serverOptions = {
let requests = 0;
let responses = 0;
const headers = {};
const headers = {
host: 'example.com'
};
const N = 100;
for (let i = 0; i < N; ++i) {
headers[`key${i}`] = i;
@ -45,8 +47,8 @@ server.maxHeadersCount = max;
server.listen(0, common.mustCall(() => {
const maxAndExpected = [ // for client
[20, 20],
[1200, 103],
[0, N + 3], // Connection, Date and Transfer-Encoding
[1200, 104],
[0, N + 4], // Host and Connection
];
const doRequest = common.mustCall(() => {
const max = maxAndExpected[responses][0];

View File

@ -60,7 +60,7 @@ server.listen(0, function() {
client2.on('close', common.mustCall());
client2.write('GET / HTTP/1.1\r\n\r\n');
client2.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
}));
client1.on('close', common.mustCall());

View File

@ -70,7 +70,7 @@ server.listen(0, function() {
client2Closed = true;
}));
client2.write('GET / HTTP/1.1\r\n\r\n');
client2.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n');
}));
client1.on('close', common.mustCall(() => {