Chromium Code Reviews| Index: lib/src/barback/barback_server.dart |
| diff --git a/lib/src/barback/barback_server.dart b/lib/src/barback/barback_server.dart |
| index b6f5d5766d02c8a355edef9c30d4b8f529bde9c7..ba055aafcdbb46728f93826e35b70bba0e6f314c 100644 |
| --- a/lib/src/barback/barback_server.dart |
| +++ b/lib/src/barback/barback_server.dart |
| @@ -6,6 +6,7 @@ import 'dart:async'; |
| import 'dart:io'; |
| import 'package:barback/barback.dart'; |
| +import "package:crypto/crypto.dart"; |
| import 'package:mime/mime.dart'; |
| import 'package:path/path.dart' as path; |
| import 'package:shelf/shelf.dart' as shelf; |
| @@ -89,7 +90,7 @@ class BarbackServer extends BaseServer<BarbackServerResult> { |
| } |
| /// Handles an HTTP request. |
| - handleRequest(shelf.Request request) { |
| + Future<shelf.Response> handleRequest(shelf.Request request) async { |
| if (request.method != "GET" && request.method != "HEAD") { |
| return methodNotAllowed(request); |
| } |
| @@ -154,14 +155,38 @@ class BarbackServer extends BaseServer<BarbackServerResult> { |
| } |
| /// Returns the body of [asset] as a response to [request]. |
| - Future<shelf.Response> _serveAsset(shelf.Request request, Asset asset) { |
| - return validateStream(asset.read()).then((stream) { |
| - addResult(new BarbackServerResult._success(request.url, asset.id)); |
| - var headers = {}; |
| - var mimeType = lookupMimeType(asset.id.path); |
| - if (mimeType != null) headers['Content-Type'] = mimeType; |
| - return new shelf.Response.ok(stream, headers: headers); |
| - }).catchError((error, trace) { |
| + Future<shelf.Response> _serveAsset(shelf.Request request, Asset asset) async { |
| + try { |
| + var pair = tee(await validateStream(asset.read())); |
| + var responseStream = pair.first; |
| + var hashStream = pair.last; |
| + |
| + // Allow the asset to be cached based on its content hash. |
| + var sha = new SHA1(); |
| + await hashStream.forEach((chunk) { |
| + sha.add(chunk); |
| + }); |
| + |
| + var assetSha = CryptoUtils.bytesToHex(sha.close()); |
|
nweiz
2016/03/12 01:30:51
CryptoUtils is going to get removed once I get aro
Bob Nystrom
2016/03/14 19:15:10
I didn't see anything related to hex in there, so
nweiz
2016/03/14 19:29:13
https://www.dartdocs.org/documentation/convert/1.0
|
| + var previousSha = request.headers["if-none-match"]; |
| + |
| + var headers = { |
| + "Cache-Control": "max-age=3600", |
|
nweiz
2016/03/12 01:30:51
It's not clear to me why this is being set. Consid
Bob Nystrom
2016/03/14 19:15:10
I'm an HTTP noob, but from what I read, you have t
|
| + "ETag": assetSha |
| + }; |
| + |
| + if (assetSha == previousSha) { |
| + // We're requesting an unchanged asset so don't push it down the wire |
| + // again. |
| + addResult(new BarbackServerResult._cached(request.url, asset.id)); |
| + return new shelf.Response.notModified(headers: headers); |
| + } else { |
| + addResult(new BarbackServerResult._success(request.url, asset.id)); |
| + var mimeType = lookupMimeType(asset.id.path); |
| + if (mimeType != null) headers['Content-Type'] = mimeType; |
| + return new shelf.Response.ok(responseStream, headers: headers); |
| + } |
| + } catch (error, trace) { |
| addResult(new BarbackServerResult._failure(request.url, asset.id, error)); |
| // If we couldn't read the asset, handle the error gracefully. |
| @@ -176,7 +201,7 @@ class BarbackServer extends BaseServer<BarbackServerResult> { |
| // Otherwise, it's some internal error. |
| return new shelf.Response.internalServerError(body: error.toString()); |
| - }); |
| + } |
| } |
| } |
| @@ -199,11 +224,20 @@ class BarbackServerResult { |
| /// Whether the request was served successfully. |
| bool get isSuccess => error == null; |
| + /// Whether the request was for a previously cached asset. |
| + final bool isCached; |
| + |
| /// Whether the request was served unsuccessfully. |
| bool get isFailure => !isSuccess; |
| BarbackServerResult._success(this.url, this.id) |
| - : error = null; |
| + : error = null, |
| + isCached = false; |
| + |
| + BarbackServerResult._cached(this.url, this.id) |
| + : error = null, |
| + isCached = true; |
| - BarbackServerResult._failure(this.url, this.id, this.error); |
| + BarbackServerResult._failure(this.url, this.id, this.error) |
| + : isCached = false; |
| } |