From 02e885fbb78e31c7154d1ca4f282e89c86b09cbe Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Mon, 1 Dec 2025 12:49:04 +0800 Subject: [PATCH] fix(opds): workaround parsing of encoded params in proxied url in cloudflare (#2575) --- apps/readest-app/src/app/api/opds/proxy/route.ts | 13 ++++++++++++- apps/readest-app/src/app/opds/CatelogManager.tsx | 4 ++-- apps/readest-app/src/app/opds/PublicationCard.tsx | 5 ++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/readest-app/src/app/api/opds/proxy/route.ts b/apps/readest-app/src/app/api/opds/proxy/route.ts index e557d01b..26cdcea5 100644 --- a/apps/readest-app/src/app/api/opds/proxy/route.ts +++ b/apps/readest-app/src/app/api/opds/proxy/route.ts @@ -1,7 +1,18 @@ import { NextRequest, NextResponse } from 'next/server'; async function handleRequest(request: NextRequest, method: 'GET' | 'HEAD') { - const url = request.nextUrl.searchParams.get('url'); + // Cloudflare Workers incorrectly decodes %26 to & in the url parameter value, + // causing query parameters within the proxied URL (like &start_index=26) to be + // treated as separate top-level parameters instead of part of the url value. + // We work around this by manually extracting the url parameter - capturing everything + // from 'url=' until we hit our known parameters (&stream= or &auth=), then decoding it. + const fullUrl = request.url; + const urlParamStart = fullUrl.indexOf('url=') + 4; + const streamParam = fullUrl.lastIndexOf('&stream='); + const authParam = fullUrl.lastIndexOf('&auth='); + const urlParamEnd = Math.min(...[streamParam, authParam].filter((i) => i > 0), fullUrl.length); + const encodedUrl = fullUrl.substring(urlParamStart, urlParamEnd); + const url = decodeURIComponent(encodedUrl); const auth = request.nextUrl.searchParams.get('auth'); const stream = request.nextUrl.searchParams.get('stream'); diff --git a/apps/readest-app/src/app/opds/CatelogManager.tsx b/apps/readest-app/src/app/opds/CatelogManager.tsx index 2e9016c1..b424d97b 100644 --- a/apps/readest-app/src/app/opds/CatelogManager.tsx +++ b/apps/readest-app/src/app/opds/CatelogManager.tsx @@ -173,7 +173,7 @@ export function CatalogManager() {

- {catalog.icon && {catalog.icon}} + {catalog.icon && {catalog.icon}} {catalog.name}