Infocatcher / Private_Tab

Adds private tabs, restartless extension for Firefox (20.0+) and SeaMonkey (2.17+)
https://addons.mozilla.org/addon/private-tab/
Other
86 stars 20 forks source link

nsISimpleContentPolicy issue #205

Closed belaviyo closed 8 years ago

belaviyo commented 8 years ago

I am using nsISimpleContentPolicy to block some network resources in my extension.

var {isPrivate} = require('sdk/private-browsing');
var policy = new Class({
  extends: Unknown,
  interfaces: ['nsISimpleContentPolicy'],
  shouldLoad: function (aContentType, aContentLocation, aRequestOrigin, aTopFrameElement, aIsTopLevel, aMimeTypeGuess, aExtra, aRequestPrincipal) {
    console.error(isPrivate(aTopFrameElement)) // <<<<<<<<
    return Ci.nsIContentPolicy.ACCEPT;
  },
  shouldProcess: () => Ci.nsIContentPolicy.ACCEPT
});
(function (factory) {
  categoryManager.addCategoryEntry('simple-content-policy', factory.contract, factory.contract, false, true);
  unload.when(() => categoryManager.deleteCategoryEntry('simple-content-policy', factory.contract, false));
  });
})(new Factory({
  Component:   policy,
  contract:    '@myaddon/simpletestpolicy;1',
  description: 'Blocks Some Resources'
}));

If I open a private window, the isPrivate(aTopFrameElement) returns true for all requests initiated from the private window as the aTopFrameElement is in the context of the private mode. However, if requests are from a private tab, isPrivate(aTopFrameElement) returns false.

Any idea how to fix this?

Infocatcher commented 8 years ago

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy#shouldLoad%28%29

aContext The nsIDOMNode or nsIDOMWindow that initiated the request, or something that can QueryInterface() to one of those; can be null if inapplicable.

May be aTopFrameElement refers to topmost browser window, that is actually non-private. You can try something like

if(
    aTopFrameElement instanceof Ci.nsIDOMChromeWindow
    && "gBrowser" in aTopFrameElement
) {
    var gBrowser = aTopFrameElement.gBrowser;
    var contentWindow = gBrowser.contentWindow || gBrowser.contentWindowAsCPOW;
    console.error(isPrivate(contentWindow));
}
Infocatcher commented 8 years ago

Also may be it's possible to ask aRequestOrigin about Ci.nsILoadContext. Something like

aRequestOrigin.loadGroup.notificationCallbacks
    .getInterface(Ci.nsILoadContext);

And then use nsILoadContext.usePrivateBrowsing.

belaviyo commented 8 years ago

It turned out aTopFrameElement is the actual XUL browser element. So I needed to dive into aTopFrameElement.contentWindow and then the isPrivate can detect the privacy context just fine.

Thanks for the help.