From fca3b13ff72f1955b836ac207172b261bcee87db Mon Sep 17 00:00:00 2001 From: Malte Legenhausen Date: Fri, 27 Jun 2025 15:54:57 +0200 Subject: [PATCH 1/4] `HttpRouter.mountApp` prefix matching fixed --- .../platform-node/test/HttpServer.test.ts | 8 +++++++ packages/platform/src/internal/httpRouter.ts | 22 +++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/platform-node/test/HttpServer.test.ts b/packages/platform-node/test/HttpServer.test.ts index 5ae3117b219..fd965f140e2 100644 --- a/packages/platform-node/test/HttpServer.test.ts +++ b/packages/platform-node/test/HttpServer.test.ts @@ -190,6 +190,14 @@ describe("HttpServer", () => { expect(todo).toEqual("/1") const root = yield* client.get("/child").pipe(Effect.flatMap((_) => _.text)) expect(root).toEqual("/") + const rootSearch = yield* client.get("/child?foo=bar").pipe(Effect.flatMap((_) => _.text)) + expect(rootSearch).toEqual("?foo=bar") + const rootSlash = yield* client.get("/child/").pipe(Effect.flatMap((_) => _.text)) + expect(rootSlash).toEqual("/") + const invalid = yield* client.get("/child1/", { + urlParams: UrlParams.fromInput({ foo: 'bar' }) + }).pipe(Effect.map((_) => _.status)) + expect(invalid).toEqual(404) }).pipe(Effect.provide(NodeHttpServer.layerTest))) it.scoped("mountApp/includePrefix", () => diff --git a/packages/platform/src/internal/httpRouter.ts b/packages/platform/src/internal/httpRouter.ts index e51148eddca..46dfebeb50f 100644 --- a/packages/platform/src/internal/httpRouter.ts +++ b/packages/platform/src/internal/httpRouter.ts @@ -245,16 +245,20 @@ const toHttpApp = ( if (mountsLen > 0) { for (let i = 0; i < mountsLen; i++) { const [path, routeContext, options] = mounts[i] - if (request.url.startsWith(path)) { - context.unsafeMap.set(RouteContext.key, routeContext) - if (options?.includePrefix !== true) { - context.unsafeMap.set(ServerRequest.HttpServerRequest.key, sliceRequestUrl(request, path)) + const pathname = request.url.split("?")[0]; + if (pathname.startsWith(path)) { + const rest = pathname.slice(path.length); + if (rest === "" || rest.startsWith("/")) { + context.unsafeMap.set(RouteContext.key, routeContext) + if (options?.includePrefix !== true) { + context.unsafeMap.set(ServerRequest.HttpServerRequest.key, sliceRequestUrl(request, path)) + } + return Effect.locally( + Effect.flatMap(routeContext.route.handler, Respondable.toResponse) as App.Default, + FiberRef.currentContext, + context + ) } - return Effect.locally( - Effect.flatMap(routeContext.route.handler, Respondable.toResponse) as App.Default, - FiberRef.currentContext, - context - ) } } } From 9cf7767711b139e7317e25042a66aae0e3194767 Mon Sep 17 00:00:00 2001 From: Malte Legenhausen Date: Tue, 1 Jul 2025 09:19:58 +0200 Subject: [PATCH 2/4] Add missing changeset --- .changeset/clear-items-send.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/clear-items-send.md diff --git a/.changeset/clear-items-send.md b/.changeset/clear-items-send.md new file mode 100644 index 00000000000..4d2792ad571 --- /dev/null +++ b/.changeset/clear-items-send.md @@ -0,0 +1,5 @@ +--- +"@effect/platform": patch +--- + +`HttpRouter.mountApp` prefix matching fixed From 966e74db6e127b0c1569eb09048d25fce832352b Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 2 Jul 2025 11:49:05 +1200 Subject: [PATCH 3/4] wip --- packages/platform/src/internal/httpRouter.ts | 25 ++++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/platform/src/internal/httpRouter.ts b/packages/platform/src/internal/httpRouter.ts index 46dfebeb50f..a8ba4bd281b 100644 --- a/packages/platform/src/internal/httpRouter.ts +++ b/packages/platform/src/internal/httpRouter.ts @@ -243,22 +243,21 @@ const toHttpApp = ( const context = Context.unsafeMake(new Map(fiber.getFiberRef(FiberRef.currentContext).unsafeMap)) const request = Context.unsafeGet(context, ServerRequest.HttpServerRequest) if (mountsLen > 0) { + const searchIndex = request.url.indexOf("?") + const pathname = searchIndex === -1 ? request.url : request.url.slice(0, searchIndex) + for (let i = 0; i < mountsLen; i++) { const [path, routeContext, options] = mounts[i] - const pathname = request.url.split("?")[0]; - if (pathname.startsWith(path)) { - const rest = pathname.slice(path.length); - if (rest === "" || rest.startsWith("/")) { - context.unsafeMap.set(RouteContext.key, routeContext) - if (options?.includePrefix !== true) { - context.unsafeMap.set(ServerRequest.HttpServerRequest.key, sliceRequestUrl(request, path)) - } - return Effect.locally( - Effect.flatMap(routeContext.route.handler, Respondable.toResponse) as App.Default, - FiberRef.currentContext, - context - ) + if (pathname === path || pathname.startsWith(path + "/")) { + context.unsafeMap.set(RouteContext.key, routeContext) + if (options?.includePrefix !== true) { + context.unsafeMap.set(ServerRequest.HttpServerRequest.key, sliceRequestUrl(request, path)) } + return Effect.locally( + Effect.flatMap(routeContext.route.handler, Respondable.toResponse) as App.Default, + FiberRef.currentContext, + context + ) } } } From ad6563401d63e970c80decb41dfc2a96339259e1 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 2 Jul 2025 11:53:49 +1200 Subject: [PATCH 4/4] fix lint --- packages/platform-node/test/HttpServer.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform-node/test/HttpServer.test.ts b/packages/platform-node/test/HttpServer.test.ts index fd965f140e2..59801f77d51 100644 --- a/packages/platform-node/test/HttpServer.test.ts +++ b/packages/platform-node/test/HttpServer.test.ts @@ -195,7 +195,7 @@ describe("HttpServer", () => { const rootSlash = yield* client.get("/child/").pipe(Effect.flatMap((_) => _.text)) expect(rootSlash).toEqual("/") const invalid = yield* client.get("/child1/", { - urlParams: UrlParams.fromInput({ foo: 'bar' }) + urlParams: { foo: "bar" } }).pipe(Effect.map((_) => _.status)) expect(invalid).toEqual(404) }).pipe(Effect.provide(NodeHttpServer.layerTest)))