Skip to content

Commit 2ae76f9

Browse files
authored
Change how a site in proxy mode is resolved (#2890)
1 parent 685325c commit 2ae76f9

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

.changeset/lucky-pens-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'gitbook': patch
3+
---
4+
5+
Change how a site in proxy mode is resolved

packages/gitbook/src/lib/links.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ export async function getBasePath(): Promise<string> {
4545
export async function getHost(): Promise<string> {
4646
assertIsNotV2();
4747
const headersList = await headers();
48+
const mode = headersList.get('x-gitbook-mode');
49+
if (mode === 'proxy') {
50+
return headersList.get('x-forwarded-host') ?? '';
51+
}
52+
4853
return headersList.get('x-gitbook-host') ?? headersList.get('host') ?? '';
4954
}
5055

packages/gitbook/src/middleware.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { type ContentAPITokenPayload, CustomizationThemeMode, GitBookAPI } from '@gitbook/api';
1+
import {
2+
type ContentAPITokenPayload,
3+
CustomizationThemeMode,
4+
GitBookAPI,
5+
type PublishedSiteContent,
6+
} from '@gitbook/api';
27
import { setContext, setTag } from '@sentry/nextjs';
38
import { getURLLookupAlternatives, normalizeURL } from '@v2/lib/data';
49
import assertNever from 'assert-never';
@@ -181,7 +186,9 @@ export async function middleware(request: NextRequest) {
181186
headers.set('x-gitbook-origin-basepath', originBasePath);
182187
headers.set(
183188
'x-gitbook-basepath',
184-
mode === 'proxy' ? originBasePath : joinPath(originBasePath, resolved.basePath)
189+
mode === 'proxy'
190+
? getProxyModeBasePath(inputURL, resolved)
191+
: joinPath(originBasePath, resolved.basePath)
185192
);
186193
headers.set('x-gitbook-content-space', resolved.space);
187194
if ('site' in resolved) {
@@ -335,7 +342,10 @@ function getInputURL(request: NextRequest): {
335342
// to determine the site to serve.
336343
const xGitbookSite = request.headers.get('x-gitbook-site-url');
337344
if (xGitbookSite) {
338-
mode = 'proxy';
345+
return {
346+
mode: 'proxy',
347+
url: new URL(xGitbookSite),
348+
};
339349
}
340350

341351
return { url, mode };
@@ -400,16 +410,8 @@ async function lookupSiteInSingleMode(url: URL): Promise<LookupResult> {
400410
* GITBOOK_MODE=proxy
401411
* When proxying a site on a different base URL.
402412
*/
403-
async function lookupSiteInProxy(request: NextRequest, _url: URL): Promise<LookupResult> {
404-
const rawSiteUrl = request.headers.get('x-gitbook-site-url');
405-
if (!rawSiteUrl) {
406-
throw new Error(
407-
'Missing x-gitbook-site-url header. It should be passed when using GITBOOK_MODE=proxy.'
408-
);
409-
}
410-
411-
const siteUrl = new URL(rawSiteUrl);
412-
return await lookupSiteInMultiMode(request, siteUrl);
413+
async function lookupSiteInProxy(request: NextRequest, url: URL): Promise<LookupResult> {
414+
return await lookupSiteInMultiMode(request, url);
413415
}
414416

415417
/**
@@ -916,3 +918,21 @@ function writeCookies<R extends NextResponse>(
916918

917919
return response;
918920
}
921+
922+
/**
923+
* Compute the final base path for a site served in proxy mode.
924+
* For e.g. if the input URL is `https://example.com/docs/v2/foo/bar` on which
925+
* the site is served at `https://example.com/docs` and the resolved base path is `/v2`
926+
* then the proxy site path would be `/docs/v2/`.
927+
*/
928+
function getProxyModeBasePath(
929+
input: URL,
930+
resolved: Pick<PublishedSiteContent, 'basePath' | 'pathname'>
931+
): string {
932+
const inputPathname = stripURLSearch(input).pathname;
933+
const proxySitePath = inputPathname
934+
.replace(resolved.pathname, '')
935+
.replace(resolved.basePath, '');
936+
937+
return joinPath(normalizePathname(proxySitePath), resolved.basePath);
938+
}

0 commit comments

Comments
 (0)