diff --git a/daphne/cli.py b/daphne/cli.py index 1c51940..53e9053 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -12,6 +12,7 @@ logger = logging.getLogger(__name__) DEFAULT_HOST = "127.0.0.1" DEFAULT_PORT = 8000 + class CommandLineInterface(object): """ Acts as the main CLI entry point for running the server. diff --git a/daphne/endpoints.py b/daphne/endpoints.py index aae44fe..3ac837d 100644 --- a/daphne/endpoints.py +++ b/daphne/endpoints.py @@ -1,9 +1,11 @@ + + def build_endpoint_description_strings( host=None, port=None, unix_socket=None, file_descriptor=None - ): +): """ Build a list of twisted endpoint description strings that the server will listen on. This is to streamline the generation of twisted endpoint description strings from easier diff --git a/daphne/http_protocol.py b/daphne/http_protocol.py index 078cfea..7a1a7fc 100755 --- a/daphne/http_protocol.py +++ b/daphne/http_protocol.py @@ -1,20 +1,16 @@ import logging -import random -import string import time import traceback import six -from twisted.internet.defer import ensureDeferred from twisted.internet.interfaces import IProtocolNegotiationFactory from twisted.protocols.policies import ProtocolWrapper from twisted.web import http from zope.interface import implementer -from six.moves.urllib_parse import unquote, unquote_plus +from six.moves.urllib_parse import unquote from .utils import parse_x_forwarded_for -from .ws_protocol import WebSocketFactory, WebSocketProtocol logger = logging.getLogger(__name__) @@ -138,7 +134,7 @@ class WebRequest(http.Request): continue for value in values: if name.lower() == b"daphne-root-path": - self.root_path = self.unquote(value) + self.root_path = unquote(value.decode("ascii")) else: self.clean_headers.append((name.lower(), value)) logger.debug("HTTP %s request for %s", self.method, self.client_addr) @@ -149,7 +145,7 @@ class WebRequest(http.Request): # TODO: Correctly say if it's 1.1 or 1.0 "http_version": self.clientproto.split(b"/")[-1].decode("ascii"), "method": self.method.decode("ascii"), - "path": self.unquote(self.path), + "path": unquote(self.path.decode("ascii")), "root_path": self.root_path, "scheme": "https" if self.isSecure() else "http", "query_string": self.query_string, @@ -213,9 +209,9 @@ class WebRequest(http.Request): logger.debug("HTTP %s response started for %s", message["status"], self.client_addr) elif message["type"] == "http.response.content": if not self._response_started: - raise ValueError("HTTP response has not yet been started but got %s" % message["type"])# Write out body + raise ValueError("HTTP response has not yet been started but got %s" % message["type"]) + # Write out body http.Request.write(self, message.get("content", b"")) - # End if there's no more content if not message.get("more_content", False): self.finish() @@ -252,22 +248,6 @@ class WebRequest(http.Request): ### Utility functions - @classmethod - def unquote(cls, value, plus_as_space=False): - """ - Python 2 and 3 compat layer for utf-8 unquoting - """ - if six.PY2: - if plus_as_space: - return unquote_plus(value).decode("utf8") - else: - return unquote(value).decode("utf8") - else: - if plus_as_space: - return unquote_plus(value.decode("ascii")) - else: - return unquote(value.decode("ascii")) - def send_disconnect(self): """ Sends a http.disconnect message. diff --git a/daphne/server.py b/daphne/server.py index 7f443c7..22629c6 100755 --- a/daphne/server.py +++ b/daphne/server.py @@ -3,12 +3,8 @@ from twisted.internet import asyncioreactor # isort:skip asyncioreactor.install() # isort:skip import asyncio -import collections import logging -import random -import string import traceback -import warnings from twisted.internet import defer, reactor from twisted.internet.endpoints import serverFromString diff --git a/daphne/utils.py b/daphne/utils.py index 450416e..b6f0fbb 100644 --- a/daphne/utils.py +++ b/daphne/utils.py @@ -1,5 +1,4 @@ import importlib -import sys from twisted.web.http_headers import Headers diff --git a/daphne/ws_protocol.py b/daphne/ws_protocol.py index 1de218c..9dfa339 100755 --- a/daphne/ws_protocol.py +++ b/daphne/ws_protocol.py @@ -6,7 +6,7 @@ import six from autobahn.twisted.websocket import ConnectionDeny, WebSocketServerFactory, WebSocketServerProtocol from twisted.internet import defer -from six.moves.urllib_parse import unquote, urlencode +from six.moves.urllib_parse import unquote from .utils import parse_x_forwarded_for @@ -61,19 +61,23 @@ class WebSocketProtocol(WebSocketServerProtocol): subprotocols = [] for header, value in self.clean_headers: if header == b"sec-websocket-protocol": - subprotocols = [x.strip() for x in self.unquote(value).split(",")] + subprotocols = [ + x.strip() + for x in + unquote(value.decode("ascii")).split(",") + ] # Make new application instance with scope self.path = request.path.encode("ascii") self.application_queue = self.server.create_application(self, { "type": "websocket", - "path": self.unquote(self.path), + "path": unquote(self.path.decode("ascii")), "headers": self.clean_headers, "query_string": self._raw_query_string, # Passed by HTTP protocol "client": self.client_addr, "server": self.server_addr, "subprotocols": subprotocols, }) - except: + except Exception as e: # Exceptions here are not displayed right, just 500. # Turn them into an ERROR log. logger.error(traceback.format_exc()) @@ -152,7 +156,7 @@ class WebSocketProtocol(WebSocketServerProtocol): if message.get("bytes", None) and message.get("text", None): raise ValueError( "Got invalid WebSocket reply message on %s - contains both bytes and text keys" % ( - channel, + message, ) ) if message.get("bytes", None): @@ -214,16 +218,6 @@ class WebSocketProtocol(WebSocketServerProtocol): ### Utils - @classmethod - def unquote(cls, value): - """ - Python 2 and 3 compat layer for utf-8 unquoting - """ - if six.PY2: - return unquote(value).decode("utf8") - else: - return unquote(value.decode("ascii")) - def duration(self): """ Returns the time since the socket was opened diff --git a/setup.cfg b/setup.cfg index 34d6b8a..eefdf95 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,5 +10,5 @@ multi_line_output = 3 [flake8] exclude = venv/*,tox/*,docs/*,testproject/*,js_client/* -ignore = E123,E128,E402,W503,E731,W601 +ignore = E123,E128,E266,E402,W503,E731,W601 max-line-length = 120 diff --git a/tests/test_http_request.py b/tests/test_http_request.py index 924519c..61be621 100644 --- a/tests/test_http_request.py +++ b/tests/test_http_request.py @@ -15,14 +15,14 @@ class TestHTTPRequest(DaphneTestCase): """ def assert_valid_http_scope( - self, - scope, - method, - path, - params=None, - headers=None, - scheme=None, - ): + self, + scope, + method, + path, + params=None, + headers=None, + scheme=None, + ): """ Checks that the passed scope is a valid ASGI HTTP scope regarding types and some urlencoding things. @@ -76,11 +76,7 @@ class TestHTTPRequest(DaphneTestCase): if server is not None: self.assert_valid_address_and_port(server) - def assert_valid_http_request_message( - self, - message, - body=None, - ): + def assert_valid_http_request_message(self, message, body=None): """ Asserts that a message is a valid http.request message """ @@ -167,13 +163,13 @@ class TestHTTPRequest(DaphneTestCase): ) @settings(max_examples=5, deadline=2000) def test_kitchen_sink( - self, - request_method, - request_path, - request_params, - request_headers, - request_body, - ): + self, + request_method, + request_path, + request_params, + request_headers, + request_body, + ): """ Throw everything at Daphne that we dare. The idea is that if a combination of method/path/headers/body would break the spec, hypothesis will eventually find it. diff --git a/tests/test_websocket.py b/tests/test_websocket.py index 16c7374..977d6ec 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -15,14 +15,14 @@ class TestWebsocket(DaphneTestCase): """ def assert_valid_websocket_scope( - self, - scope, - path="/", - params=None, - headers=None, - scheme=None, - subprotocols=None, - ): + self, + scope, + path="/", + params=None, + headers=None, + scheme=None, + subprotocols=None, + ): """ Checks that the passed scope is a valid ASGI HTTP scope regarding types and some urlencoding things. @@ -145,11 +145,11 @@ class TestWebsocket(DaphneTestCase): ) @settings(max_examples=5, deadline=2000) def test_http_bits( - self, - request_path, - request_params, - request_headers, - ): + self, + request_path, + request_params, + request_headers, + ): """ Tests that various HTTP-level bits (query string params, path, headers) carry over into the scope.