2009-11-08 3 views
17

Comment puis-je modifier le corps de la réponse HTTP dans une extension Firefox? J'ai mis en place un observateur http-on-examine-response et un objet nsIStreamListener avec le code ci-dessous. Après avoir récupéré les données, les avoir analysées et les avoir modifiées, comment repousser la réponse modifiée au navigateur Firefox? Par exemple, disons que je vais sur Google.com avec mon extension activée, l'extension devrait intercepter la réponse et changer chaque occurrence de "google" en "masque". Ainsi, lorsque la page est chargée, l'utilisateur verra "goggle" partout.Modification des réponses HTTP dans l'extension Firefox

function TmSteroidsObserver() 
{ 
    this.register(); 
} 


TmSteroidsObserver.prototype = { 
    observe: function(subject, topic, data) { 

    if (topic == "http-on-examine-response") { 

    } 
    else if (topic == "http-on-modify-request") { 
     var channel = subject.QueryInterface(Components.interfaces.nsIChannel); 
     var listener = new StreamListener(channel); 
    } 

    }, 

    register: function() { 
    var observerService = Components.classes["@mozilla.org/observer-service;1"] 
           .getService(Components.interfaces.nsIObserverService); 
    observerService.addObserver(listener, "http-on-modify-request", false); 
    observerService.addObserver(listener, "http-on-examine-response", false); 
    }, 

    unregister: function() { 
    var observerService = Components.classes["@mozilla.org/observer-service;1"] 
          .getService(Components.interfaces.nsIObserverService); 
    observerService.removeObserver(this, "http-on-modify-request"); 
    observerService.removeObserver(this, "http-on-examine-response"); 
    }, 

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

} 

function StreamListener(channel) { 

    channel.notificationCallbacks = listener; 
    channel.asyncOpen(listener, null); 

} 

StreamListener.prototype = { 
    mData: "", 
    mChannel: null, 

    // nsIStreamListener 
    onStartRequest: function (aRequest, aContext) { 
    this.mData = ""; 
    }, 

    onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) { 
    var scriptableInputStream = 
     Components.classes["@mozilla.org/scriptableinputstream;1"] 
     .createInstance(Components.interfaces.nsIScriptableInputStream); 
    scriptableInputStream.init(aStream); 

    this.mData += scriptableInputStream.read(aLength); 
    }, 

    onStopRequest: function (aRequest, aContext, aStatus) { 
    if (Components.isSuccessCode(aStatus)) { 
     // request was successfull 
     this.mCallbackFunc(this.mData); 
    } else { 
     // request failed 
     this.mCallbackFunc(null); 
    } 

    this.mChannel = null; 
    }, 

    // nsIChannelEventSink 
    onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) { 
    // if redirecting, store the new channel 
    this.mChannel = aNewChannel; 
    }, 

    // nsIInterfaceRequestor 
    getInterface: function (aIID) { 
    try { 
     return this.QueryInterface(aIID); 
    } catch (e) { 
     throw Components.results.NS_NOINTERFACE; 
    } 
    }, 

    // nsIProgressEventSink (not implementing will cause annoying exceptions) 
    onProgress : function (aRequest, aContext, aProgress, aProgressMax) { }, 
    onStatus : function (aRequest, aContext, aStatus, aStatusArg) { }, 

    // nsIHttpEventSink (not implementing will cause annoying exceptions) 
    onRedirect : function (aOldChannel, aNewChannel) { }, 

    // we are faking an XPCOM interface, so we need to implement QI 
    QueryInterface : function(aIID) { 
    if (aIID.equals(Components.interfaces.nsISupports) || 
     aIID.equals(Components.interfaces.nsIInterfaceRequestor) || 
     aIID.equals(Components.interfaces.nsIChannelEventSink) || 
     aIID.equals(Components.interfaces.nsIProgressEventSink) || 
     aIID.equals(Components.interfaces.nsIHttpEventSink) || 
     aIID.equals(Components.interfaces.nsIStreamListener)) 
     return this; 

    throw Components.results.NS_NOINTERFACE; 
    } 
}; 

Répondre

0

Le service d'observateur il suffit d'appeler vos auditeurs. Firefox recevra les demandes, appellera vos auditeurs et enverra des réponses. voir les documents Mozilla Creating HTTP POSTs.

Questions connexes