Skip to content

Commit

Permalink
Unify mitmproxy and mitmdump commandline
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
cortesi committed Mar 12, 2011
1 parent 9927eba commit 2f457e0
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 140 deletions.
110 changes: 110 additions & 0 deletions 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)
50 changes: 39 additions & 11 deletions libmproxy/console.py
Expand Up @@ -164,7 +164,7 @@ def keypress(self, (maxcol,), key):
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)
Expand Down Expand Up @@ -515,7 +515,7 @@ def keypress(self, size, key):
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:
Expand All @@ -526,7 +526,7 @@ def keypress(self, size, key):
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:
Expand Down Expand Up @@ -758,6 +758,33 @@ def delete_flow(self, f):
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
Expand Down Expand Up @@ -798,7 +825,7 @@ def __init__(self, server, options):
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)
Expand Down Expand Up @@ -987,7 +1014,7 @@ def helptext(self):
("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"),
Expand All @@ -997,6 +1024,9 @@ def helptext(self):
("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"),
]
Expand All @@ -1006,20 +1036,18 @@ def helptext(self):
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"),
]
text.extend(format_keyvals(keys, key="key", val="text", indent=4))

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"),
Expand Down Expand Up @@ -1237,7 +1265,7 @@ def loop(self):
self.load_flows
)
k = None
elif k == "c":
elif k == "t":
self.prompt("Sticky cookie: ", self.set_stickycookie)
k = None
if k:
Expand Down
114 changes: 6 additions & 108 deletions mitmdump
Expand Up @@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import sys, os.path
from libmproxy import proxy, dump, utils
from libmproxy import proxy, dump, utils, cmdline
from libmproxy.version import VERSION
from optparse import OptionParser, OptionGroup

Expand All @@ -26,130 +26,28 @@ if __name__ == '__main__':
usage = "%prog [options] [filter]",
version="%%prog %s"%VERSION,
)
parser.add_option(
"-a",
action="store", type = "str", dest="addr", default='',
help = "Address to bind proxy to (defaults to all interfaces)"
)
parser.add_option(
"-i",
action="store_true", dest="stickycookie_all", default=None,
help="Set sticky cookie for all requests."
)
parser.add_option(
"-I",
action="store", dest="stickycookie_filt", default=None, metavar="FILTER",
help="Set sticky cookie filter. Matched against requests."
)
cmdline.common_options(parser)
parser.add_option(
"--keepserving",
action="store_true", dest="keepserving", default=False,
help="Continue serving after playback."
)
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."
help="Continue serving after playback. We exit by default."
)
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 = 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 = 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)


options, args = parser.parse_args()

if options.quiet:
options.verbose = 0

stickycookie = None
if options.stickycookie_all:
stickycookie = ".*"
elif options.stickycookie_filt:
stickycookie = stickycookie_filt

config = proxy.process_certificate_option_group(parser, options)
try:
server = proxy.ProxyServer(config, options.port, options.addr)
except proxy.ProxyServerError, v:
print >> sys.stderr, "mitmdump:", v.args[0]
sys.exit(1)

dumpopts = dump.Options(
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,
keepserving = options.keepserving,
stickycookie = stickycookie,
anticache = options.anticache,
refresh_server_playback = not options.norefresh,
)
dumpopts = dump.Options(**cmdline.get_common_options(options))
dumpopts.keepserving = options.keepserving

if args:
filt = " ".join(args)
else:
Expand Down

0 comments on commit 2f457e0

Please sign in to comment.