def flow_to_json(flow: mitmproxy.flow.Flow) -> dict: """ Remove flow message content and cert to save transmission space. Args: flow: The original flow. """ f = { "id": flow.id, "intercepted": flow.intercepted, "client_conn": flow.client_conn.get_state(), "server_conn": flow.server_conn.get_state(), "type": flow.type, "modified": flow.modified(), } # .alpn_proto_negotiated is bytes, we need to decode that. for conn in "client_conn", "server_conn": if f[conn]["alpn_proto_negotiated"] is None: continue f[conn]["alpn_proto_negotiated"] = \ f[conn]["alpn_proto_negotiated"].decode(errors="backslashreplace") if flow.error: f["error"] = flow.error.get_state() if isinstance(flow, http.HTTPFlow): if flow.request: f["request"] = { "method": flow.request.method, "scheme": flow.request.scheme, "host": flow.request.host, "port": flow.request.port, "path": flow.request.path, "http_version": flow.request.http_version, "headers": tuple(flow.request.headers.items(True)), "contentLength": len( flow.request.raw_content) if flow.request.raw_content is not None else None, "contentHash": hashlib.sha256( flow.request.raw_content).hexdigest() if flow.request.raw_content is not None else None, "timestamp_start": flow.request.timestamp_start, "timestamp_end": flow.request.timestamp_end, "is_replay": flow.request.is_replay, } if flow.response: f["response"] = { "http_version": flow.response.http_version, "status_code": flow.response.status_code, "reason": flow.response.reason, "headers": tuple(flow.response.headers.items(True)), "contentLength": len( flow.response.raw_content) if flow.response.raw_content is not None else None, "contentHash": hashlib.sha256( flow.response.raw_content).hexdigest() if flow.response.raw_content is not None else None, "timestamp_start": flow.response.timestamp_start, "timestamp_end": flow.response.timestamp_end, "is_replay": flow.response.is_replay, } f.get("server_conn", {}).pop("cert", None) return f
def flow_to_json(flow: mitmproxy.flow.Flow) -> dict: """ Remove flow message content and cert to save transmission space. Args: flow: The original flow. """ f = { "id": flow.id, "intercepted": flow.intercepted, "is_replay": flow.is_replay, "client_conn": flow.client_conn.get_state(), "server_conn": flow.server_conn.get_state(), "type": flow.type, "modified": flow.modified(), "marked": flow.marked, } # .alpn_proto_negotiated is bytes, we need to decode that. for conn in "client_conn", "server_conn": if f[conn]["alpn_proto_negotiated"] is None: continue f[conn]["alpn_proto_negotiated"] = \ f[conn]["alpn_proto_negotiated"].decode(errors="backslashreplace") # There are some bytes in here as well, let's skip it until we have them in the UI. f["client_conn"].pop("tls_extensions", None) if flow.error: f["error"] = flow.error.get_state() if isinstance(flow, http.HTTPFlow): content_length: Optional[int] content_hash: Optional[str] if flow.request: if flow.request.raw_content: content_length = len(flow.request.raw_content) content_hash = hashlib.sha256( flow.request.raw_content).hexdigest() else: content_length = None content_hash = None f["request"] = { "method": flow.request.method, "scheme": flow.request.scheme, "host": flow.request.host, "port": flow.request.port, "path": flow.request.path, "http_version": flow.request.http_version, "headers": tuple(flow.request.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.request.timestamp_start, "timestamp_end": flow.request.timestamp_end, "is_replay": flow.is_replay == "request", # TODO: remove, use flow.is_replay instead. "pretty_host": flow.request.pretty_host, } if flow.response: if flow.response.raw_content: content_length = len(flow.response.raw_content) content_hash = hashlib.sha256( flow.response.raw_content).hexdigest() else: content_length = None content_hash = None f["response"] = { "http_version": flow.response.http_version, "status_code": flow.response.status_code, "reason": flow.response.reason, "headers": tuple(flow.response.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.response.timestamp_start, "timestamp_end": flow.response.timestamp_end, "is_replay": flow.is_replay == "response", # TODO: remove, use flow.is_replay instead. } if flow.response.data.trailers: f["response"]["trailers"] = tuple( flow.response.data.trailers.items(True)) f.get("server_conn", {}).pop("cert", None) f.get("client_conn", {}).pop("mitmcert", None) return f
def flow_to_json(flow: mitmproxy.flow.Flow) -> dict: """ Remove flow message content and cert to save transmission space. Args: flow: The original flow. """ f = { "id": flow.id, "intercepted": flow.intercepted, "client_conn": flow.client_conn.get_state(), "server_conn": flow.server_conn.get_state(), "type": flow.type, "modified": flow.modified(), "marked": flow.marked, } # .alpn_proto_negotiated is bytes, we need to decode that. for conn in "client_conn", "server_conn": if f[conn]["alpn_proto_negotiated"] is None: continue f[conn]["alpn_proto_negotiated"] = \ f[conn]["alpn_proto_negotiated"].decode(errors="backslashreplace") # There are some bytes in here as well, let's skip it until we have them in the UI. f["client_conn"].pop("tls_extensions", None) if flow.error: f["error"] = flow.error.get_state() if isinstance(flow, http.HTTPFlow): if flow.request: if flow.request.raw_content: content_length = len(flow.request.raw_content) content_hash = hashlib.sha256(flow.request.raw_content).hexdigest() else: content_length = None content_hash = None f["request"] = { "method": flow.request.method, "scheme": flow.request.scheme, "host": flow.request.host, "port": flow.request.port, "path": flow.request.path, "http_version": flow.request.http_version, "headers": tuple(flow.request.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.request.timestamp_start, "timestamp_end": flow.request.timestamp_end, "is_replay": flow.request.is_replay, "pretty_host": flow.request.pretty_host, } if flow.response: if flow.response.raw_content: content_length = len(flow.response.raw_content) content_hash = hashlib.sha256(flow.response.raw_content).hexdigest() else: content_length = None content_hash = None f["response"] = { "http_version": flow.response.http_version, "status_code": flow.response.status_code, "reason": flow.response.reason, "headers": tuple(flow.response.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.response.timestamp_start, "timestamp_end": flow.response.timestamp_end, "is_replay": flow.response.is_replay, } f.get("server_conn", {}).pop("cert", None) f.get("client_conn", {}).pop("mitmcert", None) return f
def flow_to_json(flow: mitmproxy.flow.Flow) -> dict: """ Remove flow message content and cert to save transmission space. Args: flow: The original flow. """ f = { "id": flow.id, "intercepted": flow.intercepted, "is_replay": flow.is_replay, "type": flow.type, "modified": flow.modified(), "marked": flow.marked, } if flow.client_conn: f["client_conn"] = { "id": flow.client_conn.id, "address": flow.client_conn.peername, "tls_established": flow.client_conn.tls_established, "timestamp_start": flow.client_conn.timestamp_start, "timestamp_tls_setup": flow.client_conn.timestamp_tls_setup, "timestamp_end": flow.client_conn.timestamp_end, # ideally idna, but we don't want errors "sni": always_str(flow.client_conn.sni, "ascii", "backslashreplace"), "cipher_name": flow.client_conn.cipher, "alpn_proto_negotiated": always_str(flow.client_conn.alpn, "ascii", "backslashreplace"), "tls_version": flow.client_conn.tls_version, } if flow.server_conn: f["server_conn"] = { "id": flow.server_conn.id, "address": flow.server_conn.address, "ip_address": flow.server_conn.peername, "source_address": flow.server_conn.sockname, "tls_established": flow.server_conn.tls_established, "alpn_proto_negotiated": always_str(flow.server_conn.alpn, "ascii", "backslashreplace"), "tls_version": flow.server_conn.tls_version, "timestamp_start": flow.server_conn.timestamp_start, "timestamp_tcp_setup": flow.server_conn.timestamp_tcp_setup, "timestamp_tls_setup": flow.server_conn.timestamp_tls_setup, "timestamp_end": flow.server_conn.timestamp_end, } if flow.server_conn.sni is True: f["server_conn"] = None else: # ideally idna, but we don't want errors f["server_conn"] = always_str(flow.server_conn.sni, "ascii", "backslashreplace") if flow.error: f["error"] = flow.error.get_state() if isinstance(flow, http.HTTPFlow): content_length: Optional[int] content_hash: Optional[str] if flow.request: if flow.request.raw_content: content_length = len(flow.request.raw_content) content_hash = hashlib.sha256(flow.request.raw_content).hexdigest() else: content_length = None content_hash = None f["request"] = { "method": flow.request.method, "scheme": flow.request.scheme, "host": flow.request.host, "port": flow.request.port, "path": flow.request.path, "http_version": flow.request.http_version, "headers": tuple(flow.request.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.request.timestamp_start, "timestamp_end": flow.request.timestamp_end, "is_replay": flow.is_replay == "request", # TODO: remove, use flow.is_replay instead. "pretty_host": flow.request.pretty_host, } if flow.response: if flow.response.raw_content: content_length = len(flow.response.raw_content) content_hash = hashlib.sha256(flow.response.raw_content).hexdigest() else: content_length = None content_hash = None f["response"] = { "http_version": flow.response.http_version, "status_code": flow.response.status_code, "reason": flow.response.reason, "headers": tuple(flow.response.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.response.timestamp_start, "timestamp_end": flow.response.timestamp_end, "is_replay": flow.is_replay == "response", # TODO: remove, use flow.is_replay instead. } if flow.response.data.trailers: f["response"]["trailers"] = tuple(flow.response.data.trailers.items(True)) return f
def flow_to_json(flow: mitmproxy.flow.Flow) -> dict: """ Remove flow message content and cert to save transmission space. Args: flow: The original flow. Sync with web/src/flow.ts. """ f = { "id": flow.id, "intercepted": flow.intercepted, "is_replay": flow.is_replay, "type": flow.type, "modified": flow.modified(), "marked": emoji.get(flow.marked, "🔴") if flow.marked else "", "comment": flow.comment, } if flow.client_conn: f["client_conn"] = { "id": flow.client_conn.id, "peername": flow.client_conn.peername, "sockname": flow.client_conn.sockname, "tls_established": flow.client_conn.tls_established, "cert": cert_to_json(flow.client_conn.certificate_list), "sni": flow.client_conn.sni, "cipher": flow.client_conn.cipher, "alpn": always_str(flow.client_conn.alpn, "ascii", "backslashreplace"), "tls_version": flow.client_conn.tls_version, "timestamp_start": flow.client_conn.timestamp_start, "timestamp_tls_setup": flow.client_conn.timestamp_tls_setup, "timestamp_end": flow.client_conn.timestamp_end, } if flow.server_conn: f["server_conn"] = { "id": flow.server_conn.id, "peername": flow.server_conn.peername, "sockname": flow.server_conn.sockname, "address": flow.server_conn.address, "tls_established": flow.server_conn.tls_established, "cert": cert_to_json(flow.server_conn.certificate_list), "sni": flow.server_conn.sni, "cipher": flow.server_conn.cipher, "alpn": always_str(flow.server_conn.alpn, "ascii", "backslashreplace"), "tls_version": flow.server_conn.tls_version, "timestamp_start": flow.server_conn.timestamp_start, "timestamp_tcp_setup": flow.server_conn.timestamp_tcp_setup, "timestamp_tls_setup": flow.server_conn.timestamp_tls_setup, "timestamp_end": flow.server_conn.timestamp_end, } if flow.error: f["error"] = flow.error.get_state() if isinstance(flow, HTTPFlow): content_length: Optional[int] content_hash: Optional[str] if flow.request.raw_content is not None: content_length = len(flow.request.raw_content) content_hash = hashlib.sha256(flow.request.raw_content).hexdigest() else: content_length = None content_hash = None f["request"] = { "method": flow.request.method, "scheme": flow.request.scheme, "host": flow.request.host, "port": flow.request.port, "path": flow.request.path, "http_version": flow.request.http_version, "headers": tuple(flow.request.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.request.timestamp_start, "timestamp_end": flow.request.timestamp_end, "pretty_host": flow.request.pretty_host, } if flow.response: if flow.response.raw_content is not None: content_length = len(flow.response.raw_content) content_hash = hashlib.sha256(flow.response.raw_content).hexdigest() else: content_length = None content_hash = None f["response"] = { "http_version": flow.response.http_version, "status_code": flow.response.status_code, "reason": flow.response.reason, "headers": tuple(flow.response.headers.items(True)), "contentLength": content_length, "contentHash": content_hash, "timestamp_start": flow.response.timestamp_start, "timestamp_end": flow.response.timestamp_end, } if flow.response.data.trailers: f["response"]["trailers"] = tuple(flow.response.data.trailers.items(True)) if flow.websocket: f["websocket"] = { "messages_meta": { "contentLength": sum(len(x.content) for x in flow.websocket.messages), "count": len(flow.websocket.messages), "timestamp_last": flow.websocket.messages[-1].timestamp if flow.websocket.messages else None, }, "closed_by_client": flow.websocket.closed_by_client, "close_code": flow.websocket.close_code, "close_reason": flow.websocket.close_reason, "timestamp_end": flow.websocket.timestamp_end, } elif isinstance(flow, TCPFlow): f["messages_meta"] = { "contentLength": sum(len(x.content) for x in flow.messages), "count": len(flow.messages), "timestamp_last": flow.messages[-1].timestamp if flow.messages else None, } return f