tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }