javascriptfirefox-addonhttp-redirectfirefox-addon-restartlessfirefox-addon-overlay

Use HTTP-on-modify-request to redirect URL


I am building an add-on for Firefox that redirect request to a new URL if the URL match some conditions. I've tried this, and it does not work.

I register an observer on HTTP-on-modify-request to process the URL, if the URL match my condition, I will redirect to a new URL.

Here is my code:

var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;

var newUrl = "https://google.com";

function isInBlacklist(url) {
// here will be somemore condition, I just use youtube.com to test
    if (url.indexOf('youtube.com') != -1) {
        return true;
    }
    return false;
}

exports.main = function(options,callbacks) {
// Create observer
httpRequestObserver =
{
    observe: function (subject, topic, data) {
        if (topic == "http-on-modify-request") {
            var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
            var uri = httpChannel.URI;
            var domainLoc = uri.host;

            if (isInBlacklist(domainLoc) === true) {
                httpChannel.cancel(Cr.NS_BINDING_ABORTED);
                var gBrowser = utils.getMostRecentBrowserWindow().gBrowser;
                var domWin = channel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
                var browser = gBrowser.getBrowserForDocument(domWin.top.document);
                browser.loadURI(newUrl);
            }
        }
    },

    register: function () {
        var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
        observerService.addObserver(this, "http-on-modify-request", false);
    },

    unregister: function () {
        var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
        observerService.removeObserver(this, "http-on-modify-request");
    }
};
//register observer
httpRequestObserver.register();
};

exports.onUnload = function(reason) {
    httpRequestObserver.unregister();
};

I am new to Firefox add-on development.


Solution

  • You can redirect a channel by calling nsIHttpChannel.redirectTo. This is not possible once the channel is opened, but in http-on-modify-request it will work.

    So in your code, you can do something like:

    Cu.import("resource://gre/modules/Services.jsm");
    // ...
    
    if (condition) {
      httpChannel.redirectTo(
        Services.io.newURI("http://example.org/", null, null));
    }
    

    It looks like you might be using the Add-on SDK. In that case, read up on Using Chrome Authority.