2013-04-17 5 views
7

Hey ich habe in der Lage, einen nsIStreamListener Listener zu schreiben, auf Antworten zu hören und den Antworttext folgenden Tutorials bei nsitraceablechannel-intercept-http-traffic zu bekommen. Aber ich bin nicht in der Lage, die an Browser gesendete Antwort zu ändern.Aktuell, wenn ich die Antwort zurücksenden und zur Kette zurücksenden, die im firebug aber nicht im Browser reflektiert wird.Wie HTTP-Antwort in Firefox-Erweiterung

Was ich vermute, ist, dass wir Standard-Listener ersetzen müssen, anstatt in der Kette zu hören. Ich kann keine Dokumente überall bekommen, die erklären, wie man das macht.

Könnte mir jemand einen Einblick geben. Dies ist hauptsächlich für Bildungszwecke.

Vielen Dank im Voraus

Edit: Ab jetzt habe ich bei einer kleinen Lösung angekommen ich in der Lage bin dieses

var old; 

function TracingListener() {} 

TracingListener.prototype = { 
    originalListener: null, 
    receivedData: null, //will be an array for incoming data. 

//For the listener this is step 1. 
onStartRequest: function (request, context) { 
    this.receivedData = []; //initialize the array 

    //Pass on the onStartRequest call to the next listener in the chain -- VERY   IMPORTANT 
    //old.onStartRequest(request, context); 
}, 

//This is step 2. This gets called every time additional data is available 
onDataAvailable: function (request, context, inputStream, offset, count) { 
    var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", 
     "nsIBinaryInputStream"); 
    binaryInputStream.setInputStream(inputStream); 

    var storageStream = CCIN("@mozilla.org/storagestream;1", 
     "nsIStorageStream"); 
    //8192 is the segment size in bytes, count is the maximum size of the stream in  bytes 
    storageStream.init(8192, count, null); 

    var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1", 
     "nsIBinaryOutputStream"); 
    binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); 

    // Copy received data as they come. 
    var data = binaryInputStream.readBytes(count); 

    this.receivedData.push(data); 

    binaryOutputStream.writeBytes(data, count); 



    //Pass it on down the chain 
    //old.onDataAvailable(request, context,storageStream.newInputStream(0), offset, count); 
}, 
onStopRequest: function (request, context, statusCode) { 
    try { 
     //QueryInterface into HttpChannel to access originalURI and requestMethod properties 
     request.QueryInterface(Ci.nsIHttpChannel); 


     //Combine the response into a single string 
     var responseSource = this.receivedData.join(''); 


     //edit data as needed 
     responseSource = "test"; 
     console.log(responseSource); 

    } catch (e) { 
     //standard function to dump a formatted version of the error to console 
     dumpError(e); 
    } 

    var stream = Cc["@mozilla.org/io/string-input-stream;1"] 
     .createInstance(Ci.nsIStringInputStream); 
    stream.setData(responseSource, -1); 

    //Pass it to the original listener 
    //old.originalListener=null; 
    old.onStartRequest(channel, context); 
    old.onDataAvailable(channel, context, stream, 0, stream.available()); 
    old.onStopRequest(channel, context, statusCode); 
}, 
QueryInterface: function (aIID) { 
    if (aIID.equals(Ci.nsIStreamListener) || 
     aIID.equals(Ci.nsISupports)) { 
     return this; 
    } 
    throw components.results.NS_NOINTERFACE; 
}, 
readPostTextFromRequest: function (request, context) { 
    try { 
     var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream; 
     if (is) { 
      var ss = is.QueryInterface(Ci.nsISeekableStream); 
      var prevOffset; 
      if (ss) { 
       prevOffset = ss.tell(); 
       ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); 
      } 

      // Read data from the stream.. 
      var charset = "UTF-8"; 
      var text = this.readFromStream(is, charset, true); 

      if (ss && prevOffset == 0) 
       ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); 

      return text; 
     } else { 
      dump("Failed to Query Interface for upload stream.\n"); 
     } 
    } catch (exc) { 
     dumpError(exc); 
    } 

    return null; 
}, 
readFromStream: function (stream, charset, noClose) { 

    var sis = CCSV("@mozilla.org/binaryinputstream;1", 
     "nsIBinaryInputStream"); 
    sis.setInputStream(stream); 

    var segments = []; 
    for (var count = stream.available(); count; count = stream.available()) 
     segments.push(sis.readBytes(count)); 

    if (!noClose) 
     sis.close(); 

    var text = segments.join(""); 
    return text; 
} 

} 

httpRequestObserver = { 

observe: function (request, aTopic, aData) { 
    if (typeof Cc == "undefined") { 
     var Cc = components.classes; 
    } 
    if (typeof Ci == "undefined") { 
     var Ci = components.interfaces; 
    } 
    if (aTopic == "http-on-examine-response") { 
     request.QueryInterface(Ci.nsIHttpChannel); 

     console.log(request.statusCode); 

     var newListener = new TracingListener(); 
     request.QueryInterface(Ci.nsITraceableChannel); 

     channel = request; 
     //newListener.originalListener 
     //add new listener as default and save old one 
     old = request.setNewListener(newListener); 
     old.originalListener = null; 

     var threadManager = Cc["@mozilla.org/thread-manager;1"] 
      .getService(Ci.nsIThreadManager); 
     threadManager.currentThread.dispatch(newListener,  Ci.nsIEventTarget.DISPATCH_NORMAL); 


    } 
}, 

QueryInterface: function (aIID) { 
    if (typeof Cc == "undefined") { 
     var Cc = components.classes; 
    } 
    if (typeof Ci == "undefined") { 
     var Ci = components.interfaces; 
    } 
    if (aIID.equals(Ci.nsIObserver) || 
     aIID.equals(Ci.nsISupports)) { 
     return this; 
    } 

    throw components.results.NS_NOINTERFACE; 

}, 
}; 

var observerService = Cc["@mozilla.org/observer-service;1"] 
.getService(Ci.nsIObserverService); 

observerService.addObserver(httpRequestObserver, 
"http-on-examine-response", false); 

Antwort

3

Dieses Beispiel für mich auf Firefox 34 (aktuelle nächtlichen) arbeitet zu tun: https://github.com/Noitidart/demo-nsITraceableChannel

heruntergeladen ich den xpi, bearbeitet bootstrap.js den Strom zu ändern:

132   // Copy received data as they come. 
133   var data = binaryInputStream.readBytes(count); 
134   data = data.replace(/GitHub/g, "TEST"); 
135   this.receivedData.push(data); 

installiert der XPI dann die github-Seite neu geladen. Es lies "TEST" in der Fußzeile.

Die Version des von Ihnen geposteten Codes übergibt die Ergebnisse nicht wirklich an den alten Listener, das ist also das erste, was geändert werden sollte.

Es hat möglicherweise auch mit Firebug oder einer anderen Erweiterung schlecht interagiert. Es ist eine gute Idee, das Problem in einem sauberen Profil zu reproduzieren (nur mit Ihrer Erweiterung).

+0

Woo meine Demo/experimentelle Arbeit hilft anderen! Danke, dass du meine Sachen zitierst! :) Wie bist du darauf gestoßen? – Noitidart

+1

Plus eins, weil ich nie wusste, dass dies verwendet werden könnte, um die angezeigte/gerenderte Quelle zu ändern. Ich dachte, es wäre nur eine Kopie von dem, was http angefordert wurde. Super cool, ich habe etwas über den Mist gelernt, den ich kopiert und geklebt habe! – Noitidart

+1

@Noitidart: über Google; schön zu wissen, dass wir uns gegenseitig geholfen haben. Gehe Open-Source! – Nickolay

Verwandte Themen