Skip to content

Instantly share code, notes, and snippets.

@kou1okada
Last active May 26, 2022 13:31
Show Gist options
  • Save kou1okada/e5a518963f4120d323da728e841c0912 to your computer and use it in GitHub Desktop.
Save kou1okada/e5a518963f4120d323da728e841c0912 to your computer and use it in GitHub Desktop.
proxy.sh - Proxy Auto-Configuration Utility

proxy.sh - Proxy Auto-Configuration Utility

Usage

Add below commands to ~/.bashrc.

. $SOMEWHERE/proxy.sh # [auto|fromsystem|pac <URL>|wpad]
#!/usr/bin/env bash
#
# Proxy Auto-Configuration Utility
# Copyright 2020 (c) Koichi OKADA. All rights reserved.
# This script is distributed under the MIT license.
#
function proxy_GetSystemWebProxy.GetProxy () # [-v <varname>] [<URL=https://google.com/>]
# Returns a proxy configured with the Internet Explorer.
# Arguments:
# <URL> : The target URL to be checked if it requires a proxy.
# Optins:
# -v <varname> : Return result to variable instead of stdout.
# Returns:
# Return proxy if URL requires a proxy.
# Otherwise, return an empty string.
# Reference:
# * Docs / .NET / .NET API / browser / System.Net / WebRequest / Methods / GetSystemWebProxy
# https://docs.microsoft.com/en-us/dotnet/api/system.net.webrequest.getsystemwebproxy
{
local powershell; read powershell < <(type -p powershell.exe pwsh.exe powershell pwsh); [ -z "$powershell" ] && return 1
local URL; [ $# = 1 -o $# = 3 ] && URL="${@: -1}"; URL="${URL:-https://google.com/}"
[ $# = 2 -o $# = 3 ] && { [ "$2" = "proxy" ] && : || local -n proxy="$2"; } || local proxy
read proxy < <("$powershell" -C '&{[System.Net.WebRequest]::GetSystemWebProxy().GetProxy($Args[0]).AbsoluteUri|sls -not $Args[0]|Write-Host -n}' "$URL")
[ $# = 2 -o $# = 3 ] && return
[ $# = 0 -o $# = 1 ] && { echo "$proxy"; return; }
return 1
}
function proxy_fromsystem ()
# Set proxy from system settings.
{
local hash; read -d " " hash < <(ipconfig.exe |& md5sum -b)
local cache="/tmp/.proxy_fromsystem.$hash"
local last; read last < <(stat -c %Y "$cache" 2>/dev/null)
local now; printf -v now "%(%s)T"
local proxy
[ -n "$OPT_PROXY_FORCE_REFRESH" ] && last=0
if (( (now - ${last:-0}) < ${OPT_PROXY_REFRESH_INTERVAL:-86400} )); then
read proxy < "$cache"
else
proxy_GetSystemWebProxy.GetProxy -v proxy || return
echo "$proxy" > "$cache"
fi
[ -n "$proxy" ] && proxy_set "$proxy" && return
proxy_unset
}
function proxy_auto ()
# Auto set proxy
{
proxy_fromsystem || proxy_wpad
}
function proxy_update_with_pac ()
# Update proxy with PAC
# Environments:
# $PROXY_PAC : An URL of the Proxy Auto-Configuration file.
{
local hash; read -d " " hash < <(ipconfig.exe |& md5sum -b)
local cache="/tmp/.wpad.sh.$hash"
local last; read last < <(stat -c %Y "$cache" 2>/dev/null)
local now; printf -v now "%(%s)T"
local proxy
[ -n "$OPT_PROXY_FORCE_REFRESH" ] && last=0
if (( (now - ${last:-0}) < ${OPT_PROXY_REFRESH_INTERVAL:-86400} )); then
read proxy < "$cache"
else
read proxy < <(
wget --no-proxy -qO - "${PROXY_PAC:=wpad/wpad.dat}" \
| grep PROXY \
| sed -E 's@^.*"\s*PROXY\s*([^"]*)\s*".*$@http://\1@g')
echo "$proxy" > "$cache"
fi
[ -n "$proxy" ] && proxy_set "$proxy"
}
function proxy_refresh ()
# Refresh Proxy
# See:
# proxy_update
{
OPT_PROXY_FORCE_REFRESH=1 proxy_auto
}
function proxy_pac () # <url>
# Update Proxy with PAC(Proxy Auto-Configuration)
{
PROXY_PAC="$1"
proxy_update_with_pac
}
function proxy_wpad ()
# Update Proxy with WPAD(Web Proxy Auto Discovery).
{
proxy_pac
}
function proxy_set () # <proxy>
# Set ftp, http, https, no proxy
# Arguments:
# proxy : Proxy schema and host and port with "schema://host:port"
{
#local ips; printf -v ips ",%s" 192.168.{0..1}.{1..254}
export no_proxy="localhost,127.0.0.1,localnet$ips"
export {ftp,http,https}_proxy="$1"
}
function proxy_unset ()
# Set ftp, http, https proxy
# Arguments:
# proxy : Proxy schema and host and port with "schema://host:port"
{
unset {ftp,http,https,no}_proxy
}
function proxy_export ()
# Export proxy settings
{
declare -p {ftp,http,https,no}_proxy 2>/dev/null
}
function proxy () # <subcommand>
# Proxy Manager
{
if type "${FUNCNAME}_${1:-auto}" >&/dev/null; then
"${FUNCNAME}_${1:-auto}" "${@:2}"
else
gawk '
/^function/,/^{/ {
if (match($0,/^function[[:space:]]+([^[:space:]]*)[[:space:]]*\(\)[[:space:]]*(#(.*))?/,m)) {print "Usage: "m[1]m[3];}
else if (match($0,/^#[[:space:]]?/)) {print substr($0,RSTART+RLENGTH);}
else {print "";}
}
' "$BASH_SOURCE"
echo "Error: Unknown subcommand: $1"
return 1
fi
}
if [ "$0" = "$BASH_SOURCE" ]; then
SCRIPT_PATH="$0"
SCRIPT_DIR="${SCRIPT_PATH%/*}"
SCRIPT_FILE="${SCRIPT_PATH##*/}"
SCRIPT_NAME="${SCRIPT_FILE%.*}"
"$SCRIPT_NAME" "$@"
else
proxy "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment