002. HTTP 代理原理及 Python 简单实现
HTTP 代理是一种网络代理服务器(Proxy Server),它能够作为客户端与 HTTP 服务器之间的中介,它的工作原理是:
当客户端向 HTTP 代理发送 HTTP 请求时,HTTP 代理会收到请求。
HTTP 代理会将请求转发给目标 HTTP 服务器。
目标 HTTP 服务器处理请求并生成响应。
HTTP 代理将响应转发给客户端。
通过使用 HTTP 代理,客户端可以访问其他服务器的资源,而不需要直接连接其他服务器。这样,客户端的真实地址就被隐藏起来,HTTP 代理也可以提供额外的功能,如缓存网页内容、过滤内容、保护隐私等。
HTTP 代理存在两种形式,分别简单介绍如下:
第一种是普通代理,它是最常见的代理服务器,能够代理 HTTP 协议的网络流量。这种代理仅扮演「中间人」角色,对于连接到它的客户端来说,它是服务端;对于要连接的服务端来说,它是客户端。它就负责在两端之间来回传送 HTTP 报文,由于 HTTPS 包经过加密,没法解析,所以也就没法代理 HTTPS 的请求。
第二种是隧道代理,它能够将客户端的请求和响应封装成隧道(Tunnel),并将隧道传输到目标服务器。隧道代理能够代理任意基于 TCP 的应用层协议的网络流量,包括 HTTP 和 HTTPS 协议。
普通代理
第二种 Web 代理原理特别简单:
HTTP 客户端向代理发送请求报文,代理服务器需要正确地处理请求和连接(例如正确处理 Connection: keep-alive),同时向服务器发送请求,并将收到的响应转发给客户端。
利用 Python 的 Flask + requests 搭建代理服务器的基本流程如下:
安装 Flask 和 requests 库。
编写 Flask 应用,定义一个路由来处理客户端的请求。
使用 requests 库发送请求给目标服务器,获取响应。
将响应返回给客户端。
示例代码如下:
这样就实现了 HTTP 协议的代理 。
隧道代理
第二种 Web 代理的原理也很简单:
HTTP 客户端通过 CONNECT 方法请求隧道代理创建一条到达任意目的服务器和端口的 TCP 连接,并对客户端和服务器之间的后继数据进行盲转发。
懒得写那么多了,直接上代码:
上述代码实现了一个 HTTP 隧道代理服务器。它使用 Python 的 http.server 模块来创建 HTTP 服务器,并使用 socket 库来处理底层的网络通信。
首先,通过调用 HTTPServer 类的构造函数,创建了一个 HTTP 服务器对象,监听 5000 端口,并重写了请求处理程序 。
然后,定义了一个 ProxyHandler 类,继承了 BaseHTTPRequestHandler 类。ProxyHandler 类中可以定义一些方法,用于处理不同的 HTTP 方法,如 GET、POST、PUT 等。
其中,do_CONNECT 方法用于处理客户端的 CONNECT 请求,即建立隧道。当客户端发送 CONNECT 请求时,服务器会调用这个方法,并解析出客户端要连接的目标服务器的地址和端口。然后,服务器使用 socket 库连接到目标服务器,并告诉客户端连接成功(Connection Established)。最后,服务器调用 handle_tcp 方法来转发客户端 socket 和目标服务器 socket 之间的数据流。
由于未定义 do_GET 方法,HTTP 协议暂时不可用。
延伸阅读
HTTP 代理原理及实现:https://juejin.cn/post/6998351770871152653
CONNECT - HTTP | MDN:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/CONNECT
HTTP 协议之 CONNECT 方法:https://blog.csdn.net/qq_23401185/article/details/124528286
由浅入深写代理(7)-https-代理:https://zhuanlan.zhihu.com/p/28767664