add addon to update the ports in alt-svc header in reverse mode (#7093)

* Add addon to update the ports in alt-svc header to the port that we're listening on

* [autofix.ci] apply automated fixes

* Add suggested changes

* Add tests

* [autofix.ci] apply automated fixes

* mypy

* style

* [autofix.ci] apply automated fixes

* Add CHANGELOG entry

* [autofix.ci] apply automated fixes

* nits

* [autofix.ci] apply automated fixes

* nit: improve option wording

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Hils <git@maximilianhils.com>
This commit is contained in:
Gaurav Jain 2024-08-17 21:50:31 +05:30 committed by GitHub
parent be4ba1153c
commit 6bb536e0ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 83 additions and 0 deletions

View file

@ -17,6 +17,8 @@
([#7067](https://github.com/mitmproxy/mitmproxy/pull/7067), @errorxyz)
- mitmproxy now officially supports Python 3.13.
([#6934](https://github.com/mitmproxy/mitmproxy/pull/6934), @mhils)
- Addon to update the hosts in alt-svc header in reverse mode
([#7093](https://github.com/mitmproxy/mitmproxy/pull/7093), @errorxyz)
## 02 August 2024: mitmproxy 10.4.2

View file

@ -27,6 +27,7 @@ from mitmproxy.addons import stickyauth
from mitmproxy.addons import stickycookie
from mitmproxy.addons import strip_ech
from mitmproxy.addons import tlsconfig
from mitmproxy.addons import update_alt_svc
from mitmproxy.addons import upstream_auth
@ -62,4 +63,5 @@ def default_addons():
savehar.SaveHar(),
tlsconfig.TlsConfig(),
upstream_auth.UpstreamAuth(),
update_alt_svc.UpdateAltSvc(),
]

View file

@ -0,0 +1,33 @@
import re
from mitmproxy import ctx
from mitmproxy.http import HTTPFlow
from mitmproxy.proxy import mode_specs
ALT_SVC = "alt-svc"
HOST_PATTERN = r"([a-zA-Z0-9.-]*:\d{1,5})"
def update_alt_svc_header(header: str, port: int) -> str:
return re.sub(HOST_PATTERN, f":{port}", header)
class UpdateAltSvc:
def load(self, loader):
loader.add_option(
"keep_alt_svc_header",
bool,
False,
"Reverse Proxy: Keep Alt-Svc headers as-is, even if they do not point to mitmproxy. Enabling this option may cause clients to bypass the proxy.",
)
def responseheaders(self, flow: HTTPFlow):
assert flow.response
if (
not ctx.options.keep_alt_svc_header
and isinstance(flow.client_conn.proxy_mode, mode_specs.ReverseMode)
and ALT_SVC in flow.response.headers
):
_, listen_port, *_ = flow.client_conn.sockname
headers = flow.response.headers
headers[ALT_SVC] = update_alt_svc_header(headers[ALT_SVC], listen_port)

View file

@ -0,0 +1,44 @@
from mitmproxy import http
from mitmproxy.addons import update_alt_svc
from mitmproxy.proxy.mode_specs import ProxyMode
from mitmproxy.test import taddons
from mitmproxy.test import tflow
def test_simple():
header = 'h3="example.com:443"; ma=3600, h2=":443"; ma=3600'
modified = update_alt_svc.update_alt_svc_header(header, 1234)
assert modified == 'h3=":1234"; ma=3600, h2=":1234"; ma=3600'
def test_updates_alt_svc_header():
upd = update_alt_svc.UpdateAltSvc()
with taddons.context(upd) as ctx:
headers = http.Headers(
host="example.com",
content_type="application/xml",
alt_svc='h3="example.com:443"; ma=3600, h2=":443"; ma=3600',
)
resp = tflow.tresp(headers=headers)
f = tflow.tflow(resp=resp)
f.client_conn.sockname = ("", 1234)
upd.responseheaders(f)
assert (
f.response.headers["alt-svc"]
== 'h3="example.com:443"; ma=3600, h2=":443"; ma=3600'
)
ctx.options.keep_alt_svc_header = True
f.client_conn.proxy_mode = ProxyMode.parse("reverse:https://example.com")
upd.responseheaders(f)
assert (
f.response.headers["alt-svc"]
== 'h3="example.com:443"; ma=3600, h2=":443"; ma=3600'
)
ctx.options.keep_alt_svc_header = False
upd.responseheaders(f)
assert (
f.response.headers["alt-svc"] == 'h3=":1234"; ma=3600, h2=":1234"; ma=3600'
)

View file

@ -33,6 +33,7 @@ export interface OptionsState {
ignore_hosts: string[];
intercept: string | undefined;
intercept_active: boolean;
keep_alt_svc_header: boolean;
keep_host_header: boolean;
key_size: number;
listen_host: string;
@ -134,6 +135,7 @@ export const defaultState: OptionsState = {
ignore_hosts: [],
intercept: undefined,
intercept_active: false,
keep_alt_svc_header: false,
keep_host_header: false,
key_size: 2048,
listen_host: "",