Skip to content

Commit

Permalink
Fix Astro middleware by collapsing duplicate leading slashes in URL path
Browse files Browse the repository at this point in the history
Fixes the following worker crash in Cloudflare Pages when accessing an
API endpoint where the URL path starts with more than one slash:

    (error) 19:51:47 [ERROR] TypeError: Invalid URL string.
      at new ClerkUrl (_astro-internal_middleware.mjs:2383:16)
      at createClerkUrl (_astro-internal_middleware.mjs:2389:10)
      at ClerkRequest.deriveUrlFromHeaders (_astro-internal_middleware.mjs:2420:12)
      at new ClerkRequest (_astro-internal_middleware.mjs:2395:26)
      at createClerkRequest (_astro-internal_middleware.mjs:2434:54)
      at astroMiddleware (_astro-internal_middleware.mjs:3657:26)
      at applyHandle (chunks/index_CJfit7_z.mjs:353:22)
      at chunks/index_CJfit7_z.mjs:372:18
      at _astro-internal_middleware.mjs:3902:26
      at applyHandle (chunks/index_CJfit7_z.mjs:353:22)
  • Loading branch information
mlafeldt committed Aug 19, 2024
1 parent 7bcab70 commit 0b8b0ed
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
5 changes: 5 additions & 0 deletions packages/backend/src/tokens/__tests__/clerkRequest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ export default (QUnit: QUnit) => {
});
assert.equal(createClerkRequest(req).clerkUrl.toString(), 'https://example.com/path?foo=bar');
});

it('should collapse duplicate leading slashes in URL path', assert => {
const req = new Request('http://localhost:3000///path');
assert.equal(createClerkRequest(req).clerkUrl.toString(), 'http://localhost:3000/path');
});
});

module('toJSON', () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/tokens/clerkRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ class ClerkRequest extends Request {
const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);
const host = req.headers.get(constants.Headers.Host);
const protocol = initialUrl.protocol;
const sanitizedPath = initialUrl.pathname.replace(/^\/+/g, '/')

const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;
const resolvedProtocol = this.getFirstValueFromHeader(forwardedProto) ?? protocol?.replace(/[:/]/, '');
const origin = resolvedHost && resolvedProtocol ? `${resolvedProtocol}://${resolvedHost}` : initialUrl.origin;

return createClerkUrl(initialUrl.pathname + initialUrl.search, origin);
return createClerkUrl(sanitizedPath + initialUrl.search, origin);
}

private getFirstValueFromHeader(value?: string | null) {
Expand Down

0 comments on commit 0b8b0ed

Please sign in to comment.