Edit a component of the currently focused flow.
(self, flow_part: str)
| 466 | "flow_part", type=mitmproxy.types.Choice("console.edit.focus.options") |
| 467 | ) |
| 468 | def edit_focus(self, flow_part: str) -> None: |
| 469 | """ |
| 470 | Edit a component of the currently focused flow. |
| 471 | """ |
| 472 | flow = self.master.view.focus.flow |
| 473 | # This shouldn't be necessary once this command is "console.edit @focus", |
| 474 | # but for now it is. |
| 475 | if not flow: |
| 476 | raise exceptions.CommandError("No flow selected.") |
| 477 | flow.backup() |
| 478 | |
| 479 | require_dummy_response = ( |
| 480 | flow_part in ("response-headers", "response-body", "set-cookies") |
| 481 | and flow.response is None |
| 482 | ) |
| 483 | if require_dummy_response: |
| 484 | flow.response = http.Response.make() |
| 485 | if flow_part == "comment": |
| 486 | self.master.switch_view("edit_focus_comment") |
| 487 | elif flow_part == "cookies": |
| 488 | self.master.switch_view("edit_focus_cookies") |
| 489 | elif flow_part == "urlencoded form": |
| 490 | self.master.switch_view("edit_focus_urlencoded_form") |
| 491 | elif flow_part == "multipart form": |
| 492 | self.master.switch_view("edit_focus_multipart_form") |
| 493 | elif flow_part == "path": |
| 494 | self.master.switch_view("edit_focus_path") |
| 495 | elif flow_part == "query": |
| 496 | self.master.switch_view("edit_focus_query") |
| 497 | elif flow_part == "request-headers": |
| 498 | self.master.switch_view("edit_focus_request_headers") |
| 499 | elif flow_part == "response-headers": |
| 500 | self.master.switch_view("edit_focus_response_headers") |
| 501 | elif m := re.match( |
| 502 | r"(?P<message>(request|response)-body|(tcp|udp|websocket)-message) \((?P<contentview>.+)\)", |
| 503 | flow_part, |
| 504 | ): |
| 505 | match m["message"]: |
| 506 | case "request-body": |
| 507 | message = flow.request |
| 508 | case "response-body": |
| 509 | message = flow.response |
| 510 | case "tcp-message" | "udp-message": |
| 511 | message = flow.messages[-1] |
| 512 | case "websocket-message": |
| 513 | message = flow.websocket.messages[-1] |
| 514 | case _: |
| 515 | assert False, "should be exhaustive" |
| 516 | |
| 517 | cv = contentviews.registry.get(m["contentview"]) |
| 518 | if not cv or not isinstance(cv, contentviews.InteractiveContentview): |
| 519 | raise CommandError( |
| 520 | f"Contentview {m['contentview']} is not bidirectional." |
| 521 | ) |
| 522 | |
| 523 | pretty = contentviews.prettify_message(message, flow, cv.name) |
| 524 | prettified = self.master.spawn_editor(pretty.text) |
| 525 |
nothing calls this directly
no test coverage detected