Я пытаюсь реализовать базовый XHR-слушатель, как описано в "Ashita" , однако при загрузке Firefox с расширением я получаю эту ошибку всякий раз, когда страница пытается загрузить, что препятствует загрузке чего-либо: Error: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIBinaryInputStream.readBytes]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: chrome://xhrlogger/content/overlay.js :: anonymous :: line 68" data: no]
Мой файл overlay.js:
if (typeof Cc == "undefined") {
var Cc = Components.classes;
}
if (typeof Ci == "undefined") {
var Ci = Components.interfaces;
}
if (typeof CCIN == "undefined") {
function CCIN(cName, ifaceName){
return Cc[cName].createInstance(Ci[ifaceName]);
}
}
if (typeof CCSV == "undefined") {
function CCSV(cName, ifaceName){
if (Cc[cName])
// if fbs fails to load, the error can be _CC[cName] has no properties
return Cc[cName].getService(Ci[ifaceName]);
else
dump("CCSV fails for cName:" + cName);
};
}
var httpRequestObserver = {
observe: function(request, aTopic, aData){
if (aTopic == "http-on-examine-response") {
var newListener = new TracingListener();
request.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = request.setNewListener(newListener);
}
},
QueryInterface: function(aIID){
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Components.results.NS_NOINTERFACE;
},
};
function TracingListener() {
this.receivedData = []; //initialize the array
}
TracingListener.prototype =
{
originalListener: null,
receivedData: null, //will be an array for incoming data.
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
this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
},
onStartRequest: function(request, context) {
this.originalListener.onStartRequest(request, context);
},
onStopRequest: function(request, context, statusCode) {
try
{
//QueryInterface into HttpChannel to access originalURI and requestMethod properties
request.QueryInterface(Ci.nsIHttpChannel);
var data = null;
if (request.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request, context);
if (postText)
data = ((String)(postText)).parseQuery();
}
//Combine the response into a single string
var responseSource = this.receivedData.join('');
//fix leading spaces bug
//(FM occasionally adds spaces to the beginning of their ajax responses...
//which breaks the XML)
responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1");
//gets the date from the response headers on the request.
//For PirateQuesting this was preferred over the date on the user's machine
var date = Date.parse(request.getResponseHeader("Date"));
//Again a PQ specific function call, but left as an example.
//This just passes a string URL, the text of the response,
//the date, and the data in the POST request (if applicable)
/* piratequesting.ProcessRawResponse(request.originalURI.spec,
responseSource,
date,
data); */
dump(date);
dump(data);
dump(responseSource);
}
catch (e)
{
//standard function to dump a formatted version of the error to console
dump(e);
}
this.originalListener.onStopRequest(request, context, statusCode);
},
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)
{
dump(exc);
}
return null;
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Components.results.NS_NOINTERFACE;
},
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;
}
}
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver,
"http-on-examine-response", false);
dump("WTFBBQ");
Любая помощь будет наиболее ценной.