返回介绍

http 代理

发布于 2024-09-21 14:54:08 字数 2669 浏览 0 评论 0 收藏 0

本文讲 http 代理,顾名思义,http 代理代理的是 http 请求,其实这里面分两类

* 普通代理 这种代理扮演的是「中间人」角色,对于连接到它的客户端来说,它是服务端;对于要连接的服务端来说,它是客户端。它就负责在两端之间来回传送 HTTP 报文。
* 隧道代理。它通过 HTTP 协议正文部分(Body)完成通讯,以 HTTP 的方式实现任意基于 TCP 的应用层协议代理。这种代理使用 HTTP 的 CONNECT 方法建立连接。

通俗一点讲,普通代理解析 http 包,然后将请求转发到目标地址,但是没法解析 https 的包,所以也就没法代理 https 的请求,但是隧道代理可以代理 https 的请求或者其他的一些协议请求。

0x01 普通代理

代码很简单

import socket
from urllib.parse import urlparse
from http.server import BaseHTTPRequestHandler, HTTPServer


class ProxyHandler(BaseHTTPRequestHandler):

def _recv_data_from_remote(self, sock):
data = b''
while True:
recv_data = sock.recv(4096)
if not recv_data:
break
data += recv_data
sock.close()
return data

def do_GET(self):
# 解析 GET 请求信息
uri = urlparse(self.path)
scheme, host, path = uri.scheme, uri.hostname, uri.path
host_ip = socket.gethostbyname(host)
port = 443 if scheme == "https" else 80

# 为了简单起见,Connection 都为 close, 也就不需要 Proxy-Connection 判断了
del self.headers['Proxy-Connection']
self.headers['Connection'] = 'close'

# 构造新的 http 请求
send_data = "GET {path} {protocol_version}\r\n".format(path=path, protocol_version=self.protocol_version)
headers = ''
for key, value in self.headers.items():
headers += "{key}: {value}\r\n".format(key=key, value=value)
headers += '\r\n'
send_data += headers

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host_ip, port))
# 发送请求到目标地址
sock.sendall(send_data.encode())
data = self._recv_data_from_remote(sock)

self.wfile.write(data)


def main():
try:
server = HTTPServer(('', 8888), ProxyHandler)
server.serve_forever()
except KeyboardInterrupt:
server.socket.close()


if __name__ == '__main__':
main()

这里面就实现了 get 请求的转发,只用单线程的方式来处理,其他的有兴趣的同学可以自己扩展下。
看下效果

python3 http_server.py

配置完代理后可以发现 http 的请求都能正常转发,但是 https 的都没法识别。

下篇教程看如何通过隧道代理解决这个问题。

参考资料

* https://imququ.com/post/web-proxy.html
* http://www.lyyyuna.com/2016/01/16/http-proxy-get1/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文