異步http/https代理,可攔截並修改報文,能夠做爲中間人工具.僅支持py3.5+.項目地址:BaseProxy。git
BaseProxy項目的本意是爲了使HTTP/HTTPS攔截更加純粹,更加易操做,學習成本更低。github
在Python領域,中間人工具很是強大和成功的是MitmProxy,可是有些地方不是很喜歡。chrome
所以BaseProxy就誕生了,不只支持HTTPS透明傳輸,還支持HTTP/HTTPS攔截,簡單易用,能夠很好地集成到大家的項目中。瀏覽器
安裝很是簡單,本項目已經發布到PyPI中...安全
pip3 install baseproxy
在test文件夾下,有不少測試用例。以startserver.py爲例。服務器
from baseproxy.proxy import AsyncMitmProxy baseproxy = AsyncMitmProxy(https=True) baseproxy.serve_forever()
使用上述代碼,就能夠將HTTPServer運行起來了.對代碼的解釋以下:框架
https=True
是對https進行解密;https=False
是對於https實行透傳AsyncMitmProxy(server_addr=('',port),https=True)
.運行結果以下:機器學習
[2018-06-22 18:46:32] INFO HTTPServer is running at address( , 8788 )......
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類,並重寫其中的deal_request函數.在deal_request函數的最後,須要將修改後的request參數返回出去.
若是想拋棄這個請求,直接返回None.
deal_request函數中的request參數類型爲Request類
成員變量
Name | 類型 | 含義 |
---|---|---|
hostname | str | 域名 |
port | int | 端口 |
command | str | 請求類型 |
path | str | 請求路徑 |
request_version | str | HTTP協議版本 |
成員函數
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類,並重寫其中的deal_response函數.在deal_response函數的最後,須要將修改後的response參數返回出去.
若是想拋棄這個響應,直接返回None.
deal_response函數中的response參數類型爲Response類
成員變量
Name | 類型 | 含義 |
---|---|---|
hostname | str | 域名 |
port | int | 端口 |
status | int | 狀態碼 |
reason | str | 狀態描述 |
response_version | str | HTTP協議版本 |
request | Request | 響應對應的請求實例 |
成員函數
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()
效果以下:
關注公衆號:七夜安全博客
知識星球已經50人了,隨着人數的增多,價格以後會上漲,越早關注越多優惠。星球的福利有不少: