cors function

Future<bool> Function(RequestContext, ResponseContext) cors([
  1. CorsOptions? options
])

Applies the given CorsOptions.

Implementation

Future<bool> Function(RequestContext, ResponseContext) cors([
  CorsOptions? options,
]) {
  options ??= CorsOptions();

  return (req, res) async {
    // access-control-allow-credentials
    if (options!.credentials == true) {
      res.headers['access-control-allow-credentials'] = 'true';
    }

    // access-control-allow-headers
    if (req.method == 'OPTIONS' && options.allowedHeaders.isNotEmpty) {
      res.headers['access-control-allow-headers'] = options.allowedHeaders.join(
        ',',
      );
    } else if (req.headers!['access-control-request-headers'] != null) {
      res.headers['access-control-allow-headers'] = req.headers!.value(
        'access-control-request-headers',
      )!;
    }

    // access-control-expose-headers
    if (options.exposedHeaders.isNotEmpty) {
      res.headers['access-control-expose-headers'] = options.exposedHeaders
          .join(',');
    }

    // access-control-allow-methods
    if (req.method == 'OPTIONS' && options.methods.isNotEmpty) {
      res.headers['access-control-allow-methods'] = options.methods.join(',');
    }

    // access-control-max-age
    if (req.method == 'OPTIONS' && options.maxAge != null) {
      res.headers['access-control-max-age'] = options.maxAge.toString();
    }

    // access-control-allow-origin
    if (options.origin == false || options.origin == '*') {
      res.headers['access-control-allow-origin'] = '*';
    } else if (options.origin is String) {
      res
        ..headers['access-control-allow-origin'] = options.origin as String
        ..headers['vary'] = 'origin';
    } else {
      var isAllowed = _isOriginAllowed(
        req.headers!.value('origin'),
        options.origin,
      );

      res.headers['access-control-allow-origin'] = isAllowed
          ? req.headers!.value('origin')!
          : false.toString();

      if (isAllowed) {
        res.headers['vary'] = 'origin';
      }
    }

    if (req.method != 'OPTIONS') return true;
    //res.statusCode = options.successStatus ?? 204;
    res.statusCode = options.successStatus;
    res.contentLength = 0;
    await res.close();
    return options?.preflightContinue ?? true;
  };
}