Socket
Socket
Sign inDemoInstall

http-cache-semantics

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http-cache-semantics - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

125

index.js

@@ -25,33 +25,40 @@ 'use strict';

function CachePolicy(req, res, {shared, cacheHeuristic} = {}) {
if (!res || !res.headers) {
throw Error("Response headers missing");
}
if (!req || !req.headers) {
throw Error("Request headers missing");
}
module.exports = class CachePolicy {
constructor(req, res, {shared, cacheHeuristic, _fromObject} = {}) {
if (_fromObject) {
this._fromObject(_fromObject);
return;
}
this._responseTime = this.now();
this._isShared = shared !== false;
this._cacheHeuristic = undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE
if (!res || !res.headers) {
throw Error("Response headers missing");
}
if (!req || !req.headers) {
throw Error("Request headers missing");
}
this._status = 'status' in res ? res.status : 200;
this._resHeaders = res.headers;
this._rescc = parseCacheControl(res.headers['cache-control']);
this._method = 'method' in req ? req.method : 'GET';
this._url = req.url;
this._reqHeaders = req.headers;
this._reqcc = parseCacheControl(req.headers['cache-control']);
this._responseTime = this.now();
this._isShared = shared !== false;
this._cacheHeuristic = undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE
// When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive
// as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1).
if (!res.headers['cache-control'] && /no-cache/.test(res.headers.pragma)) {
this._rescc['no-cache'] = true;
this._status = 'status' in res ? res.status : 200;
this._resHeaders = res.headers;
this._rescc = parseCacheControl(res.headers['cache-control']);
this._method = 'method' in req ? req.method : 'GET';
this._url = req.url;
this._host = req.headers.host;
this._noAuthorization = !req.headers.authorization;
this._reqHeaders = res.headers.vary ? req.headers : null; // Don't keep all request headers if they won't be used
this._reqcc = parseCacheControl(req.headers['cache-control']);
// When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive
// as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1).
if (!res.headers['cache-control'] && /no-cache/.test(res.headers.pragma)) {
this._rescc['no-cache'] = true;
}
}
}
CachePolicy.prototype = {
now() {
return Date.now();
},
}

@@ -71,3 +78,3 @@ storable() {

// the Authorization header field does not appear in the request, if the cache is shared,
(!this._isShared || !this._reqHeaders.authorization || this._allowsStoringAuthenticated()) &&
(!this._isShared || this._noAuthorization || this._allowsStoringAuthenticated()) &&
// the response either:

@@ -84,3 +91,3 @@ (

);
},
}

@@ -92,3 +99,3 @@ _hasExplicitExpiration() {

this._resHeaders.expires;
},
}

@@ -110,3 +117,3 @@ satisfiesWithoutRevalidation(req) {

return (!this._url || this._url === req.url) &&
(this._reqHeaders.host === req.headers.host) &&
(this._host === req.headers.host) &&
// the request method associated with the stored response allows it to be used for the presented request, and

@@ -119,3 +126,3 @@ (!req.method || this._method === req.method) &&

!this.stale() // TODO: allow stale
},
}

@@ -125,3 +132,3 @@ _allowsStoringAuthenticated() {

return this._rescc['must-revalidate'] || this._rescc.public || this._rescc['s-maxage'];
},
}

@@ -134,3 +141,3 @@ _varyMatches(req) {

// A Vary header field-value of "*" always fails to match
if (this._reqHeaders.vary === '*') {
if (this._resHeaders.vary === '*') {
return false;

@@ -144,3 +151,3 @@ }

return true;
},
}

@@ -162,3 +169,3 @@ responseHeaders() {

return headers;
},
}

@@ -176,3 +183,3 @@ /**

return dateValue;
},
}

@@ -194,3 +201,3 @@ /**

return age + residentTime;
},
}

@@ -244,13 +251,51 @@ maxAge() {

return 0;
},
}
timeToLive() {
return Math.max(0, this.maxAge() - this.age())*1000;
},
}
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,
};
}
};
module.exports = CachePolicy;
{
"name": "http-cache-semantics",
"version": "3.1.0",
"version": "3.2.0",
"description": "Parses Cache-Control headers and friends",

@@ -5,0 +5,0 @@ "main": "index.js",

# Can I cache this?
`CachePolicy` implements HTTP cache semantics. It can tell when responses can be reused from cache, taking into account [RFC 7234](http://httpwg.org/specs/rfc7234.html) rules for user agents and shared caches. It's aware of many tricky details such as the `Vary` header, proxy revalidation, authenticated responses.
`CachePolicy` can tell when responses can be reused from cache, taking into account [HTTP RFC 7234](http://httpwg.org/specs/rfc7234.html) rules for user agents and shared caches. It's aware of many tricky details such as the `Vary` header, proxy revalidation, and authenticated responses.

@@ -79,2 +79,6 @@ ## Usage

### `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

@@ -81,0 +85,0 @@

@@ -38,2 +38,7 @@ 'use strict';

assert(cache.storable());
const cache2 = CachePolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject())));
assert(cache2 instanceof CachePolicy);
assert(!cache2.stale());
assert(cache2.storable());
});

@@ -40,0 +45,0 @@

@@ -24,2 +24,7 @@ 'use strict';

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);
});

@@ -281,3 +286,8 @@

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);
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with âšĄïž by Socket Inc