Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Fix #3472, avoid form uploads from being truncated
Browse files Browse the repository at this point in the history
FormData was not creating correct request bodies for large images. This changes the code to manually construct the form upload.
  • Loading branch information
ianb committed Sep 8, 2017
1 parent dbc4750 commit 671b003
Showing 1 changed file with 64 additions and 7 deletions.
71 changes: 64 additions & 7 deletions addon/webextension/background/takeshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,75 @@ this.takeshot = (function() {
return blob;
}

/** Combines two buffers or Uint8Array's */
function concatBuffers(buffer1, buffer2) {
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0);
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
return tmp.buffer;
}

/** Returns a promise that converts a Blob to a TypedArray */
function blobToArray(blob) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.addEventListener("loadend", function() {
resolve(reader.result);
});
reader.readAsArrayBuffer(blob);
});
}

/** Creates a multipart TypedArray, given {name: value} fields
and {name: blob} files
Returns {body, "content-type"}
*/
function createMultipart(fields, fileField, fileFilename, blob) {
let boundary = "---------------------------ScreenshotBoundary" + Date.now();
return blobToArray(blob).then((blobAsBuffer) => {
let body = [];
for (let name in fields) {
body.push("--" + boundary);
body.push(`Content-Disposition: form-data; name="${name}"`);
body.push("");
body.push(fields[name]);
}
body.push("--" + boundary);
body.push(`Content-Disposition: form-data; name="${fileField}"; filename="${fileFilename}"`);
body.push(`Content-Type: ${blob.type}`);
body.push("");
body.push("");
body = body.join("\r\n");
let enc = new TextEncoder("utf-8");
body = enc.encode(body);
body = concatBuffers(body.buffer, blobAsBuffer);
let tail = "\r\n" + "--" + boundary + "--";
tail = enc.encode(tail);
body = concatBuffers(body, tail.buffer);
return {
"content-type": `multipart/form-data; boundary=${boundary}`,
body
};
});
}

function uploadShot(shot, blob) {
return auth.authHeaders().then((headers) => {
let formData = new FormData();
formData.append("shot", JSON.stringify(shot.asJson()));
formData.append("blob", blob);
let body = formData;
sendEvent("upload", "started", {eventValue: Math.floor(body.length / 1000)});
let headers;
return auth.authHeaders().then((_headers) => {
headers = _headers;
return createMultipart(
{shot: JSON.stringify(shot.asJson())},
"blob", "screenshot.png", blob
);
}).then((submission) => {
headers["content-type"] = submission["content-type"];
sendEvent("upload", "started", {eventValue: Math.floor(submission.body.length / 1000)});
return fetch(shot.jsonUrl, {
method: "PUT",
mode: "cors",
headers,
body
body: submission.body
});
}).then((resp) => {
if (!resp.ok) {
Expand Down

0 comments on commit 671b003

Please sign in to comment.