http正向代理的两种方式:一种是普通模式(RFC 7230 - HTTP/1.1:Message Syntax and Routing),一种是隧道模式(Tunneling TCP basedprotocols through Web proxy servers)
为了便于解释这些概念,先假设C是发起请求的客户端,P是正向代理服务器,S是真正提供服务器的代理服务器。
普通模式实现:
这种模式下,C发起http请求,首先组织报文:例如
POST http://your-server.com/test.html?key=val HTTP/1.1
#空行
Content-Type:application/x-www-form-urlencoded
Host:your-server.com
#空行
key1=val&key2=val2&key3=val3
因为C需要使用正向代理(一般是提前配置好代理服务器P的ip和port),
1)C首先和P服务器建立TCP连接,例如10.35.84.27:3122
2)通过和P的TCP连接发送原始http报文,如上所示
3)代理服务器P接受完整报文,处理,根据请求URL中的地址去和服务器S建立TCP连接。
注意:这里代理服务器P不会根据请求头Host中内容去建立连接,该字段被忽略,所以必须在URL中传入目标服务器的地址信息(DNS或者ip:port)
4)代理服务器P将报文处理后发往目标服务器S,报文处理一般是在请求头中加入X-Forward类信息。
5)目标服务器S将相应返回到代理服务器P,代理服务器将响应返回客户端C。
隧道模式
客户端组织报文,在发送报文前:
1)C和P先建立TCP连接
2)向P发送隧道请求行,请求建立隧道.
CONNECT your-server.com:port HTTP/1.1
# 空行
3)代理服务器P接收到该请求行后,立即向请求行中标记的目标服务器S建立TCP连接。连接建立之后立即响应
HTTP/1.1 200 Connection Established
该响应只是一个说明P和S间的TCP连接已存在,隧道建立,接下里可以继续发送数据包。
4) 客户端收到该响应后,将之前组织的报文通过和P之间的TCP连接传输,P将数据包发往S,此时P只是进行透传。这里一般通过隧道发送的数据一般是经过SSL层加密了,
P收到的数据都是密文,无法解读,只能进行透传。P只是建立了一个TCP连接池,在TCP层做转发。
对比:
隧道模式下:代理服务器P不是在得到客户端C的所有报文后才和目标服务器S建立TCP连接,而是在未获得报文时就和目标服务器建立连接,而后将客户端的报文进行转发(这里是一个一个package的转发,即每收到HTTP报文的一个TCP package后立即发完目标服务器S,对于响应也是同样,不会干涉HTTP协议层的处理,只进行TCP层转发。
普通模式下:代理服务器P需要接收报文后,并对报文进行处理后,和目标服务器S进行连接,然后接收目标服务器的所有响应报文,处理后发往客户端C。