revert modify headers parameter order

This commit is contained in:
Martin Plattner 2020-06-30 14:57:46 +02:00
parent 4cffbec291
commit 48dcc6e073
3 changed files with 32 additions and 33 deletions

View File

@ -88,17 +88,16 @@ New headers can be added, and existing headers can be overwritten or removed.
A `modify_headers` expression looks like this: A `modify_headers` expression looks like this:
{{< highlight none >}} {{< highlight none >}}
/name/value[/filter-expression] [/patt]/name/value
{{< / highlight >}} {{< / highlight >}}
Here, **name** and **value** are the header name and the value to set respectively, Here, **patt** is a mitmproxy [filter expression]({{< relref "concepts-filters">}})
e.g., ``/Host/example.org``. An empty **value** removes existing headers with that defines which flows to modify headers on, e.g., only on responses using ``~s``.
**name**, e.g., ``/Host/``. The optional **filter-expression** is a mitmproxy The parameters **name** and **value** are the header name and the value to set
[filter expression]({{< relref "concepts-filters">}}) that defines respectively, e.g., ``/Host/example.org``. An empty **value** removes existing
which flows to modify headers on, e.g., only on responses using ``~s``. headers with **name**, e.g., ``/Host/``. Existing headers are overwritten by
Existing headers are overwritten by default. default. This can be changed using filter-expressions, e.g., ``!~h Host:`` to
This can be changed using filter-expressions, e.g., ``!~h Host:`` to ignore ignore requests and responses with an existing ``Host`` header.
requests and responses with an existing ``Host`` header.
## Proxy Authentication ## Proxy Authentication

View File

@ -7,23 +7,23 @@ from mitmproxy import ctx
def parse_modify_headers(s): def parse_modify_headers(s):
""" """
Returns a (header_name, header_value, flow_filter) tuple. Returns a (flow_filter, header_name, header_value) tuple.
The general form for a modify_headers hook is as follows: The general form for a modify_headers hook is as follows:
/header_name/header_value/flow_filter [/flow_filter]/header_name/header_value
The first character specifies the separator. Example: The first character specifies the separator. Example:
:foo:bar:~q :~q:foo:bar
If only two clauses are specified, the pattern is set to match If only two clauses are specified, the pattern is set to match
universally (i.e. ".*"). Example: universally (i.e. ".*"). Example:
/foo/bar/ /foo/bar
Clauses are parsed from left to right. Extra separators are taken to be Clauses are parsed from left to right. Extra separators are taken to be
part of the final clause. For instance, the flow filter below is part of the final clause. For instance, the replacement clause below is
"foo/bar/": "foo/bar/":
/one/two/foo/bar/ /one/two/foo/bar/
@ -34,12 +34,12 @@ def parse_modify_headers(s):
flow_filter = ".*" flow_filter = ".*"
header_name, header_value = parts header_name, header_value = parts
elif len(parts) == 3: elif len(parts) == 3:
header_name, header_value, flow_filter = parts flow_filter, header_name, header_value = parts
else: else:
raise exceptions.OptionsError( raise exceptions.OptionsError(
"Invalid replacement specifier: %s" % s "Invalid modify_headers specifier: %s" % s
) )
return header_name, header_value, flow_filter return flow_filter, header_name, header_value
class ModifyHeaders: class ModifyHeaders:
@ -50,7 +50,7 @@ class ModifyHeaders:
loader.add_option( loader.add_option(
"modify_headers", typing.Sequence[str], [], "modify_headers", typing.Sequence[str], [],
""" """
Header modify pattern of the form "/header-name/header-value[/flow-filter]", where the Header modify pattern of the form "[/flow-filter]/header-name/header-value", where the
separator can be any character. An empty header-value removes existing header-name headers. separator can be any character. An empty header-value removes existing header-name headers.
""" """
) )
@ -59,20 +59,20 @@ class ModifyHeaders:
if "modify_headers" in updated: if "modify_headers" in updated:
self.lst = [] self.lst = []
for shead in ctx.options.modify_headers: for shead in ctx.options.modify_headers:
header, value, flow_pattern = parse_modify_headers(shead) flow_pattern, header, value = parse_modify_headers(shead)
flow_filter = flowfilter.parse(flow_pattern) flow_filter = flowfilter.parse(flow_pattern)
if not flow_filter: if not flow_filter:
raise exceptions.OptionsError( raise exceptions.OptionsError(
"Invalid modify_headers flow filter %s" % flow_pattern "Invalid modify_headers flow filter %s" % flow_pattern
) )
self.lst.append((header, value, flow_pattern, flow_filter)) self.lst.append((flow_pattern, flow_filter, header, value))
def run(self, f, hdrs): def run(self, f, hdrs):
for header, value, _, flow_filter in self.lst: for _, flow_filter, header, value in self.lst:
if flow_filter(f): if flow_filter(f):
hdrs.pop(header, None) hdrs.pop(header, None)
for header, value, _, flow_filter in self.lst: for _, flow_filter, header, value in self.lst:
if flow_filter(f) and value: if flow_filter(f) and value:
hdrs.add(header, value) hdrs.add(header, value)

View File

@ -13,15 +13,15 @@ class TestModifyHeaders:
x = modifyheaders.parse_modify_headers("/foo/bar/vo/ing/") x = modifyheaders.parse_modify_headers("/foo/bar/vo/ing/")
assert x == ("foo", "bar", "vo/ing/") assert x == ("foo", "bar", "vo/ing/")
x = modifyheaders.parse_modify_headers("/bar/voing") x = modifyheaders.parse_modify_headers("/bar/voing")
assert x == ("bar", "voing", ".*") assert x == (".*", "bar", "voing")
with pytest.raises(Exception, match="Invalid replacement"): with pytest.raises(Exception, match="Invalid modify_headers specifier"):
modifyheaders.parse_modify_headers("/") modifyheaders.parse_modify_headers("/")
def test_configure(self): def test_configure(self):
sh = modifyheaders.ModifyHeaders() sh = modifyheaders.ModifyHeaders()
with taddons.context(sh) as tctx: with taddons.context(sh) as tctx:
with pytest.raises(Exception, match="Invalid modify_headers flow filter"): with pytest.raises(Exception, match="Invalid modify_headers flow filter"):
tctx.configure(sh, modify_headers = ["/one/two/~b"]) tctx.configure(sh, modify_headers = ["/~b/one/two"])
tctx.configure(sh, modify_headers = ["/foo/bar/voing"]) tctx.configure(sh, modify_headers = ["/foo/bar/voing"])
def test_modify_headers(self): def test_modify_headers(self):
@ -30,8 +30,8 @@ class TestModifyHeaders:
tctx.configure( tctx.configure(
sh, sh,
modify_headers = [ modify_headers = [
"/one/two/~q", "/~q/one/two",
"/one/three/~s" "/~s/one/three"
] ]
) )
f = tflow.tflow() f = tflow.tflow()
@ -47,8 +47,8 @@ class TestModifyHeaders:
tctx.configure( tctx.configure(
sh, sh,
modify_headers = [ modify_headers = [
"/one/two/~s", "/~s/one/two",
"/one/three/~s" "/~s/one/three"
] ]
) )
f = tflow.tflow(resp=True) f = tflow.tflow(resp=True)
@ -60,8 +60,8 @@ class TestModifyHeaders:
tctx.configure( tctx.configure(
sh, sh,
modify_headers = [ modify_headers = [
"/one/two/~q", "/~q/one/two",
"/one/three/~q" "/~q/one/three"
] ]
) )
f = tflow.tflow() f = tflow.tflow()
@ -73,8 +73,8 @@ class TestModifyHeaders:
tctx.configure( tctx.configure(
sh, sh,
modify_headers = [ modify_headers = [
"/one//~q", "/~q/one/",
"/one//~s" "/~s/one/"
] ]
) )
f = tflow.tflow() f = tflow.tflow()