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