Skip to content

Commit c958b3b

Browse files
committed
docs: Document CORS preflight handler in README
1 parent 9642bda commit c958b3b

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,8 @@ Built-in helpers:
947947
classpath resource or filesystem file (content-type inferred from extension; the stream is
948948
opened and closed per request, and the handler owns its lifecycle). Throws
949949
`IllegalArgumentException` at construction if the resource or file is missing.
950+
- `Handlers.corsPreflightHandler(...)` — answers CORS `OPTIONS` preflight requests against
951+
caller-supplied allowlists. See [CORS preflight](#cors-preflight) below.
950952

951953
### Wildcards in extra routes
952954

@@ -1015,6 +1017,31 @@ empty dependency list; the exception never reaches the configured `ExceptionHand
10151017
`HEAD` are accepted; other methods return `405 Method Not Allowed` with an `Allow: GET, HEAD`
10161018
header.
10171019

1020+
### CORS preflight
1021+
1022+
`Handlers.corsPreflightHandler(...)` answers `OPTIONS` preflight requests so browsers can
1023+
perform cross-origin calls against the server. The handler is preflight-only — wire it on a
1024+
wildcard `extraRoute` covering the routes you want to expose to browsers.
1025+
1026+
``` java
1027+
var server = OpenApiServer.builder()
1028+
.spec(spec)
1029+
.handlers(handlers)
1030+
.extraRoute("/api/**", Handlers.corsPreflightHandler(
1031+
List.of("https://app.example.com"),
1032+
List.of(GET, POST, PUT, DELETE),
1033+
List.of("content-type", "authorization"),
1034+
true, // Access-Control-Allow-Credentials
1035+
Duration.ofMinutes(10))) // Access-Control-Max-Age
1036+
.build();
1037+
```
1038+
1039+
For dynamic origin policy (regex match, suffix match, tenant lookup) pass a `Predicate<String>`
1040+
instead of a `List<String>`. Allowed-headers comparison is case-insensitive. Disallowed origins,
1041+
methods, or headers return `403` with no CORS headers (the browser then blocks the request);
1042+
non-`OPTIONS` requests return `405` with `Allow: OPTIONS`; preflights missing the `Origin` or
1043+
`Access-Control-Request-Method` header return `400`.
1044+
10181045
## End-to-end example
10191046

10201047
Gson on the classpath for request/response JSON, SnakeYAML on the classpath for the spec, one

0 commit comments

Comments
 (0)