I am developing a Firefox extension on the Addon SDK (V1.9).
Objective
I need to examine HTTP requests for a specific content type before they are loaded (before the request is sent).
Problem
When adding an observer through the 'observer-service' module, I use "http-on-modify-request" to examine all HTTP requests. This provides the headers. However, when checking for content-type, it is never set on request.
Content-type is indeed set on response, which I examine using "http-on-examine-response". But this means that the request has already loaded, defeating the purpose of my extension.
Edit
@Wladimir Palant Thanks for pointing out that content-type is not set when the request headers are being sent.
I am trying to test HTTP requests' urls on a bunch of regexes that are relevant for me and block them. However, I wanted to be able to skip certain content-types (such as images) since they are not relevant for my application.
So, to wrap up on the issue. The best way to have full control of resources loading into the browser seems to be using nsIContentPolicy.
@WladimirPalant wrote a great example here. And this is how his code would look adapted to the Addon SDK (v1.9):
const { Cc, Ci, Cu, Cm, components } = require('chrome');
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let policy =
{
classDescription: "Test content policy",
classID: components.ID("{12345678-1234-1234-1234-123456789abc}"),
contractID: "@adblockplus.org/test-policy;1",
xpcom_categories: ["content-policy"],
init: function()
{
let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.registerFactory(this.classID, this.classDescription, this.contractID, this);
let catMan = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
for each (let category in this.xpcom_categories)
catMan.addCategoryEntry(category, this.contractID, this.contractID, false, true);
},
// nsIContentPolicy interface implementation
shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
{
dump("shouldLoad: " + contentType + " " +
(contentLocation ? contentLocation.spec : "null") + " " +
(requestOrigin ? requestOrigin.spec : "null") + " " +
node + " " +
mimeTypeGuess + "\n");
return Ci.nsIContentPolicy.ACCEPT;
},
shouldProcess: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
{
dump("shouldProcess: " + contentType + " " +
(contentLocation ? contentLocation.spec : "null") + " " +
(requestOrigin ? requestOrigin.spec : "null") + " " +
node + " " +
mimeTypeGuess + "\n");
return Ci.nsIContentPolicy.ACCEPT;
},
// nsIFactory interface implementation
createInstance: function(outer, iid)
{
if (outer)
throw Cr.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
// nsISupports interface implementation
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIFactory])
};
policy.init();