用于拦截响应状态代码的扩展

时间:2014-04-03 20:28:49

标签: firefox-addon

我正在开发(尝试)一个firefox扩展来拦截HTTP 500响应状态代码并取消原始请求并使用另一个自定义协议发送它。

我正在尝试实现观察者和听众,但它不适合我。我是新手,我确信我做错了什么。任何人都可以帮我弄清楚如何做到这一点。

我按照http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/教程进行了操作,它无法正常工作,也许我没有以正确的方式绑定或使用该组件。

我的代码是: chrome.manifest用于

content     lightweightandsecureprotocol    chrome/content/
content     lightweightandsecureprotocol    chrome/content/     contentaccessible=yes       

locale      lightweightandsecureprotocol    en-US   crhome/locale/en-US/                    

skin        lightweightandsecureprotocol    classic/1.0     chrome/skin/    


style chrome://global/content/customizeToolbar.xul chrome://lightweightandsecureprotocol/skin/browser.css       

overlay     chrome://browser/content/browser.xul         chrome://lightweightandsecureprotocol/content/browser.xul


component {90b7bac4-78fc-4193-a2d9-1ed7a4f675eb} components/HttpResponseObserver.js

源代码: /chrome/content/Browser.xul

<?xml version="1.0"?>
<?xml-stylesheet type="text/css"
href="chrome://lightweightandsecureprotocol/skin/browser.css"?>

<overlay id="overlay" 
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://lightweightandsecureprotocol/components/HttpResponseObserver.js"/>
<script>
    try{
     var myComponent = Components.classes['@patricia.figueroa.millan/httpresponseobserver;1']
                                .getService().wrappedJSObject;
    }catch(anError){
        dump("ERROR:" + anError);
    }
</script>


</overlay>

源代码: /components/HttpResponseObserver.js

const nsISupports = Components.interfaces.nsISupports;


const CLASS_ID = Components.ID("90b7bac4-78fc-4193-a2d9-1ed7a4f675eb");
const CLASS_NAME = "Http Response Observer";
const CONTRACT_ID = "@patricia.figueroa.millan/httpresponseobserver;1";


function HttpResponseObserver() {
    this.wrappedJSObject = this;
}

HttpResponseObserver.prototype = {
 observe: function(aSubject, aTopic, aData){
    if(aTopic=="http-on-examine-response"){

        let httpChannel=aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);

        if(httpChannel.responseStatus== 555){
            alert("555 Status code in Response ");

        }

        var newListener=new TracingListener();

        aSubject.QueryInterface(Components.interfaces.nsITraceableChannel);

        newListener.originalListener=aSubject.setNewListner(newListener);

    }

}

 QueryInterface: function(aIID)
 {

  if (!aIID.equals(nsISupports))
      throw Components.results.NS_ERROR_NO_INTERFACE;
  return this;
 }
}

var HttpResponseObserverFactory = {
singleton: null,
createInstance: function (aOuter, aIID)
{
  if (aOuter != null)
    throw Components.results.NS_ERROR_NO_AGGREGATION;
  if (this.singleton == null)
    this.singleton = new HttpResponseObserver();
  return this.singleton.QueryInterface(aIID);
}
};


var HttpResponseObserverModule = {
  registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
  {
   aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
   aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
  },

  unregisterSelf: function(aCompMgr, aLocation, aType)
  {
   aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
   aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);        
  },

 getClassObject: function(aCompMgr, aCID, aIID)
 {
   if (!aIID.equals(Components.interfaces.nsIFactory))
   throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

   if (aCID.equals(CLASS_ID))
   return HttpResponseObserverFactory;

   throw Components.results.NS_ERROR_NO_INTERFACE;
 },

canUnload: function(aCompMgr) { return true; }
};


function NSGetModule(aCompMgr, aFileSpec) { return HttpResponseObserverModule; }

//LISTENER
function TracingListener() {
   this.originalListener = null;
}

TracingListener.prototype =
{
onDataAvailable: function(request, context, inputStream, offset, count) {
    this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
},

onStartRequest: function(request, context) {
    this.originalListener.onStartRequest(request, context);
},

onStopRequest: function(request, context, statusCode) {
    this.originalListener.onStopRequest(request, context, statusCode);
},

QueryInterface: function (aIID) {
    if (aIID.equals(Components.interfaces.nsIStreamListener) ||
        aIID.equals(Components.interfaces.nsISupports)) {
        return this;
    }
    throw Components.results.NS_NOINTERFACE;
}
}

提前致谢。 :d

1 个答案:

答案 0 :(得分:0)

该示例非常复杂,该可跟踪通道示例的主要目的是获取在该uri处加载的源代码的 COPY

const { interfaces: Ci, utils: Cu, classes: Cc, results: Cr } = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');

var observers = {
    'http-on-examine-response': {
        observe: function (aSubject, aTopic, aData) {
            console.info('http-on-examine-responset: aSubject = ' + aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
            var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);

            if (httpChannel.responseStatus == 555) {
                console.log('555 Status code in Response for request url = ' + httpChannel.URI.spec);
                //httpChannel.cancel(Cr.NS_BINDING_ABORTED); //you might not need this, i think the redirectTo function handles aborting
                httpChannel.redirectTo(Services.io.newURI('about:got bad response status so redirected you', null, null));
            }
        },
        reg: function () {
            Services.obs.addObserver(observers['http-on-examine-response'], 'http-on-modify-request', false);
        },
        unreg: function () {
            Services.obs.removeObserver(observers['http-on-examine-response'], 'http-on-modify-request');
        }
    }
};

在addon启动时注册观察者运行:

//register all observers
for (var o in observers) {
    observers[o].reg();
}

并在关闭addon时取消注册所有观察者:

//unregister all observers
for (var o in observers) {
    observers[o].unreg();
}