mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 00:01:36 +00:00
eventsequence: coverage++
This commit is contained in:
parent
5a3976c43e
commit
0299bb5b2e
@ -8,7 +8,7 @@ import types
|
|||||||
|
|
||||||
from mitmproxy import exceptions
|
from mitmproxy import exceptions
|
||||||
from mitmproxy import ctx
|
from mitmproxy import ctx
|
||||||
from mitmproxy import events
|
from mitmproxy import eventsequence
|
||||||
|
|
||||||
|
|
||||||
import watchdog.events
|
import watchdog.events
|
||||||
@ -141,7 +141,7 @@ class Script:
|
|||||||
self.last_options = None
|
self.last_options = None
|
||||||
self.should_reload = threading.Event()
|
self.should_reload = threading.Event()
|
||||||
|
|
||||||
for i in events.Events:
|
for i in eventsequence.Events:
|
||||||
if not hasattr(self, i):
|
if not hasattr(self, i):
|
||||||
def mkprox():
|
def mkprox():
|
||||||
evt = i
|
evt = i
|
||||||
@ -211,7 +211,7 @@ class ScriptLoader:
|
|||||||
raise ValueError(str(e))
|
raise ValueError(str(e))
|
||||||
sc.load_script()
|
sc.load_script()
|
||||||
for f in flows:
|
for f in flows:
|
||||||
for evt, o in events.event_sequence(f):
|
for evt, o in eventsequence.iterate(f):
|
||||||
sc.run(evt, o)
|
sc.run(evt, o)
|
||||||
sc.done()
|
sc.done()
|
||||||
return sc
|
return sc
|
||||||
|
@ -37,7 +37,7 @@ Events = frozenset([
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
def event_sequence(f):
|
def iterate(f):
|
||||||
if isinstance(f, http.HTTPFlow):
|
if isinstance(f, http.HTTPFlow):
|
||||||
if f.request:
|
if f.request:
|
||||||
yield "requestheaders", f
|
yield "requestheaders", f
|
||||||
@ -70,4 +70,4 @@ def event_sequence(f):
|
|||||||
yield "tcp_error", f
|
yield "tcp_error", f
|
||||||
yield "tcp_end", f
|
yield "tcp_end", f
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise ValueError
|
@ -7,7 +7,7 @@ import sys
|
|||||||
from mitmproxy import addonmanager
|
from mitmproxy import addonmanager
|
||||||
from mitmproxy import options
|
from mitmproxy import options
|
||||||
from mitmproxy import controller
|
from mitmproxy import controller
|
||||||
from mitmproxy import events
|
from mitmproxy import eventsequence
|
||||||
from mitmproxy import exceptions
|
from mitmproxy import exceptions
|
||||||
from mitmproxy import connections
|
from mitmproxy import connections
|
||||||
from mitmproxy import http
|
from mitmproxy import http
|
||||||
@ -91,7 +91,7 @@ class Master:
|
|||||||
changed = False
|
changed = False
|
||||||
try:
|
try:
|
||||||
mtype, obj = self.event_queue.get(timeout=timeout)
|
mtype, obj = self.event_queue.get(timeout=timeout)
|
||||||
if mtype not in events.Events:
|
if mtype not in eventsequence.Events:
|
||||||
raise exceptions.ControlException(
|
raise exceptions.ControlException(
|
||||||
"Unknown event %s" % repr(mtype)
|
"Unknown event %s" % repr(mtype)
|
||||||
)
|
)
|
||||||
@ -153,7 +153,7 @@ class Master:
|
|||||||
f.request.port = self.server.config.upstream_server.address.port
|
f.request.port = self.server.config.upstream_server.address.port
|
||||||
f.request.scheme = self.server.config.upstream_server.scheme
|
f.request.scheme = self.server.config.upstream_server.scheme
|
||||||
f.reply = controller.DummyReply()
|
f.reply = controller.DummyReply()
|
||||||
for e, o in events.event_sequence(f):
|
for e, o in eventsequence.iterate(f):
|
||||||
getattr(self, e)(o)
|
getattr(self, e)(o)
|
||||||
|
|
||||||
def load_flows(self, fr: io.FlowReader) -> int:
|
def load_flows(self, fr: io.FlowReader) -> int:
|
||||||
|
@ -3,7 +3,7 @@ This module provides a @concurrent decorator primitive to
|
|||||||
offload computations from mitmproxy's main master thread.
|
offload computations from mitmproxy's main master thread.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from mitmproxy import events
|
from mitmproxy import eventsequence
|
||||||
from mitmproxy.types import basethread
|
from mitmproxy.types import basethread
|
||||||
|
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ class ScriptThread(basethread.BaseThread):
|
|||||||
|
|
||||||
|
|
||||||
def concurrent(fn):
|
def concurrent(fn):
|
||||||
if fn.__name__ not in events.Events - {"start", "configure", "tick"}:
|
if fn.__name__ not in eventsequence.Events - {"start", "configure", "tick"}:
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"Concurrent decorator not supported for '%s' method." % fn.__name__
|
"Concurrent decorator not supported for '%s' method." % fn.__name__
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,7 @@ import contextlib
|
|||||||
import mitmproxy.master
|
import mitmproxy.master
|
||||||
import mitmproxy.options
|
import mitmproxy.options
|
||||||
from mitmproxy import proxy
|
from mitmproxy import proxy
|
||||||
from mitmproxy import events
|
from mitmproxy import eventsequence
|
||||||
from mitmproxy import exceptions
|
from mitmproxy import exceptions
|
||||||
|
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ class context:
|
|||||||
is taken (as in flow interception).
|
is taken (as in flow interception).
|
||||||
"""
|
"""
|
||||||
f.reply._state = "handled"
|
f.reply._state = "handled"
|
||||||
for evt, arg in events.event_sequence(f):
|
for evt, arg in eventsequence.iterate(f):
|
||||||
h = getattr(addon, evt, None)
|
h = getattr(addon, evt, None)
|
||||||
if h:
|
if h:
|
||||||
h(arg)
|
h(arg)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from mitmproxy import controller
|
from mitmproxy import controller
|
||||||
from mitmproxy import events
|
from mitmproxy import eventsequence
|
||||||
from mitmproxy import ctx
|
from mitmproxy import ctx
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ class CallLogger:
|
|||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr in events.Events:
|
if attr in eventsequence.Events:
|
||||||
def prox(*args, **kwargs):
|
def prox(*args, **kwargs):
|
||||||
lg = (self.name, attr, args, kwargs)
|
lg = (self.name, attr, args, kwargs)
|
||||||
if attr != "log":
|
if attr != "log":
|
||||||
|
@ -1,81 +1,57 @@
|
|||||||
from mitmproxy import events
|
import pytest
|
||||||
import contextlib
|
|
||||||
from . import tservers
|
from mitmproxy import eventsequence
|
||||||
|
from mitmproxy.test import tflow
|
||||||
|
|
||||||
|
|
||||||
class Eventer:
|
@pytest.mark.parametrize("resp, err", [
|
||||||
def __init__(self, **handlers):
|
(False, False),
|
||||||
self.failure = None
|
(True, False),
|
||||||
self.called = []
|
(False, True),
|
||||||
self.handlers = handlers
|
(True, True),
|
||||||
for i in events.Events - {"tick"}:
|
])
|
||||||
def mkprox():
|
def test_http_flow(resp, err):
|
||||||
evt = i
|
f = tflow.tflow(resp=resp, err=err)
|
||||||
|
i = eventsequence.iterate(f)
|
||||||
def prox(*args, **kwargs):
|
assert next(i) == ("requestheaders", f)
|
||||||
self.called.append(evt)
|
assert next(i) == ("request", f)
|
||||||
if evt in self.handlers:
|
if resp:
|
||||||
try:
|
assert next(i) == ("responseheaders", f)
|
||||||
handlers[evt](*args, **kwargs)
|
assert next(i) == ("response", f)
|
||||||
except AssertionError as e:
|
if err:
|
||||||
self.failure = e
|
assert next(i) == ("error", f)
|
||||||
return prox
|
|
||||||
setattr(self, i, mkprox())
|
|
||||||
|
|
||||||
def fail(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SequenceTester:
|
@pytest.mark.parametrize("err", [False, True])
|
||||||
@contextlib.contextmanager
|
def test_websocket_flow(err):
|
||||||
def addon(self, addon):
|
f = tflow.twebsocketflow(err=err)
|
||||||
self.master.addons.add(addon)
|
i = eventsequence.iterate(f)
|
||||||
yield
|
assert next(i) == ("websocket_start", f)
|
||||||
self.master.addons.remove(addon)
|
assert len(f.messages) == 0
|
||||||
if addon.failure:
|
assert next(i) == ("websocket_message", f)
|
||||||
raise addon.failure
|
assert len(f.messages) == 1
|
||||||
|
assert next(i) == ("websocket_message", f)
|
||||||
|
assert len(f.messages) == 2
|
||||||
|
if err:
|
||||||
|
assert next(i) == ("websocket_error", f)
|
||||||
|
assert next(i) == ("websocket_end", f)
|
||||||
|
|
||||||
|
|
||||||
class TestBasic(tservers.HTTPProxyTest, SequenceTester):
|
@pytest.mark.parametrize("err", [False, True])
|
||||||
ssl = True
|
def test_tcp_flow(err):
|
||||||
|
f = tflow.ttcpflow(err=err)
|
||||||
|
i = eventsequence.iterate(f)
|
||||||
|
assert next(i) == ("tcp_start", f)
|
||||||
|
assert len(f.messages) == 0
|
||||||
|
assert next(i) == ("tcp_message", f)
|
||||||
|
assert len(f.messages) == 1
|
||||||
|
assert next(i) == ("tcp_message", f)
|
||||||
|
assert len(f.messages) == 2
|
||||||
|
if err:
|
||||||
|
assert next(i) == ("tcp_error", f)
|
||||||
|
assert next(i) == ("tcp_end", f)
|
||||||
|
|
||||||
def test_requestheaders(self):
|
|
||||||
|
|
||||||
def hdrs(f):
|
def test_invalid():
|
||||||
assert f.request.headers
|
with pytest.raises(ValueError):
|
||||||
assert not f.request.content
|
next(eventsequence.iterate(42))
|
||||||
|
|
||||||
def req(f):
|
|
||||||
assert f.request.headers
|
|
||||||
assert f.request.content
|
|
||||||
|
|
||||||
with self.addon(Eventer(requestheaders=hdrs, request=req)):
|
|
||||||
p = self.pathoc()
|
|
||||||
with p.connect():
|
|
||||||
assert p.request("get:'/p/200':b@10").status_code == 200
|
|
||||||
|
|
||||||
def test_100_continue_fail(self):
|
|
||||||
e = Eventer()
|
|
||||||
with self.addon(e):
|
|
||||||
p = self.pathoc()
|
|
||||||
with p.connect():
|
|
||||||
p.request(
|
|
||||||
"""
|
|
||||||
get:'/p/200'
|
|
||||||
h'expect'='100-continue'
|
|
||||||
h'content-length'='1000'
|
|
||||||
da
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
assert "requestheaders" in e.called
|
|
||||||
assert "responseheaders" not in e.called
|
|
||||||
|
|
||||||
def test_connect(self):
|
|
||||||
e = Eventer()
|
|
||||||
with self.addon(e):
|
|
||||||
p = self.pathoc()
|
|
||||||
with p.connect():
|
|
||||||
p.request("get:'/p/200:b@1'")
|
|
||||||
assert "http_connect" in e.called
|
|
||||||
assert e.called.count("requestheaders") == 1
|
|
||||||
assert e.called.count("request") == 1
|
|
||||||
|
2
tox.ini
2
tox.ini
@ -17,7 +17,7 @@ commands =
|
|||||||
--no-full-cov=mitmproxy/net/tcp.py --no-full-cov=mitmproxy/net/http/cookies.py --no-full-cov=mitmproxy/net/http/encoding.py --no-full-cov=mitmproxy/net/http/message.py --no-full-cov=mitmproxy/net/http/request.py --no-full-cov=mitmproxy/net/http/response.py --no-full-cov=mitmproxy/net/http/url.py \
|
--no-full-cov=mitmproxy/net/tcp.py --no-full-cov=mitmproxy/net/http/cookies.py --no-full-cov=mitmproxy/net/http/encoding.py --no-full-cov=mitmproxy/net/http/message.py --no-full-cov=mitmproxy/net/http/request.py --no-full-cov=mitmproxy/net/http/response.py --no-full-cov=mitmproxy/net/http/url.py \
|
||||||
--no-full-cov=mitmproxy/proxy/protocol/ --no-full-cov=mitmproxy/proxy/config.py --no-full-cov=mitmproxy/proxy/root_context.py --no-full-cov=mitmproxy/proxy/server.py \
|
--no-full-cov=mitmproxy/proxy/protocol/ --no-full-cov=mitmproxy/proxy/config.py --no-full-cov=mitmproxy/proxy/root_context.py --no-full-cov=mitmproxy/proxy/server.py \
|
||||||
--no-full-cov=mitmproxy/tools/ \
|
--no-full-cov=mitmproxy/tools/ \
|
||||||
--no-full-cov=mitmproxy/certs.py --no-full-cov=mitmproxy/connections.py --no-full-cov=mitmproxy/controller.py --no-full-cov=mitmproxy/events.py --no-full-cov=mitmproxy/export.py --no-full-cov=mitmproxy/flow.py --no-full-cov=mitmproxy/flowfilter.py --no-full-cov=mitmproxy/http.py --no-full-cov=mitmproxy/io_compat.py --no-full-cov=mitmproxy/master.py --no-full-cov=mitmproxy/optmanager.py \
|
--no-full-cov=mitmproxy/certs.py --no-full-cov=mitmproxy/connections.py --no-full-cov=mitmproxy/controller.py --no-full-cov=mitmproxy/export.py --no-full-cov=mitmproxy/flow.py --no-full-cov=mitmproxy/flowfilter.py --no-full-cov=mitmproxy/http.py --no-full-cov=mitmproxy/io_compat.py --no-full-cov=mitmproxy/master.py --no-full-cov=mitmproxy/optmanager.py \
|
||||||
--full-cov=pathod/ --no-full-cov=pathod/pathoc.py --no-full-cov=pathod/pathod.py --no-full-cov=pathod/test.py --no-full-cov=pathod/protocols/http2.py \
|
--full-cov=pathod/ --no-full-cov=pathod/pathoc.py --no-full-cov=pathod/pathod.py --no-full-cov=pathod/test.py --no-full-cov=pathod/protocols/http2.py \
|
||||||
{posargs}
|
{posargs}
|
||||||
{env:CI_COMMANDS:python -c ""}
|
{env:CI_COMMANDS:python -c ""}
|
||||||
|
Loading…
Reference in New Issue
Block a user