0.目前主要先记录HTTP协议相关,至于传输层以下的协议通信过程相关以后补充,先挖坑。
1.HTTP proxy的协议通信原理
这个其实源自于一个问题,使用http proxy访问https网站时,为何不会报非法证书,认为这是一次中间人攻击的形式呢?
在没有了解隧道方式进行代理之前,以为是proxy做了一层类似NAT的操作,也即browser发SSL连接(TCP连接)请求给proxy-client后,proxy-server接收到proxy-client的请求,直接把源ip替换为自己的ip,发到目标站点,而目标站点返回TCP响应数据包给proxy-server后,proxy-server再把目标ip替换回自身ip,发给proxy-client,proxy-client再发给browser;
这个看起来通信链路是通的,但其实这样有个很致命的问题,那就是browser需要知道目标站点的ip,也即browser本地需要进行正确的DNS解析,那这就有点尴尬了,并且要能更改数据包的ip,这个还要涉及到类似(iptables之类使用netfilter的应用),开发难度将会大大提高,开始偏向于底层应用了;
而隧道方式进行代理的实现就很elegant了,核心就是proxy-server完成目标站点DNS解析和建立TCP连接(记为sock_fd=M),同时和browser建立TCP连接(借助proxy-client,也即和proxy-client建立TCP连接,记为sock_fd=N),则只需要在M和N转发流量即可,相当于在proxy-server自己两个fd之间透传流量;
具体来说,隧道方式进行代理下,浏览器与代理进行 TCP 握手之后,发起了 CONNECT 请求,报文起始行如下:
CONNECT imququ.com:443 HTTP/1.1
对于 CONNECT 请求来说,只是用来让代理创建 TCP 连接,所以只需要提供服务器域名及端口即可,并不需要具体的资源路径。代理收到这样的请求后,需要与服务端建立 TCP 连接,并响应给浏览器这样一个 HTTP 报文:
HTTP/1.1 2