Add isRevalidationRequest function to handle specific requests (#4596)

This commit is contained in:
conico974
2026-09-08 14:18:32 +02:00
committed by GitHub
parent 8e87856501
commit 625c108196
3 changed files with 28 additions and 3 deletions
+14
View File
@@ -10,6 +10,7 @@ import {
getVisitorToken,
getVisitorType,
getVisitorUnsignedClaims,
isRevalidationRequest,
normalizeVisitorURL,
} from './visitors';
@@ -564,3 +565,16 @@ describe('getVisitorType', () => {
expect(getVisitorType(requestWith({ 'user-agent': '' }))).toBe('human');
});
});
describe('isRevalidationRequest', () => {
it('should detect the revalidation worker regardless of casing', () => {
expect(
isRevalidationRequest(new Headers({ 'User-Agent': 'GitBook-Open-Revalidation-Worker' }))
).toBe(true);
});
it('should not detect a regular request', () => {
expect(isRevalidationRequest(new Headers({ 'User-Agent': 'Mozilla/5.0' }))).toBe(false);
expect(isRevalidationRequest(new Headers())).toBe(false);
});
});
+9 -1
View File
@@ -132,6 +132,14 @@ export function getVisitorData({
};
}
/**
* Check if the request is coming from our revalidation worker. Such requests carry the visitor
* data they want to revalidate in the URL, so we must not redirect them to a normalized URL.
*/
export function isRevalidationRequest(headers: Headers): boolean {
return headers.get('user-agent')?.toLowerCase() === 'gitbook-open-revalidation-worker';
}
/**
* Get the visitor token for the request. This token can either be in the
* query parameters or stored as a cookie.
@@ -154,7 +162,7 @@ export function getVisitorToken({
// Allow the empty string to come through
if (fromUrl !== null && fromUrl !== undefined) {
if (headers.get('user-agent')?.toLowerCase() === 'gitbook-open-revalidation-worker') {
if (isRevalidationRequest(headers)) {
return { source: 'revalidation', token: fromUrl };
}
+5 -2
View File
@@ -56,6 +56,7 @@ import {
getResponseCookiesForVisitorAuth,
getVisitorData,
getVisitorType,
isRevalidationRequest,
normalizeVisitorURL,
serveVisitorClaimsDataRequest,
} from '@/lib/visitors';
@@ -339,7 +340,9 @@ async function serveSiteRoutes(requestURL: URL, request: NextRequest) {
// Make sure the URL is clean of any va token after a successful lookup,
// and of any visitor.* params that may have been passed to the URL.
//
// We only redirect if the visitor token is not coming from a revalidation request, as we don't want to redirect in that case.
// We only redirect if the request is not coming from the revalidation worker, as we don't
// want to redirect in that case. It can carry unsigned claims without any token, so we rely
// on the request headers rather than on the visitor token source.
//
// The token and the visitor.* params value are stored in cookies that are set
// on the redirect response.
@@ -347,7 +350,7 @@ async function serveSiteRoutes(requestURL: URL, request: NextRequest) {
const normalizedVisitorURL = normalizeVisitorURL(incomingURL);
if (
normalizedVisitorURL.toString() !== incomingURL.toString() &&
visitorToken?.source !== 'revalidation'
!isRevalidationRequest(request.headers)
) {
return writeResponseCookies(
NextResponse.redirect(normalizedVisitorURL.toString()),