README for ResponseCache

This commit is contained in:
Tobe O 2018-04-01 21:59:46 -04:00
parent 4c0f77e806
commit 2658c1ff82
2 changed files with 54 additions and 5 deletions

View file

@ -11,5 +11,53 @@ A `Service` class that caches data from one service, storing it in another.
An imaginable use case is storing results from MongoDB or another database in An imaginable use case is storing results from MongoDB or another database in
MemcacheD/Redis. MemcacheD/Redis.
## `Cache` ## `ResponseCache`
*TODO: Documentation* A flexible response cache for Angel.
Use this to improve real and perceived response of Web applications,
as well as to memoize expensive responses.
Supports the `If-Modified-Since` header, as well as storing the contents of
response buffers in memory.
To initialize a simple cache:
```dart
Future configureServer(Angel app) async {
// Simple instance.
var cache = new ResponseCache();
// You can also pass an invalidation timeout.
var cache = new ResponseCache(timeout: const Duration(days: 2));
// Use `patterns` to specify which resources should be cached.
cache.patterns.addAll([
'robots.txt',
new RegExp(r'\.(png|jpg|gif|txt)$'),
new Glob('/public/**/*'),
]);
// REQUIRED: The middleware that serves cached responses
app.use(cache.handleRequest);
// REQUIRED: The response finalizer that saves responses to the cache
app.responseFinalizers.add(cache.responseFinalizer);
}
```
### Purging the Cache
Call `invalidate` to remove a resource from a `ResponseCache`.
Some servers expect a reverse proxy or caching layer to support `PURGE` requests.
If this is your case, make sure to include some sort of validation (maybe IP-based)
to ensure no arbitrary attacker can hack your cache:
```dart
Future configureServer(Angel app) async {
app.addRoute('PURGE', '*', (req, res) {
if (req.ip != '127.0.0.1')
throw new AngelHttpException.forbidden();
return cache.purge(req.uri.path);
});
}
```

View file

@ -32,7 +32,7 @@ class ResponseCache {
} }
/// Removes an entry from the response cache. /// Removes an entry from the response cache.
void invalidate(String path) => _cache.remove(path); void purge(String path) => _cache.remove(path);
/// A middleware that handles requests with an `If-Modified-Since` header. /// A middleware that handles requests with an `If-Modified-Since` header.
/// ///
@ -61,7 +61,8 @@ class ResponseCache {
/// Serves content from the cache, if applicable. /// Serves content from the cache, if applicable.
Future<bool> handleRequest(RequestContext req, ResponseContext res) async { Future<bool> handleRequest(RequestContext req, ResponseContext res) async {
if (res.statusCode == 304) return true; if (!await ifModifiedSince(req, res))
return false;
// Check if there is a cache entry. // Check if there is a cache entry.
for (var pattern in patterns) { for (var pattern in patterns) {
@ -105,7 +106,7 @@ class ResponseCache {
if (now.difference(response.timestamp) < timeout) return true; if (now.difference(response.timestamp) < timeout) return true;
// If the cache entry should be invalidated, then invalidate it. // If the cache entry should be invalidated, then invalidate it.
invalidate(req.uri.path); purge(req.uri.path);
} }
// Save the response. // Save the response.