2

I am looking for a simple solution to catch any re-directions (301, 302 etc.) to retrieve the corresponding from a nsiWebProgress.

Current solution

Right now, I am using the nsIWebProgress.NOTIFY_STATE_DOCUMENT event listener, processing any STATE_REDIRECTING status responses (also known as "flags") and iterating the responseHeaders from the corresponding request's nsIHttpChannel interface , as shown below.

Question

However, I am not sure, if I am using the best event listener (NOTIFY_STATE_DOCUMENT) and if this is really the fastest possible solution.

Furthermore, I am wondering, if has processed any validation of the response's location header at this state, since I am tending to parse the location header by using the sdk/url.URL method, to be sure that the given location header is valid and no scam.


Client request:

GET /garage HTTP/1.1
Host: www.batmans.cave

Server response:

HTTP/1.1 301 Moved Permanently
Location: https://batmans.cave/garage/batmobile

Working example (simplified):

const { Ci } = require("chrome");
const LOCATION_HEADER = "location";

...

interfaces: ["nsIWebProgressListener", "nsISupportsWeakReference"],
add(browser) {
   try {
     browser.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
   } catch (error) {}
},

...

/**
 * Called when the state has changed for the window being watched changes.
 * @see https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWebProgressListener#onStateChange%28%29
 * @param {nsIWebProgress} webProgress
 * @param {nsIRequest} request
 * @param {nsresult} status
 * @param {String} message
 */
onStateChange(webProgress, request, status, message) {
  if (status & Ci.nsIWebProgressListener.STATE_REDIRECTING) {
    const window = webProgress.DOMWindow;

    if (request instanceof Ci.nsIHttpChannel) {
      const httpChannel = request.QueryInterface(Ci.nsIHttpChannel);
      let location;

      httpChannel.visitResponseHeaders(function (header, value) {
        if (header.toLowerCase() == LOCATION_HEADER) {
          location = value;
        }
      });

      if (location) {
        try {
          const url = URL(location).toString();

          console.log("redirect to", url); // OK! "https://batmans.cave/garage/batmobile"
        }
        catch (error) {}
      }
    }
  }
}
mate64
  • 9,876
  • 17
  • 64
  • 96
  • 1
    This is the best solution, because you can load it into a specific tab. The other solution is http observers, but that is at a much higher level, you will have to filter out per tab. – Noitidart Dec 08 '15 at 07:25
  • 1
    This is how to use nsIWebProgressListener in a e10s safe way - https://github.com/Noitidart/Full-Stop – Noitidart Dec 08 '15 at 07:35

0 Answers0