diff options
author | Maximilian Hils <git@maximilianhils.com> | 2014-08-08 17:49:02 +0200 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2014-08-08 17:49:02 +0200 |
commit | 4d2109ef92d59e48c08279e3b59b7cc8385e02df (patch) | |
tree | 073435551d0340f85e19384056b5f5acd2909146 | |
parent | de05484d9d08a4bc40c17c673b18bc2e0f910fff (diff) | |
download | mitmproxy-4d2109ef92d59e48c08279e3b59b7cc8385e02df.tar.gz mitmproxy-4d2109ef92d59e48c08279e3b59b7cc8385e02df.tar.bz2 mitmproxy-4d2109ef92d59e48c08279e3b59b7cc8385e02df.zip |
fix display of urls in upstream mode, refs #308
-rw-r--r-- | libmproxy/protocol/http.py | 17 | ||||
-rw-r--r-- | libmproxy/proxy/connection.py | 2 | ||||
-rw-r--r-- | test/test_protocol_http.py | 6 | ||||
-rw-r--r-- | test/tutils.py | 2 |
4 files changed, 24 insertions, 3 deletions
diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index e4f994c9..7c4d9cbb 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -461,7 +461,12 @@ class HTTPRequest(HTTPMessage): if self.host: host = self.host else: - host = self.flow.server_conn.address.host + for s in self.flow.server_conn.state: + if s[0] == "http" and s[1].get("state") == "connect": + host = s[1]["host"] + break + if not host: + host = self.flow.server_conn.address.host host = host.encode("idna") return host @@ -479,6 +484,9 @@ class HTTPRequest(HTTPMessage): """ if self.port: return self.port + for s in self.flow.server_conn.state: + if s[0] == "http" and s[1].get("state") == "connect": + return s[1]["port"] return self.flow.server_conn.address.port def get_url(self, hostheader=False): @@ -974,11 +982,16 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin): return False if flow.request.form_in == "authority" and flow.response.code == 200: - self.ssl_upgrade() # TODO: Eventually add headers (space/usefulness tradeoff) + # Make sure to add state info before the actual upgrade happens. + # During the upgrade, we may receive an SNI indication from the client, + # which resets the upstream connection. If this is the case, we must + # already re-issue the CONNECT request at this point. self.c.server_conn.state.append(("http", {"state": "connect", "host": flow.request.host, "port": flow.request.port})) + self.ssl_upgrade() + # If the user has changed the target server on this connection, # restore the original target server diff --git a/libmproxy/proxy/connection.py b/libmproxy/proxy/connection.py index 38436233..a19e3e71 100644 --- a/libmproxy/proxy/connection.py +++ b/libmproxy/proxy/connection.py @@ -138,7 +138,7 @@ class ServerConnection(tcp.TCPClient, stateobject.SimpleStateObject): self.convert_to_ssl(cert=clientcert, sni=sni) self.timestamp_ssl_setup = utils.timestamp() except tcp.NetLibError, v: - raise ProxyError(400, str(v)) + raise ProxyError(400, repr(v)) def finish(self): tcp.TCPClient.finish(self) diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index 451b7b5d..3b922c06 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -141,6 +141,12 @@ class TestProxyChainingSSL(tservers.HTTPChainProxyTest): finally: self.chain[0].tmaster.handle_request = _handle_request + def test_sni(self): + p = self.pathoc(sni="foo.com") + req = p.request("get:'/p/418:b\"content\"'") + assert req.content == "content" + assert req.status_code == 418 + class TestProxyChainingSSLReconnect(tservers.HTTPChainProxyTest): ssl = True diff --git a/test/tutils.py b/test/tutils.py index c527a64a..dc049adb 100644 --- a/test/tutils.py +++ b/test/tutils.py @@ -33,6 +33,7 @@ def tclient_conn(): def tserver_conn(): c = ServerConnection._from_state(dict( address=dict(address=("address", 22), use_ipv6=True), + state=[], source_address=dict(address=("address", 22), use_ipv6=True), cert=None )) @@ -72,6 +73,7 @@ def tresp(req=None, content="message"): cert = certutils.SSLCert.from_der(file(test_data.path("data/dercert"), "rb").read()) f.server_conn = ServerConnection._from_state(dict( address=dict(address=("address", 22), use_ipv6=True), + state=[], source_address=None, cert=cert.to_pem())) f.response = http.HTTPResponse((1, 1), 200, "OK", headers, content, time(), time()) |