Bug 1340100 - Set 'request cause' according to the original request. r=Honza
authortanhengyeow <E0032242@u.nus.edu>
Mon, 22 Oct 2018 13:48:47 +0000
changeset 490679 527ac367e301ec8b55b4b226ceeca47cb87d130f
parent 490678 e4d47f8261f74e4d19262ac68a79d76ddbd3d8f7
child 490680 ad022c9aec53ad84e86d0164e1c3f100ae5449b1
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersHonza
bugs1340100
milestone64.0a1
Bug 1340100 - Set 'request cause' according to the original request. r=Honza Set 'request cause' according to the original request. Differential Revision: https://phabricator.services.mozilla.com/D8126
devtools/client/netmonitor/src/actions/requests.js
devtools/client/netmonitor/src/reducers/requests.js
devtools/client/netmonitor/test/browser.ini
devtools/client/netmonitor/test/browser_net_edit_resend_xhr.js
devtools/client/netmonitor/test/browser_net_resend_headers.js
devtools/server/actors/network-monitor/network-observer.js
devtools/server/actors/webconsole.js
--- a/devtools/client/netmonitor/src/actions/requests.js
+++ b/devtools/client/netmonitor/src/actions/requests.js
@@ -51,16 +51,17 @@ function sendCustomRequest(connector) {
     const selected = getSelectedRequest(getState());
 
     if (!selected) {
       return;
     }
 
     // Send a new HTTP request using the data in the custom request form
     const data = {
+      cause: selected.cause,
       url: selected.url,
       method: selected.method,
       httpVersion: selected.httpVersion,
     };
     if (selected.requestHeaders) {
       data.headers = selected.requestHeaders.headers;
     }
     if (selected.requestPostData) {
--- a/devtools/client/netmonitor/src/reducers/requests.js
+++ b/devtools/client/netmonitor/src/reducers/requests.js
@@ -127,16 +127,17 @@ function requestsReducer(state = Request
 
       const clonedRequest = requests.get(selectedId);
       if (!clonedRequest) {
         return state;
       }
 
       const newRequest = {
         id: clonedRequest.id + "-clone",
+        cause: clonedRequest.cause,
         method: clonedRequest.method,
         url: clonedRequest.url,
         urlDetails: clonedRequest.urlDetails,
         requestHeaders: clonedRequest.requestHeaders,
         requestPostData: clonedRequest.requestPostData,
         requestPostDataAvailable: clonedRequest.requestPostDataAvailable,
         isCustom: true,
       };
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -117,16 +117,17 @@ subsuite = clipboard
 [browser_net_cors_requests.js]
 [browser_net_cyrillic-01.js]
 [browser_net_cyrillic-02.js]
 [browser_net_frame.js]
 skip-if = (os == 'mac') # Bug 1479782
 [browser_net_header-docs.js]
 [browser_net_edit_resend_caret.js]
 [browser_net_edit_resend_with_filtering.js]
+[browser_net_edit_resend_xhr.js]
 [browser_net_filter-01.js]
 [browser_net_filter-02.js]
 [browser_net_filter-03.js]
 [browser_net_filter-04.js]
 [browser_net_filter-autocomplete.js]
 [browser_net_filter-flags.js]
 [browser_net_footer-summary.js]
 [browser_net_headers-alignment.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_edit_resend_xhr.js
@@ -0,0 +1,48 @@
+/* Any copyright is dedicated to the Public Domain.
+*  http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Tests if editing and resending a XHR request works and the
+ * cloned request retains the same cause type.
+ */
+
+add_task(async function() {
+  const { tab, monitor } = await initNetMonitor(POST_RAW_URL);
+
+  const { document, store, windowRequire, parent } = monitor.panelWin;
+  const parentDocument = parent.document;
+  const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
+  store.dispatch(Actions.batchEnable(false));
+
+  // Executes 1 XHR request
+  await performRequests(monitor, tab, 1);
+
+  // Selects 1st XHR request
+  const xhrRequest = document.querySelectorAll(".request-list-item")[0];
+  EventUtils.sendMouseEvent({ type: "mousedown" }, xhrRequest);
+
+  // Stores original request for comparison of values later
+  const { getSelectedRequest }
+  = windowRequire("devtools/client/netmonitor/src/selectors/index");
+  const original = getSelectedRequest(store.getState());
+
+  // Context Menu > "Edit & Resend"
+  EventUtils.sendMouseEvent({ type: "contextmenu" }, xhrRequest);
+  parentDocument.querySelector("#request-list-context-resend").click();
+
+  // Waits for "Edit & Resend" panel to appear > New request "Send"
+  document.querySelector("#custom-request-send-button").click();
+
+  // Selects cloned request
+  const clonedRequest = document.querySelectorAll(".request-list-item")[1];
+  EventUtils.sendMouseEvent({ type: "mousedown" }, clonedRequest);
+  const cloned = getSelectedRequest(store.getState());
+
+  // Compares if the requests have the same cause type (XHR)
+  ok(original.cause.type === cloned.cause.type,
+  "Both requests retain the same cause type");
+
+  return teardown(monitor);
+});
--- a/devtools/client/netmonitor/test/browser_net_resend_headers.js
+++ b/devtools/client/netmonitor/test/browser_net_resend_headers.js
@@ -31,16 +31,21 @@ add_task(async function() {
   ];
 
   const wait = waitForNetworkEvents(monitor, 1);
   sendHTTPRequest({
     url: requestUrl,
     method: "POST",
     headers: requestHeaders,
     body: "Hello",
+    cause: {
+      loadingDocumentUri: "http://example.com",
+      stacktraceAvailable: true,
+      type: "xhr",
+    },
   });
   await wait;
 
   let item = getSortedRequests(store.getState()).get(0);
 
   ok(item.requestHeadersAvailable, "headers are available for lazily fetching");
 
   if (item.requestHeadersAvailable && !item.requestHeaders) {
--- a/devtools/server/actors/network-monitor/network-observer.js
+++ b/devtools/server/actors/network-monitor/network-observer.js
@@ -1126,8 +1126,14 @@ const LOAD_CAUSE_STRINGS = {
   [Ci.nsIContentPolicy.TYPE_FETCH]: "fetch",
   [Ci.nsIContentPolicy.TYPE_IMAGESET]: "imageset",
   [Ci.nsIContentPolicy.TYPE_WEB_MANIFEST]: "webManifest",
 };
 
 function causeTypeToString(causeType) {
   return LOAD_CAUSE_STRINGS[causeType] || "unknown";
 }
+
+function stringToCauseType(value) {
+  return Object.keys(LOAD_CAUSE_STRINGS)
+  .find(key => LOAD_CAUSE_STRINGS[key] === value);
+}
+exports.stringToCauseType = stringToCauseType;
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -28,16 +28,18 @@ loader.lazyRequireGetter(this, "NetUtil"
 loader.lazyRequireGetter(this, "addWebConsoleCommands", "devtools/server/actors/webconsole/utils", true);
 loader.lazyRequireGetter(this, "isCommand", "devtools/server/actors/webconsole/commands", true);
 loader.lazyRequireGetter(this, "validCommands", "devtools/server/actors/webconsole/commands", true);
 loader.lazyRequireGetter(this, "createMessageManagerMocks", "devtools/server/actors/webconsole/message-manager-mock", true);
 loader.lazyRequireGetter(this, "CONSOLE_WORKER_IDS", "devtools/server/actors/webconsole/utils", true);
 loader.lazyRequireGetter(this, "WebConsoleUtils", "devtools/server/actors/webconsole/utils", true);
 loader.lazyRequireGetter(this, "EnvironmentActor", "devtools/server/actors/environment", true);
 loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
+loader.lazyRequireGetter(this, "stringToCauseType",
+    "devtools/server/actors/network-monitor/network-observer", true);
 
 // Generated by /devtools/shared/webconsole/GenerateReservedWordsJS.py
 loader.lazyRequireGetter(this, "RESERVED_JS_KEYWORDS", "devtools/shared/webconsole/reserved-js-words");
 
 // Overwrite implemented listeners for workers so that we don't attempt
 // to load an unsupported module.
 if (isWorker) {
   loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/webconsole/worker-listeners", true);
@@ -1597,27 +1599,27 @@ WebConsoleActor.prototype =
 
   /**
    * Send a new HTTP request from the target's window.
    *
    * @param object message
    *        Object with 'request' - the HTTP request details.
    */
   async sendHTTPRequest({ request }) {
-    const { url, method, headers, body } = request;
-
+    const { url, method, headers, body, cause } = request;
     // Set the loadingNode and loadGroup to the target document - otherwise the
     // request won't show up in the opened netmonitor.
     const doc = this.window.document;
 
     const channel = NetUtil.newChannel({
       uri: NetUtil.newURI(url),
       loadingNode: doc,
       securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-      contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+      contentPolicyType: stringToCauseType(cause.type)
+      || Ci.nsIContentPolicy.TYPE_OTHER,
     });
 
     channel.QueryInterface(Ci.nsIHttpChannel);
 
     channel.loadGroup = doc.documentLoadGroup;
     channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE |
                          Ci.nsIRequest.INHIBIT_CACHING |
                          Ci.nsIRequest.LOAD_ANONYMOUS;