pac文件可以采用JavaScript语法编写,pac文件中必须包含一个叫做FindProxyForURL(url, host)的函数,因此,可以认为这个函数就是他的main函数。

每一个浏览器请求之前,都会执行一次这个函数。由于传入的参数有url和host,编写pac文件的时候,是可以实现URL级别的代理控制(即http://a.com/bhttp://a.com/c可以使用不代理)。

这个函数的执行返回值,就是告知浏览器用何种方式发出请求:

  • DIRECT 直接访问
  • PROXY 127.0.0.1:8016 http代理
  • HTTPS 127.0.0.1:8888 https代理
  • SOCKS 127.0.0.1:8888 socket4代理
  • SOCKS5 127.0.0.1:8888 socket5代理
  • DIRECT; PROXY 127.0.0.1:8016; SOCKS5 127.0.0.1:8888 依次尝试,直到能够成功请求

相关资料

小思考1: http代理和修改host是否一样?

实验准备

  • 方法一:在/etc/hots中加入127.0.0.1 twwy2.net
  • 方法二:在浏览器的pac文件进行设置:匹配到twwy.net的时候返回PROXY 127.0.0.1:80

抓包观察差异

  • 方法一
    • GET / HTTP/1.1\r\n
    • Connection: keep-alive\r\n
  • 方法二

结论

由此可见,两种方式的HTTP包构造上存在差异的,按照协议来说,应该是能抓到CONNECT这样的一个包,但是实验的时候没有抓到。如果方法二如果需要正确响应,对方必须是一个代理端口,而如果是一个正常服务的端口,则会出现异常。你可以尝试将网上/etc/hosts文件中的google.com对应的IP不在hosts文件中设置,而是用pac设置成 HTTPS IP:443等,应该响应都是异常的。

小思考2: DNS/hosts的结果是否会影响http及socket代理

实验

  • /etc/hots中加入127.0.0.2 twwy.net
  • 在浏览器的pac文件中进行设置:匹配到twwy.net的时候返回PROXY 127.0.0.1:80

结论

在浏览器中访问http://twwy.net/返回的是127.0.0.1的结果,从抓包上来看也验证了这一点。浏览器是直接根据地址向http代理请求访问http://twwy.net/这个页面,而非根据本机dns或hosts解析成127.0.0.2之后再向http代理请求。