google-chromefirefoxgoogle-chrome-extensionfirefox-addon

Retrieve a request using the requestId after the response is received in Firefox extension


I am writing a Firefox extension using the WebRequest. I am in a situation that when I receive the response, I want to look back and find the request associated with this response to retrieve a custom request header. My current code is like this:

browser.webRequest.onBeforeSendHeaders.addListener(
    addCustomHeader, // here I add custom_header:value
    {urls: ["<all_urls>"]},
    ["blocking", "requestHeaders"]
  );

...
browser.webRequest.onHeadersReceived.addListener(
    process_response, // here I want to get back to the request and retrieve the custom header value
    {urls: ["<all_urls>"]},
    ["blocking", "responseHeaders"]
  );

The value of custom_header is set as a global variable, which changes per each request. And when I receive the response of, say, request_1, I want to retrieve the header value from request_1 in the process_response() function. However, if I directly use the value, I found it may have been changed by subsequent requests, say request_2 or request_3.

I noticed the response has a requestId property, and I guess I can use it to find the corresponding request. However, I am not able to find any document or example that tells me how. I'd appreciate for any hint!


Solution

  • Use a global map variable:

    const reqMap = (() => {
      const data = new Map();
      const MAX_AGE = 10 * 60e3; // 10 minutes 
      const cleanup = () => {
        const cutOff = performance.now() - MAX_AGE;
        data.forEach(({ time }, id) => time < cutOff && data.delete(id));
      };
      return {
        set(id, value) {
          cleanup();
          data.set(id, {value, time: performance.now()});
        },
        pop(id) {
          const {value} = data.get(id) || {};
          data.delete(id);
          return value;
        },
      };
    })();
    

    function onBeforeSendHeaders(details) {
      reqMap.set(details.requestId, {any: 'data'});
    }
    
    function onHeadersReceived(details) {
      const data = reqMap.pop(details.requestId);
      if (data) {
        // ............
      }
    }