| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 71ff89f commit ed3604c
46 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3185,6 +3185,10 @@ changes: | |||
| 3185 | 3185 | * `uniqueHeaders` {Array} A list of response headers that should be sent only | |
| 3186 | 3186 | once. If the header's value is an array, the items will be joined | |
| 3187 | 3187 | using `; `. | |
| 3188 | + * `requireHostHeader` {boolean} It forces the server to respond with | ||
| 3189 | + a 400 (Bad Request) status code to any HTTP/1.1 request message | ||
| 3190 | + that lacks a Host header (as mandated by the specification). | ||
| 3191 | + **Default:** `true`. | ||
| 3188 | 3192 | ||
| 3189 | 3193 | * `requestListener` {Function} | |
| 3190 | 3194 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -473,6 +473,14 @@ function storeHTTPOptions(options) { | |||
| 473 | 473 | } else { | |
| 474 | 474 | this.connectionsCheckingInterval = 30_000; // 30 seconds | |
| 475 | 475 | } | |
| 476 | + | ||
| 477 | + const requireHostHeader = options.requireHostHeader; | ||
| 478 | + if (requireHostHeader !== undefined) { | ||
| 479 | + validateBoolean(requireHostHeader, 'options.requireHostHeader'); | ||
| 480 | + this.requireHostHeader = requireHostHeader; | ||
| 481 | + } else { | ||
| 482 | + this.requireHostHeader = true; | ||
| 483 | + } | ||
| 476 | 484 | } | |
| 477 | 485 | ||
| 478 | 486 | function setupConnectionsTracking(server) { | |
@@ -1022,7 +1030,18 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { | |||
| 1022 | 1030 | ||
| 1023 | 1031 | let handled = false; | |
| 1024 | 1032 | ||
| 1033 | + | ||
| 1025 | 1034 | if (req.httpVersionMajor === 1 && req.httpVersionMinor === 1) { | |
| 1035 | + | ||
| 1036 | + // From RFC 7230 5.4 https://datatracker.ietf.org/doc/html/rfc7230#section-5.4 | ||
| 1037 | + // A server MUST respond with a 400 (Bad Request) status code to any | ||
| 1038 | + // HTTP/1.1 request message that lacks a Host header field | ||
| 1039 | + if (server.requireHostHeader && req.headers.host === undefined) { | ||
| 1040 | + res.writeHead(400, ['Connection', 'close']); | ||
| 1041 | + res.end(); | ||
| 1042 | + return 0; | ||
| 1043 | + } | ||
| 1044 | + | ||
| 1026 | 1045 | const isRequestsLimitSet = ( | |
| 1027 | 1046 | typeof server.maxRequestsPerSocket === 'number' && | |
| 1028 | 1047 | server.maxRequestsPerSocket > 0 | |
@@ -1045,7 +1064,6 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { | |||
| 1045 | 1064 | ||
| 1046 | 1065 | if (RegExpPrototypeExec(continueExpression, req.headers.expect) !== null) { | |
| 1047 | 1066 | res._expect_continue = true; | |
| 1048 | - | ||
| 1049 | 1067 | if (server.listenerCount('checkContinue') > 0) { | |
| 1050 | 1068 | server.emit('checkContinue', req, res); | |
| 1051 | 1069 | } else { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -52,6 +52,7 @@ let maxHeaderSize; | |||
| 52 | 52 | * ServerResponse?: ServerResponse; | |
| 53 | 53 | * insecureHTTPParser?: boolean; | |
| 54 | 54 | * maxHeaderSize?: number; | |
| 55 | + * requireHostHeader?: boolean | ||
| 55 | 56 | * }} [opts] | |
| 56 | 57 | * @param {Function} [requestListener] | |
| 57 | 58 | * @returns {Server} | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,7 +47,7 @@ function test(statusCode) { | |||
| 47 | 47 | const conn = net.createConnection( | |
| 48 | 48 | server.address().port, | |
| 49 | 49 | common.mustCall(() => { | |
| 50 | - conn.write('GET / HTTP/1.1\r\n\r\n'); | ||
| 50 | + conn.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'); | ||
| 51 | 51 | ||
| 52 | 52 | let resp = ''; | |
| 53 | 53 | conn.setEncoding('utf8'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,7 +10,8 @@ function execute(options) { | |||
| 10 | 10 | const expectHeaders = { | |
| 11 | 11 | 'x-foo': 'boom', | |
| 12 | 12 | 'cookie': 'a=1; b=2; c=3', | |
| 13 | - 'connection': 'keep-alive' | ||
| 13 | + 'connection': 'keep-alive', | ||
| 14 | + 'host': 'example.com', | ||
| 14 | 15 | }; | |
| 15 | 16 | ||
| 16 | 17 | // no Host header when you set headers an array | |
@@ -43,13 +44,20 @@ function execute(options) { | |||
| 43 | 44 | // Should be the same except for implicit Host header on the first two | |
| 44 | 45 | execute({ headers: { 'x-foo': 'boom', 'cookie': 'a=1; b=2; c=3' } }); | |
| 45 | 46 | execute({ headers: { 'x-foo': 'boom', 'cookie': [ 'a=1', 'b=2', 'c=3' ] } }); | |
| 46 | - execute({ headers: [[ 'x-foo', 'boom' ], [ 'cookie', 'a=1; b=2; c=3' ]] }); | ||
| 47 | 47 | execute({ headers: [ | |
| 48 | - [ 'x-foo', 'boom' ], [ 'cookie', [ 'a=1', 'b=2', 'c=3' ]], | ||
| 48 | + [ 'x-foo', 'boom' ], | ||
| 49 | + [ 'cookie', 'a=1; b=2; c=3' ], | ||
| 50 | + [ 'Host', 'example.com' ], | ||
| 51 | + ] }); | ||
| 52 | + execute({ headers: [ | ||
| 53 | + [ 'x-foo', 'boom' ], | ||
| 54 | + [ 'cookie', [ 'a=1', 'b=2', 'c=3' ]], | ||
| 55 | + [ 'Host', 'example.com' ], | ||
| 49 | 56 | ] }); | |
| 50 | 57 | execute({ headers: [ | |
| 51 | 58 | [ 'x-foo', 'boom' ], [ 'cookie', 'a=1' ], | |
| 52 | - [ 'cookie', 'b=2' ], [ 'cookie', 'c=3'], | ||
| 59 | + [ 'cookie', 'b=2' ], [ 'cookie', 'c=3' ], | ||
| 60 | + [ 'Host', 'example.com'], | ||
| 53 | 61 | ] }); | |
| 54 | 62 | ||
| 55 | 63 | // Authorization and Host header both missing from the second | |
@@ -58,4 +66,5 @@ execute({ auth: 'foo:bar', headers: | |||
| 58 | 66 | execute({ auth: 'foo:bar', headers: [ | |
| 59 | 67 | [ 'x-foo', 'boom' ], [ 'cookie', 'a=1' ], | |
| 60 | 68 | [ 'cookie', 'b=2' ], [ 'cookie', 'c=3'], | |
| 69 | + [ 'Host', 'example.com'], | ||
| 61 | 70 | ] }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,15 +28,18 @@ const server = http.createServer(function(req, res) { | |||
| 28 | 28 | ||
| 29 | 29 | switch (req.url.substr(1)) { | |
| 30 | 30 | case 'multiple-writes': | |
| 31 | + delete req.headers.host; | ||
| 31 | 32 | assert.deepStrictEqual(req.headers, expectedHeadersMultipleWrites); | |
| 32 | 33 | res.write('hello'); | |
| 33 | 34 | res.end('world'); | |
| 34 | 35 | break; | |
| 35 | 36 | case 'end-with-data': | |
| 37 | + delete req.headers.host; | ||
| 36 | 38 | assert.deepStrictEqual(req.headers, expectedHeadersEndWithData); | |
| 37 | 39 | res.end('hello world'); | |
| 38 | 40 | break; | |
| 39 | 41 | case 'empty': | |
| 42 | + delete req.headers.host; | ||
| 40 | 43 | assert.deepStrictEqual(req.headers, expectedHeadersEndNoData); | |
| 41 | 44 | res.end(); | |
| 42 | 45 | break; | |
@@ -56,7 +59,6 @@ server.listen(0, function() { | |||
| 56 | 59 | path: '/multiple-writes' | |
| 57 | 60 | }); | |
| 58 | 61 | req.removeHeader('Date'); | |
| 59 | - req.removeHeader('Host'); | ||
| 60 | 62 | req.write('hello '); | |
| 61 | 63 | req.end('world'); | |
| 62 | 64 | req.on('response', function(res) { | |
@@ -70,7 +72,6 @@ server.listen(0, function() { | |||
| 70 | 72 | path: '/end-with-data' | |
| 71 | 73 | }); | |
| 72 | 74 | req.removeHeader('Date'); | |
| 73 | - req.removeHeader('Host'); | ||
| 74 | 75 | req.end('hello world'); | |
| 75 | 76 | req.on('response', function(res) { | |
| 76 | 77 | assert.deepStrictEqual(res.headers, { ...expectedHeadersEndWithData, 'keep-alive': 'timeout=1' }); | |
@@ -83,7 +84,6 @@ server.listen(0, function() { | |||
| 83 | 84 | path: '/empty' | |
| 84 | 85 | }); | |
| 85 | 86 | req.removeHeader('Date'); | |
| 86 | - req.removeHeader('Host'); | ||
| 87 | 87 | req.end(); | |
| 88 | 88 | req.on('response', function(res) { | |
| 89 | 89 | assert.deepStrictEqual(res.headers, { ...expectedHeadersEndNoData, 'keep-alive': 'timeout=1' }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,7 +17,7 @@ server.listen(0, mustCall(() => { | |||
| 17 | 17 | let received = ''; | |
| 18 | 18 | ||
| 19 | 19 | c.on('connect', mustCall(() => { | |
| 20 | - c.write('GET /blah HTTP/1.1\r\n\r\n'); | ||
| 20 | + c.write('GET /blah HTTP/1.1\r\nHost: example.com\r\n\r\n'); | ||
| 21 | 21 | })); | |
| 22 | 22 | c.on('data', mustCall((data) => { | |
| 23 | 23 | received += data.toString(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,6 +22,7 @@ const MakeDuplexPair = require('../common/duplexpair'); | |||
| 22 | 22 | ||
| 23 | 23 | serverSide.resume(); // Dump the request | |
| 24 | 24 | serverSide.end('HTTP/1.1 200 OK\r\n' + | |
| 25 | + 'Host: example.com\r\n' + | ||
| 25 | 26 | 'Hello: foo\x08foo\r\n' + | |
| 26 | 27 | 'Content-Length: 0\r\n' + | |
| 27 | 28 | '\r\n\r\n'); | |
@@ -39,6 +40,7 @@ const MakeDuplexPair = require('../common/duplexpair'); | |||
| 39 | 40 | ||
| 40 | 41 | serverSide.resume(); // Dump the request | |
| 41 | 42 | serverSide.end('HTTP/1.1 200 OK\r\n' + | |
| 43 | + 'Host: example.com\r\n' + | ||
| 42 | 44 | 'Hello: foo\x08foo\r\n' + | |
| 43 | 45 | 'Content-Length: 0\r\n' + | |
| 44 | 46 | '\r\n\r\n'); | |
@@ -62,6 +64,7 @@ const MakeDuplexPair = require('../common/duplexpair'); | |||
| 62 | 64 | server.emit('connection', serverSide); | |
| 63 | 65 | ||
| 64 | 66 | clientSide.write('GET / HTTP/1.1\r\n' + | |
| 67 | + 'Host: example.com\r\n' + | ||
| 65 | 68 | 'Hello: foo\x08foo\r\n' + | |
| 66 | 69 | '\r\n\r\n'); | |
| 67 | 70 | } | |
@@ -77,6 +80,7 @@ const MakeDuplexPair = require('../common/duplexpair'); | |||
| 77 | 80 | server.emit('connection', serverSide); | |
| 78 | 81 | ||
| 79 | 82 | clientSide.write('GET / HTTP/1.1\r\n' + | |
| 83 | + 'Host: example.com\r\n' + | ||
| 80 | 84 | 'Hello: foo\x08foo\r\n' + | |
| 81 | 85 | '\r\n\r\n'); | |
| 82 | 86 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,6 +19,7 @@ server.listen(0, common.mustCall(function() { | |||
| 19 | 19 | client.write( | |
| 20 | 20 | 'GET / HTTP/1.1\r\n' + | |
| 21 | 21 | 'Content-Type: text/te\x08t\r\n' + | |
| 22 | + 'Host: example.com' + | ||
| 22 | 23 | 'Connection: close\r\n\r\n'); | |
| 23 | 24 | } | |
| 24 | 25 | ); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,6 +8,7 @@ const assert = require('assert'); | |||
| 8 | 8 | function request(socket) { | |
| 9 | 9 | socket.write('GET / HTTP/1.1\r\n'); | |
| 10 | 10 | socket.write('Connection: keep-alive\r\n'); | |
| 11 | + socket.write('Host: localhost\r\n'); | ||
| 11 | 12 | socket.write('\r\n\r\n'); | |
| 12 | 13 | } | |
| 13 | 14 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments