diff options
author | Aldo Cortesi <aldo@nullcube.com> | 2013-03-17 17:31:35 +1300 |
---|---|---|
committer | Aldo Cortesi <aldo@nullcube.com> | 2013-03-17 17:37:54 +1300 |
commit | 0e993bec6f7fa77e73a08053f4558ff1fc36d022 (patch) | |
tree | a9f0763cf510028c3cd73128dfd0a48991bfedc3 | |
parent | 790ad468e4352419ef519401680f99ee3beb148d (diff) | |
download | mitmproxy-0e993bec6f7fa77e73a08053f4558ff1fc36d022.tar.gz mitmproxy-0e993bec6f7fa77e73a08053f4558ff1fc36d022.tar.bz2 mitmproxy-0e993bec6f7fa77e73a08053f4558ff1fc36d022.zip |
Add the --host option, which uses the value in the Host header for dispaly URLs.
- Can be toggled with "o" then "h" in mitmproxy
- Useful for transparent mode
-rw-r--r-- | libmproxy/cmdline.py | 6 | ||||
-rw-r--r-- | libmproxy/console/__init__.py | 9 | ||||
-rw-r--r-- | libmproxy/console/common.py | 4 | ||||
-rw-r--r-- | libmproxy/console/flowlist.py | 2 | ||||
-rw-r--r-- | libmproxy/console/flowview.py | 4 | ||||
-rw-r--r-- | libmproxy/console/help.py | 4 | ||||
-rw-r--r-- | libmproxy/flow.py | 12 | ||||
-rw-r--r-- | test/test_console_common.py | 10 | ||||
-rw-r--r-- | test/test_flow.py | 13 |
9 files changed, 56 insertions, 8 deletions
diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py index de70bea8..1d5902a9 100644 --- a/libmproxy/cmdline.py +++ b/libmproxy/cmdline.py @@ -154,6 +154,7 @@ def get_common_options(options): script = options.script, stickycookie = stickycookie, stickyauth = stickyauth, + showhost = options.showhost, wfile = options.wfile, verbosity = options.verbose, nopop = options.nopop, @@ -248,6 +249,11 @@ def common_options(parser): help="Byte size limit of HTTP request and response bodies."\ " Understands k/m/g suffixes, i.e. 3m for 3 megabytes." ) + parser.add_argument( + "--host", + action="store_true", dest="showhost", default=False, + help="Use the Host header to construct URLs for display." + ) parser.add_argument( "--no-upstream-cert", default=False, diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py index 98904c84..fe75a047 100644 --- a/libmproxy/console/__init__.py +++ b/libmproxy/console/__init__.py @@ -174,6 +174,8 @@ class StatusBar(common.WWrap): opts.append("anticache") if self.master.anticomp: opts.append("anticomp") + if self.master.showhost: + opts.append("showhost") if not self.master.refresh_server_playback: opts.append("norefresh") if self.master.killextra: @@ -338,6 +340,7 @@ class Options(object): "refresh_server_playback", "rfile", "script", + "showhost", "replacements", "rheaders", "setheaders", @@ -398,6 +401,7 @@ class ConsoleMaster(flow.FlowMaster): self.killextra = options.kill self.rheaders = options.rheaders self.nopop = options.nopop + self.showhost = options.showhost self.eventlog = options.eventlog self.eventlist = urwid.SimpleListWalker([]) @@ -918,6 +922,7 @@ class ConsoleMaster(flow.FlowMaster): ( ("anticache", "a"), ("anticomp", "c"), + ("showhost", "h"), ("killextra", "k"), ("norefresh", "n"), ("no-upstream-certs", "u"), @@ -957,6 +962,10 @@ class ConsoleMaster(flow.FlowMaster): self.anticache = not self.anticache if a == "c": self.anticomp = not self.anticomp + if a == "h": + self.showhost = not self.showhost + self.sync_list_view() + self.refresh_flow(self.currentflow) elif a == "k": self.killextra = not self.killextra elif a == "n": diff --git a/libmproxy/console/common.py b/libmproxy/console/common.py index 1cc0b5b9..d68aba3d 100644 --- a/libmproxy/console/common.py +++ b/libmproxy/console/common.py @@ -177,7 +177,7 @@ class FlowCache: flowcache = FlowCache() -def format_flow(f, focus, extended=False, padding=2): +def format_flow(f, focus, extended=False, hostheader=False, padding=2): d = dict( intercepting = f.intercepting, @@ -185,7 +185,7 @@ def format_flow(f, focus, extended=False, padding=2): req_is_replay = f.request.is_replay(), req_method = f.request.method, req_acked = f.request.reply.acked, - req_url = f.request.get_url(), + req_url = f.request.get_url(hostheader=hostheader), err_msg = f.error.msg if f.error else None, resp_code = f.response.code if f.response else None, diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index c70393a1..8fd4efce 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -105,7 +105,7 @@ class ConnectionItem(common.WWrap): common.WWrap.__init__(self, w) def get_text(self): - return common.format_flow(self.flow, self.f) + return common.format_flow(self.flow, self.f, hostheader=self.master.showhost) def selectable(self): return True diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py index 4215f170..9bec7bc6 100644 --- a/libmproxy/console/flowview.py +++ b/libmproxy/console/flowview.py @@ -88,11 +88,11 @@ footer = [ class FlowViewHeader(common.WWrap): def __init__(self, master, f): self.master, self.flow = master, f - self.w = common.format_flow(f, False, extended=True, padding=0) + self.w = common.format_flow(f, False, extended=True, padding=0, hostheader=self.master.showhost) def refresh_flow(self, f): if f == self.flow: - self.w = common.format_flow(f, False, extended=True, padding=0) + self.w = common.format_flow(f, False, extended=True, padding=0, hostheader=self.master.showhost) class CallbackCache: diff --git a/libmproxy/console/help.py b/libmproxy/console/help.py index 178b36f7..40f81955 100644 --- a/libmproxy/console/help.py +++ b/libmproxy/console/help.py @@ -98,6 +98,10 @@ class HelpView(urwid.ListBox): [("text", ": prevent compressed responses")] ), (None, + common.highlight_key("showhost", "h") + + [("text", ": use Host header for URL display")] + ), + (None, common.highlight_key("killextra", "k") + [("text", ": kill requests not part of server replay")] ), diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 13b32011..380eb026 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -459,11 +459,19 @@ class Request(HTTPMsg): query = utils.urlencode(odict.lst) self.set_url(urlparse.urlunparse([scheme, netloc, path, params, query, fragment])) - def get_url(self): + def get_url(self, hostheader=False): """ Returns a URL string, constructed from the Request's URL compnents. + + If hostheader is True, we use the value specified in the request + Host header to construct the URL. """ - return utils.unparse_url(self.scheme, self.host.encode("idna"), self.port, self.path).encode('ascii') + if hostheader: + host = self.headers.get_first("host") or self.host + else: + host = self.host + host = host.encode("idna") + return utils.unparse_url(self.scheme, host, self.port, self.path).encode('ascii') def set_url(self, url): """ diff --git a/test/test_console_common.py b/test/test_console_common.py new file mode 100644 index 00000000..29bf7b84 --- /dev/null +++ b/test/test_console_common.py @@ -0,0 +1,10 @@ +import libmproxy.console.common as common +from libmproxy import utils, flow, encoding +import tutils + + +def test_format_flow(): + f = tutils.tflow_full() + assert common.format_flow(f, True) + assert common.format_flow(f, True, hostheader=True) + assert common.format_flow(f, True, extended=True) diff --git a/test/test_flow.py b/test/test_flow.py index c1ae1a9f..fce4e98a 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -497,7 +497,7 @@ class TestSerialize: fm = flow.FlowMaster(None, s) fm.load_flows(r) assert len(s._flow_list) == 6 - + def test_filter(self): sio = StringIO() fl = filt.parse("~c 200") @@ -783,6 +783,17 @@ class TestRequest: r.content = flow.CONTENT_MISSING assert not r._assemble() + def test_get_url(self): + h = flow.ODictCaseless() + h["test"] = ["test"] + c = flow.ClientConnect(("addr", 2222)) + r = flow.Request(c, (1, 1), "host", 22, "https", "GET", "/", h, "content") + assert r.get_url() == "https://host:22/" + assert r.get_url(hostheader=True) == "https://host:22/" + r.headers["Host"] = ["foo.com"] + assert r.get_url() == "https://host:22/" + assert r.get_url(hostheader=True) == "https://foo.com:22/" + def test_path_components(self): h = flow.ODictCaseless() c = flow.ClientConnect(("addr", 2222)) |