From 78be865eb40f1dc1a761c5f5d82a33a33efff33d Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Thu, 14 Nov 2019 07:13:16 +0100 Subject: [PATCH] Fixed #276 -- Ensured 500 response when app sends malformed headers. (#281) --- daphne/server.py | 7 ++++++- tests/http_base.py | 8 ++++++-- tests/test_http_response.py | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/daphne/server.py b/daphne/server.py index de04b8a..f980989 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -219,7 +219,12 @@ class Server(object): "disconnected", None ): return - self.check_headers_type(message) + try: + self.check_headers_type(message) + except ValueError: + # Ensure to send SOME reply. + protocol.basic_error(500, b"Server Error", "Server Error") + raise # Let the protocol handle it protocol.handle_reply(message) diff --git a/tests/http_base.py b/tests/http_base.py index 71d9618..f3a8340 100644 --- a/tests/http_base.py +++ b/tests/http_base.py @@ -56,12 +56,16 @@ class DaphneTestCase(unittest.TestCase): # Return scope, messages, response return test_app.get_received() + (response,) - def run_daphne_raw(self, data, timeout=1): + def run_daphne_raw(self, data, *, responses=None, timeout=1): """ - Runs daphne and sends it the given raw bytestring over a socket. Returns what it sends back. + Runs Daphne and sends it the given raw bytestring over a socket. + Accepts list of response messages the application will reply with. + Returns what Daphne sends back. """ assert isinstance(data, bytes) with DaphneTestingInstance() as test_app: + if responses is not None: + test_app.add_send_messages(responses) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(timeout) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/tests/test_http_response.py b/tests/test_http_response.py index afb8e39..08c34bb 100644 --- a/tests/test_http_response.py +++ b/tests/test_http_response.py @@ -169,3 +169,21 @@ class TestHTTPResponse(DaphneTestCase): str(context.exception), "Header value 'True' expected to be `bytes`, but got ``", ) + + def test_headers_type_raw(self): + """ + Daphne returns a 500 error response if the application sends invalid + headers. + """ + response = self.run_daphne_raw( + b"GET / HTTP/1.0\r\n\r\n", + responses=[ + { + "type": "http.response.start", + "status": 200, + "headers": [["foo", b"bar"]], + }, + {"type": "http.response.body", "body": b""}, + ], + ) + self.assertTrue(response.startswith(b"HTTP/1.0 500 Internal Server Error"))