forked from svrjs/svrjs
Move matchHostname function to separate source file, and add unit tests for the function.
This commit is contained in:
parent
519e68465a
commit
f48125f4f2
4 changed files with 80 additions and 49 deletions
|
@ -6,6 +6,7 @@ const generateServerString = require("../utils/generateServerString.js");
|
|||
const serverHTTPErrorDescs = require("../res/httpErrorDescriptions.js");
|
||||
const fixNodeMojibakeURL = require("../utils/urlMojibakeFixer.js");
|
||||
const ipMatch = require("../utils/ipMatch.js");
|
||||
const matchHostname = require("../utils/matchHostname.js");
|
||||
const svrjsInfo = require("../../svrjs.json");
|
||||
const version = svrjsInfo.version;
|
||||
|
||||
|
@ -14,29 +15,6 @@ if (!process.err5xxcounter) process.err5xxcounter = 0;
|
|||
if (!process.reqcounter) process.reqcounter = 0;
|
||||
|
||||
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 = () => {
|
||||
return generateServerString(config.exposeServerVersion);
|
||||
};
|
||||
|
@ -48,7 +26,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
let vhostP = null;
|
||||
config.customHeadersVHost.every(function (vhost) {
|
||||
if (
|
||||
matchHostname(vhost.host) &&
|
||||
matchHostname(vhost.host, req.headers.host) &&
|
||||
ipMatch(vhost.ip, req.socket ? req.socket.localAddress : undefined)
|
||||
) {
|
||||
vhostP = vhost;
|
||||
|
@ -398,7 +376,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
if (
|
||||
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)
|
||||
)
|
||||
) {
|
||||
|
|
|
@ -3,6 +3,7 @@ const url = require("url");
|
|||
const createRegex = require("../utils/createRegex.js");
|
||||
const ipMatch = require("../utils/ipMatch.js");
|
||||
const sanitizeURL = require("../utils/urlSanitizer.js");
|
||||
const matchHostname = require("../utils/matchHostname.js");
|
||||
|
||||
module.exports = (req, res, logFacilities, config, next) => {
|
||||
try {
|
||||
|
@ -11,29 +12,6 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
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
|
||||
const rewriteURL = (address, map, callback, _fileState, _mapBegIndex) => {
|
||||
let rewrittenURL = address;
|
||||
|
@ -71,7 +49,7 @@ module.exports = (req, res, logFacilities, config, next) => {
|
|||
tempRewrittenURL = address;
|
||||
}
|
||||
if (
|
||||
matchHostname(mapEntry.host) &&
|
||||
matchHostname(mapEntry.host, req.headers.host) &&
|
||||
ipMatch(
|
||||
mapEntry.ip,
|
||||
req.socket ? req.socket.localAddress : undefined,
|
||||
|
|
24
src/utils/matchHostname.js
Normal file
24
src/utils/matchHostname.js
Normal 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;
|
51
tests/utils/matchHostname.test.js
Normal file
51
tests/utils/matchHostname.test.js
Normal 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);
|
||||
});
|
||||
});
|
Reference in a new issue