From 1fb6f2b26bab030797da3500db49a477f69ba30d Mon Sep 17 00:00:00 2001 From: Aviv Cohn Date: Mon, 25 Apr 2016 14:57:06 +0300 Subject: [PATCH] Raising error in HTTP11Response if created with illegal attributes An HTTP response must either specify a content-length header, specify 'close' for a connection header to signal that the connection will be closed after the response, or be a chunked response. If none of these conditions are true, we raise a detailed ValueError, instead of the plain assertion. --- hyper/http11/response.py | 13 ++++++++----- test/test_http11.py | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/hyper/http11/response.py b/hyper/http11/response.py index ee23be08..b86baee8 100644 --- a/hyper/http11/response.py +++ b/hyper/http11/response.py @@ -58,11 +58,14 @@ def __init__(self, code, reason, headers, sock, connection=None): b'chunked' in self.headers.get(b'transfer-encoding', []) ) - # One of the following must be true: we must expect that the connection - # will be closed following the body, or that a content-length was sent, - # or that we're getting a chunked response. - # FIXME: Remove naked assert, replace with something better. - assert self._expect_close or self._length is not None or self._chunked + if not self._expect_close \ + and not self._chunked \ + and self._length is None: + raise ValueError('A response must either specify a ' + 'content-length, be a chunked ' + 'response, or specify that the ' + 'connection be closed after the response. ' + 'None of these conditions were met.') # This object is used for decompressing gzipped request bodies. Right # now we only support gzip because that's all the RFC mandates of us. diff --git a/test/test_http11.py b/test/test_http11.py index 37eb5c2e..04a42548 100644 --- a/test/test_http11.py +++ b/test/test_http11.py @@ -837,6 +837,18 @@ def test_closing_chunked_reads_dont_call_close_callback(self): assert r._sock is None assert connection.close.call_count == 1 + def test_regular_response_with_missing_headers_raises_error(self): + headers = {} + sock = DummySocket() + connection = mock.MagicMock() + + with pytest.raises(ValueError) as exc_info: + HTTP11Response(200, 'OK', headers, sock, connection) + assert 'A response must either specify a content-length, ' \ + 'be a chunked response, or specify that the ' \ + 'connection be closed after the response. ' \ + in str(exc_info) + class DummySocket(object): def __init__(self):