| Index: sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
|
| diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
|
| similarity index 66%
|
| rename from sdk/lib/_internal/pub/lib/src/barback/server.dart
|
| rename to sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
|
| index fabaddcb70cf66e22008011cc86f71480511992d..d8d76c0426c33e84a9cd0d53305076150849a7ff 100644
|
| --- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
|
| +++ b/sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
|
| @@ -15,6 +15,7 @@ import 'package:stack_trace/stack_trace.dart';
|
| import '../barback.dart';
|
| import '../log.dart' as log;
|
| import '../utils.dart';
|
| +import 'base_server.dart';
|
| import 'build_environment.dart';
|
| import 'web_socket_api.dart';
|
|
|
| @@ -22,16 +23,7 @@ import 'web_socket_api.dart';
|
| typedef bool AllowAsset(AssetId id);
|
|
|
| /// A server that serves assets transformed by barback.
|
| -class BarbackServer {
|
| - /// The [BuildEnvironment] being served.
|
| - final BuildEnvironment _environment;
|
| -
|
| - /// The underlying HTTP server.
|
| - final HttpServer _server;
|
| -
|
| - /// All currently open [WebSocket] connections.
|
| - final _webSockets = new Set<WebSocket>();
|
| -
|
| +class BarbackServer extends BaseServer<BarbackServerResult> {
|
| /// The directory in the root which will serve as the root of this server as
|
| /// a native platform path.
|
| ///
|
| @@ -40,15 +32,6 @@ class BarbackServer {
|
| /// are available.
|
| final String rootDirectory;
|
|
|
| - /// The server's port.
|
| - final int port;
|
| -
|
| - /// The server's address.
|
| - final InternetAddress address;
|
| -
|
| - /// The server's base URL.
|
| - Uri get url => baseUrlForAddress(address, port);
|
| -
|
| /// Optional callback to determine if an asset should be served.
|
| ///
|
| /// This can be set to allow outside code to filter out assets. Pub serve
|
| @@ -58,14 +41,10 @@ class BarbackServer {
|
| /// If this is `null`, all assets may be served.
|
| AllowAsset allowAsset;
|
|
|
| - /// The results of requests handled by the server.
|
| - ///
|
| - /// These can be used to provide visual feedback for the server's processing.
|
| - /// This stream is also used to emit any programmatic errors that occur in the
|
| - /// server.
|
| - Stream<BarbackServerResult> get results => _resultsController.stream;
|
| - final _resultsController =
|
| - new StreamController<BarbackServerResult>.broadcast();
|
| + // TODO(rnystrom): Remove this when the Editor is using the admin server.
|
| + // port. See #17640.
|
| + /// All currently open [WebSocket] connections.
|
| + final _webSockets = new Set<WebSocket>();
|
|
|
| /// Creates a new server and binds it to [port] of [host].
|
| ///
|
| @@ -79,19 +58,15 @@ class BarbackServer {
|
| });
|
| }
|
|
|
| - BarbackServer._(this._environment, HttpServer server, this.rootDirectory)
|
| - : _server = server,
|
| - port = server.port,
|
| - address = server.address {
|
| - Chain.track(_server).listen(_handleRequest, onError: (error, stackTrace) {
|
| - _resultsController.addError(error, stackTrace);
|
| - close();
|
| - });
|
| - }
|
| + BarbackServer._(BuildEnvironment environment, HttpServer server,
|
| + this.rootDirectory)
|
| + : super(environment, server);
|
|
|
| - /// Closes this server.
|
| + // TODO(rnystrom): Remove this when the Editor is using the admin server.
|
| + // port. See #17640.
|
| + /// Closes the server.
|
| Future close() {
|
| - var futures = [_server.close(), _resultsController.close()];
|
| + var futures = [super.close()];
|
| futures.addAll(_webSockets.map((socket) => socket.close()));
|
| return Future.wait(futures);
|
| }
|
| @@ -115,18 +90,20 @@ class BarbackServer {
|
| if (parts.isNotEmpty && parts.first == "/") parts = parts.skip(1);
|
|
|
| var relativePath = path.url.join(rootDirectory, path.url.joinAll(parts));
|
| - return new AssetId(_environment.rootPackage.name, relativePath);
|
| + return new AssetId(environment.rootPackage.name, relativePath);
|
| }
|
|
|
| /// Handles an HTTP request.
|
| - void _handleRequest(HttpRequest request) {
|
| + void handleRequest(HttpRequest request) {
|
| + // TODO(rnystrom): Remove this when the Editor is using the admin server.
|
| + // port. See #17640.
|
| if (WebSocketTransformer.isUpgradeRequest(request)) {
|
| _handleWebSocket(request);
|
| return;
|
| }
|
|
|
| if (request.method != "GET" && request.method != "HEAD") {
|
| - _methodNotAllowed(request);
|
| + methodNotAllowed(request);
|
| return;
|
| }
|
|
|
| @@ -136,30 +113,30 @@ class BarbackServer {
|
| } on FormatException catch (ex) {
|
| // If we got here, we had a path like "/packages" which is a special
|
| // directory, but not a valid path since it lacks a following package name.
|
| - _notFound(request, ex.message);
|
| + notFound(request, ex.message);
|
| return;
|
| }
|
|
|
| // See if the asset should be blocked.
|
| if (allowAsset != null && !allowAsset(id)) {
|
| - _notFound(request, "Asset $id is not available in this configuration.");
|
| + notFound(request, "Asset $id is not available in this configuration.");
|
| return;
|
| }
|
|
|
| - _logRequest(request, "Loading $id");
|
| - _environment.barback.getAssetById(id).then((result) {
|
| - _logRequest(request, "getAssetById($id) returned");
|
| + logRequest(request, "Loading $id");
|
| + environment.barback.getAssetById(id).then((result) {
|
| + logRequest(request, "getAssetById($id) returned");
|
| return result;
|
| }).then((asset) => _serveAsset(request, asset)).catchError((error, trace) {
|
| if (error is! AssetNotFoundException) throw error;
|
| - return _environment.barback.getAssetById(id.addExtension("/index.html"))
|
| + return environment.barback.getAssetById(id.addExtension("/index.html"))
|
| .then((asset) {
|
| if (request.uri.path.endsWith('/')) return _serveAsset(request, asset);
|
|
|
| // We only want to serve index.html if the URL explicitly ends in a
|
| // slash. For other URLs, we redirect to one with the slash added to
|
| // implicitly support that too. This follows Apache's behavior.
|
| - _logRequest(request, "302 Redirect to ${request.uri}/");
|
| + logRequest(request, "302 Redirect to ${request.uri}/");
|
| request.response.statusCode = 302;
|
| request.response.headers.add('location', '${request.uri}/');
|
| request.response.close();
|
| @@ -171,27 +148,39 @@ class BarbackServer {
|
| }).catchError((error, trace) {
|
| if (error is! AssetNotFoundException) {
|
| trace = new Chain.forTrace(trace);
|
| - _logRequest(request, "$error\n$trace");
|
| + logRequest(request, "$error\n$trace");
|
|
|
| - _resultsController.addError(error, trace);
|
| + addError(error, trace);
|
| close();
|
| return;
|
| }
|
|
|
| - _resultsController.add(
|
| - new BarbackServerResult._failure(request.uri, id, error));
|
| - _notFound(request, error);
|
| + addResult(new BarbackServerResult._failure(request.uri, id, error));
|
| + notFound(request, error);
|
| });
|
| }
|
|
|
| + // TODO(rnystrom): Remove this when the Editor is using the admin server.
|
| + // port. See #17640.
|
| + /// Creates a web socket for [request] which should be an upgrade request.
|
| + void _handleWebSocket(HttpRequest request) {
|
| + Chain.track(WebSocketTransformer.upgrade(request)).then((socket) {
|
| + _webSockets.add(socket);
|
| + var api = new WebSocketApi(socket, environment);
|
| +
|
| + return api.listen().whenComplete(() {
|
| + _webSockets.remove(api);
|
| + });
|
| + }).catchError(addError);
|
| + }
|
| +
|
| /// Serves the body of [asset] on [request]'s response stream.
|
| ///
|
| /// Returns a future that completes when the response has been succesfully
|
| /// written.
|
| Future _serveAsset(HttpRequest request, Asset asset) {
|
| return validateStream(asset.read()).then((stream) {
|
| - _resultsController.add(
|
| - new BarbackServerResult._success(request.uri, asset.id));
|
| + addResult(new BarbackServerResult._success(request.uri, asset.id));
|
| var mimeType = lookupMimeType(asset.id.path);
|
| if (mimeType != null) {
|
| request.response.headers.add('content-type', mimeType);
|
| @@ -201,23 +190,22 @@ class BarbackServer {
|
| // Log successful requests both so we can provide debugging
|
| // information and so scheduled_test knows we haven't timed out while
|
| // loading transformers.
|
| - _logRequest(request, "Served ${asset.id}");
|
| + logRequest(request, "Served ${asset.id}");
|
| request.response.close();
|
| });
|
| }).catchError((error, trace) {
|
| - _resultsController.add(
|
| - new BarbackServerResult._failure(request.uri, asset.id, error));
|
| + addResult(new BarbackServerResult._failure(request.uri, asset.id, error));
|
|
|
| // If we couldn't read the asset, handle the error gracefully.
|
| if (error is FileSystemException) {
|
| // Assume this means the asset was a file-backed source asset
|
| // and we couldn't read it, so treat it like a missing asset.
|
| - _notFound(request, error);
|
| + notFound(request, error);
|
| return;
|
| }
|
|
|
| trace = new Chain.forTrace(trace);
|
| - _logRequest(request, "$error\n$trace");
|
| + logRequest(request, "$error\n$trace");
|
|
|
| // Otherwise, it's some internal error.
|
| request.response.statusCode = 500;
|
| @@ -226,48 +214,6 @@ class BarbackServer {
|
| request.response.close();
|
| });
|
| }
|
| -
|
| - /// Creates a web socket for [request] which should be an upgrade request.
|
| - void _handleWebSocket(HttpRequest request) {
|
| - Chain.track(WebSocketTransformer.upgrade(request)).then((socket) {
|
| - _webSockets.add(socket);
|
| - var api = new WebSocketApi(socket, _environment);
|
| -
|
| - return api.listen().whenComplete(() {
|
| - _webSockets.remove(api);
|
| - });
|
| - }).catchError(_resultsController.addError);
|
| - }
|
| -
|
| - /// Responds to [request] with a 405 response and closes it.
|
| - void _methodNotAllowed(HttpRequest request) {
|
| - _logRequest(request, "405 Method Not Allowed");
|
| - request.response.statusCode = 405;
|
| - request.response.reasonPhrase = "Method Not Allowed";
|
| - request.response.headers.add('Allow', 'GET, HEAD');
|
| - request.response.write(
|
| - "The ${request.method} method is not allowed for ${request.uri}.");
|
| - request.response.close();
|
| - }
|
| -
|
| - /// Responds to [request] with a 404 response and closes it.
|
| - void _notFound(HttpRequest request, message) {
|
| - _logRequest(request, "404 Not Found");
|
| -
|
| - // Force a UTF-8 encoding so that error messages in non-English locales are
|
| - // sent correctly.
|
| - request.response.headers.contentType =
|
| - ContentType.parse("text/plain; charset=utf-8");
|
| -
|
| - request.response.statusCode = 404;
|
| - request.response.reasonPhrase = "Not Found";
|
| - request.response.write(message);
|
| - request.response.close();
|
| - }
|
| -
|
| - /// Log [message] at [log.Level.FINE] with metadata about [request].
|
| - void _logRequest(HttpRequest request, String message) =>
|
| - log.fine("BarbackServer ${request.method} ${request.uri}\n$message");
|
| }
|
|
|
| /// The result of the server handling a URL.
|
|
|