This is my encodeFormData function, it works if the image is < 200x200 in size, however if I have a bigger image, the data is corrupt, I know this because when I post the data to the loadOneTab, the website says its corrupt -
I think the issue is there is a max size on the nsIArrayBufferStream, so I tried to chunk it, this now gives me ābad requestsā so Im not doing something right in here:
var cByteLen = 0;
var chunkSize = 7000;
while (cByteLen < v.byteLength) {
var abstream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"].createInstance(Ci.nsIArrayBufferInputStream);
var thisChunkSize = cByteLen + chunkSize < v.byteLength ? cByteLen + chunkSize : v.byteLength - cByteLen;
console.error('thisChunkSize:', thisChunkSize);
abstream.setData(v, cByteLen, thisChunkSize);
cByteLen = cByteLen + thisChunkSize;
mpis.appendStream(abstream);
}
What makes you think nsIArrayBufferInputStream is the problem? Have you tried a different type of input stream with large amounts of data? It is relatively simple to stream directly from a file instead if going through an arraybuffer, since you already have a file. Have you tried transferring chunks into small arraybuffers and multiplexing those instead of trying to multiplex lots of streams out of a single arraybuffer?
Thanks Litho! Because I used to be able to do this without issue for any size with canvas.mozFetchAsStream but that got deprecated - https://bugzilla.mozilla.org/show_bug.cgi?id=1206030 . I donāt have a file, I have a blob, from canvas.toBlob
I tried chunking it in āreply 2ā and I appended that to the multipart stream but the page wouldnt even load
Have you tried it with a storage stream instead of a multiplex stream? I donāt know how multiplex streams work, but Iām a little concerned that you are doing all sorts of looping over stuff, redeclaring and reusing variables, and then hoping that everything is still there when you come to use the multiple stream at the very end. Using a storage stream would be one less possibility for fouling things up.
Or of course you can post blobs directly, since you already have a blob. Just concatenate several string or blob objects to a single blob, then post the result.
Iām not sure what there is to explain. You have a blob and some strings. You can concatenate strings and blobs into a blob. You can pass a blob directly as the post data. Should be a lot simpler than messing with streams.
Ah no problem thanks so much for trying though I actually resorted to this method first months ago, but had this same size issue. So then switched to mozFetchAsStream back then, that had no issue, but that deprecated so now I canāt escape I have to get this working haha.
Iāve been playing with array buffers and theyāre a pain. Handy if you want to actually parse binary data (or write it piece by piece), otherwise more trouble than theyāre worth. Canāt do anything with them, canāt reliably convert them to and from formats you can do anything with.
I still have no idea what is wrong with the way you tried this, but I know how to do it a different way. No blobs, since loadOneTab() wonāt take them, and no array buffers since they cause too much trouble.
canvas.toDataURL() gives a base64 encoded image
atob(dataUrl.split(ā,ā)[1]) gives a binary string for the image data
storageStream.getOutputStream() gets a stream you can add data to
binaryOutputStream.setOutputStream() allows binary string input to the storage stream
binaryOutputStream.writeBytes() puts the binary string into the stream
outputStream.newInputStream() can be used for your post data stream.
Simples
The good news is it works. The bad news is it isnāt exactly elegant. Probably faster than using blobs and array buffers though.
Warning: I tried to simplify this by just putting the binary string into an nsIStringInputStream. It worked! However, Iām reliably informed that it will fail in some situations because nsIStringInputStream cannot always safely handle strings containing null characters.
Thanks for that note, Iāll just put it in as a temporary work around till I figure out that array buffer or blob thing. Maybe the team that deprecated mozFetchAsStream can help, an alternative has to exist no? Otherwise they wouldnāt deprecate no?
Ssshhhh, someone might hear you and deprecate it. Although 100ms is hardly a serious delay in response to a user click, you can use FileReader to asynchronously get a data url from a Blob if you really want. I would have thought that was the least worrying part of this dogās breakfast piece of code
Shoot already found instances where it fails. Ok forget, temporary work around Iāll commit the ultimate sin and resort to nsIFile for now haha - http://stackoverflow.com/a/25020668/1828637 - will delete self on closeCi.nsIFileInputStream.DELETE_ON_CLOSE