Bug 1397448: Part 1 - Generate WebRequest message objects in WebRequest.jsm. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 06 Sep 2017 17:43:38 -0700
changeset 661994 eabab61d9a1ed48fccc976c98c68df06b30dea63
parent 661993 4139fb57113194ade6c0f710c7bba080af3078e3
child 661995 d0203f150125876d0e07e8b1889d487f708328b2
push id78919
push usermaglione.k@gmail.com
push dateSat, 09 Sep 2017 23:05:23 +0000
reviewersmixedpuppy
bugs1397448
milestone57.0a1
Bug 1397448: Part 1 - Generate WebRequest message objects in WebRequest.jsm. r?mixedpuppy Aside from moving this logic closer to the place the input data is generated, this significantly reduces the number of cross-compartment wrappers involved in creating those messages, especially with JSM global sharing enabled. MozReview-Commit-ID: 6IvetcHnMfC
toolkit/components/extensions/ext-webRequest.js
toolkit/modules/addons/WebRequest.jsm
--- a/toolkit/components/extensions/ext-webRequest.js
+++ b/toolkit/components/extensions/ext-webRequest.js
@@ -41,47 +41,20 @@ function WebRequestEventManager(context,
       }
       if (filter.tabId != null && browserData.tabId != filter.tabId) {
         return;
       }
       if (filter.windowId != null && browserData.windowId != filter.windowId) {
         return;
       }
 
-      let data2 = {
-        requestId: data.requestId,
-        url: data.url,
-        originUrl: data.originUrl,
-        documentUrl: data.documentUrl,
-        method: data.method,
-        tabId: browserData.tabId,
-        type: data.type,
-        timeStamp: Date.now(),
-        frameId: data.windowId,
-        parentFrameId: data.parentWindowId,
-      };
+      let event = data.serialize(eventName);
+      event.tabId = browserData.tabId;
 
-      const maybeCached = ["onResponseStarted", "onBeforeRedirect", "onCompleted", "onErrorOccurred"];
-      if (maybeCached.includes(eventName)) {
-        data2.fromCache = !!data.fromCache;
-      }
-
-      if ("ip" in data) {
-        data2.ip = data.ip;
-      }
-
-      let optional = ["requestHeaders", "responseHeaders", "statusCode", "statusLine", "error", "redirectUrl",
-                      "requestBody", "scheme", "realm", "isProxy", "challenger", "proxyInfo"];
-      for (let opt of optional) {
-        if (opt in data) {
-          data2[opt] = data[opt];
-        }
-      }
-
-      return fire.sync(data2);
+      return fire.sync(event);
     };
 
     let filter2 = {};
     if (filter.urls) {
       let perms = new MatchPatternSet([...context.extension.whiteListedHosts.patterns,
                                        ...context.extension.optionalOrigins.patterns]);
 
       filter2.urls = new MatchPatternSet(filter.urls);
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -178,16 +178,50 @@ class ResponseHeaderChanger extends Head
       if (name.toLowerCase() === "content-type") {
         value = this.channel._contentType || value;
       }
       yield [name, value];
     }
   }
 }
 
+const MAYBE_CACHED_EVENTS = new Set([
+  "onResponseStarted", "onBeforeRedirect", "onCompleted", "onErrorOccurred",
+]);
+
+const OPTIONAL_PROPERTIES = [
+  "requestHeaders", "responseHeaders", "statusCode", "statusLine", "error", "redirectUrl",
+  "requestBody", "scheme", "realm", "isProxy", "challenger", "proxyInfo", "ip",
+];
+
+function serializeRequestData(eventName) {
+  let data = {
+    requestId: this.requestId,
+    url: this.url,
+    originUrl: this.originUrl,
+    documentUrl: this.documentUrl,
+    method: this.method,
+    type: this.type,
+    timeStamp: Date.now(),
+    frameId: this.windowId,
+    parentFrameId: this.parentWindowId,
+  };
+
+  if (MAYBE_CACHED_EVENTS.has(eventName)) {
+    data.fromCache = !!this.fromCache;
+  }
+
+  for (let opt of OPTIONAL_PROPERTIES) {
+    if (typeof this[opt] !== "undefined") {
+      data[opt] = this[opt];
+    }
+  }
+  return data;
+}
+
 var HttpObserverManager;
 
 var nextFakeRequestId = 1;
 
 var ContentPolicyManager = {
   policyData: new Map(),
   policies: new Map(),
   idMap: new Map(),
@@ -208,17 +242,17 @@ var ContentPolicyManager = {
       let callback = this.policies.get(id);
       if (!callback) {
         // It's possible that this listener has been removed and the
         // child hasn't learned yet.
         continue;
       }
       let response = null;
       let listenerKind = "onStop";
-      let data = Object.assign({requestId, browser}, msg.data);
+      let data = Object.assign({requestId, browser, serialize: serializeRequestData}, msg.data);
       data.URI = data.url;
 
       delete data.ids;
       try {
         response = callback(data);
         if (response) {
           if (response.cancel) {
             listenerKind = "onError";
@@ -689,16 +723,18 @@ HttpObserverManager = {
       isSystemPrincipal: channel.isSystemLoad,
 
       windowId: channel.windowId,
       parentWindowId: channel.parentWindowId,
 
       ip: channel.remoteAddress,
 
       proxyInfo: channel.proxyInfo,
+
+      serialize: serializeRequestData,
     };
 
     // force the protocol to be ws again.
     if (data.type == "websocket" && data.url.startsWith("http")) {
       data.url = `ws${data.url.substring(4)}`;
     }
 
     return Object.assign(data, extraData);