From 2f457e041e61328aad6a129ae1494ad7feb432c6 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 12 Mar 2011 14:30:12 +1300 Subject: Unify mitmproxy and mitmdump commandline - Extract common options into cmdline.py - Change mitmproxy keybindings to fit command line Some cmdline options and keybindings aren't in operation yet - just stubs where functionality will be added in the next few commits. --- libmproxy/cmdline.py | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ libmproxy/console.py | 50 +++++++++++++++++------ 2 files changed, 149 insertions(+), 11 deletions(-) create mode 100644 libmproxy/cmdline.py (limited to 'libmproxy') diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py new file mode 100644 index 00000000..789cfaec --- /dev/null +++ b/libmproxy/cmdline.py @@ -0,0 +1,110 @@ +import proxy +import optparse + + +def get_common_options(options): + stickycookie = None + if options.stickycookie_all: + stickycookie = ".*" + elif options.stickycookie_filt: + stickycookie = stickycookie_filt + return dict( + verbosity = options.verbose, + wfile = options.wfile, + request_script = options.request_script, + response_script = options.response_script, + server_replay = options.server_replay, + kill = options.kill, + rheaders = options.rheaders, + client_replay = options.client_replay, + stickycookie = stickycookie, + anticache = options.anticache, + refresh_server_playback = not options.norefresh, + ) + + +def common_options(parser): + parser.add_option( + "-a", + action="store", type = "str", dest="addr", default='', + help = "Address to bind proxy to (defaults to all interfaces)" + ) + parser.add_option( + "-p", + action="store", type = "int", dest="port", default=8080, + help = "Proxy service port." + ) + parser.add_option( + "-q", + action="store_true", dest="quiet", + help="Quiet." + ) + parser.add_option( + "--anticache", + action="store_true", dest="anticache", default=False, + help="Strip out request headers that might cause the server to return 304-not-modified." + ) + parser.add_option( + "--reqscript", + action="store", dest="request_script", default=None, + help="Script to run when a request is recieved." + ) + parser.add_option( + "--respscript", + action="store", dest="response_script", default=None, + help="Script to run when a response is recieved." + ) + parser.add_option( + "-t", + action="store_true", dest="stickycookie_all", default=None, + help="Set sticky cookie for all requests." + ) + parser.add_option( + "-T", + action="store", dest="stickycookie_filt", default=None, metavar="FILTER", + help="Set sticky cookie filter. Matched against requests." + ) + parser.add_option( + "-v", + action="count", dest="verbose", default=1, + help="Increase verbosity. Can be passed multiple times." + ) + parser.add_option( + "-w", + action="store", dest="wfile", default=None, + help="Write flows to file." + ) + group = optparse.OptionGroup(parser, "Client Replay") + group.add_option( + "-c", + action="store", dest="client_replay", default=None, metavar="PATH", + help="Replay client requests from a saved file." + ) + parser.add_option_group(group) + + group = optparse.OptionGroup(parser, "Server Replay") + group.add_option( + "-s", + action="store", dest="server_replay", default=None, metavar="PATH", + help="Replay server responses from a saved file." + ) + group.add_option( + "-k", + action="store_true", dest="kill", default=False, + help="Kill extra requests during replay." + ) + group.add_option( + "--rheader", + action="append", dest="rheaders", type="str", + help="Request headers to be considered during replay. " + "Can be passed multiple times." + ) + group.add_option( + "--norefresh", + action="store_true", dest="norefresh", default=False, + help= "Disable response refresh, " + "which updates times in cookies and headers for replayed responses." + ) + parser.add_option_group(group) + + proxy.certificate_option_group(parser) diff --git a/libmproxy/console.py b/libmproxy/console.py index e9992a0f..f95d028e 100644 --- a/libmproxy/console.py +++ b/libmproxy/console.py @@ -164,7 +164,7 @@ class ConnectionItem(WWrap): elif key == "R": self.state.revert(self.flow) self.master.sync_list_view() - elif key == "s": + elif key == "w": self.master.prompt("Save this flow: ", self.master.save_one_flow, self.flow) elif key == "z": self.master.kill_connection(self.flow) @@ -515,7 +515,7 @@ class ConnectionView(WWrap): elif key == "R": self.state.revert(self.flow) self.master.refresh_connection(self.flow) - elif key == "s": + elif key == "w": self.master.prompt("Save this flow: ", self.master.save_one_flow, self.flow) elif key == "v": if self.state.view_flow_mode == VIEW_FLOW_REQUEST: @@ -526,7 +526,7 @@ class ConnectionView(WWrap): t = conn.headers.get("content-type", [None]) t = t[0] self.master.spawn_external_viewer(conn.content, t) - elif key == "w": + elif key == "b": if self.state.view_flow_mode == VIEW_FLOW_REQUEST: self.master.prompt("Save request body: ", self.save_body) else: @@ -758,6 +758,33 @@ class ConsoleState(flow.State): return ret + +class Options(object): + __slots__ = [ + "anticache", + "beep", + "client_replay", + "keepserving", + "kill", + "intercept", + "limit", + "refresh_server_playback", + "request_script", + "response_script", + "rheaders", + "server_replay", + "stickycookie", + "verbosity", + "wfile", + ] + def __init__(self, **kwargs): + for k, v in kwargs.items(): + setattr(self, k, v) + for i in self.__slots__: + if not hasattr(self, i): + setattr(self, i, None) + + #begin nocover VIEW_CONNLIST = 0 VIEW_FLOW = 1 @@ -798,7 +825,7 @@ class ConsoleMaster(flow.FlowMaster): print >> sys.stderr, "Beep error:", r sys.exit(1) - r = self.set_stickycookie(options.sticky) + r = self.set_stickycookie(options.stickycookie) if r: print >> sys.stderr, "Sticky cookies error:", r sys.exit(1) @@ -987,7 +1014,7 @@ class ConsoleMaster(flow.FlowMaster): ("A", "accept all intercepted connections"), ("a", "accept this intercepted connection"), ("B", "set beep filter pattern"), - ("c", "set sticky cookie expression"), + ("c", "client replay"), ("i", "set interception pattern"), ("j, k", "up, down"), ("l", "set limit filter pattern"), @@ -997,6 +1024,9 @@ class ConsoleMaster(flow.FlowMaster): ("r", "replay request"), ("R", "revert changes to request"), ("S", "save all flows matching current limit"), + ("s", "server replay"), + ("t", "set sticky cookie expression"), + ("w", "save this flow"), ("page up/down", "page up/down"), ("enter", "view connection"), ] @@ -1006,7 +1036,6 @@ class ConsoleMaster(flow.FlowMaster): keys = [ ("C", "clear connection list"), ("d", "delete connection from view"), - ("s", "save this t flow"), ("z", "kill and delete connection, even if it's mid-intercept"), ("space", "page down"), ] @@ -1014,12 +1043,11 @@ class ConsoleMaster(flow.FlowMaster): text.extend([("head", "\n\nConnection view keys:\n")]) keys = [ - ("e", "edit response/request"), + ("b", "save request/response body"), + ("e", "edit request/response"), ("m", "change view mode (raw, indent, hex)"), ("p", "previous flow"), - ("s", "save this flow"), - ("v", "view contents in external viewer"), - ("w", "save request or response body"), + ("v", "view body in external viewer"), ("|", "run script"), ("tab", "toggle response/request view"), ("space", "next flow"), @@ -1237,7 +1265,7 @@ class ConsoleMaster(flow.FlowMaster): self.load_flows ) k = None - elif k == "c": + elif k == "t": self.prompt("Sticky cookie: ", self.set_stickycookie) k = None if k: -- cgit v1.2.3