105

I am developing a new Firefox addon that intercept all Firefox's network traffic (http(s) requests with http-on-modify-request)

With my current code, I am able to separate requests coming from web-pages/tabs and all the other components (RSS feed updates, XHR requests from XPCOM components, extensions, extensions manager, etc.)

I would like to identify who initiate a request other than the tab's traffic with precision not just the whole group? (RSS, XPCOM components, extensions, extensions manager, etc)

Example: a hypothetical custom variable requestRequestor would have a value to identify a specific addon or RSS update etc.

I found this similar question but without a solution.

Current code to identify the whole group (getting the browser that fires the http-on-modify-request notification) is:

Components.utils.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(httpObs, 'http-on-modify-request', false);
//Services.obs.removeObserver(httpObs, 'http-on-modify-request'); //uncomment this line, or run this line when you want to remove the observer

var httpObs = {
    observe: function (aSubject, aTopic, aData) {
        if (aTopic == 'http-on-modify-request') {
            /*start - do not edit here*/
            var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel); //i used nsIHttpChannel but i guess you can use nsIChannel, im not sure why though
            var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
            //var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
            var loadContext;
            try {
                loadContext = interfaceRequestor.getInterface(Components.interfaces.nsILoadContext);
            } catch (ex) {
                try {
                    loadContext = aSubject.loadGroup.notificationCallbacks.getInterface(Components.interfaces.nsILoadContext);
                    //in ff26 aSubject.loadGroup.notificationCallbacks was null for me, i couldnt find a situation where it wasnt null, but whenever this was null, and i knew a loadContext is supposed to be there, i found that "interfaceRequestor.getInterface(Components.interfaces.nsILoadContext);" worked fine, so im thinking in ff26 it doesnt use aSubject.loadGroup.notificationCallbacks anymore, but im not sure
                } catch (ex2) {
                    loadContext = null;
                    //this is a problem i dont know why it would get here
                }
            }
            /*end do not edit here*/
            /*start - do all your edits below here*/
            var url = oHttp.URI.spec; //can get url without needing loadContext
            if (loadContext) {
                var contentWindow = loadContext.associatedWindow; //this is the HTML window of the page that just loaded
                //aDOMWindow this is the firefox window holding the tab
                var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
                var gBrowser = aDOMWindow.gBrowser; //this is the gBrowser object of the firefox window this tab is in
                var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
                var browser = aTab.linkedBrowser; //this is the browser within the tab //this is what the example in the previous section gives
                //end getting other useful stuff
            } else {
                Components.utils.reportError('EXCEPTION: Load Context Not Found!!');
                //this is likely no big deal as the channel proably has no associated window, ie: the channel was loading some resource. but if its an ajax call you may end up here
            }
        }
    }
};
intika
  • 8,448
  • 5
  • 36
  • 55
  • 9
    Wow fantastic work here, did you see this topic: http://stackoverflow.com/questions/27483651/firefox-addon-monitoring-network/27492685#27492685 Its more of a topic which you may be able to contribute to, Im very interested to see how you are identifying sources so far. – Noitidart Jun 30 '15 at 05:03
  • 2
    Thanks bro for your link the more info i have on firefox requests etc. the more my addon will be better, working on an advanced security addon, not easy though, (it's just a hobby the addon will be public ;) i will let you know on github) – intika Jun 30 '15 at 05:35
  • My pleasure man helping you will help share with the open source firefox world some real cool tech so keep up the awesome work! – Noitidart Jun 30 '15 at 07:25
  • 1
    Also here's a the `loadContextAndGoodies` function I wrote which can use some improvement, I wrote it awhile ago but please enhance if possible. https://gist.github.com/Noitidart/644494bdc26f996739ef#file-_ff-addon-snippet-loadcontextandgoodies-js-L38 you seem to be using an older version of that snippet in your code above, so using this snippet would clean up that code above, and the snippet probably has some enhancments (i dont know i didnt compare :P ) – Noitidart Jun 30 '15 at 07:28
  • 2
    yeah i saw your code in the other question just added it and testing it ;) will post a pull request if needed ;) – intika Jun 30 '15 at 08:13
  • 2
    thanks for the PR I did a pr on your pr :) https://gist.github.com/Noitidart/644494bdc26f996739ef#comment-1483890 – Noitidart Jul 01 '15 at 02:10
  • Wouldn't the `referer` (mind the misspelling) header be what you're looking for? Assuming that you want to separate traffic coming from Tabs and Extensions (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) – Joeri May 04 '20 at 11:33
  • @intika maybe you can try to capture the stacktrace of the request. I know you can log it via `console.trace(obj)` or capture it in a variable via `Error().trace`. So maybe that could word, though it would be a rather dirty solution – Joeri May 04 '20 at 22:45
  • @Joeri The Referer request header contains the address of the previous **web page**... so no, the referer can not be used here it can not identify which component made the request neither it is meant for that. the current code already separate requests from web-pages/tabs and the other firefox's components (feed updates, extensions requests, XHR requests from XPCOM components, etc). The question is detailed enough, the code is meant to be used in an extension and tracing a request is useless as it won't permit to identify the requester. – intika May 04 '20 at 22:56
  • 1
    Not really an answer but... I faced this problem in the past, and I believe it's an internal limitation of Firefox -- it simply doesn't track who initiated the request and why. It may be useful to know that Chrome dev tools (recently!) got this feature: https://developers.google.com/web/updates/2019/12/devtools#initiators – Jacopo May 05 '20 at 03:14
  • have you seen this answer https://stackoverflow.com/questions/10719606/is-it-possible-to-know-the-target-domwindow-for-an-httprequest Found this answer from this art https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/3.5/Updating_extensions#Getting_a_load_context_from_a_request – Michael Warner May 18 '20 at 12:03
  • @MichaelWarner your linked an interesting QA, but unfortunately `nsILoadContext` only work for request made by a **window object**, and thus can not help to identify the other targeted requests they are out of it's scope... the current code already separate request from window object and the other components. – intika May 18 '20 at 12:25

1 Answers1

2

As of June 2020, there is no official method/way of achieving http request requester filtering/identification.

Currently the only possibility is what is done on the question's code which is separating requests from web-pages/tabs and the other Firefox's components (feed updates, extensions requests, XHR requests from XPCOM components, etc).

As mentioned on the comments this is an internal limitation of Firefox. The current Firefox's core code does not implement a requester tracking and thus does not know who initiated the request and why. It may be useful to know that Chrome dev tools got recently this feature.

intika
  • 8,448
  • 5
  • 36
  • 55