Чего не хватает в моей реализации XPCOMponent расширения nsIContentPolicy Firefox / IceWeasel для вызова shouldLoad? - PullRequest
0 голосов
/ 05 января 2012

Короче

Почему, исходя из приведенного ниже кода, функция shouldLoad не вызывается?

Более длинная версия

Моя цель

Я пытаюсь создать расширение Firefox / Iceweasel, которое будет отменять / перенаправлять определенные URL-запросы.

Фон

Исходя из того, что я видел в Интернете, один из способов (если я хочу перехватывать каждый запрос, а не только верхний документ) состоит в том, чтобы создать компонент XPCOM, который реализует интерфейс nsIContentPolicy, и зарегистрировать этот компонент в расширение и иметь функцию shouldLoad, которая проверяет запрошенный URL-адрес и, при необходимости, отклоняет его.

Задача

Я реализовал компонент в меру своих усилий и интегрировал его с моим расширением. Компонент, кажется, работает в том смысле, что он регистрируется в compreg.dat и т. Д., НО - насколько я могу судить, функция shouldLoad не вызывается.

Подробнее

Среда

Я занимаюсь разработкой Debian Linux с использованием версии IceWeasel, соответствующей FireFox 3.5.16.

расширение

Мое расширение основано на примере расширения, заданном на http://kb.mozillazine.org/Getting_started_with_extension_development#reg-em По сути, все, что он делает, это добавляет пункт меню, который открывает диалоговое окно, похожее на предупреждение «Здравствуй, мир». у него есть регистрация onLoad, которая запускается и выдает предупреждение «OnLoad Reporting!». Оповещение срабатывает каждый раз без проблем.

Ссылка

Я установил расширение Redirector, похоже, работающее по тем же принципам, 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, grep для политики содержимого в compreg.dat дает следующий результат:

...
@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» в URL (что заставляет поверить, что функция shouldLoad не вызывается).

Дальнейшая информация

Я не добавил ничего о расширении файла chrome.manifest. Я считаю, что мне не нужно делать это в версии 3.5.x FF / IW.

Вопросы

  1. Что не так? :)

  2. Нужно ли мне что-то добавить в chrome.manifest? Или это только для FF 4 +?

  3. Нужно ли как-то еще создавать экземпляр компонента / сервиса? Как, скажем, в overlay.js в хуке onLoad?

  4. Нужно ли регистрировать компонент как действительный для расширения более явным образом, и если да, то как?

Заранее спасибо!

1 Ответ

1 голос
/ 05 января 2012

Похоже, вы не проверяли, что ваш shouldLoad метод действительно не вызывается. Я бы предложил использовать функцию dump () , чтобы увидеть, что на самом деле происходит в вашем компоненте. Кажется более вероятным, что он вызывается, но он выдает исключение типа «aContext.loadURI не является функцией». Причина в том, что aContext для TYPE_DOCUMENT вызовов - это объект HTMLDocument, и у него нет метода loadURI. Вы, вероятно, хотите позвонить aContext.defaultView.location.replace() вместо. Но выполнение этого с помощью политики контента будет уязвимостью безопасности (фактически, выполнение всего из политики контента, которая может привести к выполнению сценариев веб-страницы, было бы уязвимостью безопасности). Если вы посмотрите на определение интерфейса , вы увидите, что оно сопровождается большими предупреждениями.

Таким образом, манипуляции, подобные этой, должны происходить с задержкой, чтобы убедиться, что это происходит, когда двигатель находится в согласованном состоянии. Например. Вы могли бы сделать:

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

Нужно ли как-то еще создавать экземпляр компонента / сервиса? Как, скажем, в overlay.js в хуке onLoad?

Нет, это происходит автоматически с помощью встроенного компонента политики содержимого.

Нужно ли регистрировать компонент как действительный для расширения более явным образом, и если да, то как?

Не знаю, что вы имеете в виду.

...