Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: lib/src/barback/barback_server.dart

Issue 1790503005: Provide and respect HTTP cache headers in pub serve. (Closed) Base URL: https://github.com/dart-lang/pub.git@master
Patch Set: Revise! Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | lib/src/command/serve.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..a159b642d72a484ed10e74e18412dbab1cd4a835 100644
--- a/lib/src/barback/barback_server.dart
+++ b/lib/src/barback/barback_server.dart
@@ -3,9 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
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 +91,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 +156,39 @@ 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 = BASE64.encode(sha.close());
+ var previousSha = request.headers["if-none-match"];
+
+ var headers = {
+ // Enabled browser caching of the asset.
+ "Cache-Control": "max-age=3600",
+ "ETag": assetSha
+ };
+
+ if (assetSha == previousSha) {
+ // We're requesting an unchanged asset so don't push its body 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 +203,7 @@ class BarbackServer extends BaseServer<BarbackServerResult> {
// Otherwise, it's some internal error.
return new shelf.Response.internalServerError(body: error.toString());
- });
+ }
}
}
@@ -199,11 +226,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;
}
« no previous file with comments | « no previous file | lib/src/command/serve.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698