mitmproxy實踐


首先附上github地址:https://github.com/mitmproxy/mitmprox,上面的內容永遠是最新的

  1. 作為一名測試穿戴設備相關app的工程師,與數據打交道是常事,那么,如果想要獲取app上傳給服務器的文件,怎么獲取?
    上傳文件,http請求頭header的Content-Type字段multipart/form-data
    注意:如果要修改請求參數,必須得了解Content_Type的類型,Content_Type主要告知請求的消息主要用了何種編碼,常見3中類型:

application/x-www-form-urlencoded
form形式,提交的數據按照 key1=val1&key2=val2 的方式進行編碼
application/json
JSON編碼方式,消息主體是序列化后的 JSON 字符串
multipart/form-data
主要是傳輸二進制流等,boundary區分普通文件內容和二進制流內容
def request(flow: http.HTTPFlow) -> None:
target=["/course/data/save"]
url_path = flow.request.path
print("完整收到請求(包括body部分)={}".format(url_path))
if url_path.split("?")[0] in target:
ctx.log.info("#"50)
ctx.log.info("課程接口")
ctx.log.info(flow.request.url)
fp=open("courseData.dat","wb")
for key,value in flow.request.multipart_form.items():
print(key)
if key==b"courseData":#文件名
fp.write(value)
fp.close()
2. 接口返回字段變更,為了兼容,暫時未去掉,未來去掉,這種情況下,app需要做好兼容性測試,那么需要通過模擬刪除相應字段
def response(self,flow: http.HTTPFlow) -> None:
if flowfilter.match(self.filter, flow):
url_path = flow.request.path
if "
由於隱私該處省略" in url_path:
ctx.log.warn("#" * 60)
res=json.loads(flow.response.text)
for i in res.get("data"):
i.pop('happenDate')#刪除happenDate字段,這個地方得看返回內容的結構
flow.response.set_text(json.dumps(res))
3. 筆者測試的app在header中需要帶上一段自定義的字段,當中途新增接口,有時候后開發會忘記添加,那么,測試人員在測試迭代需求的時候,需要檢查一遍新增接口請求,閱讀完接口后可編寫腳本,待發布app時直接執行
def request(self,flow: http.HTTPFlow) -> None:
if url_path.split("?")[0] in "
特定接口*":
ctx.log.warn("#" * 60)
dict_obj = json.loads(flow.request.headers.get("selfHeader","{}")) # 字典字符串,headers為字典對象
4.自定義options
默認options:
https://docs.mitmproxy.org/stable/concepts-options/

自定義filter

def load(self, loader):
"""
腳本載入時執行,對應--options參數,默認有多個可供選擇的項,如flow_detail,同時可在載入腳本時自定義選項
option格式:(name,typespec,defult,help)
"""
loader.add_option("filter", str, "", "過濾規則")

def configure(self,updated):
"""腳本載入,讀取配置"""
self.filter =flowfilter.parse(ctx.options.filter) #得到一個過濾器

def request(self,flow: http.HTTPFlow) -> None:
if flowfilter.match(self.filter, flow):
print("filter")
結語
在使用fitler這個過濾功能時,發現源代碼有一處錯誤,如

class FDomain(_Rex):
code = "d"
help = "Domain"
flags = re.IGNORECASE
is_binary = False

@only(http.HTTPFlow, websocket.WebSocketFlow)
def __call__(self, f):
    if isinstance(f, websocket.WebSocketFlow):
        f = f.handshake_flow
    return bool(
        self.re.search(f.request.host) or
        self.re.search(f.request.pretty_host) #這里應該添加str,否則一直報錯,其他地方類似
    )

作者:小蝸牛的成長
鏈接:https://www.jianshu.com/p/23fe9858b2bb
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM