diff --git a/mitmproxy/flowfilter.py b/mitmproxy/flowfilter.py index 5b67c0766..2e619397c 100644 --- a/mitmproxy/flowfilter.py +++ b/mitmproxy/flowfilter.py @@ -382,6 +382,30 @@ class FDst(_Rex): return f.server_conn.address and self.re.search(r) +class FReplay(_Action): + code = "replay" + help = "Match replayed flows" + + def __call__(self, f): + return f.is_replay is not None + + +class FReplayClient(_Action): + code = "replayq" + help = "Match replayed client request" + + def __call__(self, f): + return f.is_replay == 'request' + + +class FReplayServer(_Action): + code = "replays" + help = "Match replayed server response" + + def __call__(self, f): + return f.is_replay == 'response' + + class _Int(_Action): def __init__(self, num): @@ -444,6 +468,9 @@ filter_unary: Sequence[Type[_Action]] = [ FErr, FHTTP, FMarked, + FReplay, + FReplayClient, + FReplayServer, FReq, FResp, FTCP, diff --git a/test/mitmproxy/test_flowfilter.py b/test/mitmproxy/test_flowfilter.py index 243748419..aa579d6b0 100644 --- a/test/mitmproxy/test_flowfilter.py +++ b/test/mitmproxy/test_flowfilter.py @@ -24,6 +24,9 @@ class TestParsing: assert flowfilter.parse("~m foobar") assert flowfilter.parse("~u foobar") assert flowfilter.parse("~q ~c 10") + assert flowfilter.parse("~replay") + assert flowfilter.parse("~replayq") + assert flowfilter.parse("~replays") p = flowfilter.parse("~q ~c 10") self._dump(p) assert len(p.lst) == 2 @@ -296,6 +299,18 @@ class TestMatchingHTTPFlow: assert self.q("!~c 201 !~c 202", s) assert not self.q("!~c 201 !~c 200", s) + def test_replay(self): + f = tflow.tflow() + assert not self.q("~r", f) + f.is_replay = "request" + assert self.q("~r", f) + assert self.q("~rc", f) + assert not self.q("~rs", f) + f.is_replay = "response" + assert self.q("~r", f) + assert not self.q("~rc", f) + assert self.q("~rs", f) + class TestMatchingTCPFlow: