1

In my Firefox extension I download the file, then the extension should upload it. I do the following -

// downloading file
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                .createInstance(Components.interfaces.nsIWebBrowserPersist);
var file = Components.classes["@mozilla.org/file/directory_service;1"]
              .getService(Components.interfaces.nsIProperties)
              .get("TmpD", Components.interfaces.nsIFile);
file.append("temp.torrent");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);

var fURI = synoext.srv.io.newURI(url,null,null);
  const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
  const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
  persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
persist.progressListener = {
  onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
    },
  onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
    if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP) {
      // file has been downloaded, upload it 
      Components.utils.import("resource://gre/modules/NetUtil.jsm");
      NetUtil.asyncFetch(file, function(inputStream, status) {
        if (!Components.isSuccessCode(status)) {
          return;
        }

        var filedata = NetUtil.readInputStreamToString(inputStream, inputStream.available());
        var boundary = "-----------------------ZzzZzzZzz";

        var postdata = "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"api\""+"\r\n";
        postdata += "\r\n";
        postdata += "SYNO.DownloadStation.Task"+"\r\n";

        postdata += "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"version\""+"\r\n";
        postdata += "\r\n";
        postdata += "1"+"\r\n";

        postdata += "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"method\""+"\r\n";
        postdata += "\r\n";
        postdata += "create"+"\r\n";

        postdata += "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"file\"; filename=\""+file.leafName+"\""+"\r\n";
        postdata += "Content-Type: application/x-bittorrent"+"\r\n";
        postdata += "\r\n";
        postdata += filedata;
        postdata += "--"+boundary;
        postdata += "\r\n";

        var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                            .createInstance(Components.interfaces.nsIXMLHttpRequest);
        req.open('POST', "http://192.168.1.5:5000/webapi/DownloadStation/task.cgi", true); // asynch
        req.onload = function() {
          // file uploaded
        };

        req.setRequestHeader('Content-Type', 'multipart/form-data; boundary='+boundary);
        // req.setRequestHeader('Content-Length', postdata.length);
        req.send(postdata);
      });

But the file uploaded incorrectly. Original file in my test case is 31Kb, but uploaded file is 46Kb. If I check filedata.length, then it is correct - 31Kb.

1 Answer 1

4

Don't create the POST body yourself, instead use the FormData object.

var formData = Components.classes["@mozilla.org/files/formdata;1"].createInstance(Components.interfaces.nsIDOMFormData);
formData.append(key, value);

formData.append("file", File(file));
Sign up to request clarification or add additional context in comments.

8 Comments

OK, but original question remains - how to pass nsiFile there? The doc says nothing about it.
Thanks, this is exactly what I did yesterday. But is it cross-platform approach? Users started to complain that my extension with this code doesn't work on Mac.
Hi @paa , helped very much with the formData example. But, why do you use File(file) around an object "file" already of type nsiFile ?
FormData works with Blobs. File provides the suitable wrapper (nsIDOMFile, which inherits from nsIDOMBlob) around nsIFile
@paa How do I use it in my main.js? When I enter it like this, it gives me an error. ("File undefined")
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.