Browse Source

feat(shell-proxy): allow excluding endpoints with `NO_PROXY` (#11924)

Abhinav 7 months ago
parent
commit
f36c6db0ea

+ 5 - 0
plugins/shell-proxy/README.md

@@ -23,6 +23,7 @@ Set `SHELLPROXY_URL` environment variable to the URL of the proxy server:
 
 ```sh
 SHELLPROXY_URL="http://127.0.0.1:8123"
+SHELLPROXY_NO_PROXY="localhost,127.0.0.1"
 proxy enable
 ```
 
@@ -36,11 +37,15 @@ Example:
 ```sh
 #!/bin/bash
 
+# HTTP Proxy
 if [[ "$(uname)" = Darwin ]]; then
   echo "http://127.0.0.1:6152" # Surge Mac
 else
   echo "http://127.0.0.1:8123" # polipo
 fi
+
+# No Proxy
+echo "localhost,127.0.0.1"
 ```
 
 ### Method 3

+ 18 - 5
plugins/shell-proxy/proxy.py

@@ -6,6 +6,7 @@ from subprocess import check_output, list2cmdline
 cwd = os.path.dirname(__file__)
 ssh_agent = os.path.join(cwd, "ssh-agent.py")
 proxy_env = "SHELLPROXY_URL"
+no_proxy_env = "SHELLPROXY_NO_PROXY"
 proxy_config = os.environ.get("SHELLPROXY_CONFIG") or os.path.expandvars("$HOME/.config/proxy")
 
 usage="""shell-proxy: no proxy configuration found.
@@ -15,18 +16,30 @@ See the plugin README for more information.""".format(env=proxy_env, config=prox
 
 def get_http_proxy():
     default_proxy = os.environ.get(proxy_env)
-    if default_proxy:
-        return default_proxy
+    no_proxy = os.environ.get(no_proxy_env)
+    if default_proxy and no_proxy:
+        return default_proxy, no_proxy
+
     if os.path.isfile(proxy_config):
-        return check_output(proxy_config).decode("utf-8").strip()
+        proxy_configdata = [line.strip() for line in check_output(proxy_config).decode("utf-8").splitlines()]
+        if len(proxy_configdata) >= 1:
+            if not default_proxy:
+                default_proxy = proxy_configdata[0]
+            if len(proxy_configdata) == 2 and not no_proxy:
+                no_proxy = proxy_configdata[1]
+    
+    if default_proxy:
+        return default_proxy, no_proxy
     print(usage, file=sys.stderr)
     sys.exit(1)
 
 
-def make_proxies(url: str):
+def make_proxies(url: str, no_proxy: str):
     proxies = {"%s_PROXY" % _: url for _ in ("HTTP", "HTTPS", "FTP", "RSYNC", "ALL")}
     proxies.update({name.lower(): value for (name, value) in proxies.items()})
     proxies["GIT_SSH"] = ssh_agent
+    if no_proxy:
+        proxies.update({"NO_PROXY": no_proxy, "no_proxy": no_proxy})
     return proxies
 
 
@@ -35,7 +48,7 @@ def merge(mapping: dict):
 
 
 class CommandSet:
-    proxies = make_proxies(get_http_proxy())
+    proxies = make_proxies(*get_http_proxy())
     aliases = {
         _: "env __SSH_PROGRAM_NAME__=%s %s" % (_, ssh_agent)
         for _ in ("ssh", "sftp", "scp", "slogin", "ssh-copy-id")

+ 1 - 1
plugins/shell-proxy/shell-proxy.plugin.zsh

@@ -27,7 +27,7 @@ eval '
 
     # capture the output of the proxy script and bail out if it fails
     local output
-    output="$(SHELLPROXY_URL="$SHELLPROXY_URL" SHELLPROXY_CONFIG="$SHELLPROXY_CONFIG" "$proxy" "$1")" ||
+    output="$(SHELLPROXY_URL="$SHELLPROXY_URL" SHELLPROXY_NO_PROXY="$SHELLPROXY_NO_PROXY" SHELLPROXY_CONFIG="$SHELLPROXY_CONFIG" "$proxy" "$1")" ||
       return $?
 
     # evaluate the output generated by the proxy script