1
0
Fork 0
forked from svrjs/svrjs

Changed URL parser from WHATWG to custom one and adapted code accordingly

This commit is contained in:
Dorian Niemiec 2024-08-27 18:03:47 +02:00
parent f247e7a035
commit 8589f0a6e4
8 changed files with 39 additions and 28 deletions

View file

@ -8,6 +8,8 @@ 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 matchHostname = require("../utils/matchHostname.js");
const generateServerString = require("../utils/generateServerString.js"); const generateServerString = require("../utils/generateServerString.js");
const parseURL = require("../utils/urlParser.js");
let serverconsole = {}; let serverconsole = {};
let middleware = []; let middleware = [];
@ -695,7 +697,7 @@ function requestHandler(req, res) {
} }
try { try {
req.parsedURL = new URL( req.parsedURL = parseURL(
req.url, req.url,
"http" + "http" +
(req.socket.encrypted ? "s" : "") + (req.socket.encrypted ? "s" : "") +

View file

@ -20,8 +20,8 @@ module.exports = (req, res, logFacilities, config, next) => {
res.redirect( res.redirect(
req.originalParsedURL.pathname + req.originalParsedURL.pathname +
"/" + "/" +
req.parsedURL.search + (req.parsedURL.search ? req.parsedURL.search : "") +
req.parsedURL.hash, (req.parsedURL.hash ? req.parsedURL.hash : ""),
); );
} }
}); });

View file

@ -3,6 +3,7 @@ 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"); const matchHostname = require("../utils/matchHostname.js");
const parseURL = require("../utils/urlParser.js");
module.exports = (req, res, logFacilities, config, next) => { module.exports = (req, res, logFacilities, config, next) => {
try { try {
@ -90,7 +91,7 @@ module.exports = (req, res, logFacilities, config, next) => {
logFacilities.resmessage(`URL rewritten: ${req.url} => ${rewrittenURL}`); logFacilities.resmessage(`URL rewritten: ${req.url} => ${rewrittenURL}`);
req.url = rewrittenURL; req.url = rewrittenURL;
try { try {
req.parsedURL = new URL( req.parsedURL = parseURL(
req.url, req.url,
`http${req.socket.encrypted ? "s" : ""}://${ `http${req.socket.encrypted ? "s" : ""}://${
req.headers.host req.headers.host
@ -110,7 +111,9 @@ module.exports = (req, res, logFacilities, config, next) => {
config.allowDoubleSlashes, config.allowDoubleSlashes,
); );
const preparedReqUrl2 = const preparedReqUrl2 =
req.parsedURL.pathname + req.parsedURL.search + req.parsedURL.hash; req.parsedURL.pathname +
(req.parsedURL.search ? req.parsedURL.search : "") +
(req.parsedURL.hash ? req.parsedURL.hash : "");
if ( if (
req.url != preparedReqUrl2 || req.url != preparedReqUrl2 ||
@ -124,13 +127,15 @@ module.exports = (req, res, logFacilities, config, next) => {
return; return;
} else if (sHref != req.parsedURL.pathname) { } else if (sHref != req.parsedURL.pathname) {
var rewrittenAgainURL = var rewrittenAgainURL =
sHref + req.parsedURL.search + req.parsedURL.hash; sHref +
(req.parsedURL.search ? req.parsedURL.search : "") +
(req.parsedURL.hash ? req.parsedURL.hash : "");
logFacilities.resmessage( logFacilities.resmessage(
"URL sanitized: " + req.url + " => " + rewrittenAgainURL, "URL sanitized: " + req.url + " => " + rewrittenAgainURL,
); );
req.url = rewrittenAgainURL; req.url = rewrittenAgainURL;
try { try {
req.parsedURL = new URL( req.parsedURL = parseURL(
req.url, req.url,
`http${req.socket.encrypted ? "s" : ""}://${ `http${req.socket.encrypted ? "s" : ""}://${
req.headers.host req.headers.host

View file

@ -1,4 +1,5 @@
const sanitizeURL = require("../utils/urlSanitizer.js"); const sanitizeURL = require("../utils/urlSanitizer.js");
const parseURL = require("../utils/urlParser.js");
module.exports = (req, res, logFacilities, config, next) => { module.exports = (req, res, logFacilities, config, next) => {
// Sanitize URL // Sanitize URL
@ -7,17 +8,21 @@ module.exports = (req, res, logFacilities, config, next) => {
config.allowDoubleSlashes, config.allowDoubleSlashes,
); );
let preparedReqUrl = let preparedReqUrl =
req.parsedURL.pathname + req.parsedURL.search + req.parsedURL.hash; req.parsedURL.pathname +
(req.parsedURL.search ? req.parsedURL.search : "") +
(req.parsedURL.hash ? req.parsedURL.hash : "");
// Check if URL is "dirty" // Check if URL is "dirty"
if (req.parsedURL.pathname != sanitizedHref && !req.isProxy) { if (req.parsedURL.pathname != sanitizedHref && !req.isProxy) {
let sanitizedURL = let sanitizedURL =
sanitizedHref + req.parsedURL.search + req.parsedURL.hash; sanitizedHref +
(req.parsedURL.search ? req.parsedURL.search : "") +
(req.parsedURL.hash ? req.parsedURL.hash : "");
logFacilities.resmessage(`URL sanitized: ${req.url} => ${sanitizedURL}`); logFacilities.resmessage(`URL sanitized: ${req.url} => ${sanitizedURL}`);
if (config.rewriteDirtyURLs) { if (config.rewriteDirtyURLs) {
req.url = sanitizedURL; req.url = sanitizedURL;
try { try {
req.parsedURL = new URL( req.parsedURL = parseURL(
req.url, req.url,
`http${req.socket.encrypted ? "s" : ""}://${ `http${req.socket.encrypted ? "s" : ""}://${
req.headers.host req.headers.host

View file

@ -1,6 +1,7 @@
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 parseURL = require("../utils/urlParser.js");
module.exports = (req, res, logFacilities, config, next) => { module.exports = (req, res, logFacilities, config, next) => {
const matchHostname = (hostname) => { const matchHostname = (hostname) => {
@ -30,8 +31,8 @@ module.exports = (req, res, logFacilities, config, next) => {
if (!req.isProxy) { if (!req.isProxy) {
let preparedReqUrl3 = config.allowPostfixDoubleSlashes let preparedReqUrl3 = config.allowPostfixDoubleSlashes
? req.parsedURL.pathname.replace(/\/+/, "/") + ? req.parsedURL.pathname.replace(/\/+/, "/") +
req.parsedURL.search + (req.parsedURL.search ? req.parsedURL.search : "") +
req.parsedURL.hash (req.parsedURL.hash ? req.parsedURL.hash : "")
: req.url; : req.url;
let urlWithPostfix = preparedReqUrl3; let urlWithPostfix = preparedReqUrl3;
let postfixPrefix = ""; let postfixPrefix = "";
@ -78,7 +79,7 @@ module.exports = (req, res, logFacilities, config, next) => {
); );
req.url = urlWithPostfix; req.url = urlWithPostfix;
try { try {
req.parsedURL = new URL( req.parsedURL = parseURL(
req.url, req.url,
`http${req.socket.encrypted ? "s" : ""}://${ `http${req.socket.encrypted ? "s" : ""}://${
req.headers.host req.headers.host
@ -98,7 +99,9 @@ module.exports = (req, res, logFacilities, config, next) => {
config.allowDoubleSlashes, config.allowDoubleSlashes,
); );
const preparedReqUrl2 = const preparedReqUrl2 =
req.parsedURL.pathname + req.parsedURL.search + req.parsedURL.hash; req.parsedURL.pathname +
(req.parsedURL.search ? req.parsedURL.search : "") +
(req.parsedURL.hash ? req.parsedURL.hash : "");
if ( if (
req.url != preparedReqUrl2 || req.url != preparedReqUrl2 ||
@ -112,13 +115,15 @@ module.exports = (req, res, logFacilities, config, next) => {
return; return;
} else if (sHref != req.parsedURL.pathname) { } else if (sHref != req.parsedURL.pathname) {
let rewrittenAgainURL = let rewrittenAgainURL =
sHref + req.parsedURL.search + req.parsedURL.hash; sHref +
(req.parsedURL.search ? req.parsedURL.search : "") +
(req.parsedURL.hash ? req.parsedURL.hash : "");
logFacilities.resmessage( logFacilities.resmessage(
`URL sanitized: ${req.url} => ${rewrittenAgainURL}`, `URL sanitized: ${req.url} => ${rewrittenAgainURL}`,
); );
req.url = rewrittenAgainURL; req.url = rewrittenAgainURL;
try { try {
req.parsedURL = new URL( req.parsedURL = parseURL(
req.url, req.url,
`http${req.socket.encrypted ? "s" : ""}://${ `http${req.socket.encrypted ? "s" : ""}://${
req.headers.host req.headers.host

View file

@ -1,4 +1,3 @@
const parseURL = require("../utils/urlParserLegacy.js");
let formidable = undefined; let formidable = undefined;
try { try {
formidable = require("formidable"); formidable = require("formidable");
@ -8,16 +7,11 @@ try {
}; };
} }
const legacyParsedURLSymbol = Symbol("legacyParsedURL");
module.exports = (legacyMod) => { module.exports = (legacyMod) => {
const legacyModHandler = new legacyMod(); const legacyModHandler = new legacyMod();
let middleware = (req, res, logFacilities, config, next) => { let middleware = (req, res, logFacilities, config, next) => {
if (!req[legacyParsedURLSymbol]) let ext = req.parsedURL.pathname.match(/[^/]\.([^.]+)$/);
req[legacyParsedURLSymbol] = parseURL(req.url);
let ext = req[legacyParsedURLSymbol].pathname.match(/[^/]\.([^.]+)$/);
if (!ext) ext = ""; if (!ext) ext = "";
// Function to parse incoming POST data from the request // Function to parse incoming POST data from the request
@ -66,10 +60,10 @@ module.exports = (legacyMod) => {
res, // res res, // res
logFacilities, // serverconsole logFacilities, // serverconsole
res.responseEnd, // responseEnd res.responseEnd, // responseEnd
req[legacyParsedURLSymbol].pathname, // href req.parsedURL.pathname, // href
ext, // ext ext, // ext
req[legacyParsedURLSymbol], // uobject req.parsedURL, // uobject
req[legacyParsedURLSymbol].search, // search req.parsedURL.search, // search
"index.html", // defaultpage "index.html", // defaultpage
config.users, // users config.users, // users
config.page404, // page404 config.page404, // page404

View file

@ -1,6 +1,6 @@
const parseURL = require("../../src/utils/urlParserLegacy.js"); const parseURL = require("../../src/utils/urlParser.js");
describe("URL parser (for SVR.JS 2.x and 3.x mods)", () => { describe("URL parser", () => {
test("should parse a simple URL", () => { test("should parse a simple URL", () => {
const parsedUrl = parseURL("http://example.com"); const parsedUrl = parseURL("http://example.com");
expect(parsedUrl.protocol).toBe("http:"); expect(parsedUrl.protocol).toBe("http:");