Browse Source

Revalidation request

master
Andrew Stewart Gibson 8 years ago
committed by Kornel Lesiński
parent
commit
50608382c9
  1. 25
      index.js
  2. 65
      test/revalidatetest.js

25
index.js

@ -347,4 +347,29 @@ module.exports = class CachePolicy {
reqcc: this._reqcc,
};
}
validationRequest(req) {
this._assertRequestHasHeaders(req);
if (!(this._resHeaders.etag || this._resHeaders["last-modified"])) {
return null; // no validators available
}
// revalidation allowed via HEAD
if (!this._requestMatches(req, true)) {
return null; // not for the same resource
}
const vreq = Object.assign({}, req);
vreq.headers = Object.assign({}, 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) {
vreq.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']) {
vreq.headers['if-modified-since'] = this._resHeaders['last-modified'];
}
return vreq;
}
};

65
test/revalidatetest.js

@ -0,0 +1,65 @@
'use strict';
const assert = require('assert');
const CachePolicy = require('..');
const simpleRequest = {method:'GET',headers:{host:'www.w3c.org'},url:'/Protocols/rfc2616/rfc2616-sec14.html'};
const simpleRequestBut = overrides=>Object.assign({},simpleRequest,overrides);
const cacheableResponse = {headers:{'cache-control':'max-age=111'}};
const etaggedResponse = {headers:Object.assign({'etag':'"123456789"'},cacheableResponse.headers)};
const lastModifiedResponse = {headers:Object.assign({'last-modified':'Tue, 15 Nov 1994 12:45:26 GMT'},cacheableResponse.headers)};
const multiValidatorResponse = {headers:Object.assign({},etaggedResponse.headers,lastModifiedResponse.headers)};
const alwaysVariableResponse = {headers:Object.assign({'vary':'*'},cacheableResponse.headers)};
describe('Can be revalidated?', function() {
it('ok if method changes to HEAD',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
assert(cache.validationRequest(simpleRequestBut({method:'HEAD'})));
});
it('not if method mismatch (other than HEAD)',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
assert(!cache.validationRequest(simpleRequestBut({method:'POST'})));
});
it('not if url mismatch',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
assert(!cache.validationRequest(simpleRequestBut({url:'/yomomma'})));
});
it('not if host mismatch',function(){
const cache = new CachePolicy(simpleRequest,etaggedResponse);
assert(!cache.validationRequest(simpleRequestBut({headers:{host:'www.w4c.org'}})))
});
it('not if vary fields prevent',function(){
const cache = new CachePolicy(simpleRequest,alwaysVariableResponse);
assert(!cache.validationRequest(simpleRequest));
});
it('when entity tag validator is present', function() {
const cache = new CachePolicy(simpleRequest, etaggedResponse);
assert(cache.validationRequest(simpleRequest));
});
it('when last-modified validator is present', function() {
const cache = new CachePolicy(simpleRequest, lastModifiedResponse);
assert(cache.validationRequest(simpleRequest));
});
it('not without validators', function() {
const cache = new CachePolicy(simpleRequest, cacheableResponse);
assert(!cache.validationRequest(simpleRequest));
})
});
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'];
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'];
assert.equal(actual,expected);
});
});
Loading…
Cancel
Save