CORSConfig.default lists GET, HEAD, POST, PUT, DELETE as allowed methods, but not PATCH. Any service using CORSInterceptor.default will silently 403 the preflight for PATCH requests, which is a common method for partial-update REST endpoints (RFC 5789).
Source:
|
allowedMethods = AllowedMethods.Some(Set(Method.GET, Method.HEAD, Method.POST, Method.PUT, Method.DELETE)), |
val default: CORSConfig = CORSConfig(
allowedOrigin = AllowedOrigin.All,
allowedCredentials = AllowedCredentials.Deny,
allowedMethods = AllowedMethods.Some(Set(Method.GET, Method.HEAD, Method.POST, Method.PUT, Method.DELETE)),
// ...
)
The handler that reads this set returns no Access-Control-Allow-Methods header for unknown methods (lines ~105-108), so the browser aborts the request before it ever reaches the route. The failure mode is a missing CORS header, which is hard to debug from the browser side.
Suggested fix — add Method.PATCH to the default set. (OPTIONS is intentionally excluded since it's the preflight method itself.)
allowedMethods = AllowedMethods.Some(
Set(Method.GET, Method.HEAD, Method.POST, Method.PUT, Method.PATCH, Method.DELETE)
),
Happy to PR.
CORSConfig.defaultlistsGET, HEAD, POST, PUT, DELETEas allowed methods, but notPATCH. Any service usingCORSInterceptor.defaultwill silently 403 the preflight forPATCHrequests, which is a common method for partial-update REST endpoints (RFC 5789).Source:
tapir/server/core/src/main/scala/sttp/tapir/server/interceptor/cors/CORSConfig.scala
Line 129 in 88d662d
The handler that reads this set returns no
Access-Control-Allow-Methodsheader for unknown methods (lines ~105-108), so the browser aborts the request before it ever reaches the route. The failure mode is a missing CORS header, which is hard to debug from the browser side.Suggested fix — add
Method.PATCHto the default set. (OPTIONSis intentionally excluded since it's the preflight method itself.)Happy to PR.