CacheEntry.sys.mjs (3040B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const lazy = {}; 6 7 ChromeUtils.defineESModuleGetters( 8 lazy, 9 { 10 NetworkHelper: 11 "resource://devtools/shared/network-observer/NetworkHelper.sys.mjs", 12 }, 13 { global: "contextual" } 14 ); 15 16 /** 17 * Global cache session object. 18 */ 19 let gCacheSession = null; 20 21 /** 22 * Get (and create if necessary) a cache session / cache storage session. 23 * 24 * @param {nsIRequest} request 25 */ 26 function getCacheSession(request) { 27 if (!gCacheSession) { 28 try { 29 const cacheService = Services.cache2; 30 if (cacheService) { 31 let loadContext = lazy.NetworkHelper.getRequestLoadContext(request); 32 if (!loadContext) { 33 // Get default load context if we can't fetch. 34 loadContext = Services.loadContextInfo.default; 35 } 36 gCacheSession = cacheService.diskCacheStorage(loadContext); 37 } 38 } catch (e) { 39 gCacheSession = null; 40 } 41 } 42 43 return gCacheSession; 44 } 45 46 /** 47 * Parses a cache entry returned from the backend to build a response cache 48 * object. 49 * 50 * @param {nsICacheEntry} cacheEntry 51 * The cache entry from the backend. 52 * 53 * @returns {object} 54 * A responseCache object expected by RDP. 55 */ 56 function buildResponseCacheObject(cacheEntry) { 57 const cacheObject = {}; 58 try { 59 if (cacheEntry.storageDataSize) { 60 cacheObject.storageDataSize = cacheEntry.storageDataSize; 61 } 62 } catch (e) { 63 // We just need to handle this in case it's a js file of 0B. 64 } 65 if (cacheEntry.expirationTime) { 66 cacheObject.expirationTime = cacheEntry.expirationTime; 67 } 68 if (cacheEntry.fetchCount) { 69 cacheObject.fetchCount = cacheEntry.fetchCount; 70 } 71 if (cacheEntry.lastFetched) { 72 cacheObject.lastFetched = cacheEntry.lastFetched; 73 } 74 if (cacheEntry.lastModified) { 75 cacheObject.lastModified = cacheEntry.lastModified; 76 } 77 if (cacheEntry.deviceID) { 78 cacheObject.deviceID = cacheEntry.deviceID; 79 } 80 return cacheObject; 81 } 82 83 /** 84 * Does the fetch for the cache entry from the session. 85 * 86 * @param {nsIRequest} request 87 * The request object. 88 * 89 * @returns {Promise} 90 * Promise which resolve a response cache object object, or null if none 91 * was available. 92 */ 93 export function getResponseCacheObject(request) { 94 const cacheSession = getCacheSession(request); 95 if (!cacheSession) { 96 return Promise.resolve(null); 97 } 98 99 return new Promise(resolve => { 100 cacheSession.asyncOpenURI( 101 request.URI, 102 "", 103 Ci.nsICacheStorage.OPEN_SECRETLY, 104 { 105 onCacheEntryCheck: () => { 106 return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; 107 }, 108 onCacheEntryAvailable: cacheEntry => { 109 if (cacheEntry) { 110 const cacheObject = buildResponseCacheObject(cacheEntry); 111 resolve(cacheObject); 112 } else { 113 resolve(null); 114 } 115 }, 116 } 117 ); 118 }); 119 }