improve logic

This commit is contained in:
Rishi Raj Jain 2023-09-28 00:51:46 +05:30
parent f3062b74fe
commit cda779f97e
2 changed files with 33 additions and 26 deletions

View file

@ -29,30 +29,21 @@ export function createServer(
) { ) {
const listener: http.RequestListener = (req, res) => { const listener: http.RequestListener = (req, res) => {
if (req.url) { if (req.url) {
let pathname: string | undefined = removeBase(req.url); let pathname: string = removeBase(req.url);
pathname = pathname[0] === '/' ? pathname : '/' + pathname; pathname = pathname[0] === '/' ? pathname : '/' + pathname;
let encodedURI = parsePathname(pathname, host, port); const pathnameWithSlash = pathname.endsWith('/') ? pathname : pathname + '/';
const pathnameWithoutSlash = pathname.endsWith('/')
? pathname.substring(0, pathname.length - 1)
: pathname;
// Ensure that the url always has the directory path
let pathToSend = parsePathname(pathnameWithSlash, host, port);
if (!encodedURI) { if (!pathToSend) {
res.writeHead(400); res.writeHead(400);
res.end('Bad request.'); res.end('Bad request.');
return res; return res;
} }
let pathToSend = encodedURI;
if (trailingSlash === 'never') {
if (pathname.endsWith('/')) {
encodedURI = parsePathname(pathname.substring(0, pathname.length - 1), host, port);
if (!encodedURI) {
res.writeHead(400);
res.end('Bad request.');
return res;
}
}
pathToSend = encodedURI + '/';
}
const stream = send(req, pathToSend, { const stream = send(req, pathToSend, {
root: fileURLToPath(client), root: fileURLToPath(client),
dotfiles: pathname.startsWith('/.well-known/') ? 'allow' : 'deny', dotfiles: pathname.startsWith('/.well-known/') ? 'allow' : 'deny',
@ -71,20 +62,35 @@ export function createServer(
handler(req, res); handler(req, res);
}); });
stream.on('directory', () => { stream.on('directory', () => {
// On directory find, redirect to the trailing slash let location: URL;
let location: string;
if (req.url!.includes('?')) { if (req.url!.includes('?')) {
const [url = '', search] = req.url!.split('?'); const [url = '', search] = req.url!.split('?');
location = `${url}/?${search}`; location = new URL(`${url}/?${search}`);
} else { } else {
location = req.url + '/'; location = new URL(req.url + '/');
} }
switch (trailingSlash) {
if (!pathToSend.endsWith('/')) { case 'never': {
// Redirect to a url with no trailingSlash if the incoming url had a trailingSlash
if (pathname.endsWith('/')) {
res.statusCode = 301; res.statusCode = 301;
res.setHeader('Location', location); location.pathname = pathnameWithoutSlash;
res.setHeader('Location', location.toString());
res.end(location); res.end(location);
} }
break;
}
case 'always': {
// Redirect to a url with trailingSlash if the incoming url did not have a trailingSlash
if (!pathname.endsWith('/')) {
res.statusCode = 301;
location.pathname = pathnameWithSlash;
res.setHeader('Location', location.toString());
res.end(location);
}
break;
}
}
}); });
stream.on('file', () => { stream.on('file', () => {
forwardError = true; forwardError = true;

View file

@ -45,6 +45,7 @@ describe('Trailing Slash In Production', () => {
it('redirects each route to have trailing slash', async () => { it('redirects each route to have trailing slash', async () => {
const res = await fetch(`http://${server.host}:${server.port}/one`); const res = await fetch(`http://${server.host}:${server.port}/one`);
expect(res.url).to.contain('one/'); expect(res.url).to.contain('one/');
expect(res.status).to.equal(301);
}); });
}); });