Almost
This commit is contained in:
parent
5d5ac7bef9
commit
4e2176f393
2 changed files with 76 additions and 22 deletions
|
@ -66,8 +66,11 @@ class Router {
|
||||||
if (route is! SymlinkRoute) {
|
if (route is! SymlinkRoute) {
|
||||||
router._routes.add(route.clone());
|
router._routes.add(route.clone());
|
||||||
} else if (route is SymlinkRoute) {
|
} else if (route is SymlinkRoute) {
|
||||||
router._routes.add(new SymlinkRoute(route.path, route.pattern,
|
final newRouter = route.router.clone();
|
||||||
newMounted[route.pattern] = route.router.clone()));
|
newMounted[route.path] = newRouter;
|
||||||
|
final symlink = new SymlinkRoute(route.path, route.pattern, newRouter)
|
||||||
|
.._head = route._head;
|
||||||
|
router._routes.add(symlink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +91,14 @@ class Router {
|
||||||
buf.writeln(header);
|
buf.writeln(header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf.writeln('<root>');
|
||||||
|
|
||||||
indent() {
|
indent() {
|
||||||
for (int i = 0; i < tabs; i++) buf.write(tab);
|
for (int i = 0; i < tabs; i++) buf.write(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
dumpRouter(Router router) {
|
dumpRouter(Router router) {
|
||||||
indent();
|
indent();
|
||||||
buf.writeln('- <root>');
|
|
||||||
tabs++;
|
tabs++;
|
||||||
|
|
||||||
for (Route route in router.routes) {
|
for (Route route in router.routes) {
|
||||||
|
@ -103,9 +107,7 @@ class Router {
|
||||||
|
|
||||||
if (route is SymlinkRoute) {
|
if (route is SymlinkRoute) {
|
||||||
buf.writeln();
|
buf.writeln();
|
||||||
tabs++;
|
|
||||||
dumpRouter(route.router);
|
dumpRouter(route.router);
|
||||||
tabs--;
|
|
||||||
} else {
|
} else {
|
||||||
if (showMatchers) buf.write(' (${route.matcher.pattern})');
|
if (showMatchers) buf.write(' (${route.matcher.pattern})');
|
||||||
|
|
||||||
|
@ -231,44 +233,57 @@ class Router {
|
||||||
requestMiddleware[name] = middleware;
|
requestMiddleware[name] = middleware;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RoutingResult _dumpResult(String path, RoutingResult result) {
|
||||||
|
_printDebug('Resolved "/$path" to ${result.deepestRoute}');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// Finds the first [Route] that matches the given path,
|
/// Finds the first [Route] that matches the given path,
|
||||||
/// with the given method.
|
/// with the given method.
|
||||||
RoutingResult resolve(String fullPath, String path, {String method: 'GET'}) {
|
RoutingResult resolve(String fullPath, String path, {String method: 'GET'}) {
|
||||||
final cleanFullPath = fullPath.replaceAll(_straySlashes, '');
|
final cleanFullPath = fullPath.replaceAll(_straySlashes, '');
|
||||||
final cleanPath = path.replaceAll(_straySlashes, '');
|
final cleanPath = path.replaceAll(_straySlashes, '');
|
||||||
|
_printDebug(
|
||||||
|
'Now resolving $method "/$cleanPath", fullPath: $cleanFullPath');
|
||||||
|
|
||||||
for (Route route in routes) {
|
for (Route route in routes) {
|
||||||
if (route is SymlinkRoute && route._head != null) {
|
if (route is SymlinkRoute && route._head != null) {
|
||||||
final match = route._head.firstMatch(cleanFullPath);
|
final match = route._head.firstMatch(cleanPath);
|
||||||
|
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
final tail = cleanPath
|
final tail = cleanPath
|
||||||
.replaceFirst(match[0], '')
|
.replaceAll(route._head, '')
|
||||||
.replaceAll(_straySlashes, '');
|
.replaceAll(_straySlashes, '');
|
||||||
_printDebug('Matched head "${match[0]}" to $route. Tail: "$tail"');
|
_printDebug('Matched head "${match[0]}" to $route. Tail: "$tail"');
|
||||||
|
route.router.debug = route.router.debug || debug;
|
||||||
final nested =
|
final nested =
|
||||||
route.router.resolve(cleanFullPath, tail, method: method);
|
route.router.resolve(cleanFullPath, tail, method: method);
|
||||||
return new RoutingResult(
|
return _dumpResult(
|
||||||
|
cleanPath,
|
||||||
|
new RoutingResult(
|
||||||
match: match,
|
match: match,
|
||||||
nested: nested,
|
nested: nested,
|
||||||
params: route.parseParameters(cleanPath),
|
params: route.parseParameters(cleanPath),
|
||||||
sourceRoute: route,
|
sourceRoute: route,
|
||||||
sourceRouter: this,
|
sourceRouter: this,
|
||||||
tail: tail);
|
tail: tail));
|
||||||
}
|
}
|
||||||
} else if (route.method == '*' || route.method == method) {
|
} else if (route.method == '*' || route.method == method) {
|
||||||
final match = route.match(cleanPath);
|
final match = route.match(cleanPath);
|
||||||
|
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
return new RoutingResult(
|
return _dumpResult(
|
||||||
|
cleanPath,
|
||||||
|
new RoutingResult(
|
||||||
match: match,
|
match: match,
|
||||||
params: route.parseParameters(cleanPath),
|
params: route.parseParameters(cleanPath),
|
||||||
sourceRoute: route,
|
sourceRoute: route,
|
||||||
sourceRouter: this);
|
sourceRouter: this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_printDebug('Could not resolve path "/$cleanPath".');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,11 +296,17 @@ class Router {
|
||||||
var result = router.resolve(fullPath, path, method: method);
|
var result = router.resolve(fullPath, path, method: method);
|
||||||
|
|
||||||
while (result != null) {
|
while (result != null) {
|
||||||
|
if (!results.contains(result))
|
||||||
results.add(result);
|
results.add(result);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
result.deepestRouter._routes.remove(result.deepestRoute);
|
result.deepestRouter._routes.remove(result.deepestRoute);
|
||||||
result = router.resolve(fullPath, path, method: method);
|
result = router.resolve(fullPath, path, method: method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_printDebug(
|
||||||
|
'Results of $method "/${fullPath.replaceAll(_straySlashes, '')}": ${results.map((r) => r.deepestRoute).toList()}');
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +335,8 @@ class Router {
|
||||||
copiedMiddleware[middlewareName];
|
copiedMiddleware[middlewareName];
|
||||||
}
|
}
|
||||||
|
|
||||||
final route = new SymlinkRoute(path, path, _mounted[path] = router);
|
final route = new SymlinkRoute(path, path, router);
|
||||||
|
_mounted[route.path] = router;
|
||||||
_routes.add(route);
|
_routes.add(route);
|
||||||
route._head = new RegExp(route.matcher.pattern.replaceAll(_rgxEnd, ''));
|
route._head = new RegExp(route.matcher.pattern.replaceAll(_rgxEnd, ''));
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,30 @@ main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final beatles = new Router();
|
||||||
|
|
||||||
|
beatles.post('/spinal_clacker', (req, res) {
|
||||||
|
res.write('come ');
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
final yellow = new Router()
|
||||||
|
..get('/submarine', (req, res) {
|
||||||
|
res.write('we all live in a');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
beatles.group('/big', (router) {
|
||||||
|
router.mount('/yellow', yellow);
|
||||||
|
});
|
||||||
|
|
||||||
|
beatles.all('*', (req, res) {
|
||||||
|
res.write('together');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
router.mount('/beatles', beatles);
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
client = new http.Client();
|
client = new http.Client();
|
||||||
|
|
||||||
|
@ -122,5 +146,13 @@ main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('use', () {});
|
group('mount', () {
|
||||||
|
group('path', () {
|
||||||
|
test('top-level', () async {
|
||||||
|
final res = await client.get('$url/beatles/spinal_clacker');
|
||||||
|
print('Response: ${res.body}');
|
||||||
|
expect(res.body, equals('come together'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue