diff --git a/mitmproxy/proxy/protocol/http.py b/mitmproxy/proxy/protocol/http.py index 5f9dafab6..ac410eebd 100644 --- a/mitmproxy/proxy/protocol/http.py +++ b/mitmproxy/proxy/protocol/http.py @@ -268,6 +268,11 @@ class HttpLayer(base.Layer): self.log("request", "debug", [repr(request)]) + # set first line format to relative in regular mode, + # see https://github.com/mitmproxy/mitmproxy/issues/1759 + if self.mode is HTTPMode.regular and request.first_line_format == "absolute": + request.first_line_format = "relative" + # update host header in reverse proxy mode if self.config.options.mode == "reverse": f.request.headers["Host"] = self.config.upstream_server.address.host diff --git a/pathod/pathod.py b/pathod/pathod.py index a8658361d..8d57897b7 100644 --- a/pathod/pathod.py +++ b/pathod/pathod.py @@ -144,6 +144,7 @@ class PathodHandler(tcp.BaseHandler): path = req.path http_version = req.http_version headers = req.headers + first_line_format = req.first_line_format clientcert = None if self.clientcert: @@ -167,6 +168,7 @@ class PathodHandler(tcp.BaseHandler): sni=self.sni, remote_address=self.address(), clientcert=clientcert, + first_line_format=first_line_format ), cipher=None, ) diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py index 9429ab0fa..a7d8cea50 100644 --- a/test/mitmproxy/test_server.py +++ b/test/mitmproxy/test_server.py @@ -282,6 +282,21 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin): assert d.content == b"bar" self.master.addons.remove(s) + def test_first_line_rewrite(self): + """ + If mitmproxy is a regular HTTP proxy, it must rewrite an absolute-form request like + GET http://example.com/foo HTTP/1.0 + to + GET /foo HTTP/1.0 + when sending the request upstream. While any server should technically accept + the absolute form, this is not the case in practice. + """ + req = "get:'%s/p/200'" % self.server.urlbase + p = self.pathoc() + with p.connect(): + assert p.request(req).status_code == 200 + assert self.server.last_log()["request"]["first_line_format"] == "relative" + class TestHTTPAuth(tservers.HTTPProxyTest): def test_auth(self):