我的nsIContentPolicy Firefox / IceWeasel扩展XPCOMponent实现中缺少什么来调用shouldLoad?

时间:2012-01-05 11:03:15

标签: firefox xpcom

简而言之

为什么,基于下面详述的代码,未调用的是shouldLoad函数?

更长的版本

我的目标

我正在尝试构建一个Firefox / Iceweasel扩展,它将取消/重定向某些网址请求。

背景

基于我在网上看到的,一种方法(如果我想拦截每个请求而不仅仅是顶层文档)这样做是为了创建一个实现nsIContentPolicy接口的XPCOM组件,并注册该组件扩展名,并使用shouldLoad函数检查请求的URL并在适当的时候拒绝。

问题

我已尽最大努力实施了一个组件,并将其与我的扩展程序集成在一起。该组件似乎在compreg.dat等中注册的意义上工作,但是,就我所知,shouldLoad函数不会被调用。

详细信息

环境

我正在使用与FireFox 3.5.16相对应的IceWeasel版本在Debian Linux上进行开发。

延期

我的扩展程序基于给出的示例扩展名 http://kb.mozillazine.org/Getting_started_with_extension_development#reg-em 从本质上讲,它所做的只是添加一个菜单项,打开一个类似警报的对话框,说明你好世界。它有一个onLoad注册,触发并提示“onLoad Reporting!”。警报每次都会毫无问题地触发。

参考

我已经安装了扩展重定向器,看似按照相同的原则运行, https://addons.mozilla.org/en-US/firefox/addon/redirector/ 并且它有效(因此我的代码可能是错误,而不是环境恶劣)。

零件

我的组件实施基于我在互联网上找到的各种来源。 我把它放在目录{pathtoextension} /helloworld/components/PolicyComponent.js中的一个文件中,其代码如下:

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");  
const CI = Components.interfaces, CC = Components.classes, CR = Components.results;  

var componentobj = null;

function PolicyComponent()
{
    // this.wrappedJSObject = this;
}  

PolicyComponent.prototype = {  
  classDescription: "My QWERTY nsIContentPolicy XPCOM Component",  
  classID:          Components.ID("{6ffd2f60-3784-11e1-b86c-0800200c9a66}"),  
  contractID:       "@abc.def.com/policycomp;1",  
  QueryInterface: XPCOMUtils.generateQI([CI.nsIContentPolicy]),  


  testFunction: function() { return "Your component is not entirely broken!"; },  

  _xpcom_categories: [{
        category: "content-policy"
    }],

    _xpcom_factory  :
    {
        createInstance: function(outer, iid)
        {
            if (outer)
            { throw CR.NS_ERROR_NO_AGGREGATION;}
            if (componentobj == null)
            {
                componentobj = new PolicyComponent();   
            }
            else {}
            return componentobj.QueryInterface(iid);
        }
    },



    shouldLoad: function(contentType, contentLocation, requestOrigin, aContext, mimeTypeGuess, extra)
    {
        if (contentType != Ci.nsIContentPolicy.TYPE_DOCUMENT) {
                return Ci.nsIContentPolicy.ACCEPT;
            }

        if(-1 != contentLocation.spec.search("abc"))
            {
                aContext.loadURI("http://www.stroustrup.com/", requestOrigin, null);
                return Ci.nsIContentPolicy.REJECT_REQUEST;
            }
        return CI.nsIContentPolicy.ACCEPT;
    },

    shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra) {
        return CI.nsIContentPolicy.ACCEPT;
    }    

};  
var components = [PolicyComponent];  

if (XPCOMUtils.generateNSGetFactory)  
    var NSGetFactory = XPCOMUtils.generateNSGetFactory([PolicyComponent]);  
else  
    var NSGetModule = XPCOMUtils.generateNSGetModule([PolicyComponent]);
状态

该组件似乎被IceWeasel认可。如果我删除compreg.dat和xpti.dat并重新启动IceWeasel,compreg.dat中的grep on content-policy会给出以下结果:

...
@mozilla.org/embedding/browser/content-policy;1,{f66bc334-1dd1-11b2-bab2-90e04fe15c19}
content-policy,@mozilla.org/data-document-content-policy;1,@mozilla.org/data-document-content-policy;1
content-policy,My QWERTY nsIContentPolicy XPCOM Component,@abc.def.com/policycomp;1
content-policy,@mozilla.org/no-data-protocol-content-policy;1,@mozilla.org/no-data-protocol-content-policy;1
...

所以看起来组件至少有一些正确的东西。 但是,我仍然可以在网址中使用“abc”访问网页(这使得相信不会调用shouldLoad函数)。

更多信息

我没有添加任何有关chrome.manifest文件扩展名的内容。我相信我不需要在FF / IW版本3.5.x中这样做。

问题

  1. 怎么了? :)

  2. 我需要在chrome.manifest中添加一些内容吗?或者仅适用于FF 4 +?

  3. 我是否需要以某种方式进一步实例化组件/服务?比如说onLoad hook中的overlay.js?

  4. 我是否需要以更明确的方式将组件注册为对扩展有效,如果是,如何?

  5. 提前致谢!

1 个答案:

答案 0 :(得分:1)

看起来您没有确认您的shouldLoad方法确实没有被调用。我建议使用dump() function来查看组件中发生的事情。它似乎更有可能被调用,但它抛出一个异常,如“aContext.loadURI不是一个函数”。原因是aContext次调用的TYPE_DOCUMENT是一个HTMLDocument对象,并且没有loadURI方法。您可能想要拨打aContext.defaultView.location.replace()。但是,从内容策略执行此操作将是一个安全漏洞(事实上,从内容策略中执行任何可能导致网页脚本运行将是一个安全漏洞)。如果您查看interface definition,您会看到附带大警告。

所以像这样的操作需要延迟发生,以确保在引擎处于一致状态时发生。例如。你可以这样做:

aContext.defaultView.setTimeout("window.location.replace('http://www.stroustrup.com/')", 0);
  

怎么了? :)

除了我上面提到的,您可能不应该定义自定义_xpcom_factory功能。内容策略始终用作服务,这意味着它们是自动单例。访问该组件的您自己的代码当然也应该使用getService()

  

我需要在chrome.manifest中添加一些内容吗?或者仅适用于FF 4 +?

是的,对于FF4 +。类似的东西:

component {6ffd2f60-3784-11e1-b86c-0800200c9a66} components/PolicyComponent.js
contract @abc.def.com/policycomp;1 {6ffd2f60-3784-11e1-b86c-0800200c9a66}
category content-policy @abc.def.com/policycomp;1 @abc.def.com/policycomp;1
  

我是否需要以某种方式进一步实例化组件/服务?比如说onLoad hook中的overlay.js?

不,这是由内置内容策略组件自动发生的。

  

我是否需要以更明确的方式将组件注册为对扩展有效,如果是,请如何?

不知道你的意思。