2013-04-17 28 views
7

Hey tôi đã có thể viết một trình nghe nsIStreamListener để lắng nghe các câu trả lời và nhận được văn bản trả lời theo các hướng dẫn tại nsitraceablechannel-intercept-http-traffic. Nhưng tôi không thể sửa đổi phản hồi được gửi tới trình duyệt. trả lại phản hồi và được gửi trở lại chuỗi nó phản ánh trong firebug nhưng không có trong trình duyệt.Cách sửa đổi phản hồi http trong tiện ích mở rộng của Firefox

Điều tôi đoán là chúng tôi sẽ phải thay thế người nghe mặc định thay vì nghe trong chuỗi. Tôi không thể nhận bất kỳ tài liệu nào ở bất kỳ nơi nào giải thích cách thực hiện việc này.

Có ai có thể cho tôi một số thông tin chi tiết về điều này.Đây là chủ yếu cho mục đích giáo dục.

Cảm ơn trước

Chỉnh sửa: Tính đến bây giờ tôi đã đi đến một giải pháp ít i am có thể làm điều này

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

Trả lời

3

Ví dụ này làm việc cho tôi trên Firefox 34 (hiện tại đêm): https://github.com/Noitidart/demo-nsITraceableChannel

tôi đã tải về xpi, bootstrap.js chỉnh sửa để thay đổi luồng:

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

cài đặt XPI rồi tải lại trang github. Nó đọc "TEST" ở chân trang.

Phiên bản mã bạn đã đăng không thực sự chuyển kết quả trở lại cho người nghe cũ, vì vậy đó là điều đầu tiên cần được thay đổi.

Nó cũng có thể đã tương tác với Firebug hoặc một tiện ích mở rộng khác. Đó là một ý tưởng tốt để thử tái tạo vấn đề trong một hồ sơ sạch (chỉ với phần mở rộng của bạn được cài đặt).

+0

Woo tác phẩm thử nghiệm/thử nghiệm của tôi đang trợ giúp người khác! Cảm ơn bạn đã trích dẫn nội dung của tôi! :) Làm thế nào bạn đi qua btw đó? – Noitidart

+1

Thêm một vì tôi không bao giờ biết rằng điều này có thể được sử dụng để sửa đổi nguồn được hiển thị/hiển thị. Tôi nghĩ rằng đó chỉ là để có được một bản sao của những gì đã được yêu cầu http. Siêu mát mẻ tôi đã học được một cái gì đó về crap tôi sao chép dán và nghiền nát togather! – Noitidart

+1

@Noitidart: qua Google; rất vui khi biết chúng tôi đã giúp đỡ lẫn nhau. Mở mã nguồn mở! – Nickolay

Các vấn đề liên quan