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) => {
|
||||
if (req.url) {
|
||||
let pathname: string | undefined = removeBase(req.url);
|
||||
let pathname: string = removeBase(req.url);
|
||||
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.end('Bad request.');
|
||||
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, {
|
||||
root: fileURLToPath(client),
|
||||
dotfiles: pathname.startsWith('/.well-known/') ? 'allow' : 'deny',
|
||||
|
@ -71,19 +62,34 @@ export function createServer(
|
|||
handler(req, res);
|
||||
});
|
||||
stream.on('directory', () => {
|
||||
// On directory find, redirect to the trailing slash
|
||||
let location: string;
|
||||
let location: URL;
|
||||
if (req.url!.includes('?')) {
|
||||
const [url = '', search] = req.url!.split('?');
|
||||
location = `${url}/?${search}`;
|
||||
location = new URL(`${url}/?${search}`);
|
||||
} else {
|
||||
location = req.url + '/';
|
||||
location = new URL(req.url + '/');
|
||||
}
|
||||
|
||||
if (!pathToSend.endsWith('/')) {
|
||||
res.statusCode = 301;
|
||||
res.setHeader('Location', location);
|
||||
res.end(location);
|
||||
switch (trailingSlash) {
|
||||
case 'never': {
|
||||
// Redirect to a url with no trailingSlash if the incoming url had a trailingSlash
|
||||
if (pathname.endsWith('/')) {
|
||||
res.statusCode = 301;
|
||||
location.pathname = pathnameWithoutSlash;
|
||||
res.setHeader('Location', location.toString());
|
||||
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', () => {
|
||||
|
|
|
@ -45,6 +45,7 @@ describe('Trailing Slash In Production', () => {
|
|||
it('redirects each route to have trailing slash', async () => {
|
||||
const res = await fetch(`http://${server.host}:${server.port}/one`);
|
||||
expect(res.url).to.contain('one/');
|
||||
expect(res.status).to.equal(301);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue