2013-04-17 10 views
7

अरे, मैं प्रतिक्रियाओं को सुनने के लिए एक nsIStreamListener श्रोता लिखने में सक्षम हूं और nsitraceablechannel-intercept-http-traffic पर ट्यूटोरियल्स के बाद प्रतिक्रिया पाठ प्राप्त करने में सक्षम हूं। लेकिन मैं ब्राउज़र पर भेजी गई प्रतिक्रिया को संशोधित करने में असमर्थ हूं। असल में यदि मैं प्रतिक्रिया वापस करें और श्रृंखला में वापस भेज दिया यह फ़ायरबग में प्रतिबिंबित करता है लेकिन ब्राउज़र में नहीं।फ़ायरफ़ॉक्स एक्सटेंशन में http प्रतिक्रिया को संशोधित करने के लिए

मैं अनुमान लगा रहा हूं कि हमें श्रृंखला में सुनने के बजाय डिफ़ॉल्ट श्रोता को प्रतिस्थापित करना होगा। मुझे कोई भी दस्तावेज़ नहीं मिल सकता है जो यह बताता है कि यह कैसे करें।

क्या कोई मुझे इसमें कुछ अंतर्दृष्टि दे सकता है। यह मुख्य रूप से शिक्षा उद्देश्यों के लिए है।

अग्रिम धन्यवाद

संपादित करें: अब तक मैं एक छोटे से समाधान पर आ चुके हैं मैं फ़ायरफ़ॉक्स 34 (वर्तमान रात) पर मेरे लिए काम करता है इस

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

उत्तर

3

यह उदाहरण ऐसा करने में सक्षम हूँ: https://github.com/Noitidart/demo-nsITraceableChannel

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); 
:

मैं धारा को संशोधित करने के XPI, संपादित bootstrap.js डाउनलोड किया

ने XPI स्थापित किया और फिर जिथब पेज को पुनः लोड किया। यह पाद लेख में "परीक्षण" पढ़ा।

आपके द्वारा पोस्ट किए गए कोड का संस्करण वास्तव में पुराने श्रोता को परिणाम पास नहीं करता है, इसलिए यह पहली बात है जिसे बदला जाना चाहिए।

यह फ़ायरबग या किसी अन्य एक्सटेंशन से भी बुरी तरह से बातचीत कर सकता है। एक स्वच्छ प्रोफ़ाइल में समस्या को पुन: उत्पन्न करने का प्रयास करना एक अच्छा विचार है (केवल आपके एक्सटेंशन को इंस्टॉल किया गया है)।

+0

वू मेरा डेमो/प्रयोगात्मक काम दूसरों की मदद कर रहा है! मेरी सामग्री उद्धृत करने के लिए धन्यवाद! :) आप उस बीटीडब्ल्यू में कैसे आए? – Noitidart

+1

प्लस वन क्योंकि मुझे कभी नहीं पता था कि इसका उपयोग प्रदर्शित/प्रस्तुत स्रोत को संशोधित करने के लिए किया जा सकता है। मैंने सोचा कि यह सिर्फ http की मांग की गई प्रतिलिपि प्राप्त करने के लिए था। सुपर कूल मैंने बकवास के बारे में कुछ सीखा जो मैंने चिपकाया और मैश किए हुए टोगर की प्रतिलिपि बनाई! – Noitidart

+1

@ नोइटिडार्ट: Google के माध्यम से; जानना अच्छा लगा कि हमने एक-दूसरे की मदद की। ओपन-सोर्स जाओ! – Nickolay

संबंधित मुद्दे