-
Notifications
You must be signed in to change notification settings - Fork 1
/
replayserverex.py
92 lines (77 loc) · 2.55 KB
/
replayserverex.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import logging
from typing import List
import mitmproxy.types
from mitmproxy import command
from mitmproxy import ctx
from mitmproxy import exceptions
from mitmproxy import hooks
from mitmproxy import io
from mitmproxy.addons import serverplayback
from mitmproxy.flow import Flow
from mitmproxy.http import HTTPFlow
from mitmproxy.log import ALERT
from mitmproxy.tools.console import overlay
def _find_addon() -> serverplayback.ServerPlayback:
addon = ctx.master.addons.get("serverplayback")
if not addon:
raise ValueError("Cannot find addon 'serverplayback'")
return addon
class ReplayServerEx:
@command.command("replay.server.file.add")
def load_file(self, path: mitmproxy.types.Path) -> None:
"""
Append server responses from file.
"""
try:
flows = io.read_flows_from_paths([path])
except exceptions.FlowReadException as e:
raise exceptions.CommandError(e, str(e))
self._add_flows(flows)
@command.command("replay.server.list")
def list_flows(self) -> None:
"""
Show server responses list.
"""
recorded_flows: List[Flow] = []
for flows in _find_addon().flowmap.values():
for f in flows:
recorded_flows.append(f)
if len(recorded_flows) == 0:
logging.getLogger().log(ALERT, "No flows")
return
choices = []
for f in recorded_flows:
if not isinstance(f, HTTPFlow):
continue
c = FlowChoice(f.request.url)
c.flow = f
choices.append(c)
def callback(opt):
if opt.flow not in ctx.master.view:
logging.getLogger().log(ALERT, "Not found")
else:
ctx.master.view.focus.flow = opt.flow
ctx.master.overlay(
overlay.Chooser(ctx.master, "Flows", choices, "", callback)
)
def _add_flows(self, flows: list[Flow]) -> None:
"""
Replay server responses from flows.
"""
addon = _find_addon()
updated = 0
for f in flows:
if isinstance(f, HTTPFlow) and f.response:
flowlist = addon.flowmap.setdefault(addon._hash(f), [])
flowlist.append(f)
updated = updated + 1
ctx.master.addons.trigger(hooks.UpdateHook([]))
logging.getLogger().log(ALERT, "Added %d flows" % updated)
class FlowChoice(str):
"""
A str subclass which holds 'flow' instance
"""
pass
addons = [
ReplayServerEx()
]