Python杂记--使用asyncio构建HTTP代理服务器

Python杂记--使用asyncio构建HTTP代理服务器

    • 引言
    • 基础知识
    • 代码实现

引言

        本文将介绍 HTTP 代理的基本原理,并带领读者构建一个自己的 HTTP 代理服务器。代码中不会涉及到任何第三方库,全部由 asyncio 实现,性能优秀,安全可靠。


基础知识

        HTTP 代理(HyperText Transfer Protocol Proxy)是一种网络代理服务器,充当位于客户端和目标服务器之间的中间人。流程为,首先接收来自客户端的 HTTP 请求,然后转发这些请求到目标服务器,并将目标服务器的响应返回给客户端,如下所示:

        在上述流程中,我们需要知道来自客户端的 HTTP 请求的所有内容,包括请求方法,URL等信息,才能实现转发。但众所周知,目前大多数网站都是通过 HTTPS 访问的,而 HTTPS 是加密的,作为代理服务器,拿不到请求方法等敏感信息,那么还能够用 HTTP 代理转发 HTTPS 流量吗?答案是肯定的。此时需要用到 HTTP 中很少见的一种请求方法:CONNECT。客户端首先发送 CONNECT 请求,告诉代理服务器我想连接 A 网站,代理服务器就可以和 A 网站建立连接,实现流量的双向转发,而这不需要对内容进行解密,所以是安全的。具体流程如下所示:


代码实现

        原理其实是很简单的,在 Python 中具体实现如下所示:

import asyncio
from urllib.parse import urlparse


async def pipe(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
    while True:
        data = await reader.read(4096)
        if len(data) == 0:
            break
        writer.write(data)


async def http_proxy(c_reader: asyncio.StreamReader, c_writer: asyncio.StreamWriter, url: str, header: bytes):
    result = urlparse(url)
    host, port = result.hostname, 80 if result.port is None else result.port
    s_reader, s_writer = await asyncio.open_connection(host, port)
    s_writer.write(header)
    async with asyncio.TaskGroup() as tg:
        tg.create_task(pipe(c_reader, s_writer))
        tg.create_task(pipe(s_reader, c_writer)).add_done_callback(lambda _: c_reader.feed_eof())
    s_writer.close()
    c_writer.close()


async def https_proxy(c_reader: asyncio.StreamReader, c_writer: asyncio.StreamWriter, url: str):
    host, port = url.split(':')
    s_reader, s_writer = await asyncio.open_connection(host, port)
    c_writer.write(b'HTTP/1.1 200 Connection Established\r\n\r\n')
    async with asyncio.TaskGroup() as tg:
        tg.create_task(pipe(c_reader, s_writer))
        tg.create_task(pipe(s_reader, c_writer)).add_done_callback(lambda _: c_reader.feed_eof())
    s_writer.close()
    c_writer.close()


async def handler(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
    header = await reader.readuntil(b'\r\n\r\n')
    method, url, _ = header.decode('utf-8').splitlines()[0].split(' ')
    if method == 'CONNECT':
        return await https_proxy(reader, writer, url)
    await http_proxy(reader, writer, url, header)


async def main():
    server = await asyncio.start_server(handler, '127.0.0.1', 8080)
    async with server:
        await server.serve_forever()


asyncio.run(main())

        运行后就在本地构建好了代理,我们使用 requests 库进行测试:

import requests
response = requests.get('https://www.baidu.com', proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/543960.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云服务器安装Mysql、MariaDB、Redis、tomcat

前置工作 进入根目录 cd / 进入/user/local文件夹 上传压缩包 rz 压缩包 Mysql 1.下载并安装MySQL官方的 Yum Repository wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-…

ssh爆破服务器的ip-疑似肉鸡

最近发现自己的ssh一直有一些人企图使用ssh暴力破解的方式进行密码破解.就查看了一下,真是网络安全太可怕了. 大家自己的服务器密码还是要设置好,管好,做好最基本的安全措施,不然最后只能沦为肉鸡. ssh登陆日志可以在/var/log下看到,ubuntu的话为auth.log,centos为secure文件 查…

设计模式代码实战-桥接模式

1、问题描述 小明家有一个万能遥控器,能够支持多个品牌的电视。每个电视可以执行开机、关机和切换频道的操作,请你使用桥接模式模拟这个操作。 输入示例 6 0 2 1 2 0 4 0 3 1 4 1 3 输出示例 Sony TV is ON TCL TV is ON Switching Sony TV channel S…

Oracle 19c RAC 补丁升级 补丁回退

补丁升级流程 补丁升级 停止集群备份家目录 两节点分别操作 cd /u01/app/19.3.0/grid/bin/ crsctl stop crs tar -zcvf /u01/app.tar.gz /u01/app /u01/app/19.0.0/grid/bin/crsctl start crs 两节点OPatch替换 --- 表示 root 用户,$ 表示 Oracle 用户提示符&#…

NLP_知识图谱_图谱问答实战

文章目录 图谱问答NERac自动机实体链接实体消歧 多跳问答neo4j_graph执行流程结构图![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1577c1d9c9e342b3acbf79824aae980f.png)company_data![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/20f567d877c743b…

python爬虫-----Selenium (第二十二天)

🎈🎈作者主页: 喔的嘛呀🎈🎈 🎈🎈所属专栏:python爬虫学习🎈🎈 ✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天…

(一)基于IDEA的JAVA基础15

还是先来说一下: Arrays工具类 Arrays是java.util包提供的工具类 提供了操作数组的方法,如排序,查询等。 如排序(升序)使用sort方法 语法: Arrays.sort(数组名); 还是直接写来看看: public class Test01 { public static void main(String[] args)…

攻防世界12-baby_web

12-baby_web 题目说想想初始页面是哪个,一般都是index.php,然后如题分析即可。 我们在链接后面拼接上/index.php,返回后发现界面又回到了1.php,有可能是重定向。 我们点击检查-网络,发现没有index的请求,…

系统架构最佳实践 -- 供应链系统架构

供应链系统是现代企业管理中不可或缺的一部分,它涉及到从原材料采购到产品销售的整个生产流程。一个高效的供应链系统可以帮助企业实现成本控制、库存优化和客户满意度提升等目标。在本文中,我们将讨论供应链系统的设计与实践。 一、供应链系统设计 业务…

数字乡村创新实践探索农业现代化与乡村振兴新路径:科技赋能农村全面振兴与农民幸福新篇章

随着信息技术的飞速发展,数字乡村成为推动农业现代化与乡村振兴的重要战略举措。科技赋能下的数字乡村创新实践,不仅提升了农业生产的智能化水平,也为乡村治理和农民生活带来了翻天覆地的变化。本文旨在探讨数字乡村创新实践在农业现代化与乡…

数据库数据恢复—Sql Server数据库文件丢失如何恢复数据?

服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因&#xf…

Spring框架中的单例bean是线程安全的吗?

无状态bean: 无状态的Bean的行为不受其内部状态的影响,每次调用都是基于传入的参数进行计算,而不依赖于任何之前的状态。 (例如上面例子:userService是不能修改的,是无状态的bean) 因此: Spring框架中的…

基于51单片机的无线病床呼叫系统设计—LCD1602显示

基于51单片机的无线病床呼叫系统 (仿真+程序+原理图+设计报告) 功能介绍 具体功能: 1.病人按下按键,LCD1602显示对应的床位号; 2.多人同时呼叫,显示屏同时显示&#xf…

Vitis HLS 学习笔记--优化循环启动间隔(II)

目录 1. 概述 2. 常规矩阵乘法 3. 数据依赖性和内存访问模式 4. 优化循环 5. 总结 1. 概述 Initiation Interval(II)定义为启动连续操作之间的时间间隔,以时钟周期为单位。低的II是高性能和高资源利用率的关键。 较高的II意味着在单位…

《手把手教你》系列基础篇(八十六)-java+ selenium自动化测试-框架设计基础-Log4j实现日志输出(详解教程)

1.简介 自动化测试中如何输出日志文件。任何软件,都会涉及到日志输出。所以,在测试人员报bug,特别是崩溃的bug,一般都要提供软件产品的日志文件。开发通过看日志文件,知道这个崩溃产生的原因,至少知道触发崩…

java:特殊文件(properties,xml)和日志

特殊文件 txt(文本文件) txt文件是一种纯文本文件,用于存储文本信息 优缺点:txt文件简单易用,可以使用任何文本编辑器打开和编辑,但不支持数据类型和结构,所有信息均用纯文本形式保存 适合简单的配置信息存储 properties文件 properties文件是一种键值对文件,用于存储配置…

2024最新在线工具箱网站系统源码

2024最新在线工具箱网站系统源码 下载地址: 2024最新在线工具箱网站系统源码-JXASP源码网https://www.jxasp.com/think-php/12489.html

数据库世界信息速递-- TIDB 怎么走向世界如何保证稳定性和可靠性(译)

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(…

LeetCode刷题记(三):61~90题

61. 旋转链表 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例 1: 输入:head [1,2,3,4,5], k 2 输出:[4,5,1,2,3]示例 2: 输入:head [0,1,2], k 4 输出&…

C#.net手术麻醉信息系统源码,集成HIS、EMR、LIS、PACS系统

手术麻醉信息系统可以实现手术室监护仪、麻醉机、呼吸机、输液泵等设备输出数据的自动采集,采集的数据能据如实准确地反映患者生命体征参数的变化,并实现信息高度共享,根据采集结果,综合其他患者数据,自动生成手术麻醉…