Bug 125025 - Properly decode response body; r=gasolin
MozReview-Commit-ID: 1vbWxLfieIq
--- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js
+++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js
@@ -2,17 +2,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-disable block-scoped-var */
"use strict";
const { EVENTS } = require("../constants");
const { CurlUtils } = require("devtools/client/shared/curl");
-const { fetchHeaders, formDataURI } = require("../utils/request-utils");
+const {
+ b64DecodeUnicode,
+ fetchHeaders,
+ formDataURI,
+} = require("../utils/request-utils");
/**
* This object is responsible for fetching additional HTTP
* data from the backend.
*/
class FirefoxDataProvider {
constructor({webConsoleClient, actions}) {
// Options
@@ -22,17 +26,17 @@ class FirefoxDataProvider {
// Internal properties
this.payloadQueue = [];
// Public methods
this.addRequest = this.addRequest.bind(this);
this.updateRequest = this.updateRequest.bind(this);
// Internals
- this.fetchImage = this.fetchImage.bind(this);
+ this.fetchResponseBody = this.fetchResponseBody.bind(this);
this.fetchRequestHeaders = this.fetchRequestHeaders.bind(this);
this.fetchResponseHeaders = this.fetchResponseHeaders.bind(this);
this.fetchPostData = this.fetchPostData.bind(this);
this.fetchResponseCookies = this.fetchResponseCookies.bind(this);
this.fetchRequestCookies = this.fetchRequestCookies.bind(this);
this.getPayloadFromQueue = this.getPayloadFromQueue.bind(this);
this.isQueuePayloadReady = this.isQueuePayloadReady.bind(this);
this.pushPayloadToQueue = this.pushPayloadToQueue.bind(this);
@@ -107,17 +111,17 @@ class FirefoxDataProvider {
let [
imageObj,
requestHeadersObj,
responseHeadersObj,
postDataObj,
requestCookiesObj,
responseCookiesObj,
] = await Promise.all([
- this.fetchImage(mimeType, responseContent),
+ this.fetchResponseBody(mimeType, responseContent),
this.fetchRequestHeaders(requestHeaders),
this.fetchResponseHeaders(responseHeaders),
this.fetchPostData(requestPostData),
this.fetchRequestCookies(requestCookies),
this.fetchResponseCookies(responseCookies),
]);
let payload = Object.assign({},
@@ -132,24 +136,30 @@ class FirefoxDataProvider {
this.pushPayloadToQueue(id, payload);
if (this.actions.updateRequest && this.isQueuePayloadReady(id)) {
await this.actions.updateRequest(id, this.getPayloadFromQueue(id).payload, true);
}
}
- async fetchImage(mimeType, responseContent) {
+ async fetchResponseBody(mimeType, responseContent) {
let payload = {};
if (mimeType && responseContent && responseContent.content) {
let { encoding, text } = responseContent.content;
let response = await this.getLongString(text);
if (mimeType.includes("image/")) {
payload.responseContentDataUri = formDataURI(mimeType, encoding, response);
+ } else if (encoding === "base64") {
+ response = b64DecodeUnicode(response);
+ }
+
+ if (mimeType.includes("text/")) {
+ payload.responseContentDataUri = formDataURI(mimeType, encoding, response);
}
responseContent.content.text = response;
payload.responseContent = responseContent;
}
return payload;
}
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -104,16 +104,36 @@ function decodeUnicodeUrl(string) {
return decodeURIComponent(string);
} catch (err) {
// Ignore error and return input string directly.
}
return string;
}
/**
+ * Decode base64 string. From bytestream, to percent-encoding,
+ * to original string.
+ *
+ * See also: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
+ *
+ * @param {string} url - a string
+ * @return {string} decoded string
+ */
+function b64DecodeUnicode(str) {
+ try {
+ return decodeURIComponent(atob(str).split("").map(function (c) {
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
+ }).join(""));
+ } catch (err) {
+ // Ignore error and return input string directly.
+ }
+ return str;
+}
+
+/**
* Helper for getting an abbreviated string for a mime type.
*
* @param {string} mimeType - mime type
* @return {string} abbreviated mime type
*/
function getAbbreviatedMimeType(mimeType) {
if (!mimeType) {
return "";
@@ -370,16 +390,17 @@ function getResponseHeader(item, header)
if (responseHeader.name.toLowerCase() == header) {
return responseHeader.value;
}
}
return null;
}
module.exports = {
+ b64DecodeUnicode,
getFormDataSections,
fetchHeaders,
formDataURI,
writeHeaderText,
decodeUnicodeUrl,
getAbbreviatedMimeType,
getEndTime,
getFormattedProtocol,