mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
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:
parent
71ff89f929
commit
ed3604cd64
@ -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}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -52,6 +52,7 @@ let maxHeaderSize;
|
||||
* ServerResponse?: ServerResponse;
|
||||
* insecureHTTPParser?: boolean;
|
||||
* maxHeaderSize?: number;
|
||||
* requireHostHeader?: boolean
|
||||
* }} [opts]
|
||||
* @param {Function} [requestListener]
|
||||
* @returns {Server}
|
||||
|
@ -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');
|
||||
|
@ -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'],
|
||||
] });
|
||||
|
@ -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' });
|
||||
|
@ -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();
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
);
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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`);
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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(
|
||||
|
@ -17,6 +17,7 @@ server.listen(0, common.mustCall(() => {
|
||||
|
||||
const req = [
|
||||
'POST / HTTP/1.1',
|
||||
'Host: example.com',
|
||||
'Content-Length: 11',
|
||||
'',
|
||||
'hello world',
|
||||
|
41
test/parallel/test-http-request-host-header.js
Normal file
41
test/parallel/test-http-request-host-header.js
Normal 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();
|
||||
}));
|
||||
});
|
||||
}));
|
||||
}
|
@ -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}`);
|
||||
|
@ -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());
|
||||
|
@ -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(() => {
|
||||
|
@ -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: ');
|
||||
|
@ -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(() => {
|
||||
|
@ -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`);
|
||||
|
@ -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`);
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
|
@ -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: ');
|
||||
|
@ -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(() => {
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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.');
|
||||
});
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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) => {
|
||||
|
@ -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({
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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];
|
||||
|
@ -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());
|
||||
|
@ -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(() => {
|
||||
|
Loading…
Reference in New Issue
Block a user