Skip to content

Commit

Permalink
ensure cors middleware also affects error responses (#3780)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart authored Oct 14, 2024
1 parent 2465abd commit 1b1ef29
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/calm-rivers-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/platform": patch
---

ensure cors middleware also affects error responses
51 changes: 32 additions & 19 deletions packages/platform/src/internal/httpMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { HttpApp } from "@effect/platform"
import { HttpApp } from "@effect/platform"
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import * as FiberRef from "effect/FiberRef"
Expand Down Expand Up @@ -276,28 +276,41 @@ export const cors = (options?: {
? { "access-control-max-age": opts.maxAge.toString() }
: undefined

const headersFromRequest = (request: ServerRequest.HttpServerRequest) => {
const origin = request.headers["origin"]
return Headers.unsafeFromRecord({
...allowOrigin(origin),
...allowCredentials,
...exposeHeaders
})
}

const headersFromRequestOptions = (request: ServerRequest.HttpServerRequest) => {
const origin = request.headers["origin"]
const accessControlRequestHeaders = request.headers["access-control-request-headers"]
return Headers.unsafeFromRecord({
...allowOrigin(origin),
...allowCredentials,
...exposeHeaders,
...allowMethods,
...allowHeaders(accessControlRequestHeaders),
...maxAge
})
}

const preResponseHandler = (request: ServerRequest.HttpServerRequest, response: HttpServerResponse) =>
Effect.succeed(ServerResponse.setHeaders(response, headersFromRequest(request)))

return <E, R>(httpApp: HttpApp.Default<E, R>): HttpApp.Default<E, R> =>
Effect.withFiberRuntime((fiber) => {
const context = fiber.getFiberRef(FiberRef.currentContext)
const request = Context.unsafeGet(
context,
ServerRequest.HttpServerRequest
)
const origin = request.headers["origin"]
const accessControlRequestHeaders = request.headers["access-control-request-headers"]
const corsHeaders = Headers.unsafeFromRecord({
...allowOrigin(origin),
...allowCredentials,
...exposeHeaders
})
const request = Context.unsafeGet(context, ServerRequest.HttpServerRequest)
if (request.method === "OPTIONS") {
Object.assign(corsHeaders, {
...allowMethods,
...allowHeaders(accessControlRequestHeaders),
...maxAge
})
return Effect.succeed(ServerResponse.empty({ status: 204, headers: corsHeaders }))
return Effect.succeed(ServerResponse.empty({
status: 204,
headers: headersFromRequestOptions(request)
}))
}
return Effect.map(httpApp, ServerResponse.setHeaders(corsHeaders))
return Effect.zipRight(HttpApp.appendPreResponseHandler(preResponseHandler), httpApp)
})
}

0 comments on commit 1b1ef29

Please sign in to comment.