Bug 1332949 - In the network panel copy posted data or response data in binary format doesn't work correctly. r?honza
MozReview-Commit-ID: Kz4kj18U30Y
--- a/devtools/client/netmonitor/src/request-list-context-menu.js
+++ b/devtools/client/netmonitor/src/request-list-context-menu.js
@@ -18,16 +18,17 @@ const {
getSelectedRequest,
getSortedRequests,
} = require("./selectors/index");
const { L10N } = require("./utils/l10n");
const { showMenu } = require("./utils/menu");
const {
getUrlQuery,
parseQueryString,
+ isBinary,
} = require("./utils/request-utils");
function RequestListContextMenu({
cloneSelectedRequest,
openStatistics,
}) {
this.cloneSelectedRequest = cloneSelectedRequest;
this.openStatistics = openStatistics;
@@ -228,17 +229,17 @@ RequestListContextMenu.prototype = {
let params = getUrlQuery(this.selectedRequest.url).split("&");
copyString(params.join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n"));
},
/**
* Copy the request form data parameters (or raw payload) from
* the currently selected item.
*/
- copyPostData() {
+ async copyPostData() {
let { formDataSections, requestPostData } = this.selectedRequest;
let params = [];
// Try to extract any form data parameters.
formDataSections.forEach(section => {
let paramsArray = parseQueryString(section);
if (paramsArray) {
params = [...params, ...paramsArray];
@@ -247,20 +248,27 @@ RequestListContextMenu.prototype = {
let string = params
.map(param => param.name + (param.value ? "=" + param.value : ""))
.join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
// Fall back to raw payload.
if (!string) {
string = requestPostData.postData.text;
+ let verify = await isBinary(string);
+
+ if (verify) {
+ string = JSON.stringify(string);
+ }
+
if (Services.appinfo.OS !== "WINNT") {
string = string.replace(/\r/g, "");
}
}
+
copyString(string);
},
/**
* Copy a cURL command from the currently selected item.
*/
copyAsCurl() {
let selected = this.selectedRequest;
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -335,16 +335,52 @@ function getEndTime(item, firstRequestSt
* a firstRequestStartedMillis.
*/
function getResponseTime(item, firstRequestStartedMillis = 0) {
let { startedMillis, totalTime, eventTimings = { timings: {} } } = item;
return startedMillis + totalTime - firstRequestStartedMillis -
eventTimings.timings.receive;
}
+function between(num, first, last) {
+ return num >= first && num <= last;
+}
+
+function nonprintable(code) {
+ return between(code, 0, 8) || code == 0xb || between(code, 0xe, 0x1f) || code == 0x7f;
+}
+
+async function isBinary(string) {
+ let blob = new Blob([string], {type: "application/octet-binary"});
+ return new Promise((resolve, reject) => {
+ let reader = new FileReader();
+
+ reader.onerror = (event) => {
+ reject(event);
+ return false;
+ };
+
+ reader.onloadend = (event) => {
+ let buff = reader.result;
+ let view = new Uint8Array(buff);
+
+ for (let count = 0; count < view.length; count++) {
+ if (nonprintable(view[count])) {
+ resolve(true);
+ return true;
+ }
+ }
+ resolve(false);
+ return false;
+ };
+
+ reader.readAsArrayBuffer(blob);
+ });
+}
+
module.exports = {
getFormDataSections,
fetchHeaders,
formDataURI,
writeHeaderText,
decodeUnicodeUrl,
getAbbreviatedMimeType,
getEndTime,
@@ -356,9 +392,10 @@ module.exports = {
getUrlHost,
getUrlHostName,
getUrlQuery,
getUrlScheme,
parseQueryString,
parseFormData,
propertiesEqual,
ipToLong,
+ isBinary,
};