Pregunta

I am trying to upload a file to a WebDAC server. iLocalFile is a reference to a local input file:

  var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
                    .createInstance(Ci.nsIFileInputStream);
  inputStream.init(iLocalFile, DELETE_ON_CLOSE, 0, 0);

  var oIOService = Cc["@mozilla.org/network/io-service;1"]
                   .getService(Ci.nsIIOService)
  var oHttpChannel = oIOService.newChannel(sRemoteFileName, "", null);
  oHttpChannel.QueryInterface(Ci.nsIHttpChannel);
  oHttpChannel.requestMethod = 'PUT';
  oHttpChannel.QueryInterface(Ci.nsIUploadChannel);
  oHttpChannel.setUploadStream(inputStream, 'application/pdf', -1);

  var result = '';
  console.log('Upload starting')
  oHttpChannel.asyncOpen(in nsIStreamListener, result);

My problem is that I don't know how to implement the nsIStreamListener. I would be quite happy to thow away the response content if failure/success is still available.


Edit 1: Solution

As per the selected answer with the following modification:

  var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
                    .createInstance(Ci.nsIFileInputStream);
  inputStream.init(iLocalFile, -1, 0, 0);
  xhr.send(inputStream);
¿Fue útil?

Solución

If your WebDAV server is OK with just put (sans locks)...

I'd just use XMLHttpRequest, as it provides a higher-level API than raw streams (and also avoids some performance/snappiness pitfalls). Just prepare use something like xhr.send(File(iLocalFile.path)).

If you still want to use raw channels and a stream listener:

Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let listener = {
  QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]),
  onStartRequest: function(aRequest, aContext) {
    // request started
  },
  onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aSize) {
   // responseData. May be called multiple times!
   // You probably need to buffer the data from the input stream
   // if you're interested in the response text and manually convert
   // it afterwards.
   // E.g. wrap in nsIBinaryInputStream and .readArrayBuffer()
   // + TextDecoder in onStopRequest.
  },
  onStopRequest: function(aRequest, aContext, aStatusCode) {
   // request done. aStatusCode is an nsresult, not the http code ;)
   //You may want to check this with Components.isSuccessCode
  }
};

Where aRequest is the original or redirected channel QI'ed to nsIRequest (you can QI it to nsIChannel, etc. again). And where aContext is the context argument (2nd) passed to asyncOpen. Since we're at it: You cannot really pass a string there. null would be OK (let your listener keep track of stuff).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top