Index: lib/src/package_config_handler.dart |
diff --git a/lib/src/package_config_handler.dart b/lib/src/package_config_handler.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fd792901fca3599e58fc62843f34b0d20fd75413 |
--- /dev/null |
+++ b/lib/src/package_config_handler.dart |
@@ -0,0 +1,42 @@ |
+// Copyright (c) 2016, 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. |
+ |
+import 'package:package_resolver/package_resolver.dart'; |
+import 'package:path/path.dart' as p; |
+import 'package:shelf/shelf.dart'; |
+import 'package:shelf_static/shelf_static.dart'; |
+ |
+import 'async_handler.dart'; |
+ |
+/// A shelf handler that serves a virtual packages directory based on a package |
+/// config. |
+class PackageConfigHandler { |
+ /// The static handlers for serving entries in the package config, indexed by |
+ /// name. |
+ final _packageHandlers = new Map<String, Handler>(); |
+ |
+ /// The information specifying how to do package resolution. |
+ PackageResolver _resolver; |
+ |
+ PackageConfigHandler(this._resolver); |
+ |
+ /// The callback for handling a single request. |
+ call(Request request) { |
+ var segments = request.url.pathSegments; |
+ return _handlerFor(segments.first)(request.change(path: segments.first)); |
+ } |
+ |
+ /// Creates a handler for [package] based on the package map in [resolver]. |
+ Handler _handlerFor(String package) { |
+ return _packageHandlers.putIfAbsent(package, () { |
+ return new AsyncHandler(_resolver.urlFor(package).then((url) { |
+ var handler = url == null |
+ ? (_) => new Response.notFound("Package $package not found.") |
+ : createStaticHandler(p.fromUri(url), serveFilesOutsidePath: true); |
+ |
+ return handler; |
+ })); |
+ }); |
+ } |
+} |