diff --git a/requirements.txt b/requirements.txt index 3acfbb1f..cef8660e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,3 @@ httptools ujson uvloop aiofiles -multidict diff --git a/sanic/response.py b/sanic/response.py index 9c7bd2b5..bb3a1f9d 100644 --- a/sanic/response.py +++ b/sanic/response.py @@ -106,11 +106,11 @@ class HTTPResponse: for name, value in self.headers.items(): try: headers += ( - b'%b: %b\r\n' % (name.encode(), value.encode('utf-8'))) + b'%b: %b\r\n' % (name.title().encode(), value.encode('utf-8'))) except AttributeError: headers += ( b'%b: %b\r\n' % ( - str(name).encode(), str(value).encode('utf-8'))) + str(name).title().encode(), str(value).encode('utf-8'))) # Try to pull from the common codes first # Speeds up response rate 6% over pulling from all diff --git a/sanic/server.py b/sanic/server.py index ec207d26..62a4c1a7 100644 --- a/sanic/server.py +++ b/sanic/server.py @@ -1,7 +1,6 @@ import asyncio from functools import partial from inspect import isawaitable -from multidict import CIMultiDict from signal import SIGINT, SIGTERM from time import time from httptools import HttpRequestParser @@ -18,11 +17,30 @@ from .request import Request from .exceptions import RequestTimeout, PayloadTooLarge, InvalidUsage +current_time = None + + class Signal: stopped = False -current_time = None +class CIDict(dict): + """ + Case Insensitive dict where all keys are converted to lowercase + This does not maintain the inputted case when calling items() or keys() + in favor of speed, since headers are case insensitive + """ + def get(self, key, default=None): + return super().get(key.casefold(), default) + + def __getitem__(self, key): + return super().__getitem__(key.casefold()) + + def __setitem__(self, key, value): + return super().__setitem__(key.casefold(), value) + + def __contains__(self, key): + return super().__contains__(key.casefold()) class HttpProtocol(asyncio.Protocol): @@ -127,7 +145,7 @@ class HttpProtocol(asyncio.Protocol): self.request = Request( url_bytes=self.url, - headers=CIMultiDict(self.headers), + headers=CIDict(self.headers), version=self.parser.get_http_version(), method=self.parser.get_method().decode() )