BaseProxy
异步http/https代理,可拦截并修改报文,能被用于中间人工具,支持py3.5+.项目地址:。
目录
意义
BaseProxy项目的本意是为了使HTTP/HTTPS拦截更加纯粹,更加易操作,学习成本更低。
在Python领域,中间人工具非常强大和成功的是MitmProxy,但是有些地方不是很喜欢。
Windows上安装比较费时费力
功能太多了,可惜我用不到这么多(似乎不是它的错,哈哈)
随着版本升级,采用插件化框架,需要定制功能,需要写个插件成为它的一部分(我只是想集成它而已).
因此BaseProxy就诞生了,不仅支持HTTPS透明传输,还支持HTTP/HTTPS拦截,简单易用,可以很好地集成到你们的项目中。
安装
安装非常简单,本项目已经发布到PyPI中...
pip3 install baseproxy
使用配置
启动baseproxy
在test文件夹下,有很多测试用例。以startserver.py为例。
from baseproxy.proxy import AsyncMitmProxy
baseproxy = AsyncMitmProxy(https=True)
baseproxy.serve_forever()
使用上述代码,就可以将HTTPServer运行起来了.对代码的解释如下:
https=True是对https进行解密; https=False是对于https实行透传
baseproxy默认运行在8788端口,如果想改变端口的话,修改为 AsyncMitmProxy(server_addr=(,port),https=True).
运行结果如下:
[2018-06-22 18:46:32] INFO HTTPServer is running at address( , 8788 )......
安装CA证书
1.将chrome浏览器代理服务器设置为127.0.0.1:8788,推荐使用SwitchyOmega插件.
2.设置好代理,并将baseproxy运行后,访问www.baidu.com.
3.这时候访问被拒绝,需要安装证书.在当前网页访问 baseproxy.ca,下载证书.
4.双击下载的证书,并安装到合法机构中.
5.接着访问百度就可以了.
注意:只有 https=True时,才需要安装CA证书。
开发
经过上一步的使用配置,baseproxy已经可以正常运行了,但是这样是远远不够的.baseproxy还提供了接口,方便开发者对http请求和响应进行修改.
接口
baseproxy提供了两个接口,一个是修改请求,一个是修改响应.
拦截请求class ReqIntercept(InterceptPlug):
def deal_request(self,request):
pass
对于请求的拦截,需要继承ReqIntercept类,并重写其中的dealrequest函数.在dealrequest函数的最后,需要将修改后的request参数返回出去. 如果想抛弃这个请求,直接返回None.
request参数deal_request函数中的request参数类型为Request类
成员变量
Name类型含义hostnamestr域名portint端口commandstr请求类型pathstr请求路径request_versionstrHTTP协议版本成员函数
def set_headers(self,headers)
- headers:类型为dict
- 用于设置头部
def get_header(self,key):
- key:类型为str
- 用于获取指定头部,返回str
def get_headers(self):
- 用于获取整个头部,返回为dict
def set_header(self,key,value):
- 头部 key,类型str
- 头部 value,类型str
- 用于设置头信息
def get_body_data(self):
- 获取请求体内容,返回类型为bytes
def set_body_data(self,body):
- 设置请求体内容,body类型为bytes
拦截响应class RspIntercept(InterceptPlug):
def deal_response(self,response):
pass
对于响应的拦截,需要继承RspIntercept类,并重写其中的dealresponse函数.在dealresponse函数的最后,需要将修改后的response参数返回出去. 如果想抛弃这个响应,直接返回None.
response参数deal_response函数中的response参数类型为Response类
成员变量
Name类型含义hostnamestr域名portint端口statusint状态码reasonstr状态描述response_versionstrHTTP协议版本requestRequest响应对应的请求实例成员函数
def set_headers(self,headers)
- headers:类型为dict
- 用于设置头部
def get_header(self,key):
- key:类型为str
- 用于获取指定头部,返回str
def get_headers(self):
- 用于获取整个头部,返回为dict
def set_header(self,key,value):
- 头部 key,类型str
- 头部 value,类型str
- 用于设置头信息
def get_body_data(self):
- 获取响应体内容,返回类型为bytes
def set_body_data(self,body):
- 设置响应体内容,body类型为bytes
def get_body_str(self,decoding=None):
- decoding:编码,默认为None,内部采用chardet探测
- 返回响应体,类型为str.如果无法解码,返回None
def set_body_str(self,body_str,encoding=None):
- encoding:编码,默认为None,内部采用chardet探测
- 设置响应体,body_str类型为str
注册拦截插件
将拦截类完成后,需要注册到baseproxy中,需要调用AsyncMitmProxy的register函数.示例如下:
from baseproxy.proxy import ReqIntercept, RspIntercept, AsyncMitmProxy
__author__ = qiye
__date__ = 2018/6/21 23:35
class DebugInterceptor(ReqIntercept, RspIntercept):
def deal_request(self, request):
return request
def deal_response(self, response):
return response
if __name__=="__main__":
baseproxy = AsyncMitmProxy(https=False)
baseproxy.register(DebugInterceptor)
baseproxy.serve_forever()
小例子
将淘宝中的所有产品图片换成我的二维码.代码在test文件夹的replace_image.py中,内容如下:
from baseproxy.proxy import RspIntercept, AsyncMitmProxy
class ImageInterceptor( RspIntercept):
def deal_response(self, response):
if response.get_header("Content-Type") and image in response.get_header("Content-Type"):
with open("../img/qiye2.jpg",rb) as f:
response.set_body_data(f.read())
return response
if __name__ == "__main__":
baseproxy = AsyncMitmProxy(https=True)
baseproxy.register(ImageInterceptor)
baseproxy.serve_forever()
效果如下:
参考项目
MitmProxy
proxy2
福利
关注:七夜安全博客
回复【1】:领取 Python数据分析 教程大礼包
回复【2】:领取 Python Flask 全套教程
回复【3】:领取 某学院 机器学习 教程
回复【4】:领取 爬虫 教程
回复【5】:领取编译原理 教程
知识星球已经50人,随着人数的增加,价格会有一定的涨幅,越早关注越多优惠。星球的福利有很多:
比如上面的教程,已经提前在知识星球中分享
可以发表一些问题,大家一块解决
我之后写的电子书,录制的教学视频,对于知识星球的朋友都是优惠的(基本上免费)
一些节假日会给大家发个红包或者赠书
书籍推荐
广告流畅的Python
作者:[巴西]卢西亚诺·拉马略(Luciano Ramalho)
当当 购买Python 黑帽子:黑客与渗透测试编程之道
作者:dangdang
当当 详情 广告Python核心编程 第3版
作者:[美]卫斯理 春(Wesley Chun)
当当 购买 广告Python爬虫开发与项目实战
作者:范传辉
当当 购买