سؤال

I am developing (trying) a firefox extension to intercept HTTP 500 responses status code and cancel the original request and sending it with another custom protocol.

I am trying to implement and observer and a listener but it is not working for me. I am new in this and I am sure that I am doing something wrong. Can anyone help me to figure out how to do this.

I followed the http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/ tutorial and It is not working, maybe I am not binding or using the component in the correct manner.

My code is: 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

Source Code : /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>

Source Code: /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;
}
}

Thanks in advance. :D

هل كانت مفيدة؟

المحلول

that example is very complex, the main purpose of that traceable channel example is to get a COPY of the sourcecode that gets loaded at that uri.

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');
        }
    }
};

to register the observer on startup of addon run this:

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

and on shutdown of addon unregister all observers like this:

//unregister all observers
for (var o in observers) {
    observers[o].unreg();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top