ignore superfluous newlines after HTTP CONNECT, fix #4870 (#4871)

This commit is contained in:
Maximilian Hils 2021-10-19 13:25:22 +02:00 committed by GitHub
parent 0ad4a5983e
commit 79f464bc78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 3 deletions

View File

@ -592,11 +592,11 @@ class HttpStream(layer.Layer):
)
if 200 <= self.flow.response.status_code < 300:
yield SendHttp(ResponseHeaders(self.stream_id, self.flow.response, True), self.context.client)
yield SendHttp(ResponseEndOfMessage(self.stream_id), self.context.client)
self.child_layer = self.child_layer or layer.NextLayer(self.context)
yield from self.child_layer.handle_event(events.Start())
self._handle_event = self.passthrough
yield SendHttp(ResponseHeaders(self.stream_id, self.flow.response, True), self.context.client)
yield SendHttp(ResponseEndOfMessage(self.stream_id), self.context.client)
else:
yield from self.send_response()

View File

@ -122,7 +122,10 @@ class Http1Connection(HttpConnection, metaclass=abc.ABCMeta):
self.state = self.passthrough
if self.buf:
already_received = self.buf.maybe_extract_at_most(len(self.buf))
yield from self.state(events.DataReceived(self.conn, already_received))
# Some clients send superfluous newlines after CONNECT, we want to eat those.
already_received = already_received.lstrip(b"\r\n")
if already_received:
yield from self.state(events.DataReceived(self.conn, already_received))
def passthrough(self, event: events.Event) -> layer.CommandGenerator[None]:
assert self.stream_id

View File

@ -1324,3 +1324,23 @@ def test_chunked_and_content_length_set_by_addon(tctx):
b"Transfer-Encoding: chunked\r\n\r\n"
b"0\r\n\r\n")
)
def test_connect_more_newlines(tctx):
"""Ignore superfluous \r\n in CONNECT request, https://github.com/mitmproxy/mitmproxy/issues/4870"""
server = Placeholder(Server)
playbook = Playbook(http.HttpLayer(tctx, HTTPMode.regular))
nl = Placeholder(layer.NextLayer)
assert (
playbook
>> DataReceived(tctx.client, b"CONNECT example.com:80 HTTP/1.1\r\n\r\n\r\n")
<< http.HttpConnectHook(Placeholder())
>> reply()
<< OpenConnection(server)
>> reply(None)
<< SendData(tctx.client, b'HTTP/1.1 200 Connection established\r\n\r\n')
>> DataReceived(tctx.client, b"\x16\x03\x03\x00\xb3\x01\x00\x00\xaf\x03\x03")
<< layer.NextLayerHook(nl)
)
assert nl().data_client() == b"\x16\x03\x03\x00\xb3\x01\x00\x00\xaf\x03\x03"