Index: lib/src/util/path_handler.dart |
diff --git a/lib/src/util/path_handler.dart b/lib/src/util/path_handler.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..45ce45a22b7567876cd2cd37f2db9671cea169b1 |
--- /dev/null |
+++ b/lib/src/util/path_handler.dart |
@@ -0,0 +1,58 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library test.util.path_handler; |
+ |
+import 'package:path/path.dart' as p; |
+import 'package:shelf/shelf.dart' as shelf; |
+ |
+import '../utils.dart'; |
+ |
+/// A handler that routes to sub-handlers based on exact path prefixes. |
+class PathHandler { |
+ /// A trie of path components to handlers. |
+ final _paths = new _Node(); |
+ |
+ /// The shelf handler. |
+ shelf.Handler get handler => _onRequest; |
+ |
+ PathHandler(); |
+ |
+ /// Routes requests at or under [path] to [handler]. |
+ /// |
+ /// If [path] is a parent or child directory of another path in this handler, |
+ /// the longest matching prefix wins. |
+ void add(String path, shelf.Handler handler) { |
+ var node = _paths; |
+ for (var component in p.url.split(path)) { |
+ node = node.children.putIfAbsent(component, () => new _Node()); |
+ } |
+ node.handler = handler; |
+ } |
+ |
+ _onRequest(shelf.Request request) { |
+ var handler; |
+ var handlerIndex; |
+ var node = _paths; |
+ var components = p.url.split(shelfUrl(request).path); |
+ for (var i = 0; i < components.length; i++ ) { |
+ node = node.children[components[i]]; |
+ if (node == null) break; |
+ if (node.handler == null) continue; |
+ handler = node.handler; |
+ handlerIndex = i; |
+ } |
+ |
+ if (handler == null) return new shelf.Response.notFound("Not found."); |
+ |
+ return handler(shelfChange(request, |
+ path: p.joinAll(components.take(handlerIndex + 1)))); |
+ } |
+} |
+ |
+/// A trie node. |
+class _Node { |
+ shelf.Handler handler; |
+ final children = new Map<String, _Node>(); |
+} |