Browse Source

JSON roundtrippin

master
Kornel Lesiński 9 years ago
parent
commit
5f209411a8
  1. 4
      README.md
  2. 47
      index.js
  3. 5
      test/requesttest.js
  4. 10
      test/responsetest.js

4
README.md

@ -76,6 +76,10 @@ It generally means the response can't be used any more without revalidation with
Returns number of *milliseconds* until the response becomes stale. After that time (when `timeToLive() <= 0`) the response won't be usable without revalidation.
### `toObject()`/`fromObject(json)`
Chances are you'll want to store the `CachePolicy` object along with the cached response. `obj = policy.toObject()` gives a plain JSON-serializable object. `policy = CachePolicy.fromObject(obj)` creates an instance from it.
# Yo, FRESH
![satisfiesWithoutRevalidation](fresh.jpg)

47
index.js

@ -23,7 +23,12 @@ function parseCacheControl(header) {
}
module.exports = class CachePolicy {
constructor(req, res, {shared, cacheHeuristic} = {}) {
constructor(req, res, {shared, cacheHeuristic, _fromObject} = {}) {
if (_fromObject) {
this._fromObject(_fromObject);
return;
}
if (!res || !res.headers) {
throw Error("Response headers missing");
}
@ -240,4 +245,44 @@ module.exports = class CachePolicy {
stale() {
return this.maxAge() <= this.age();
}
static fromObject(obj) {
return new this(undefined, undefined, {_fromObject:obj});
}
_fromObject(obj) {
if (this._responseTime) throw Error("Reinitialized");
if (!obj || obj.v !== 1) throw Error("Invalid serialization");
this._responseTime = obj.t;
this._isShared = obj.sh;
this._cacheHeuristic = obj.ch;
this._status = obj.st;
this._resHeaders = obj.resh;
this._rescc = obj.rescc;
this._method = obj.m;
this._url = obj.u;
this._host = obj.h;
this._noAuthorization = obj.a;
this._reqHeaders = obj.reqh;
this._reqcc = obj.reqcc;
}
toObject() {
return {
v:1,
t: this._responseTime,
sh: this._isShared,
ch: this._cacheHeuristic,
st: this._status,
resh: this._resHeaders,
rescc: this._rescc,
m: this._method,
u: this._url,
h: this._host,
a: this._noAuthorization,
reqh: this._reqHeaders,
reqcc: this._reqcc,
};
}
};

5
test/requesttest.js

@ -35,6 +35,11 @@ describe('Request properties', function() {
const cache = new CachePolicy({method:'GET',headers:{'authorization': 'test'}}, {headers:{'cache-control':'max-age=0,s-maxage=12'}});
assert(!cache.stale());
assert(cache.storable());
const cache2 = CachePolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject())));
assert(cache2 instanceof CachePolicy);
assert(!cache2.stale());
assert(cache2.storable());
});
it('Private auth is OK', function() {

10
test/responsetest.js

@ -21,6 +21,11 @@ describe('Response headers', function() {
const cache = new CachePolicy(req, {headers:{'cache-control': ',,,,max-age = 456 ,'}});
assert(!cache.stale());
assert.equal(cache.maxAge(), 456);
const cache2 = CachePolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject())));
assert(cache2 instanceof CachePolicy);
assert(!cache2.stale());
assert.equal(cache2.maxAge(), 456);
});
it('quoted syntax', function() {
@ -277,5 +282,10 @@ describe('Response headers', function() {
assert.equal(h.custom, 'header');
assert.equal(h.age, '11');
assert.equal(res.headers.age, '10');
const cache2 = TimeTravellingPolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject())));
assert(cache2 instanceof TimeTravellingPolicy);
const h2 = cache2.responseHeaders();
assert.deepEqual(h, h2);
});
});

Loading…
Cancel
Save