diff options
Diffstat (limited to 'libmproxy')
-rw-r--r-- | libmproxy/console/__init__.py | 4 | ||||
-rw-r--r-- | libmproxy/console/connlist.py | 5 | ||||
-rw-r--r-- | libmproxy/console/connview.py | 6 | ||||
-rw-r--r-- | libmproxy/flow.py | 37 |
4 files changed, 43 insertions, 9 deletions
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py index 6fc37a47..ca80d013 100644 --- a/libmproxy/console/__init__.py +++ b/libmproxy/console/__init__.py @@ -516,9 +516,7 @@ class ConsoleMaster(flow.FlowMaster): def focus_current(self): if self.currentflow: try: - ids = [id(i) for i in self.state.view] - idx = ids.index(id(self.currentflow)) - self.conn_list_view.set_focus(idx) + self.conn_list_view.set_focus(self.state.index(self.currentflow)) except (IndexError, ValueError): pass diff --git a/libmproxy/console/connlist.py b/libmproxy/console/connlist.py index 957e797b..f54b8061 100644 --- a/libmproxy/console/connlist.py +++ b/libmproxy/console/connlist.py @@ -8,6 +8,7 @@ def _mkhelp(): ("a", "accept this intercepted connection"), ("C", "clear connection list or eventlog"), ("d", "delete flow"), + ("D", "duplicate flow"), ("e", "toggle eventlog"), ("l", "set limit filter pattern"), ("L", "load saved flows"), @@ -101,6 +102,10 @@ class ConnectionItem(common.WWrap): self.flow.kill(self.master) self.state.delete_flow(self.flow) self.master.sync_list_view() + elif key == "D": + f = self.master.duplicate_flow(self.flow) + self.master.currentflow = f + self.master.focus_current() elif key == "l": self.master.prompt("Limit: ", self.state.limit_txt, self.master.set_limit) self.master.sync_list_view() diff --git a/libmproxy/console/connview.py b/libmproxy/console/connview.py index d668bfe2..ed038a11 100644 --- a/libmproxy/console/connview.py +++ b/libmproxy/console/connview.py @@ -10,6 +10,7 @@ def _mkhelp(): ("a", "accept this intercepted connection"), ("b", "save request/response body"), ("d", "delete flow"), + ("D", "duplicate flow"), ("e", "edit request/response"), ("m", "change body display mode"), (None, @@ -463,6 +464,11 @@ class ConnectionView(common.WWrap): f = self.flow f.kill(self.master) self.state.delete_flow(f) + elif key == "D": + f = self.master.duplicate_flow(self.flow) + self.master.view_flow(f) + self.master.currentflow = f + self.master.statusbar.message("Duplicated.") elif key == "e": if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST: self.master.prompt_onekey( diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 81199035..db4cde5e 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -851,6 +851,17 @@ class Flow: self.intercepting = False self._backup = None + def copy(self): + rc = self.request.copy() + f = Flow(rc) + if self.response: + f.response = self.response.copy() + f.response.request = rc + if self.error: + f.error = self.error.copy() + f.error.request = rc + return f + @classmethod def _from_state(klass, state): f = klass(None) @@ -997,6 +1008,9 @@ class State(object): def flow_count(self): return len(self._flow_map) + def index(self, f): + return self._flow_list.index(f) + def active_flow_count(self): c = 0 for i in self._flow_list: @@ -1011,6 +1025,7 @@ class State(object): f = Flow(req) self._flow_list.append(f) self._flow_map[req] = f + assert len(self._flow_list) == len(self._flow_map) if f.match(self._limit): self.view.append(f) return f @@ -1235,17 +1250,27 @@ class FlowMaster(controller.Master): return controller.Master.tick(self, q) + def duplicate_flow(self, f): + return self.load_flow(f.copy()) + + def load_flow(self, f): + """ + Loads a flow, and returns a new flow object. + """ + if f.request: + fr = self.handle_request(f.request) + if f.response: + self.handle_response(f.response) + if f.error: + self.handle_error(f.error) + return fr + def load_flows(self, fr): """ Load flows from a FlowReader object. """ for i in fr.stream(): - if i.request: - self.handle_request(i.request) - if i.response: - self.handle_response(i.response) - if i.error: - self.handle_error(i.error) + self.load_flow(i) def process_new_request(self, f): if self.stickycookie_state: |