platform/lib/angel_cors.dart

82 lines
2.6 KiB
Dart
Raw Normal View History

2016-12-05 02:16:54 +00:00
/// Angel CORS middleware.
library angel_cors;
import 'package:angel_framework/angel_framework.dart';
import 'src/cors_options.dart';
export 'src/cors_options.dart';
/// Determines if a request origin is CORS-able.
typedef bool CorsFilter(String origin);
bool _isOriginAllowed(String origin, allowedOrigin) {
if (allowedOrigin is List) {
return allowedOrigin.any((x) => _isOriginAllowed(origin, x));
} else if (allowedOrigin is String) {
return origin == allowedOrigin;
} else if (allowedOrigin is RegExp) {
return allowedOrigin.hasMatch(origin);
} else if (allowedOrigin is CorsFilter) {
return allowedOrigin(origin);
} else {
return allowedOrigin != false;
}
}
/// Applies the given [CorsOptions].
RequestMiddleware cors([CorsOptions options]) {
final opts = options ?? new CorsOptions();
return (RequestContext req, ResponseContext res) async {
// Access-Control-Allow-Credentials
if (opts.credentials == true) {
2016-12-21 17:43:42 +00:00
res.heades['Access-Control-Allow-Credentials'] = 'true';
2016-12-05 02:16:54 +00:00
}
// Access-Control-Allow-Headers
2016-12-05 05:15:28 +00:00
if (req.method == 'OPTIONS' && opts.allowedHeaders.isNotEmpty) {
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Allow-Headers'] =
opts.allowedHeaders.join(',');
2017-04-15 19:45:29 +00:00
} else if (req.headers['Access-Control-Request-Headers'] != null) {
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Allow-Headers'] =
2017-04-15 19:45:29 +00:00
req.headers.value('Access-Control-Request-Headers');
2016-12-05 02:16:54 +00:00
}
// Access-Control-Expose-Headers
if (opts.exposedHeaders.isNotEmpty) {
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Expose-Headers'] =
opts.exposedHeaders.join(',');
2016-12-05 02:16:54 +00:00
}
// Access-Control-Allow-Methods
2016-12-05 05:15:28 +00:00
if (req.method == 'OPTIONS' && opts.methods.isNotEmpty) {
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Allow-Methods'] = opts.methods.join(',');
2016-12-05 02:16:54 +00:00
}
// Access-Control-Max-Age
2016-12-05 05:15:28 +00:00
if (req.method == 'OPTIONS' && opts.maxAge != null) {
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Max-Age'] = opts.maxAge.toString();
2016-12-05 02:16:54 +00:00
}
// Access-Control-Allow-Origin
if (opts.origin == false || opts.origin == '*') {
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Allow-Origin'] = '*';
2016-12-05 02:16:54 +00:00
} else if (opts.origin is String) {
res
2016-12-21 17:43:42 +00:00
..headers['Access-Control-Allow-Origin'] = opts.origin
..headers['Vary'] = 'Origin';
2016-12-05 02:16:54 +00:00
} else {
bool isAllowed =
_isOriginAllowed(req.headers.value('Origin'), opts.origin);
2016-12-21 17:43:42 +00:00
res.headers['Access-Control-Allow-Origin'] =
isAllowed ? req.headers.value('Origin') : false.toString();
2016-12-05 02:16:54 +00:00
if (isAllowed) {
2016-12-21 17:43:42 +00:00
res.headers['Vary'] = 'Origin';
2016-12-05 02:16:54 +00:00
}
}
2016-12-05 05:15:28 +00:00
return req.method != 'OPTIONS' || opts.preflightContinue;
2016-12-05 02:16:54 +00:00
};
}