ASGIApp should ignore the HTTP flows loaded from somewhere (#4324)

This commit is contained in:
林玮 (Jade Lin) 2020-12-12 18:17:38 +08:00 committed by GitHub
parent 4f46400184
commit 380ac072aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 2 deletions

View File

@ -11,6 +11,7 @@ Unreleased: mitmproxy next
* Addon to suppress unwanted error messages sent by mitmproxy. (@anneborcherding) * Addon to suppress unwanted error messages sent by mitmproxy. (@anneborcherding)
* Updated imports and styles for web scanner helper addons. (@anneborcherding) * Updated imports and styles for web scanner helper addons. (@anneborcherding)
* Inform when underscore-formatted options are used in client arg. (@jrblixt) * 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) * 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) * Fixed the web UI showing blank page on clicking details tab when server address is missing (@samhita-sopho)

View File

@ -3,8 +3,8 @@ import urllib.parse
import asgiref.compatibility import asgiref.compatibility
import asgiref.wsgi import asgiref.wsgi
from mitmproxy import ctx, http from mitmproxy import ctx, http
from mitmproxy.controller import DummyReply
class ASGIApp: class ASGIApp:
@ -24,9 +24,17 @@ class ASGIApp:
def name(self) -> str: def name(self) -> str:
return f"asgiapp:{self.host}:{self.port}" 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: def request(self, flow: http.HTTPFlow) -> None:
assert flow.reply 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 flow.reply.take() # pause hook completion
asyncio.ensure_future(serve(self.asgi_app, flow)) asyncio.ensure_future(serve(self.asgi_app, flow))

View File

@ -1,10 +1,15 @@
import asyncio
import json import json
import sys
from unittest import mock
import flask import flask
import pytest
from flask import request from flask import request
from .. import tservers from .. import tservers
from mitmproxy.addons import asgiapp from mitmproxy.addons import asgiapp
from mitmproxy.test import tflow
tapp = flask.Flask(__name__) tapp = flask.Flask(__name__)
@ -68,3 +73,12 @@ class TestApp(tservers.HTTPProxyTest):
ret = p.request("get:'http://noresponseapp/'") ret = p.request("get:'http://noresponseapp/'")
assert ret.status_code == 500 assert ret.status_code == 500
assert b"ASGI Error" in ret.content 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()