1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | export function getCacheExpiry(xhr){
|
9 | const expiresHeader = xhr.getResponseHeader('Expires');
|
10 | const cacheControlHeader = xhr.getResponseHeader('Cache-Control');
|
11 |
|
12 | let expiry = parseCacheControlHeader(cacheControlHeader);
|
13 | if(expiry === undefined) {
|
14 | expiry = parseExpiresHeader(expiresHeader);
|
15 | }
|
16 | expiry = nullifyInvalidExpiration(expiry);
|
17 | return expiry;
|
18 | }
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | function parseCacheControlHeader(cacheControlHeader){
|
27 | if(cacheControlHeader === null || cacheControlHeader === undefined){
|
28 | return undefined;
|
29 | }
|
30 | const headerData = cacheControlHeader.split(',');
|
31 | let expiry, keyword;
|
32 | for(let i=0; i<headerData.length; i++){
|
33 | keyword = headerData[i].trim();
|
34 | if(keyword.includes('max-age')){
|
35 | expiry = parseCacheControlAge(keyword, expiry);
|
36 | }else{
|
37 | expiry = parseCacheControlKeyword(keyword, expiry);
|
38 | }
|
39 | }
|
40 | return expiry;
|
41 | }
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | function parseCacheControlAge(maxAge, expiry){
|
49 | if(expiry === null){
|
50 | return expiry;
|
51 | }
|
52 | let seconds = maxAge.split('=')[1].trim();
|
53 | seconds = parseInt(seconds, 10);
|
54 | if(isNaN(seconds)){
|
55 | return undefined;
|
56 | }else{
|
57 | return nowPlusSeconds(seconds);
|
58 | }
|
59 | }
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | function parseCacheControlKeyword(keyword, expiry){
|
66 | if(keyword.includes('public') || keyword.includes('private')){
|
67 | return expiry;
|
68 | }
|
69 | if(keyword.includes('no-cache') || keyword.includes('no-store')){
|
70 | return null;
|
71 | }
|
72 | if(keyword.includes('must-revalidate') || keyword.includes('proxy-revalidate')){
|
73 | return expiry;
|
74 | }
|
75 | if(keyword.includes('s-maxage')){
|
76 | return expiry;
|
77 | }
|
78 | return expiry;
|
79 | }
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 | function parseExpiresHeader(expiresHeader){
|
88 | if(expiresHeader === null || expiresHeader === undefined) {
|
89 | return undefined;
|
90 | }
|
91 | const expires = new Date(expiresHeader);
|
92 | if(expires.toString() === 'Invalid Date'){
|
93 | return null;
|
94 | }
|
95 | return expires;
|
96 | }
|
97 |
|
98 |
|
99 |
|
100 |
|
101 | function nullifyInvalidExpiration(expiration){
|
102 | if(expiration instanceof Date && expiration < new Date()){
|
103 | return null;
|
104 | }
|
105 | return expiration;
|
106 | }
|
107 |
|
108 |
|
109 |
|
110 |
|
111 | export function nowPlusSeconds(seconds){
|
112 | const now = new Date();
|
113 | now.setTime(now.getTime() + seconds * 1000);
|
114 | return now;
|
115 | }
|