HTTP代理就是接受一个客户端请求,然后转发给另外一台服务器。
正向代理Forward Proxy一般可以接受多个客户端连入,并且支持到不同的服务器的请求。正向代理 的客户端必须清楚它在使用代理服务器,并且在请求时要发送完整的URL给代理服务器,而不像一般请求在请求行只有URI, 这样代理服务器才可以知道目标地址。
反向代理则实际上是网站或者服务器的一个前端组件。它只服务于特定的网站,作为前端负载均衡或者其它功能的提供者。它把所有请求发送给特定的后端服务器。客户端往往不知道也不关心自己访问的是反向代理还是真正提供服务器的服务器。
我们一般说的代理服务是指正向代理。
代理服务的逻辑实际上很简单,就是看请求的第一行,根据请求URL中的主机信息建立一个到那台主机的连接,并且把客户端请求的信息发送给服务器端就可以了。代理服务器应该在发送请求时去掉URL中的主机部分。通常情况下代理服务器会加入特定的头部(Via等)给服务器,服务器会知道请求来自于代理。
代理请求时有两种情况,一种是HTTP请求,客户端请求数据对代理服务器来说都是明文。另一种是HTTPS请求,也叫TUNNEL。对于HTTPS的请求,客户端通过通过CONNECT host:port 的格式请求建立隧道模式。在隧道模式下,代理服务器只是帮助客户端建立一个到服务器端的Socket连接。客户端和最终的服务器端会在这个连接中进行端到端的SSL握手。因此,在隧道模式下代理服务器无法看到客户的和服务器端的通信内容,只能以二进制的格式转发加密过的信息。这也就保证了HTTPS在代理方式下是安全的。
所以实现一个简单代理服务器逻辑如下:
对每一客户端连接
如果是HTTP请求
从客户端请求中分析出主机和端口号
把客户端请求信息转发给服务器端
把服务器端返回内容转发给客户端
在转发过程中可以缓存、篡改、添加内容
如果是HTTPS请求
根据客户端请求的主机和端口号建立到服务器的Socket
返回给客户端一个连接已经建立的响应信息
开始以二进制的方式转发客户端和服务器端的信息
用Java来实现一个简单版本,大概就是一百多行代码。
用SSL/TLS来实现,那就是一个安全的代理服务器了。再写一个本地服务解密。这也算是安全访问国际互联网的第101种方式吧。
代码都在这里:
https://github.com/xqluo2016/HttpProxy
领取专属 10元无门槛券
私享最新 技术干货