| 92 | self.replay_http_https(raw_text, flow_id) |
| 93 | |
| 94 | def replay_http_https(self, raw_text, flow_id): |
| 95 | lines = raw_text.splitlines() |
| 96 | method, path, _ = lines[0].split(" ", 2) |
| 97 | |
| 98 | headers = {} |
| 99 | body = b"" |
| 100 | in_body = False |
| 101 | |
| 102 | for line in lines[1:]: |
| 103 | if line.strip() == "": |
| 104 | in_body = True |
| 105 | continue |
| 106 | if in_body: |
| 107 | body += line.encode() + b"\n" |
| 108 | else: |
| 109 | if ":" in line: |
| 110 | k, v = line.split(":", 1) |
| 111 | headers[k.strip()] = v.strip() |
| 112 | |
| 113 | host = headers.get("Host") |
| 114 | if not host: |
| 115 | raise Exception("Replay failed: Host header missing") |
| 116 | |
| 117 | scheme = "https" if headers.get(":scheme") == "https" else "http" |
| 118 | port = 443 if scheme == "https" else 80 |
| 119 | |
| 120 | if ":" in host: |
| 121 | host, port = host.split(":", 1) |
| 122 | port = int(port) |
| 123 | |
| 124 | req = mitmproxy.http.Request.make( |
| 125 | method=method, |
| 126 | url=f"{scheme}://{host}{path}", |
| 127 | headers=headers, |
| 128 | content=body, |
| 129 | ) |
| 130 | |
| 131 | client = Client(peername=("127.0.0.1", 0), sockname=("127.0.0.1", 0)) |
| 132 | server = Server(address=(host, port)) |
| 133 | |
| 134 | flow = mitmproxy.http.HTTPFlow(client, server) |
| 135 | |
| 136 | |
| 137 | flow.request = req |
| 138 | flow.metadata["drana_replay_ui_id"] = flow_id |
| 139 | |
| 140 | ctx.master.commands.call("replay.client", [flow]) |
| 141 | print(f"[Proxy] Replayed {method} {host}{path}") |
| 142 | |
| 143 | def _build_replay_flow(self, raw_text): |
| 144 | lines = raw_text.splitlines() |