代理服务

通过以上描述,我们知道,http代理服务器即是一个http协议的中继。其所完成的任务是插入浏览器与服务器之间的通信,截获浏览器的http请求,并模拟浏览器向服务器发起http请求,并把服务器的http回应,转回应于浏览器。这个动作对应浏览器来说,是透明的,但是对于开发者来说,可以在代理服务器上做手脚,修改双向的报文。可以通过两种方式来实现http代理,其一为应用程序代理,其二tcp代理,其特征分别为:

应用层代理,浏览器与代理服务器,代理服务器与服务器两个通信组队之间,分别建立tcp连接,并进行tcp数据传输。代理服务器与浏览器握手之后,截获浏览器发出的GET报文,获取HOST字段与服务器握手,并把GET报文进行处理之后,转发给服务器,等待服务器的回包,并转发给浏览器。整个流程可以在应用层完成。 

图5 应用层代理服务器

图5 应用层代理服务器

可以看出代理服务器对客户端上来的GET报文有修改:1)HTTP/1.1修改为HTTP/1.0, 这样修改有两个作用,服务器对HTTP/1.0请求的回应报文没有Content-Length, 或CHUNCK的标示,而这两个标示与应用程序数据的长度相关,如果采用HTTP/1.1的请求,则在修改服务器的回包之后(回包长度发生变化),需要重新修改Content-Length或CHUNCK两个属性的值,而这两个值的修改增加了开发的难度;其二,服务器对HTTP/1.0回应不会保持长连接,即图中服务器响应index.html之后,tcp连接关闭,这样对于代理软件来说,软件容易稳定,降低了开发难度。

· TCP层代理

Ø TCP报文插入

在TCP层做报文注入,涉及到了修改报文双向sequence, ack-sequence值的问题。原因在于seq值与ack值与实际报文长度相关,如果修改了报文长度,显然需要修改seq, ack值: 

图6 TCP之SEQ与ACK

图6 TCP之SEQ与ACK

Ø TCP层代理报文插入

如图7所示,代理需要维护两个状态机,收到服务端带fin报文的数据包之后,和服务端完成结束握手;同时去除fin报文的fin标志,把改报文发给浏览器,同时完成和浏览器的报文插入以及结束握手: 

图7 TCP之SEQ与ACK

图7 TCP之SEQ与ACK

Ø TCP层代理状态机

1. Eth0收到http报文的结束帧(带fin)

1. Eth0收到http报文的结束帧(带fin)

2. 代理去掉fin标志

代理去掉fin标志

3. 代理插入一段报文,并加上fin标志 

代理插入一段报文,并加上fin标志

代理插入一段报文,并加上fin标志

4.浏览器对原始的http结束报文回应fin:

浏览器对原始的http结束报文回应fin

问题:看起来服务器到浏览器的fin报文,并没有被代理扔掉,故而浏览器收到了两帧fin报文。


相关内容