mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 10:03:31 +00:00
Normalize the URL by redirecting (#141)
This commit is contained in:
@@ -64,4 +64,30 @@ describe('getURLLookupAlternatives', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should normalize duplicated slashes', () => {
|
||||
expect(getURLLookupAlternatives(new URL('https://docs.mycompany.com//hello'))).toEqual([
|
||||
{
|
||||
extraPath: 'hello',
|
||||
url: 'https://docs.mycompany.com/',
|
||||
},
|
||||
{
|
||||
extraPath: '',
|
||||
url: 'https://docs.mycompany.com/hello',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should normalize trailing slash', () => {
|
||||
expect(getURLLookupAlternatives(new URL('https://docs.mycompany.com/hello/'))).toEqual([
|
||||
{
|
||||
extraPath: 'hello',
|
||||
url: 'https://docs.mycompany.com/',
|
||||
},
|
||||
{
|
||||
extraPath: '',
|
||||
url: 'https://docs.mycompany.com/hello',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
+11
-1
@@ -2,7 +2,8 @@
|
||||
* For a given GitBook URL, return a list of alternative URLs that could be matched against to lookup the content.
|
||||
* The approach is optimized to aim at reusing cached lookup results as much as possible.
|
||||
*/
|
||||
export function getURLLookupAlternatives(url: URL) {
|
||||
export function getURLLookupAlternatives(input: URL) {
|
||||
const url = normalizeURL(input);
|
||||
const alternatives: Array<{ url: string; extraPath: string }> = [];
|
||||
|
||||
const pushAlternative = (url: URL, extraPath: string) => {
|
||||
@@ -85,3 +86,12 @@ export function getURLLookupAlternatives(url: URL) {
|
||||
|
||||
return alternatives;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a URL to remove duplicate slashes and trailing slashes
|
||||
*/
|
||||
export function normalizeURL(url: URL) {
|
||||
const result = new URL(url);
|
||||
result.pathname = url.pathname.replace(/\/{2,}/g, '/').replace(/\/$/, '');
|
||||
return result;
|
||||
}
|
||||
|
||||
+8
-3
@@ -12,10 +12,9 @@ import {
|
||||
userAgent,
|
||||
withAPI,
|
||||
} from '@/lib/api';
|
||||
import { buildVersion } from '@/lib/build';
|
||||
import { createContentSecurityPolicyNonce, getContentSecurityPolicy } from '@/lib/csp';
|
||||
|
||||
import { buildVersion } from './lib/build';
|
||||
import { getURLLookupAlternatives } from './lib/middleware';
|
||||
import { getURLLookupAlternatives, normalizeURL } from '@/lib/middleware';
|
||||
|
||||
export const config = {
|
||||
matcher:
|
||||
@@ -73,6 +72,12 @@ export async function middleware(request: NextRequest) {
|
||||
userAgent: userAgent(),
|
||||
});
|
||||
|
||||
// Redirect to normalize the URL
|
||||
const normalized = normalizeURL(url);
|
||||
if (normalized.toString() !== url.toString()) {
|
||||
return NextResponse.redirect(normalized.toString());
|
||||
}
|
||||
|
||||
// The visitor authentication can either be passed as a query parameter
|
||||
// or can be stored in a cookie after the initial auth.
|
||||
const visitorAuthToken =
|
||||
|
||||
Reference in New Issue
Block a user