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

Commit

Permalink
Upload jpeg (#3513)
Browse files Browse the repository at this point in the history
* Start #220, allow JPEG uploads, and respect content-type for JPEG or PNG

* Fix #220, use JPEG for large shots

- Allows JPEGs on the server, both to pass content checks, and to make use of stored content-types (instead of assuming image/png).
- Puts an clip.image.type into shot objects
- Uses .jpg for filenames when appropriate
- Adds a new buildSetting for controlling the cutoff when we use JPEG
- If a PNG image is too large, tries to make a JPEG and substitutes if the JPEG is actually smaller
- Refactor some data:-URL and blob converstion functions into their own module
  • Loading branch information
ianb authored and jaredhirsch committed Sep 19, 2017
1 parent 197b691 commit 82139ed
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 72 deletions.
6 changes: 2 additions & 4 deletions addon/webextension/background/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* globals selectorLoader, analytics, communication, catcher, log, makeUuid, auth, senderror, startBackground */
/* globals selectorLoader, analytics, communication, catcher, log, makeUuid, auth, senderror, startBackground, blobConverters */

"use strict";

Expand Down Expand Up @@ -223,9 +223,7 @@ this.main = (function() {
communication.register("downloadShot", (sender, info) => {
// 'data:' urls don't work directly, let's use a Blob
// see http://stackoverflow.com/questions/40269862/save-data-uri-as-file-using-downloads-download-api
const binary = atob(info.url.split(',')[1]); // just the base64 data
const data = Uint8Array.from(binary, char => char.charCodeAt(0))
const blob = new Blob([data], {type: "image/png"})
const blob = blobConverters.dataUrlToBlob(info.url);
let url = URL.createObjectURL(blob);
let downloadId;
let onChangedCallback = catcher.watchFunction(function(change) {
Expand Down
1 change: 1 addition & 0 deletions addon/webextension/background/selectorLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ this.selectorLoader = (function() {
"catcher.js",
"assertIsTrusted.js",
"assertIsBlankDocument.js",
"blobConverters.js",
"background/selectorLoader.js",
"selector/callBackground.js",
"selector/util.js"
Expand Down
1 change: 1 addition & 0 deletions addon/webextension/background/startBackground.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ this.startBackground = (function() {
"log.js",
"makeUuid.js",
"catcher.js",
"blobConverters.js",
"background/selectorLoader.js",
"background/communication.js",
"background/auth.js",
Expand Down
36 changes: 4 additions & 32 deletions addon/webextension/background/takeshot.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* globals communication, shot, main, auth, catcher, analytics, buildSettings */
/* globals communication, shot, main, auth, catcher, analytics, buildSettings, blobConverters */

"use strict";

Expand Down Expand Up @@ -33,10 +33,10 @@ this.takeshot = (function() {
}
let convertBlobPromise = Promise.resolve();
if (buildSettings.uploadBinary && !imageBlob) {
imageBlob = base64ToBinary(shot.getClip(shot.clipNames()[0]).image.url);
imageBlob = blobConverters.dataUrlToBlob(shot.getClip(shot.clipNames()[0]).image.url);
shot.getClip(shot.clipNames()[0]).image.url = "";
} else if (!buildSettings.uploadBinary && imageBlob) {
convertBlobPromise = blobToDataUrl(imageBlob).then((dataUrl) => {
convertBlobPromise = blobConverters.blobToDataUrl(imageBlob).then((dataUrl) => {
shot.getClip(shot.clipNames()[0]).image.url = dataUrl;
});
imageBlob = null;
Expand Down Expand Up @@ -120,13 +120,6 @@ this.takeshot = (function() {
}));
}

function base64ToBinary(url) {
const binary = atob(url.split(',')[1]);
const data = Uint8Array.from(binary, char => char.charCodeAt(0));
const blob = new Blob([data], {type: "image/png"});
return blob;
}

/** Combines two buffers or Uint8Array's */
function concatBuffers(buffer1, buffer2) {
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
Expand All @@ -135,35 +128,14 @@ this.takeshot = (function() {
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);
});
}

function blobToDataUrl(blob) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.addEventListener("loadend", function() {
resolve(reader.result);
});
reader.readAsDataURL(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) => {
return blobConverters.blobToArray(blob).then((blobAsBuffer) => {
let body = [];
for (let name in fields) {
body.push("--" + boundary);
Expand Down
44 changes: 44 additions & 0 deletions addon/webextension/blobConverters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
this.blobConverters = (function () {
let exports = {};

exports.dataUrlToBlob = function(url) {
const binary = atob(url.split(',')[1]);
let contentType = exports.getTypeFromDataUrl(url);
if (contentType != "image/png" && contentType != "image/jpeg") {
contentType = "image/png";
}
const data = Uint8Array.from(binary, char => char.charCodeAt(0));
const blob = new Blob([data], {type: contentType});
return blob;
};

exports.getTypeFromDataUrl = function(url) {
let contentType = url.split(',')[0];
contentType = contentType.split(';')[0];
contentType = contentType.split(':')[1];
return contentType;
};

exports.blobToArray = function(blob) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.addEventListener("loadend", function() {
resolve(reader.result);
});
reader.readAsArrayBuffer(blob);
});
};

exports.blobToDataUrl = function(blob) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.addEventListener("loadend", function() {
resolve(reader.result);
});
reader.readAsDataURL(blob);
});
};

return exports;
})();
null;
3 changes: 2 additions & 1 deletion addon/webextension/buildSettings.js.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ window.buildSettings = {
defaultSentryDsn: process.env.SCREENSHOTS_SENTRY,
logLevel: process.env.SCREENSHOTS_LOG_LEVEL || "warn",
captureText: (process.env.SCREENSHOTS_CAPTURE_TEXT === "true"),
uploadBinary: (process.env.SCREENSHOTS_UPLOAD_BINARY === "true")
uploadBinary: (process.env.SCREENSHOTS_UPLOAD_BINARY === "true"),
pngToJpegCutoff: parseInt(process.env.SCREENSHOTS_PNG_TO_JPEG_CUTOFF || 2500000, 10)
};
null;
25 changes: 15 additions & 10 deletions addon/webextension/selector/shooter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* globals global, documentMetadata, util, uicontrol, ui, catcher */
/* globals buildSettings, domainFromUrl, randomString, shot */
/* globals buildSettings, domainFromUrl, randomString, shot, blobConverters */

"use strict";

Expand Down Expand Up @@ -29,13 +29,6 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
return result;
}

function base64ToBinary(url) {
const binary = atob(url.split(',')[1]);
const data = Uint8Array.from(binary, char => char.charCodeAt(0));
const blob = new Blob([data], {type: "image/png"});
return blob;
}

catcher.registerHandler((errorObj) => {
callBackground("reportError", sanitizeError(errorObj));
});
Expand Down Expand Up @@ -70,7 +63,16 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
} finally {
ui.iframe.unhide();
}
return canvas.toDataURL();
let limit = buildSettings.pngToJpegCutoff;
let dataUrl = canvas.toDataURL();
if (limit && dataUrl.length > limit) {
let jpegDataUrl = canvas.toDataURL("image/jpeg");
if (jpegDataUrl.length < dataUrl.length) {
// Only use the JPEG if it is actually smaller
dataUrl = jpegDataUrl;
}
}
return dataUrl;
};

let isSaving = null;
Expand Down Expand Up @@ -106,13 +108,16 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
captureText = util.captureEnclosedText(selectedPos);
}
let dataUrl = url || screenshotPage(selectedPos, captureType);
let type = blobConverters.getTypeFromDataUrl(dataUrl);
type = type ? type.split("/")[1] : null;
if (dataUrl) {
imageBlob = base64ToBinary(dataUrl);
imageBlob = blobConverters.dataUrlToBlob(dataUrl);
shotObject.delAllClips();
shotObject.addClip({
createdDate: Date.now(),
image: {
url: "data:",
type,
captureType,
text: captureText,
location: selectedPos,
Expand Down
6 changes: 6 additions & 0 deletions bin/load_test_exercise_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
width=400,
height=267,
),
dict(
source="https://upload.wikimedia.org/wikipedia/en/thumb/a/a9/Example.jpg/111px-Example.jpg",
url="data:image/jpeg;base64,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",
width=111,
height=120,
),
dict(
source="http://www.1x1px.me/",
url="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=",
Expand Down
14 changes: 12 additions & 2 deletions server/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,13 @@ app.put("/data/:id/:domain", upload.single('blob'), function(req, res) {
bodyObj = JSON.parse(req.body.shot);
let clipId = Object.getOwnPropertyNames(bodyObj.clips)[0];
let b64 = req.file.buffer.toString("base64");
b64 = "data:image/png;base64," + b64;
let contentType = req.file.mimetype;
if (contentType != "image/png" && contentType != "image/jpeg") {
// Force PNG as a fallback
mozlog.warn("invalid-upload-content-type", {contentType});
contentType = "image/png";
}
b64 = `data:${contentType};base64,${b64}`;
bodyObj.clips[clipId].image.url = b64;
} else if (req.body) {
bodyObj = req.body;
Expand Down Expand Up @@ -829,7 +835,11 @@ app.get("/images/:imageid", function(req, res) {
el
}).send();
}
res.header("Content-Type", "image/png");
let contentType = obj.contentType;
if (contentType != "image/png" && contentType != "image/jpeg") {
contentType = "image/png";
}
res.header("Content-Type", contentType);
if (download) {
if (dbschema.getKeygrip().verify(new Buffer(download, 'utf8'), sig)) {
res.header("Content-Disposition", contentDisposition(download));
Expand Down
Loading

0 comments on commit 82139ed

Please sign in to comment.