improve logic
This commit is contained in:
parent
f3062b74fe
commit
cda779f97e
2 changed files with 33 additions and 26 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue