blob: 7994d4806b01d3a7a143788a50fdacaf8113fcfe [file] [log] [blame]
// 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 'dart:async';
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;
/// The callback for handling a single request.
FutureOr<Response> 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;