Bug 1377325 - Refactor ProxyScriptContext.js r?mattw draft
authorEric Jung <eric.jung@getfoxyproxy.org>
Thu, 29 Jun 2017 17:00:27 -0700
changeset 602429 37b89ee1e3e46e3e2dcd741f6c0fccedc11af9f6
parent 601255 cc903e3f61894e60c3b0efaf05e9a446d1d85888
child 602430 c765cffb08bef71b42593dc2248ae0b8d6b82e24
child 602738 30e60de61fe12e71b37e15fdf4b1db9f9c0d0d39
push id66438
push userbmo:eric@ericjung.net
push dateFri, 30 Jun 2017 00:34:19 +0000
reviewersmattw
bugs1377325
milestone56.0a1
Bug 1377325 - Refactor ProxyScriptContext.js r?mattw
toolkit/components/extensions/ProxyScriptContext.jsm
--- a/toolkit/components/extensions/ProxyScriptContext.jsm
+++ b/toolkit/components/extensions/ProxyScriptContext.jsm
@@ -133,107 +133,106 @@ class ProxyScriptContext extends BaseCon
 
     if (!ret || typeof ret !== "string") {
       this.extension.emit("proxy-error", {
         message: "FindProxyForURL: Return type must be a string",
       });
       return defaultProxyInfo;
     }
 
-    let rules = ret.split(";");
+    let rules = [];
+    for (let rule of ret.split(";")) {
+      try {
+        rule = this.parseLegacyRule(rule);
+        if (rule.type === PROXY_TYPES.DIRECT) {
+          break;
+        }
+        rules.push(rule);
+      } catch (e) {
+        this.extension.emit("proxy-error", {
+          message: "FindProxyForURL: " + (e.message || e),
+        });
+        break;
+      }
+    }
+
     let proxyInfo = this.createProxyInfo(rules);
 
     return proxyInfo || defaultProxyInfo;
   }
 
   /**
    * Creates a new proxy info object using the return value of FindProxyForURL.
    *
    * @param {Array<string>} rules The list of proxy rules returned by FindProxyForURL.
    *    (e.g. ["PROXY 1.2.3.4:8080", "SOCKS 1.1.1.1:9090", "DIRECT"])
    * @returns {nsIProxyInfo} The proxy info to apply for the given URI.
    */
   createProxyInfo(rules) {
-    if (!rules.length) {
-      return null;
+    let proxyInfo = null;
+    while (rules.length) {
+      let {type, host, port} = rules.pop();
+      proxyInfo = ProxyService.newProxyInfo(
+        type, host, port, 0, PROXY_TIMEOUT_SEC, proxyInfo);
+      if (type === "DIRECT") {
+        return proxyInfo;
+      }
     }
+    return proxyInfo;
+  }
 
-    let rule = rules[0].trim();
+  parseLegacyRule(rule) {
+    rule = rule.trim();
 
     if (!rule) {
-      this.extension.emit("proxy-error", {
-        message: "FindProxyForURL: Missing Proxy Rule",
-      });
-      return null;
+      throw new Error("Missing Proxy Rule");
     }
 
     let parts = rule.split(/\s+/);
     if (!parts[0]) {
-      this.extension.emit("proxy-error", {
-        message: `FindProxyForURL: Too many arguments passed for proxy rule: "${rule}"`,
-      });
-      return null;
+      throw new Error(`Too few arguments passed for proxy rule: "${rule}"`);
     }
 
     if (parts.length > 2) {
-      this.extension.emit("proxy-error", {
-        message: `FindProxyForURL: Too many arguments passed for proxy rule: "${rule}"`,
-      });
-      return null;
+      throw new Error(`Too many arguments passed for proxy rule: "${rule}"`);
     }
 
-    switch (parts[0].toLowerCase()) {
+    let type = parts[0].toLowerCase();
+    switch (type) {
       case PROXY_TYPES.PROXY:
       case PROXY_TYPES.HTTP:
       case PROXY_TYPES.HTTPS:
       case PROXY_TYPES.SOCKS:
       case PROXY_TYPES.SOCKS4:
         if (!parts[1]) {
-          this.extension.emit("proxy-error", {
-            message: `FindProxyForURL: Missing argument for proxy type: "${parts[0]}"`,
-          });
-          return null;
+          throw new Error(`Missing argument for proxy type: "${parts[0]}"`);
         }
 
         if (parts.length != 2) {
-          this.extension.emit("proxy-error", {
-            message: `FindProxyForURL: Too many arguments for proxy rule: "${rule}"`,
-          });
-          return null;
+          throw new Error(`Too many arguments for proxy rule: "${rule}"`);
         }
 
         let [host, port] = parts[1].split(":");
         if (!host || !port) {
-          this.extension.emit("proxy-error", {
-            message: `FindProxyForURL: Unable to parse host and port from proxy rule: "${rule}"`,
-          });
-          return null;
+          throw new Error(`Unable to parse host and port from proxy rule: "${rule}"`);
         }
 
-        let type = parts[0];
-        if (parts[0].toLowerCase() == PROXY_TYPES.PROXY) {
+        if (type == PROXY_TYPES.PROXY) {
           // PROXY_TYPES.HTTP and PROXY_TYPES.PROXY are synonyms
           type = PROXY_TYPES.HTTP;
         }
 
-        let failoverProxy = this.createProxyInfo(rules.slice(1));
-        return ProxyService.newProxyInfo(type, host, port, 0,
-          PROXY_TIMEOUT_SEC, failoverProxy);
+        return {type, host, port};
       case PROXY_TYPES.DIRECT:
         if (parts.length != 1) {
-          this.extension.emit("proxy-error", {
-            message: `FindProxyForURL: Invalid argument for proxy type: "${parts[0]}"`,
-          });
+          throw new Error(`Invalid argument for proxy type: "${parts[0]}"`);
         }
-        return null;
+        return {type};
       default:
-        this.extension.emit("proxy-error", {
-          message: `FindProxyForURL: Unrecognized proxy type: "${parts[0]}"`,
-        });
-        return null;
+        throw new Error(`Unrecognized proxy type: "${parts[0]}"`);
     }
   }
 
   /**
    * Unloads the proxy filter and shuts down the sandbox.
    */
   unload() {
     super.unload();