1
0
Fork 0
forked from svrjs/svrjs

Move matchHostname function to separate source file, and add unit tests for the function.

This commit is contained in:
Dorian Niemiec 2024-08-24 17:21:09 +02:00
parent 519e68465a
commit f48125f4f2
4 changed files with 80 additions and 49 deletions

View file

@ -6,6 +6,7 @@ const generateServerString = require("../utils/generateServerString.js");
const serverHTTPErrorDescs = require("../res/httpErrorDescriptions.js"); const serverHTTPErrorDescs = require("../res/httpErrorDescriptions.js");
const fixNodeMojibakeURL = require("../utils/urlMojibakeFixer.js"); const fixNodeMojibakeURL = require("../utils/urlMojibakeFixer.js");
const ipMatch = require("../utils/ipMatch.js"); const ipMatch = require("../utils/ipMatch.js");
const matchHostname = require("../utils/matchHostname.js");
const svrjsInfo = require("../../svrjs.json"); const svrjsInfo = require("../../svrjs.json");
const version = svrjsInfo.version; const version = svrjsInfo.version;
@ -14,29 +15,6 @@ if (!process.err5xxcounter) process.err5xxcounter = 0;
if (!process.reqcounter) process.reqcounter = 0; if (!process.reqcounter) process.reqcounter = 0;
module.exports = (req, res, logFacilities, config, next) => { module.exports = (req, res, logFacilities, config, next) => {
const matchHostname = (hostname) => {
if (typeof hostname == "undefined" || hostname == "*") {
return true;
} else if (
req.headers.host &&
hostname.indexOf("*.") == 0 &&
hostname != "*."
) {
const hostnamesRoot = hostname.substring(2);
if (
req.headers.host == hostnamesRoot ||
(req.headers.host.length > hostnamesRoot.length &&
req.headers.host.indexOf("." + hostnamesRoot) ==
req.headers.host.length - hostnamesRoot.length - 1)
) {
return true;
}
} else if (req.headers.host && req.headers.host == hostname) {
return true;
}
return false;
};
config.generateServerString = () => { config.generateServerString = () => {
return generateServerString(config.exposeServerVersion); return generateServerString(config.exposeServerVersion);
}; };
@ -48,7 +26,7 @@ module.exports = (req, res, logFacilities, config, next) => {
let vhostP = null; let vhostP = null;
config.customHeadersVHost.every(function (vhost) { config.customHeadersVHost.every(function (vhost) {
if ( if (
matchHostname(vhost.host) && matchHostname(vhost.host, req.headers.host) &&
ipMatch(vhost.ip, req.socket ? req.socket.localAddress : undefined) ipMatch(vhost.ip, req.socket ? req.socket.localAddress : undefined)
) { ) {
vhostP = vhost; vhostP = vhost;
@ -398,7 +376,7 @@ module.exports = (req, res, logFacilities, config, next) => {
if ( if (
list[_i].scode != errorCode || list[_i].scode != errorCode ||
!( !(
matchHostname(list[_i].host) && matchHostname(list[_i].host, req.headers.host) &&
ipMatch(list[_i].ip, req.socket ? req.socket.localAddress : undefined) ipMatch(list[_i].ip, req.socket ? req.socket.localAddress : undefined)
) )
) { ) {

View file

@ -3,6 +3,7 @@ const url = require("url");
const createRegex = require("../utils/createRegex.js"); const createRegex = require("../utils/createRegex.js");
const ipMatch = require("../utils/ipMatch.js"); const ipMatch = require("../utils/ipMatch.js");
const sanitizeURL = require("../utils/urlSanitizer.js"); const sanitizeURL = require("../utils/urlSanitizer.js");
const matchHostname = require("../utils/matchHostname.js");
module.exports = (req, res, logFacilities, config, next) => { module.exports = (req, res, logFacilities, config, next) => {
try { try {
@ -11,29 +12,6 @@ module.exports = (req, res, logFacilities, config, next) => {
res.error(400); res.error(400);
} }
const matchHostname = (hostname) => {
if (typeof hostname == "undefined" || hostname == "*") {
return true;
} else if (
req.headers.host &&
hostname.indexOf("*.") == 0 &&
hostname != "*."
) {
const hostnamesRoot = hostname.substring(2);
if (
req.headers.host == hostnamesRoot ||
(req.headers.host.length > hostnamesRoot.length &&
req.headers.host.indexOf("." + hostnamesRoot) ==
req.headers.host.length - hostnamesRoot.length - 1)
) {
return true;
}
} else if (req.headers.host && req.headers.host == hostname) {
return true;
}
return false;
};
// Handle URL rewriting // Handle URL rewriting
const rewriteURL = (address, map, callback, _fileState, _mapBegIndex) => { const rewriteURL = (address, map, callback, _fileState, _mapBegIndex) => {
let rewrittenURL = address; let rewrittenURL = address;
@ -71,7 +49,7 @@ module.exports = (req, res, logFacilities, config, next) => {
tempRewrittenURL = address; tempRewrittenURL = address;
} }
if ( if (
matchHostname(mapEntry.host) && matchHostname(mapEntry.host, req.headers.host) &&
ipMatch( ipMatch(
mapEntry.ip, mapEntry.ip,
req.socket ? req.socket.localAddress : undefined, req.socket ? req.socket.localAddress : undefined,

View file

@ -0,0 +1,24 @@
function matchHostname(hostname, reqHostname) {
if (typeof hostname == "undefined" || hostname == "*") {
return true;
} else if (
reqHostname &&
hostname.indexOf("*.") == 0 &&
hostname != "*."
) {
const hostnamesRoot = hostname.substring(2);
if (
reqHostname == hostnamesRoot ||
(reqHostname.length > hostnamesRoot.length &&
reqHostname.indexOf("." + hostnamesRoot) ==
reqHostname.length - hostnamesRoot.length - 1)
) {
return true;
}
} else if (reqHostname && reqHostname == hostname) {
return true;
}
return false;
};
module.exports = matchHostname;

View file

@ -0,0 +1,51 @@
const matchHostname = require('../../src/utils/matchHostname');
describe('matchHostname', () => {
test('should return true if hostname is undefined', () => {
expect(matchHostname(undefined, 'example.com')).toBe(true);
});
test('should return true if hostname is "*"', () => {
expect(matchHostname('*', 'example.com')).toBe(true);
});
test('should return true if reqHostname matches hostname exactly', () => {
expect(matchHostname('example.com', 'example.com')).toBe(true);
});
test('should return false if reqHostname does not match hostname exactly', () => {
expect(matchHostname('example.com', 'example.org')).toBe(false);
});
test('should return true if hostname starts with "*." and reqHostname matches the root', () => {
expect(matchHostname('*.example.com', 'sub.example.com')).toBe(true);
});
test('should return false if hostname starts with "*." and reqHostname does not match the root', () => {
expect(matchHostname('*.example.com', 'example.org')).toBe(false);
});
test('should return true if hostname starts with "*." and reqHostname is the root', () => {
expect(matchHostname('*.example.com', 'example.com')).toBe(true);
});
test('should return false if hostname is "*."', () => {
expect(matchHostname('*.', 'example.com')).toBe(false);
});
test('should return false if reqHostname is undefined', () => {
expect(matchHostname('example.com', undefined)).toBe(false);
});
test('should return false if hostname does not start with "*." and reqHostname does not match', () => {
expect(matchHostname('sub.example.com', 'example.com')).toBe(false);
});
test('should return true if hostname starts with "*." and reqHostname matches the root with additional subdomains', () => {
expect(matchHostname('*.example.com', 'sub.sub.example.com')).toBe(true);
});
test('should return false if hostname starts with "*." and reqHostname does not match the root with additional subdomains', () => {
expect(matchHostname('*.example.com', 'sub.sub.example.org')).toBe(false);
});
});