зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1542172 - Firefox freezes when inspecting large POST data. r=Honza
Truncate the Request Payload if it exceeds the `devtools.netmonitor.requestBodyLimit` pref and show `Request has been truncated` error in the Params Tab Differential Revision: https://phabricator.services.mozilla.com/D27898 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
73a324ee2d
Коммит
e8ed10a457
|
@ -141,6 +141,11 @@ jsonpScopeName=JSONP → callback %S()
|
|||
# the truncation limit and thus was truncated.
|
||||
responseTruncated=Response has been truncated
|
||||
|
||||
# LOCALIZATION NOTE (requestTruncated): This is the text displayed
|
||||
# in the params tab of the network details pane when the request is over
|
||||
# the truncation limit and thus was truncated.
|
||||
requestTruncated=Request has been truncated
|
||||
|
||||
# LOCALIZATION NOTE (responsePreview): This is the text displayed
|
||||
# in the response tab of the network details pane for an HTML preview.
|
||||
responsePreview=Preview
|
||||
|
|
|
@ -327,6 +327,15 @@
|
|||
margin-left: 4px;
|
||||
}
|
||||
|
||||
/* Params tabpanel */
|
||||
|
||||
.network-monitor .request-error-header {
|
||||
margin: 0;
|
||||
padding: 3px 8px;
|
||||
background-color: var(--theme-highlight-red);
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
/* Response tabpanel */
|
||||
|
||||
.network-monitor .response-error-header {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const Services = require("Services");
|
||||
const { connect } = require("devtools/client/shared/redux/visibility-handler-connect");
|
||||
const { L10N } = require("../utils/l10n");
|
||||
const {
|
||||
|
@ -30,6 +31,7 @@ const PARAMS_FILTER_TEXT = L10N.getStr("paramsFilterText");
|
|||
const PARAMS_FORM_DATA = L10N.getStr("paramsFormData");
|
||||
const PARAMS_POST_PAYLOAD = L10N.getStr("paramsPostPayload");
|
||||
const PARAMS_QUERY_STRING = L10N.getStr("paramsQueryString");
|
||||
const REQUEST_TRUNCATED = L10N.getStr("requestTruncated");
|
||||
const SECTION_NAMES = [
|
||||
JSON_SCOPE_NAME,
|
||||
PARAMS_FORM_DATA,
|
||||
|
@ -115,7 +117,7 @@ class ParamsPanel extends Component {
|
|||
}
|
||||
|
||||
const object = {};
|
||||
let json;
|
||||
let json, error;
|
||||
|
||||
// Query String section
|
||||
if (query) {
|
||||
|
@ -129,16 +131,27 @@ class ParamsPanel extends Component {
|
|||
}
|
||||
|
||||
// Request payload section
|
||||
|
||||
const limit = Services.prefs.getIntPref("devtools.netmonitor.requestBodyLimit");
|
||||
// Check if the request post data has been truncated, in which case no parse should
|
||||
// be attempted.
|
||||
if (postData && limit <= postData.length) {
|
||||
error = REQUEST_TRUNCATED;
|
||||
}
|
||||
|
||||
if (formDataSections && formDataSections.length === 0 && postData) {
|
||||
try {
|
||||
json = JSON.parse(postData);
|
||||
} catch (error) {
|
||||
// Continue regardless of parsing error
|
||||
if (!error) {
|
||||
try {
|
||||
json = JSON.parse(postData);
|
||||
} catch (err) {
|
||||
// Continue regardless of parsing error
|
||||
}
|
||||
|
||||
if (json) {
|
||||
object[JSON_SCOPE_NAME] = sortObjectKeys(json);
|
||||
}
|
||||
}
|
||||
|
||||
if (json) {
|
||||
object[JSON_SCOPE_NAME] = sortObjectKeys(json);
|
||||
}
|
||||
object[PARAMS_POST_PAYLOAD] = {
|
||||
EDITOR_CONFIG: {
|
||||
text: postData,
|
||||
|
@ -151,6 +164,9 @@ class ParamsPanel extends Component {
|
|||
|
||||
return (
|
||||
div({ className: "panel-container" },
|
||||
error && div({ className: "request-error-header", title: error },
|
||||
error
|
||||
),
|
||||
PropertiesView({
|
||||
object,
|
||||
filterPlaceHolder: PARAMS_FILTER_TEXT,
|
||||
|
|
|
@ -213,6 +213,7 @@ skip-if = true # Bug 1373558
|
|||
skip-if = true # TODO: fix the test
|
||||
[browser_net_timing-division.js]
|
||||
[browser_net_tracking-resources.js]
|
||||
[browser_net_truncate-post-data.js]
|
||||
[browser_net_truncate.js]
|
||||
[browser_net_view-source-debugger.js]
|
||||
[browser_net_waterfall-click.js]
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Bug 1542172 -
|
||||
* Verifies that requests with large post data are truncated and error is displayed.
|
||||
*/
|
||||
add_task(async function() {
|
||||
const { monitor, tab } = await initNetMonitor(POST_JSON_URL);
|
||||
|
||||
info("Starting test... ");
|
||||
|
||||
const { L10N } = require("devtools/client/netmonitor/src/utils/l10n");
|
||||
|
||||
const { document, store, windowRequire } = monitor.panelWin;
|
||||
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
info("Perform requests");
|
||||
await performRequestsAndWait();
|
||||
|
||||
await waitUntil(() => document.querySelector(".request-list-item"));
|
||||
const item = document.querySelectorAll(".request-list-item")[0];
|
||||
await waitUntil(() => item.querySelector(".requests-list-type").title);
|
||||
|
||||
wait = waitForDOM(document, "#params-panel .tree-section", 1);
|
||||
store.dispatch(Actions.toggleNetworkDetails());
|
||||
EventUtils.sendMouseEvent({ type: "click" }, document.querySelector("#params-tab"));
|
||||
await wait;
|
||||
|
||||
const tabpanel = document.querySelector("#params-panel");
|
||||
is(tabpanel.querySelector(".request-error-header") === null, false,
|
||||
"The request error header doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector(".request-error-header").textContent,
|
||||
"Request has been truncated", "The error message shown is incorrect");
|
||||
const jsonView = tabpanel.querySelector(".tree-section .treeLabel") || {};
|
||||
is(jsonView.textContent === L10N.getStr("jsonScopeName"), false,
|
||||
"The params json view doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("pre") === null, false,
|
||||
"The Request Payload has the intended visibility.");
|
||||
|
||||
return teardown(monitor);
|
||||
async function performRequestsAndWait() {
|
||||
const wait = waitForNetworkEvents(monitor, 1);
|
||||
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
|
||||
content.wrappedJSObject.performLargePostDataRequest();
|
||||
});
|
||||
await wait;
|
||||
}
|
||||
});
|
|
@ -15,7 +15,7 @@
|
|||
<p>POST raw test</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
/* exported performRequests */
|
||||
/* exported performRequests performLargePostDataRequest */
|
||||
"use strict";
|
||||
|
||||
function post(address, message, callback) {
|
||||
|
@ -36,6 +36,14 @@
|
|||
// Done.
|
||||
});
|
||||
}
|
||||
|
||||
function performLargePostDataRequest() {
|
||||
const limit = 1048576;
|
||||
const data = "x".repeat(2 * limit);
|
||||
post("sjs_simple-test-server.sjs", JSON.stringify(data), function() {
|
||||
// Done.
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ const NetworkEventActor = protocol.ActorClassWithSpec(networkEventSpec, {
|
|||
// bug 1462561 - Use "json" type and manually manage/marshall actors to woraround
|
||||
// protocol.js performance issue
|
||||
this.manage(postData.text);
|
||||
const dataSize = postData.text.str.length;
|
||||
const dataSize = postData.size;
|
||||
postData.text = postData.text.form();
|
||||
|
||||
this.emit("network-event-update:post-data", "requestPostData", {
|
||||
|
|
|
@ -395,7 +395,15 @@ NetworkObserver.prototype = {
|
|||
case gActivityDistributor.ACTIVITY_SUBTYPE_REQUEST_BODY_SENT:
|
||||
this._onRequestBodySent(httpActivity);
|
||||
if (httpActivity.sentBody !== null) {
|
||||
httpActivity.owner.addRequestPostData({ text: httpActivity.sentBody });
|
||||
const limit = Services.prefs.getIntPref("devtools.netmonitor.requestBodyLimit");
|
||||
const size = httpActivity.sentBody.length;
|
||||
if (size > limit && limit > 0) {
|
||||
httpActivity.sentBody = httpActivity.sentBody.substr(0, limit);
|
||||
}
|
||||
httpActivity.owner.addRequestPostData({
|
||||
text: httpActivity.sentBody,
|
||||
size: size,
|
||||
});
|
||||
httpActivity.sentBody = null;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -38,11 +38,12 @@ pref("devtools.debugger.remote-websocket", false);
|
|||
// Force debugger server binding on the loopback interface
|
||||
pref("devtools.debugger.force-local", true);
|
||||
|
||||
// Limit for intercepted response bodies (1 MB)
|
||||
// Limit for intercepted request and response bodies (1 MB)
|
||||
// Possible values:
|
||||
// 0 => the response body has no limit
|
||||
// n => represents max number of bytes stored
|
||||
pref("devtools.netmonitor.responseBodyLimit", 1048576);
|
||||
pref("devtools.netmonitor.requestBodyLimit", 1048576);
|
||||
|
||||
// DevTools default color unit
|
||||
pref("devtools.defaultColorUnit", "authored");
|
||||
|
|
Загрузка…
Ссылка в новой задаче