HttpRouter: ignoreDuplicateSlashes (on by default) collapses // inside query string values
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 88/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- backend
Direzione di ricerca
Inizia in packages/effect/src/http/FindMyWay/internal/router.ts, in find(), dove removeDuplicateSlashes(path) viene chiamato prima di safeDecodeURI(path) (intorno a L344-L350). Ristruttura in modo che la querystring venga separata per prima e che solo la porzione di percorso venga normalizzata, preservando l'invariante secondo cui sliceParameter lavora sulla stessa stringa, come indicato nel commento sopra la chiamata. Aggiungi un test in packages/effect/test/http che copra un valore di query contenente // non codificato (ad es. ?u=https://x.com/y) con la configurazione predefinita del router; si considera concluso quando il valore di query raggiunge il handler invariato mentre le barre duplicate nel percorso vengono ancora accorpate.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What version of Effect is running?
[email protected]. The code is unchanged on main (757821fe).
What steps can reproduce the bug?
The vendored FindMyWay router enables ignoreDuplicateSlashes: true by default (router.ts#L56). In find(), when the URL is not "clean", removeDuplicateSlashes(path) runs on the whole URL (L344-L346) before safeDecodeURI(path) splits off the querystring (L350). As a result, // in the query string is collapsed too.
import { Effect } from "effect"
import { FindMyWay, HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http"
// 1. FindMyWay directly
const router = FindMyWay.make<string>({})
router.on("GET", "/a", "handler")
console.log("FindMyWay:", router.find("GET", "/a?u=https://x.com/y")?.searchParams)
// 2. HttpRouter end to end
const app = HttpRouter.add(
"GET",
"/oauth/authorize",
Effect.gen(function*() {
const params = yield* HttpServerRequest.ParsedSearchParams
return HttpServerResponse.jsonUnsafe(params)
})
)
for (const routerConfig of [undefined, { ignoreDuplicateSlashes: false }]) {
const { handler, dispose } = HttpRouter.toWebHandler(app, { routerConfig })
const res = await handler(new Request("http://localhost/oauth/authorize?resource=https://example.com/api/mcp"))
console.log(`HttpRouter (routerConfig: ${JSON.stringify(routerConfig)}):`, await res.text())
await dispose()
}
Output with bun repro.ts and [email protected]:
FindMyWay: { u: "https:/x.com/y" }
HttpRouter (routerConfig: undefined): {"resource":"https:/example.com/api/mcp"}
HttpRouter (routerConfig: {"ignoreDuplicateSlashes":false}): {"resource":"https://example.com/api/mcp"}
What is the expected behavior?
Duplicate-slash normalization should apply to the path only. Query values should reach the handler (ParsedSearchParams, HttpApi query schemas) unchanged: resource = "https://example.com/api/mcp".
What do you see instead?
resource = "https:/example.com/api/mcp". Percent-encoded values (https%3A%2F%2F…) are not affected. Unencoded values are, and RFC 3986 §3.4 allows unencoded : and / in a query. OAuth 2.0 parameters such as RFC 8707 resource and redirect_uri are URLs, and some clients send them unencoded. Because ignoreDuplicateSlashes is enabled by default, these requests are silently corrupted with no error. In our case, an MCP OAuth /authorize endpoint rejected a valid resource.
Additional information
Suggested fix: in find(), split on the first ? (or let safeDecodeURI separate the querystring first), run removeDuplicateSlashes on the path part only, then continue. The comment above that call says it must run before safeDecodeURI so sliceParameter works on the same string. Normalizing only the path part before reattaching ? + querystring keeps that invariant. Route registration (on, L98-L100) is not affected in practice because route paths have no query.
Upstream: delvedor/find-my-way has the same ordering on its current main (index.js find), and [email protected] with ignoreDuplicateSlashes: true produces the same { u: "https:/x.com/y" }. I found no upstream issue or fix for it. Upstream defaults this option to false, so the bug has more impact here, where it is enabled by default.
Workaround: disable the option through RouterConfig, for example HttpRouter.toWebHandler(app, { routerConfig: { ignoreDuplicateSlashes: false } }) / HttpRouter.serve(app, { routerConfig: ... }), or provide HttpRouter.RouterConfig.
- Lingua principale
- TypeScript
- Stelle
- 16.7k
- Fork
- 808
- Merge medio
- 10h 36m
- PR unite (30g)
- 449
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Effect-TS/effect
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 86/100
Effect-TS/effect#8863 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
BrowserWorkerRunner: port finalizer throws when the worker global has no close() (Bun)Forse già presa @santiago-ramos-02 l’ha presa 7 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Effect-TS/effect#8635 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
Effect-TS/effect#8101 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 67/100
Effect-TS/effect#8860 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Effect-TS/effect
Issue simili
-
bug DUP Reservations
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
bcgov/reserve-rec-public#952 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
daufderheide/racecoordinator_ai#948 ·
I maintainer di solito rispondono entro 1 giorno
-
Bug pulumi/pulumi
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
bug priority:high
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
api bug claude
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
diegosouzapw/OmniRoute#15764 ·
I maintainer di solito rispondono entro 2 giorni