Skip to content
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,18 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {

let handled = false;


if (req.httpVersionMajor === 1 && req.httpVersionMinor === 1) {
Comment thread
marco-ippolito marked this conversation as resolved.

// 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 (req.headers.host === undefined) {
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
res.writeHead(400, ['Connection', 'close']);
res.end();
return 0;
}

const isRequestsLimitSet = (
typeof server.maxRequestsPerSocket === 'number' &&
server.maxRequestsPerSocket > 0
Expand All @@ -1045,7 +1056,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 {
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-chunked-304.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
17 changes: 13 additions & 4 deletions test/parallel/test-http-client-headers-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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'],
] });
6 changes: 3 additions & 3 deletions test/parallel/test-http-content-length.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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' });
Expand All @@ -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' });
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-header-badrequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-http-insecure-parser-per-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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');
Expand All @@ -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');
}
Expand All @@ -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');
}
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-http-insecure-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
);
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-http-keep-alive-drop-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-http-keep-alive-max-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-malformed-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
1 change: 1 addition & 0 deletions test/parallel/test-http-max-header-size-per-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down
8 changes: 5 additions & 3 deletions test/parallel/test-http-max-headers-count.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-pipeline-assertionerror-finish.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-http-req-close-robust-from-tampering.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ server.listen(0, common.mustCall(() => {

const req = [
'POST / HTTP/1.1',
'Host: example.com',
'Content-Length: 11',
'',
'hello world',
Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-http-request-host-header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'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();
}));
});
}));
2 changes: 1 addition & 1 deletion test/parallel/test-http-response-splitting.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-server-close-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-server-close-idle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: ');
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-http-server-headers-timeout-pipelining.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-http-server-keep-alive-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: ');
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-http-server-request-timeout-pipelining.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
Loading