现在,在将Web请求从客户端传送到服务器的路径上,经过两个或多个代理是很常见的。比如,出于安全和节省费用的考虑,很多公司都会用缓存代理服务器来访问因特网,而且很多大型ISP都会使用代理缓存来提高性能并实现各种特性。现在,有相当比例的Web请求都是通过代理转发的。同时,出于性能原因,把内容复制到遍布全球的替代物缓存库中的情形也越来越常见了。
代理是由不同厂商开发的。它们有不同的特性和缺陷,由各种不同的组织负责管理。随着代理的逐渐流行,我们要能够追踪经过代理的报文流,以检测出各种问题,其重要性就跟追踪经过不同交换机和路由器传输的IP分组流一样。
Via首部字段列出了与报文途经的每个中间节点(代理或网关)有关的信息。报文每经过一个节点,都必须将这个中间节点添加到Via列表的末尾。Via首部字段用于记录报文的转发,诊断报文循环,标识请求/响应链上所有发送者的协议能力。
代理也可以用Via首部来检测网络中的路由循环。代理应该在发送一条请求之前,在Via首部插入一个与其自身有关的独特字符串,并在输入的请求中查找这个字符串,以检测网络中是否存在路由循环。
1、Via的语法
Via首部字段包含一个由逗号分隔的路标(waypoint)。每个路标都表示一个独立的代理服务器或网关,且包含与那个中间节点的协议和地址有关的信息。每个Via路标中最多包含4个组件:一个可选的协议名(默认为HTTP)、一个必选的协议版本、一个必选的节点名和一个可选的描述性注释。
- 协议名:中间节点收到的协议。如果协议为HTTP的话,协议名就是可选的。否则,要在版本之前加上协议名,中间用“/”分隔。网关将HTTP请求连接到其他协议(HTTPS、FTP等)时,可能会使用非HTTP协议。
- 协议版本:所收到的报文版本。版本的格式与协议有关。HTTP使用的是标准版本号(1.0、1.1等)。版本包含在Via字段中,这样,之后的应用程序就会知道前面所有中间节点的协议能力了。
- 节点名:中间节点的主机和可选端口号(如果没有包含端口号,可以假定使用的是协议的默认端口号)。在某些情况下,出于隐私方面的考虑,某个组织可能不愿意给出真实的主机名,在这种情况下可以用一个假名来代替。
- 节点注释:进一步描述这个中间节点的可选注释。通常会在这里包含厂商和版本信息,有些代理服务器还会在注释字段中包含一些与此设备上所发生事件有关的诊断信息。
2、Via的请求和响应路径
请求和响应报文都会经过代理进行传输,因此,请求和响应报文中都要有Via首部。请求和响应通常都是通过同一条TCP连接传送的,所以响应报文会沿着与请求报文相同的路径回传。如果一条请求报文经过了代理proxy1和proxy2,相应的响应报文就会通过代理proxy2、proxy1进行传输。因此,响应的Via首部基本上总是与请求的Via首部相反。
3、Via与网关
有些代理会为使用非HTTP协议的服务器提供网关的功能。Via首部记录了这些协议转换,这样,HTTP应用程序就会了解代理链上各点的协议处理能力以及所做的协议转换了。
4、Server和Via首部
Server响应首部字段对原始服务器使用的软件进行了描述。这里有几个例子:
Server:Apache/1.3.14 PHP/b4.0.4 Server:Netscape-Enterprise/4.1 Server:Microsoft-IIS/6.0
如果响应报文是通过代理转发的,一定要确保代理没有修改Server首部。Server首部是用于原始服务器的。代理应该添加的是Via条目。
5、Via的隐私和安全问题
有时候,我们并不希望在Via字符串中使用确切的主机名。总地来说,除非显式地允许了这种行为,否则,当代理服务器作为网络防火墙的一部分使用时,是不应该转发防火墙后面那些主机的名字和端口号的,因为防火墙后面的网络结构信息可能会被恶意群体利用。
如果不允许进行Via节点名转发,作为安全防线的一部分使用的代理就应该用适当的假名来取代那台主机的名字。一般来说,即使隐藏了真实名称,代理也应该尝试着为每台代理服务器保留一个Via路标条目。
对那些有着非常强烈的隐私要求,需要隐藏内部网络设计和拓扑结构的组织来说,代理应该将一个(接收协议值相同的)有序Via路标条目序列合并成一个联合条目。