NS_ERROR_FAILURE

I try to implement a basic XHR listener as described in "Ashita" however when loading firefox using the extension I get this error every time I try to load a page that doesn’t allow anything to load: 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]

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

Any help would be most appreciated.

+4
source share
1 answer

Mine seems to be working fine with less code. Try replacing your onDataAvailable function code with:

  var binaryInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream); binaryInputStream.setInputStream(inputStream); this.receivedData.push(binaryInputStream.readBytes(count)); 
+1
source

Source: https://habr.com/ru/post/1299810/


All Articles