Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

HttpRouter: ignoreDuplicateSlashes (on by default) collapses // inside query string values

Aperta Adatta ai principianti
#8,881 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

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

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Effect-TS/effect

Tutte le issue di Effect-TS/effect

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.