Skip to content

Commit 4d72a84

Browse files
committed
feat: add support for custom output file names
1 parent 70938f6 commit 4d72a84

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ These endpoints allow dynamic control of recording and local response mapping.
124124
### ▶️ Start Recording
125125

126126
```bash
127+
# Default recording, outputs to flows.json
127128
curl http://localhost:9999/start_recording
129+
130+
# Optional name for recording, outputs to "name" pass
131+
curl http://localhost:9999/start_recording?name=output_file_name"
128132
```
129133
130134
### ⏹️ Stop Recording and Save

proxy-session-controller.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from http.server import BaseHTTPRequestHandler, HTTPServer
33
from mitmproxy import ctx, http
44
import json
5+
from urllib.parse import urlparse, parse_qs
56

67
class Recorder:
78
def __init__(self):
89
self.recording = False
910
self.flows = []
11+
self.output_filename = "flows.json"
1012

1113
def request(self, flow: http.HTTPFlow):
1214
if self.recording:
@@ -38,8 +40,8 @@ def try_parse_json(self, content, headers):
3840
return content # fall back to raw if invalid JSON
3941
return content
4042

41-
def save_flows_as_json(self, path="flows.json"):
42-
ctx.log.info(f"Saving {len(self.flows)} flows to {path}")
43+
def save_flows_as_json(self):
44+
ctx.log.info(f"Saving {len(self.flows)} flows to {self.output_filename}")
4345
data = []
4446
for flow in self.flows:
4547
if flow.response:
@@ -62,21 +64,29 @@ def save_flows_as_json(self, path="flows.json"):
6264
"body": response_content
6365
}
6466
})
65-
with open(path, "w") as f:
67+
with open(self.output_filename, "w") as f:
6668
json.dump(data, f, indent=2)
6769

6870
class ControlServer(BaseHTTPRequestHandler):
6971
recorder = None # class variable
7072
map_local = {} # class variable for local mapping
7173

7274
def do_GET(self):
73-
if self.path == "/start_recording":
75+
parsed = urlparse(self.path)
76+
path = parsed.path
77+
query = parse_qs(parsed.query)
78+
79+
if path == "/start_recording":
7480
ControlServer.recorder.recording = True
7581
ControlServer.recorder.flows = []
82+
83+
name = query.get("name", ["flows"])[0]
84+
ControlServer.recorder.output_filename = f"{name}.json"
85+
7686
self.send_response(200)
7787
self.end_headers()
78-
self.wfile.write(b"Recording started")
79-
elif self.path == "/stop_recording":
88+
self.wfile.write(f"Recording started as {name}.json".encode())
89+
elif path == "/stop_recording":
8090
ControlServer.recorder.recording = False
8191
ControlServer.recorder.save_flows_as_json()
8292
self.send_response(200)

0 commit comments

Comments
 (0)