Repository: mitmproxy/mitmproxy

Issue:
removing ":authority" pseudo header, then executing request crashes mitmproxy
##### Steps to reproduce the problem:

1. Run mitmproxy
2. Visit some http2 website, e.g. google.com
3. Edit the request (enter + e + 7) and remove the :authority header (d + q).
4. Replay the request (r).
5. mitmproxy crashes

Stacktrace:
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/mitmproxy/master.py", line 86, in run_loop
    loop()oding:            gzip, deflate, br
  File "/usr/lib/python3.7/site-packages/urwid/main_loop.py", line 286, in run
    self._run()e-requests:  1
  File "/usr/lib/python3.7/site-packages/urwid/main_loop.py", line 384, in _run
    self.event_loop.run() tab to view                                           [m:auto]
  File "/usr/lib/python3.7/site-packages/urwid/main_loop.py", line 1484, in run
    reraise(*exc_info)
  File "/usr/lib/python3.7/site-packages/urwid/compat.py", line 58, in reraise
    raise value
  File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/lib/python3.7/site-packages/urwid/raw_display.py", line 404, in <lambda>
    event_loop, callback, self.get_available_raw_input())
  File "/usr/lib/python3.7/site-packages/urwid/raw_display.py", line 502, in parse_input
    callback(processed, processed_codes)
  File "/usr/lib/python3.7/site-packages/urwid/main_loop.py", line 411, in _update
    self.process_input(keys)
  File "/usr/lib/python3.7/site-packages/urwid/main_loop.py", line 511, in process_input
    k = self._topmost_widget.keypress(self.screen_size, k)
  File "/usr/lib/python3.7/site-packages/mitmproxy/tools/console/window.py", line 313, in keypress
    k
  File "/usr/lib/python3.7/site-packages/mitmproxy/tools/console/keymap.py", line 143, in handle
    return self.executor(b.command)
  File "/usr/lib/python3.7/site-packages/mitmproxy/tools/console/commandexecutor.py", line 17, in __call__
    ret = self.master.commands.execute(cmd)
  File "/usr/lib/python3.7/site-packages/mitmproxy/command.py", line 245, in execute
    return self.call_strings(parts[0], parts[1:])
  File "/usr/lib/python3.7/site-packages/mitmproxy/command.py", line 233, in call_strings
    return self.commands[path].call(args)
  File "/usr/lib/python3.7/site-packages/mitmproxy/command.py", line 105, in call
    ret = self.func(*self.prepare_args(args))
  File "/usr/lib/python3.7/site-packages/mitmproxy/command.py", line 275, in wrapper
    return function(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/mitmproxy/addons/clientplayback.py", line 204, in start_replay
    host = hf.request.headers.pop(":authority")
  File "/usr/lib/python3.7/_collections_abc.py", line 795, in pop
    value = self[key]
  File "/usr/lib/python3.7/site-packages/mitmproxy/coretypes/multidict.py", line 39, in __getitem__
    raise KeyError(key)
KeyError: ':authority'

mitmproxy has crashed!
Please lodge a bug report at:
	https://github.com/mitmproxy/mitmproxy


##### System information

Mitmproxy: 4.0.4
Python:    3.7.3
OpenSSL:   OpenSSL 1.1.1c  28 May 2019
Platform:  Linux-5.1.6-arch1-1-ARCH-x86_64-with-arch


Discussion:

Resolving patch:
diff --git a/mitmproxy/addons/clientplayback.py b/mitmproxy/addons/clientplayback.py
--- a/mitmproxy/addons/clientplayback.py
+++ b/mitmproxy/addons/clientplayback.py
@@ -203,8 +203,9 @@ def start_replay(self, flows: typing.Sequence[flow.Flow]) -> None:
             # https://github.com/mitmproxy/mitmproxy/issues/2197
             if hf.request.http_version == "HTTP/2.0":
                 hf.request.http_version = "HTTP/1.1"
-                host = hf.request.headers.pop(":authority")
-                hf.request.headers.insert(0, "host", host)
+                host = hf.request.headers.pop(":authority", None)
+                if host is not None:
+                    hf.request.headers.insert(0, "host", host)
             self.q.put(hf)
         ctx.master.addons.trigger("update", lst)
 


Test patch: