Use HTTP-on-modify-request to redirect URL

2.4k views Asked by At

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.

2

There are 2 answers

0
nmaier On BEST ANSWER

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.

0
Janaka Bandara On

You could simply do a

httpChannel.URI.spec = newUrl;

instead of

httpChannel.cancel(Cr.NS_BINDING_ABORTED);
...
browser.loadURI(newUrl);

Not sure how 'safe' it would be in your case, since I'm not exactly sure how other headers in the request (e.g. Cookie) would be manipulated when you change the URL to point to an entirely different domain at this stage.