From 380ac072aab831c40e286aa99f4b515a7f27e4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=8E=AE=20=28Jade=20Lin=29?= Date: Sat, 12 Dec 2020 18:17:38 +0800 Subject: [PATCH] ASGIApp should ignore the HTTP flows loaded from somewhere (#4324) --- CHANGELOG.rst | 1 + mitmproxy/addons/asgiapp.py | 12 ++++++++++-- test/mitmproxy/addons/test_asgiapp.py | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ffd33c525..071763d22 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,7 @@ Unreleased: mitmproxy next * Addon to suppress unwanted error messages sent by mitmproxy. (@anneborcherding) * Updated imports and styles for web scanner helper addons. (@anneborcherding) * Inform when underscore-formatted options are used in client arg. (@jrblixt) +* ASGIApp should ignore the HTTP flows loaded from somewhere. (@linw1995) * Binaries are now built with Python 3.9 (@mhils) * Fixed the web UI showing blank page on clicking details tab when server address is missing (@samhita-sopho) diff --git a/mitmproxy/addons/asgiapp.py b/mitmproxy/addons/asgiapp.py index 5edb6ac84..8c4b3a238 100644 --- a/mitmproxy/addons/asgiapp.py +++ b/mitmproxy/addons/asgiapp.py @@ -3,8 +3,8 @@ import urllib.parse import asgiref.compatibility import asgiref.wsgi - from mitmproxy import ctx, http +from mitmproxy.controller import DummyReply class ASGIApp: @@ -24,9 +24,17 @@ class ASGIApp: def name(self) -> str: return f"asgiapp:{self.host}:{self.port}" + def should_serve(self, flow: http.HTTPFlow) -> bool: + assert flow.reply + return bool( + (flow.request.pretty_host, flow.request.port) == (self.host, self.port) + and not flow.reply.has_message + and not isinstance(flow.reply, DummyReply) # ignore the HTTP flows of this app loaded from somewhere + ) + def request(self, flow: http.HTTPFlow) -> None: assert flow.reply - if (flow.request.pretty_host, flow.request.port) == (self.host, self.port) and not flow.reply.has_message: + if self.should_serve(flow): flow.reply.take() # pause hook completion asyncio.ensure_future(serve(self.asgi_app, flow)) diff --git a/test/mitmproxy/addons/test_asgiapp.py b/test/mitmproxy/addons/test_asgiapp.py index c5cadebc3..a4e8d672a 100644 --- a/test/mitmproxy/addons/test_asgiapp.py +++ b/test/mitmproxy/addons/test_asgiapp.py @@ -1,10 +1,15 @@ +import asyncio import json +import sys +from unittest import mock import flask +import pytest from flask import request from .. import tservers from mitmproxy.addons import asgiapp +from mitmproxy.test import tflow tapp = flask.Flask(__name__) @@ -68,3 +73,12 @@ class TestApp(tservers.HTTPProxyTest): ret = p.request("get:'http://noresponseapp/'") assert ret.status_code == 500 assert b"ASGI Error" in ret.content + + @pytest.mark.skipif(sys.version_info < (3, 8), reason='requires Python 3.8 or higher') + def test_app_not_serve_loading_flows(self): + with mock.patch('mitmproxy.addons.asgiapp.serve') as mck: + flow = tflow.tflow() + flow.request.host = "testapp" + flow.request.port = 80 + asyncio.run_coroutine_threadsafe(self.master.load_flow(flow), self.master.channel.loop).result() + mck.assert_not_awaited()