-
Notifications
You must be signed in to change notification settings - Fork 28
/
cache.js
109 lines (95 loc) · 3.19 KB
/
cache.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
var CacheStore = require("perstore/store/cache").Cache,
shash = require("narwhal/sha").hash;
exports.FetchCache= function(cache, nextApp) {
var config = require("perstore/util/settings").cache || {};
config.alwaysVaryOn = config.alwaysVaryOn || [];
return function(request) {
if (!request.queryString) {
var fp = request.pathInfo;
config.alwaysVaryOn.forEach(function(h){
fp = fp + request.headers[h];
});
request.fingerprintKey = fp;
var fingerprint = shash(fp).toString(16);
request.cacheFingerprint=fingerprint;
var cached = cache.get(fingerprint);
if (cached && cached.content){
var response=JSON.parse(cached.content);
if (response.headers.vary){
var varies = response.headers.vary.split(",");
if (varies.length>0){
var total=0;
varies.forEach(function(v){
if ((config.alwaysVaryOn.indexOf(v)<0) && (request.headers[v])){
total++;
fp = fp + request.headers[v];
}
});
if(total>0){
fingerprint = shash(fp).toString(16);
request.cacheFingerprint = fingerprint;
if(cached && cached.content) {
response = JSON.parse(cached.content);
}else{
response=null;
}
}
request.fingerprintKey = fp;
}
}
if (response) {
//TODO switch to using stat/mtime instead of cacheTimestamp
var expiration = response.cacheTimestamp + ((config.seconds || 60) * 1000);
var current = new Date().getTime();
if (current < expiration){
delete request.cacheFingerprint;
return response;
}
}
}
}
if (nextApp){
return nextApp(request);
}else{
return
}
};
};
exports.UpdateCache = function(cache, nextApp){
var config = require("perstore/util/settings").cache || {};
config.alwaysVaryOn = config.alwaysVaryOn || [];
return function(request) {
var response = nextApp(request);
var fingerprint;
if ( response.status=="200" && request.cacheFingerprint &&
(response.headers['cache-control']!="no-cache") &&
(response.headers['cache-control']!='no-store')){
if (response.headers.vary){
var fp = request.fingerprintKey;
var varies = response.headers.vary.split(",");
if (varies.length>0){
varies.forEach(function(v){
if ((config.alwaysVaryOn && config.alwaysVaryOn.indexOf(v)<0)&&(request.headers[v])){
fp = fp + request.headers[v];
}
});
fingerprint = shash(fp).toString(16);
}
}else{
fingerprint=request.cacheFingerprint;
}
var body = "";
if (response.body.forEach) {
response.body.forEach(function(content){
body+=content;
});
}
var tmp = response.body;
response.body=[body];
response.cacheTimestamp = new Date().getTime();
cache.put({id:fingerprint,content:JSON.stringify(response)});
response.body=tmp;
}
return response;
}
};