Browse Source

Change API to just return headers

master
Kornel Lesiński 8 years ago
parent
commit
c7641381cd
  1. 10
      README.md
  2. 15
      index.js
  3. 26
      test/revalidatetest.js

10
README.md

@ -83,7 +83,11 @@ If it returns `false`, then the response may not be matching at all (e.g. it's f
### `responseHeaders()`
Returns updated, filtered set of response headers. Proxies MUST always remove hop-by-hop headers (such as `TE` and `Connection`) and update response age to avoid doubling cache time.
Returns updated, filtered set of response headers to return to clients receiving the cached response. This function is necessary, because proxies MUST always remove hop-by-hop headers (such as `TE` and `Connection`) and update response `Age` to avoid doubling cache time.
### `revalidationHeaders()`
Returns updated, filtered set of request headers to send to the origin server to check if the cached response can be reused. With this set of headers, the origin server may return status 304 indicating the response is still fresh.
### `timeToLive()`
@ -109,7 +113,9 @@ Chances are you'll want to store the `CachePolicy` object along with the cached
* Default cacheability of statuses and methods.
* Requests for stale data.
* Filtering of hop-by-hop headers.
* Basic revalidation request
## Unimplemented
* There's no API for revalidation yet.
* Revalidation of multiple representations
* Updating of response after revalidation

15
index.js

@ -348,29 +348,28 @@ module.exports = class CachePolicy {
};
}
validationRequest(incoming_req) {
revalidationHeaders(incoming_req) {
this._assertRequestHasHeaders(incoming_req);
if (!this._resHeaders.etag && !this._resHeaders['last-modified']) {
return incoming_req; // no validators available
return incoming_req.headers; // no validators available
}
// revalidation allowed via HEAD
if (!this._requestMatches(incoming_req, true)) {
return incoming_req; // not for the same resource
return incoming_req.headers; // not for the same resource
}
const upstream_req = Object.assign({}, incoming_req);
upstream_req.headers = Object.assign({}, incoming_req.headers);
const headers = Object.assign({}, incoming_req.headers);
/* MUST send that entity-tag in any cache validation request (using If-Match or If-None-Match) if an entity-tag has been provided by the origin server. */
if (this._resHeaders.etag) {
upstream_req.headers['if-none-match'] = this._resHeaders.etag;
headers['if-none-match'] = this._resHeaders.etag;
}
/* SHOULD send the Last-Modified value in non-subrange cache validation requests (using If-Modified-Since) if only a Last-Modified value has been provided by the origin server.
Note: This implementation does not understand partial responses (206) */
if (this._resHeaders['last-modified'] && this.storable()) {
upstream_req.headers['if-modified-since'] = this._resHeaders['last-modified'];
headers['if-modified-since'] = this._resHeaders['last-modified'];
}
return upstream_req;
return headers;
}
};

26
test/revalidatetest.js

@ -21,42 +21,42 @@ const alwaysVariableResponse = {headers:Object.assign({'vary':'*'},cacheableResp
describe('Can be revalidated?', function() {
it('ok if method changes to HEAD', function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
const vReq = cache.validationRequest(simpleRequestBut({method:'HEAD'}));
assert.equal(vReq.headers['if-none-match'], '"123456789"');
const headers = cache.revalidationHeaders(simpleRequestBut({method:'HEAD'}));
assert.equal(headers['if-none-match'], '"123456789"');
});
it('not if method mismatch (other than HEAD)',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
const incomingRequest = simpleRequestBut({method:'POST'});
// Returns the same object unmodified, which means no custom validation
assert.strictEqual(incomingRequest, cache.validationRequest(incomingRequest));
assert.strictEqual(incomingRequest.headers, cache.revalidationHeaders(incomingRequest));
});
it('not if url mismatch',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
const incomingRequest = simpleRequestBut({url:'/yomomma'});
assert.strictEqual(incomingRequest, cache.validationRequest(incomingRequest));
assert.strictEqual(incomingRequest.headers, cache.revalidationHeaders(incomingRequest));
});
it('not if host mismatch',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
const incomingRequest = simpleRequestBut({headers:{host:'www.w4c.org'}});
assert.strictEqual(incomingRequest, cache.validationRequest(incomingRequest));
assert.strictEqual(incomingRequest.headers, cache.revalidationHeaders(incomingRequest));
});
it('not if vary fields prevent',function(){
const cache = new CachePolicy(simpleRequest,alwaysVariableResponse);
assert.strictEqual(simpleRequest, cache.validationRequest(simpleRequest));
assert.strictEqual(simpleRequest.headers, cache.revalidationHeaders(simpleRequest));
});
it('when entity tag validator is present', function() {
const cache = new CachePolicy(simpleRequest, etaggedResponse);
const vReq = cache.validationRequest(simpleRequest);
assert.equal(vReq.headers['if-none-match'], '"123456789"');
const headers = cache.revalidationHeaders(simpleRequest);
assert.equal(headers['if-none-match'], '"123456789"');
});
it('when last-modified validator is present', function() {
const cache = new CachePolicy(simpleRequest, lastModifiedResponse);
const vReq = cache.validationRequest(simpleRequest);
assert.equal(vReq.headers['if-modified-since'], 'Tue, 15 Nov 1994 12:45:26 GMT');
const headers = cache.revalidationHeaders(simpleRequest);
assert.equal(headers['if-modified-since'], 'Tue, 15 Nov 1994 12:45:26 GMT');
});
it('not without validators', function() {
const cache = new CachePolicy(simpleRequest, cacheableResponse);
assert.strictEqual(simpleRequest, cache.validationRequest(simpleRequest));
assert.strictEqual(simpleRequest.headers, cache.revalidationHeaders(simpleRequest));
})
});
@ -65,13 +65,13 @@ describe('Validation request', function(){
it('must contain any etag', function(){
const cache = new CachePolicy(simpleRequest,multiValidatorResponse);
const expected = multiValidatorResponse.headers.etag;
const actual = cache.validationRequest(simpleRequest).headers['if-none-match'];
const actual = cache.revalidationHeaders(simpleRequest)['if-none-match'];
assert.equal(actual,expected);
});
it('should send the Last-Modified value',function(){
const cache = new CachePolicy(simpleRequest,multiValidatorResponse);
const expected = multiValidatorResponse.headers['last-modified'];
const actual = cache.validationRequest(simpleRequest).headers['if-modified-since'];
const actual = cache.revalidationHeaders(simpleRequest)['if-modified-since'];
assert.equal(actual,expected);
});

Loading…
Cancel
Save