feat(19.7-01): in-process dispatch marker and compiled handler lookup

- bouncer.Dispatch, WithDispatch, Dispatched: context-only pre-resolved
  principal marker honoured by Registry.Middleware for listed guard names
- cabana.ResolveBackend honours a backend-kind marker; additive
  ResolveBackendToken, ScopeLimitFor and BackendPrincipal resolvers
- surf.Router.Handler and compileHandlers: one compiled chain per route,
  shared by BuildRouter validation and compile
- smoke tests TestDispatchSmoke, TestDispatchedSmoke, TestDispatchMarkerSmoke
- READMEs and docs/services/{authentication,routing}.md updated
This commit is contained in:
Jakub Zych
2026-10-22 16:00:19 +02:00
parent a74a218cd9
commit 1bd91a4522
14 changed files with 522 additions and 11 deletions

View File

@@ -281,6 +281,8 @@ for _, rt := range r.Routes() {
// POST /api/blog/posts/{id}/comments acme.blog [throttle:60,1 acme.auth throttle:blog.comments body.limit:65536]
```
`surf.Router.Handler` hands out the compiled chain of one route by method and pattern, for example `r.Handler("GET", "/api/blog/posts/{id}")`. The chain is the route exactly as the mux serves it: constraints, the named middleware (guards, throttles), the body limit, locale, recovery and the CORS profile. A framework component that calls a route in-process, such as the MCP module, serves that handler with a request it builds itself, setting the path values and `Pattern` as the mux would; the caller's identity reaches the guard through the [dispatch marker](authentication.md#guards-and-middleware), never through a header. The lookup answers false for an unknown route and before `surf.BuildRouter` compiled the routes.
## CORS
CORS is configured with the keys of Laravel's `config/cors.php`, under `http.cors`, and applies only to paths that match `http.cors.paths`. With no `http.cors` section, no CORS headers are sent: