[sans-io] include non-standard ports in host header, refs #4280

This commit is contained in:
Maximilian Hils 2020-12-10 09:22:38 +01:00
parent 8ae2ab2aca
commit 52479e94bb
3 changed files with 43 additions and 2 deletions

View File

@ -79,7 +79,15 @@ class Proxyserver:
"Determine when server connections should be established.", "Determine when server connections should be established.",
choices=("eager", "lazy") choices=("eager", "lazy")
) )
# Hack: Update allowed events to include new ones. # FIXME: repeated option
loader.add_option(
"keep_host_header", bool, False,
"""
Reverse Proxy: Keep the original host header instead of rewriting it
to the reverse proxy target.
"""
)
# FIXME: Update allowed events to include new ones.
eventsequence.Events = frozenset( eventsequence.Events = frozenset(
eventsequence.Events | set(commands.all_hooks.keys()) eventsequence.Events | set(commands.all_hooks.keys())
) )

View File

@ -180,7 +180,11 @@ class HttpStream(layer.Layer):
# update host header in reverse proxy mode # update host header in reverse proxy mode
if self.context.options.mode.startswith("reverse:") and not self.context.options.keep_host_header: if self.context.options.mode.startswith("reverse:") and not self.context.options.keep_host_header:
self.flow.request.host_header = self.context.server.address[0] self.flow.request.host_header = url.hostport(
"https" if self.context.server.tls else "http",
self.context.server.address[0],
self.context.server.address[1],
)
yield HttpRequestHeadersHook(self.flow) yield HttpRequestHeadersHook(self.flow)
if (yield from self.check_killed(True)): if (yield from self.check_killed(True)):

View File

@ -1,5 +1,7 @@
import copy import copy
import pytest
from mitmproxy.http import HTTPFlow from mitmproxy.http import HTTPFlow
from mitmproxy.proxy.protocol.http import HTTPMode from mitmproxy.proxy.protocol.http import HTTPMode
from mitmproxy.proxy2.commands import CloseConnection, OpenConnection, SendData from mitmproxy.proxy2.commands import CloseConnection, OpenConnection, SendData
@ -102,3 +104,30 @@ def test_upstream_https(tctx):
<< SendData(upstream, h2_server_settings_ack) << SendData(upstream, h2_server_settings_ack)
<< SendData(tctx1.client, b"HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n") << SendData(tctx1.client, b"HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n")
) )
@pytest.mark.parametrize("keep_host_header", [True, False])
def test_reverse_proxy(tctx, keep_host_header):
"""Test mitmproxy in reverse proxy mode.
- make sure that we connect to the right host
- make sure that we respect keep_host_header
- make sure that we include non-standard ports in the host header (#4280)
"""
server = Placeholder(Server)
tctx.options.mode = "reverse:http://localhost:8000"
tctx.options.keep_host_header = keep_host_header
assert (
Playbook(modes.ReverseProxy(tctx), hooks=False)
>> DataReceived(tctx.client, b"GET /foo HTTP/1.1\r\n"
b"Host: example.com\r\n\r\n")
<< NextLayerHook(Placeholder(NextLayer))
>> reply_next_layer(lambda ctx: http.HttpLayer(ctx, HTTPMode.transparent))
<< OpenConnection(server)
>> reply(None)
<< SendData(server, b"GET /foo HTTP/1.1\r\n"
b"Host: " + (b"example.com" if keep_host_header else b"localhost:8000") + b"\r\n\r\n")
>> DataReceived(server, b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n")
<< SendData(tctx.client, b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n")
)
assert server().address == ("localhost", 8000)