| Index: pkg/appengine/lib/src/server/assets.dart
|
| diff --git a/pkg/appengine/lib/src/server/assets.dart b/pkg/appengine/lib/src/server/assets.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5c7be7d1e3a2ab6efc14b53ed855e10bb9885c20
|
| --- /dev/null
|
| +++ b/pkg/appengine/lib/src/server/assets.dart
|
| @@ -0,0 +1,142 @@
|
| +// Copyright (c) 2014, 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 appengine.assets;
|
| +
|
| +import 'dart:async';
|
| +import 'dart:io';
|
| +
|
| +import 'package:http_server/http_server.dart' show VirtualDirectory;
|
| +import 'package:path/path.dart' show normalize;
|
| +
|
| +import '../appengine_context.dart';
|
| +import '../client_context.dart';
|
| +
|
| +class AssetsManager {
|
| + static final root = 'build/web';
|
| +
|
| + final Uri pubServeUrl;
|
| + final bool usePubServe;
|
| + final client = new HttpClient();
|
| + final VirtualDirectory vd = new VirtualDirectory(root);
|
| +
|
| + AssetsManager(Uri pubServeUrl, bool isDevEnvironment)
|
| + : usePubServe = isDevEnvironment && pubServeUrl != null,
|
| + pubServeUrl = pubServeUrl;
|
| +
|
| + Future _proxyToPub(HttpRequest request, String path) {
|
| + const RESPONSE_HEADERS = const [
|
| + HttpHeaders.CONTENT_LENGTH,
|
| + HttpHeaders.CONTENT_TYPE ];
|
| +
|
| + var uri = pubServeUrl.resolve(path);
|
| + return client.openUrl(request.method, uri)
|
| + .then((proxyRequest) {
|
| + proxyRequest.headers.removeAll(HttpHeaders.ACCEPT_ENCODING);
|
| + return proxyRequest.close();
|
| + })
|
| + .then((proxyResponse) {
|
| + proxyResponse.headers.forEach((name, values) {
|
| + if (RESPONSE_HEADERS.contains(name)) {
|
| + request.response.headers.set(name, values);
|
| + }
|
| + });
|
| + request.response.statusCode = proxyResponse.statusCode;
|
| + request.response.reasonPhrase = proxyResponse.reasonPhrase;
|
| + return proxyResponse.pipe(request.response);
|
| + })
|
| + .catchError((e) {
|
| + // TODO(kevmoo) Use logging here
|
| + print("Unable to connect to 'pub serve' for '${request.uri}': $e");
|
| + throw new AssetError(
|
| + "Unable to connect to 'pub serve' for '${request.uri}': $e");
|
| + });
|
| + }
|
| +
|
| + Future _serveFromFile(HttpRequest request, String path) {
|
| + // Check if the request path is pointing to a static resource.
|
| + path = normalize(path);
|
| + return FileSystemEntity.isFile(root + path).then((exists) {
|
| + if (exists) {
|
| + return vd.serveFile(new File(root + path), request);
|
| + } else {
|
| + return _serve404(request);
|
| + }
|
| + });
|
| + }
|
| +
|
| + Future<Stream<List<int>>> _readFromPub(String path) {
|
| + var uri = pubServeUrl.resolve(path);
|
| + return client.openUrl('GET', uri)
|
| + .then((request) => request.close())
|
| + .then((response) {
|
| + if (response.statusCode == HttpStatus.OK) {
|
| + return response;
|
| + } else {
|
| + throw new AssetError(
|
| + "Failed to fetch asset '$path' from pub: "
|
| + "${response.statusCode}.");
|
| + }
|
| + })
|
| + .catchError((error) {
|
| + if (error is! AssetError) {
|
| + error = new AssetError(
|
| + "Failed to fetch asset '$path' from pub: '${path}': $error");
|
| + }
|
| + throw error;
|
| + });
|
| + }
|
| +
|
| + Future<Stream<List<int>>> _readFromFile(String path) {
|
| + path = normalize(path);
|
| + return FileSystemEntity.isFile(root + path).then((exists) {
|
| + if (exists) {
|
| + return new File(root + path).openRead();
|
| + } else {
|
| + throw new AssetError("Asset '$path' not found");
|
| + }
|
| + });
|
| + }
|
| +
|
| + Future _serve404(HttpRequest request) {
|
| + // Serve 404.
|
| + return request.drain().then((_) {
|
| + request.response.statusCode = HttpStatus.NOT_FOUND;
|
| + return request.response.close();
|
| + });
|
| + }
|
| +
|
| + Future<Stream<List<int>>> read(String path) {
|
| + if (usePubServe) {
|
| + return _readFromPub(path);
|
| + } else {
|
| + return _readFromFile(path);
|
| + }
|
| + }
|
| +
|
| + Future serve(HttpRequest request, String path) {
|
| + if (usePubServe) {
|
| + return _proxyToPub(request, path);
|
| + } else {
|
| + return _serveFromFile(request, path);
|
| + }
|
| + }
|
| +}
|
| +
|
| +class AssetsImpl implements Assets {
|
| + final HttpRequest request;
|
| + final AppengineContext appengineContext;
|
| +
|
| + AssetsImpl(this.request, this.appengineContext);
|
| +
|
| + Future<Stream<List<int>>> read([String path]) {
|
| + return appengineContext.assets.read(
|
| + path == null ? request.uri.path : path);
|
| + }
|
| +
|
| + void serve([String path]) {
|
| + appengineContext.assets.serve(request,
|
| + path == null ? request.uri.path : path);
|
| + }
|
| +}
|
|
|