[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.",
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 | set(commands.all_hooks.keys())
)

View File

@ -180,7 +180,11 @@ class HttpStream(layer.Layer):
# update host header in reverse proxy mode
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)
if (yield from self.check_killed(True)):

View File

@ -1,5 +1,7 @@
import copy
import pytest
from mitmproxy.http import HTTPFlow
from mitmproxy.proxy.protocol.http import HTTPMode
from mitmproxy.proxy2.commands import CloseConnection, OpenConnection, SendData
@ -102,3 +104,30 @@ def test_upstream_https(tctx):
<< SendData(upstream, h2_server_settings_ack)
<< 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)