handlePreFlight function

Request handlePreFlight(
  1. Request req,
  2. Cors cors
)

Implementation

Request handlePreFlight(Request req, Cors cors) {
  if (req.method != 'OPTIONS') {
    req.messenger
        .addError(('[cors] Preflight aborted. ${req.method}!="OPTIONS'));
    req.respond.serverError();
    return req;
  }

  req.innerRequest.response.headers
      .add(HttpHeaders.varyHeader, 'Access-Control-Request-Method');
  req.innerRequest.response.headers
      .add(HttpHeaders.varyHeader, 'Access-Control-Request-Headers');

  final origin = Uri.tryParse(req.headers.value('Origin') ?? '')!;

  if (origin == null || !origin.hasScheme || !origin.hasAuthority) {
    req.messenger.addError(
        ('[cors] Preflight aborted. Could not determine the origin.'));
  }

  req.innerRequest.response.headers.add(HttpHeaders.varyHeader, 'Origin');

  if (!cors.isAllowedOrigin(origin.origin)) {
    req.messenger.addError('[cors] Preflight aborted. Not an allowed origin.');
    req.respond.badRequest();
    return req;
  }

  final method = req.headers.value('Access-Control-Request-Method') ?? '';
  if (method.isEmpty || !cors.isAllowedMethod(method)) {
    req.messenger.addError('[cors] Preflight aborted. Not an allowed method.');
    req.respond.badRequest();
    return req;
  }

  final headers = req.headers.value('Access-Control-Request-Headers') ?? '';
  final split = headers.split(',');
  final parsedHeaders =
      split.map((e) => recase.ReCase(e.trim()).headerCase).toList();

  if (parsedHeaders.length == 0 || !cors.areAllowedHeaders(parsedHeaders)) {
    req.messenger.addError('[cors] Preflight aborted. Not an allowed header.');
    req.respond.badRequest();
    return req;
  }

  req.innerRequest.response.headers
      .add('Access-Control-Allow-Origin', origin.origin);
  req.innerRequest.response.headers
      .add('Access-Control-Allow-Methods', method.toUpperCase());
  if (parsedHeaders.length > 0) {
    req.innerRequest.response.headers
        .add('Access-Control-Allow-Headers', parsedHeaders.join(', '));
  }

  if (cors.allowCredentials != null && cors.allowCredentials) {
    req.innerRequest.response.headers
        .add('Access-Control-Allow-Credentials', 'true');
  }

  if (cors.maxAge != null && cors.maxAge > 0) {
    req.innerRequest.response.headers
        .add('Access-Control-Max-Age', cors.maxAge.toString());
  }

  req.respond.code(200);
  req.cancel();
  return req;
}