withCors function
Future<GenkitHttpResponse>
withCors(
- CorsOptions options,
- GenkitHttpRequest request,
- GenkitHttpHandler inner
Applies options around inner; answers preflight OPTIONS itself.
The building block behind the cors option of GenkitRouter.serve and
GenkitRouter.handleHttpRequest, for HTTP framework adapters (e.g.
asShelfHandler in package:genkit_shelf):
final response = await withCors(cors, request, (request) async =>
await router.handle(request) ?? notFound());
Implementation
Future<GenkitHttpResponse> withCors(
CorsOptions options,
GenkitHttpRequest request,
GenkitHttpHandler inner,
) async {
final allowAny = options.allowedOrigins.contains('*');
final origin = request.headers['origin'];
final String? allowOrigin;
if (allowAny) {
allowOrigin = '*';
} else if (origin != null && options.allowedOrigins.contains(origin)) {
allowOrigin = origin;
} else {
allowOrigin = null;
}
final headers = <String, String>{
// With a restricted list the response depends on the request origin, so
// caches must key on it. That includes responses without CORS headers (no
// or a disallowed `Origin`): cached, they would be handed to an allowed
// origin and the browser would block them.
if (!allowAny) 'vary': 'Origin',
if (allowOrigin != null) ...{
'access-control-allow-origin': allowOrigin,
if (options.exposedHeaders.isNotEmpty)
'access-control-expose-headers': options.exposedHeaders.join(', '),
},
};
if (request.method == 'OPTIONS') {
return GenkitHttpResponse(
statusCode: 204,
headers: {
...headers,
if (allowOrigin != null) ...{
'access-control-allow-methods': 'POST, OPTIONS',
if (options.allowedHeaders.isNotEmpty)
'access-control-allow-headers': options.allowedHeaders.join(', '),
},
},
);
}
final response = await inner(request);
if (headers.isEmpty) return response;
final existingVary = response.headers['vary'];
final vary = headers['vary'];
return GenkitHttpResponse(
statusCode: response.statusCode,
headers: {
...response.headers,
...headers,
// Append to an existing `Vary` (e.g. `Accept-Encoding`) instead of
// clobbering it.
if (vary != null && existingVary != null)
'vary': _appendVary(existingVary, vary),
},
body: response.body,
);
}