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 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)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
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