Skip to content
qnnp

让curl支持PAC自动代理的优化方案

发布于: | 没有评论 | 分类:

在MacOS或Linux系统中,使用命令行进行一些操作或执行一些脚本时,我们经常会遇到以下问题:

  • 部分链接需要使用代理才能访问;
  • 如果设置了代理,则很多不需要代理的链接访问速度会变得很慢;
  • 代理是按照流量收费的,不希望那些不需要代理的链接走代理通道。
  • 工作环境很复杂、有一些链接只能通过代理访问

在系统代理中,通常可以通过设置PAC(Proxy auto-config)脚本实现系统自动判断网络链接是否需要走代理,但在命令行中由于curl没有JavaScript功能,因此无法支持PAC实现自动代理。

为了解决这个问题,我们可以编写自定义脚本替代curl命令,使curl支持PAC功能。在进行命令替换操作之前,请先安装quickjs

ShellScript
# homebrebrew 
brew install quickjs
# Ubuntu 原生使用
# apt install quickjs
# 其他系统按各自方法安装
展开

具体替换用的curl实现代码如下:

ShellScript
#!/bin/bash

# 优先使用 PAC_PATH
PAC_PATH=~/.hosts/pac.loc/pac.js
PAC_URL=http://127.0.0.1/pac.js

CURL_BINARY_PATH=/usr/local/opt/curl/bin/curl
# CURL_BINARY_PATH=/usr/bin/curl
QJS_BINARY_PATH=/usr/local/bin/qjs

# main

REQUEST_URI=""
SKIP_NEXT=false
ARGS=""
for arg in "$@"; do
  if [[ "$arg" == -* ]]; then
    ARGS="${ARGS} ${arg}"
  else
    ARGS="${ARGS} '$(sed -r "s:([']):\\\1:g" <<< "${arg}")'"
  fi
  if [[ ${SKIP_NEXT} == true ]]; then
    SKIP_NEXT=false
  else
    if [[ ${arg} =~ ^https?:// ]]; then
      REQUEST_URI="${arg}"
    fi
  fi

  if [[ ${arg} == "--proxy" || ${arg} == "-x" ]]; then
    SKIP_NEXT=true
  fi
done

if [[ "${REQUEST_URI}" == "" ]]; then
  sh -c "${CURL_BINARY_PATH} ${ARGS}"
else
  SCRIPT="
    $([[ "${PAC_PATH}" == "" ]] && ${CURL_BINARY_PATH} -s "${PAC_URL}" || cat "${PAC_PATH}")
    const args = '${REQUEST_URI}'.match(/^[a-zA-Z]+:\/\/([^/]+)/);
    const proxy = FindProxyForURL(...args);
    if(proxy !== 'DIRECT') {
      const [proto,host] = proxy.split(/[ ;]+/);
      if(proto === 'SOCKS5') {
        console.log('--proxy socks5h://' + host);
      }
      if(proto === 'PROXY') {
        console.log('--proxy ' + host);
      }
    }
  "
  PROXY="$(${QJS_BINARY_PATH} -e "${SCRIPT}")"
  sh -c "${CURL_BINARY_PATH} ${PROXY} ${ARGS}"
fi
展开

将以上代码保存为~/.curl_with_pac.sh并添加执行权限chmod +x ~/.curl_with_pac.sh。然后编辑~/.zshrc文件新增如下配置:

ShellScript
alias curl='~/.curl_with_pac.sh'
展开

通过以上优化方案,我们可以让curl支持PAC自动代理,提高网络访问效率。

标签:

5 1 投票
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论

0
希望看到您的想法,请您发表评论x