HttpRoute constructor
HttpRoute(
- String route,
- FutureOr callback(
- HttpRequest req,
- HttpResponse res
- ServerUniverseMethodType method, {
- List<
FutureOr Function(HttpRequest req, HttpResponse res)> middleware = const [],
Implementation
HttpRoute(this.route, this.callback, this.method, {this.middleware = const []}) : usesWildcardMatcher = route.contains('*') {
// Split route path into segments
/// Because in dart 2.18 uri parsing is more permissive, using a \ in regex
/// is being counted as a /, so we need to add an r and join them together
/// VERY happy for a more elegant solution here than some random escape
/// sequence.
const escapeChar = '@@@^';
var escapedPath = route.normalizePath.replaceAll('\\', escapeChar);
var segments = Uri.tryParse('/${escapedPath}')?.pathSegments ?? [route.normalizePath];
segments = segments.map((e) => e.replaceAll(escapeChar, '\\')).toList();
var pattern = '^';
for (var segment in segments) {
if (segment == '*' && segment != segments.first && segment == segments.last) {
// Generously match path if last segment is wildcard (*)
// Example: 'some/path/*' => should match 'some/path', 'some/path/', 'some/path/with/children'
// but not 'some/pathological'
pattern += r'(?:/.*|)';
break;
} else if (segment != segments.first) {
// Add path separators
pattern += '/';
}
// parse parameter if any
final param = HttpRouteParam.tryParse(segment);
if (param != null) {
if (_params.containsKey(param.name)) {
throw DuplicateParameterException(param.name);
}
_params[param.name] = param;
// ignore: prefer_interpolation_to_compose_strings
segment = r'(?<' + param.name + r'>' + param.pattern + ')';
} else {
// escape period character
segment = segment.replaceAll('.', r'\.');
// wildcard ('*') to anything
segment = segment.replaceAll('*', '.*?');
}
pattern += segment;
}
pattern += r'$';
matcher = RegExp(pattern, caseSensitive: false);
}