From 198290da1cee036057752b96c42117a66ddc5321 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:37:13 +0200 Subject: [PATCH 01/14] Work on adapting istr --- aiohttp/client.py | 8 +- aiohttp/hdrs.py | 168 +++++++++++++++--------------- aiohttp/helpers.py | 14 ++- aiohttp/protocol.py | 4 +- aiohttp/web_urldispatcher.py | 14 ++- setup.py | 2 +- tests/test_websocket_handshake.py | 50 ++++----- 7 files changed, 128 insertions(+), 132 deletions(-) diff --git a/aiohttp/client.py b/aiohttp/client.py index 51099b0a464..7230b7999ed 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -9,7 +9,7 @@ import warnings import urllib.parse -from multidict import MultiDictProxy, MultiDict, CIMultiDict, upstr +from multidict import MultiDictProxy, MultiDict, CIMultiDict, istr import aiohttp from .client_reqrep import ClientRequest, ClientResponse @@ -70,7 +70,7 @@ def __init__(self, *, connector=None, loop=None, cookies=None, headers = CIMultiDict() self._default_headers = headers if skip_auto_headers is not None: - self._skip_auto_headers = frozenset([upstr(i) + self._skip_auto_headers = frozenset([istr(i) for i in skip_auto_headers]) else: self._skip_auto_headers = frozenset() @@ -158,7 +158,7 @@ def _request(self, method, url, *, redirects = 0 history = [] - method = upstr(method) + method = method.upper() # Merge with default headers and transform to CIMultiDict headers = self._prepare_headers(headers) @@ -175,7 +175,7 @@ def _request(self, method, url, *, skip_headers = set(self._skip_auto_headers) if skip_auto_headers is not None: for i in skip_auto_headers: - skip_headers.add(upstr(i)) + skip_headers.add(istr(i)) while True: diff --git a/aiohttp/hdrs.py b/aiohttp/hdrs.py index cfccd3df715..f994319e48d 100644 --- a/aiohttp/hdrs.py +++ b/aiohttp/hdrs.py @@ -1,91 +1,91 @@ """HTTP Headers constants.""" -from multidict import upstr +from multidict import istr -METH_ANY = upstr('*') -METH_CONNECT = upstr('CONNECT') -METH_HEAD = upstr('HEAD') -METH_GET = upstr('GET') -METH_DELETE = upstr('DELETE') -METH_OPTIONS = upstr('OPTIONS') -METH_PATCH = upstr('PATCH') -METH_POST = upstr('POST') -METH_PUT = upstr('PUT') -METH_TRACE = upstr('TRACE') +METH_ANY = '*' +METH_CONNECT = 'CONNECT' +METH_HEAD = 'HEAD' +METH_GET = 'GET' +METH_DELETE = 'DELETE' +METH_OPTIONS = 'OPTIONS' +METH_PATCH = 'PATCH' +METH_POST = 'POST' +METH_PUT = 'PUT' +METH_TRACE = 'TRACE' METH_ALL = {METH_CONNECT, METH_HEAD, METH_GET, METH_DELETE, METH_OPTIONS, METH_PATCH, METH_POST, METH_PUT, METH_TRACE} -ACCEPT = upstr('ACCEPT') -ACCEPT_CHARSET = upstr('ACCEPT-CHARSET') -ACCEPT_ENCODING = upstr('ACCEPT-ENCODING') -ACCEPT_LANGUAGE = upstr('ACCEPT-LANGUAGE') -ACCEPT_RANGES = upstr('ACCEPT-RANGES') -ACCESS_CONTROL_MAX_AGE = upstr('ACCESS-CONTROL-MAX-AGE') -ACCESS_CONTROL_ALLOW_CREDENTIALS = upstr('ACCESS-CONTROL-ALLOW-CREDENTIALS') -ACCESS_CONTROL_ALLOW_HEADERS = upstr('ACCESS-CONTROL-ALLOW-HEADERS') -ACCESS_CONTROL_ALLOW_METHODS = upstr('ACCESS-CONTROL-ALLOW-METHODS') -ACCESS_CONTROL_ALLOW_ORIGIN = upstr('ACCESS-CONTROL-ALLOW-ORIGIN') -ACCESS_CONTROL_EXPOSE_HEADERS = upstr('ACCESS-CONTROL-EXPOSE-HEADERS') -ACCESS_CONTROL_REQUEST_HEADERS = upstr('ACCESS-CONTROL-REQUEST-HEADERS') -ACCESS_CONTROL_REQUEST_METHOD = upstr('ACCESS-CONTROL-REQUEST-METHOD') -AGE = upstr('AGE') -ALLOW = upstr('ALLOW') -AUTHORIZATION = upstr('AUTHORIZATION') -CACHE_CONTROL = upstr('CACHE-CONTROL') -CONNECTION = upstr('CONNECTION') -CONTENT_DISPOSITION = upstr('CONTENT-DISPOSITION') -CONTENT_ENCODING = upstr('CONTENT-ENCODING') -CONTENT_LANGUAGE = upstr('CONTENT-LANGUAGE') -CONTENT_LENGTH = upstr('CONTENT-LENGTH') -CONTENT_LOCATION = upstr('CONTENT-LOCATION') -CONTENT_MD5 = upstr('CONTENT-MD5') -CONTENT_RANGE = upstr('CONTENT-RANGE') -CONTENT_TRANSFER_ENCODING = upstr('CONTENT-TRANSFER-ENCODING') -CONTENT_TYPE = upstr('CONTENT-TYPE') -COOKIE = upstr('COOKIE') -DATE = upstr('DATE') -DESTINATION = upstr('DESTINATION') -DIGEST = upstr('DIGEST') -ETAG = upstr('ETAG') -EXPECT = upstr('EXPECT') -EXPIRES = upstr('EXPIRES') -FROM = upstr('FROM') -HOST = upstr('HOST') -IF_MATCH = upstr('IF-MATCH') -IF_MODIFIED_SINCE = upstr('IF-MODIFIED-SINCE') -IF_NONE_MATCH = upstr('IF-NONE-MATCH') -IF_RANGE = upstr('IF-RANGE') -IF_UNMODIFIED_SINCE = upstr('IF-UNMODIFIED-SINCE') -KEEP_ALIVE = upstr('KEEP-ALIVE') -LAST_EVENT_ID = upstr('LAST-EVENT-ID') -LAST_MODIFIED = upstr('LAST-MODIFIED') -LINK = upstr('LINK') -LOCATION = upstr('LOCATION') -MAX_FORWARDS = upstr('MAX-FORWARDS') -ORIGIN = upstr('ORIGIN') -PRAGMA = upstr('PRAGMA') -PROXY_AUTHENTICATE = upstr('PROXY_AUTHENTICATE') -PROXY_AUTHORIZATION = upstr('PROXY-AUTHORIZATION') -RANGE = upstr('RANGE') -REFERER = upstr('REFERER') -RETRY_AFTER = upstr('RETRY-AFTER') -SEC_WEBSOCKET_ACCEPT = upstr('SEC-WEBSOCKET-ACCEPT') -SEC_WEBSOCKET_VERSION = upstr('SEC-WEBSOCKET-VERSION') -SEC_WEBSOCKET_PROTOCOL = upstr('SEC-WEBSOCKET-PROTOCOL') -SEC_WEBSOCKET_KEY = upstr('SEC-WEBSOCKET-KEY') -SEC_WEBSOCKET_KEY1 = upstr('SEC-WEBSOCKET-KEY1') -SERVER = upstr('SERVER') -SET_COOKIE = upstr('SET-COOKIE') -TE = upstr('TE') -TRAILER = upstr('TRAILER') -TRANSFER_ENCODING = upstr('TRANSFER-ENCODING') -UPGRADE = upstr('UPGRADE') -WEBSOCKET = upstr('WEBSOCKET') -URI = upstr('URI') -USER_AGENT = upstr('USER-AGENT') -VARY = upstr('VARY') -VIA = upstr('VIA') -WANT_DIGEST = upstr('WANT-DIGEST') -WARNING = upstr('WARNING') -WWW_AUTHENTICATE = upstr('WWW-AUTHENTICATE') +ACCEPT = istr('ACCEPT') +ACCEPT_CHARSET = istr('ACCEPT-CHARSET') +ACCEPT_ENCODING = istr('ACCEPT-ENCODING') +ACCEPT_LANGUAGE = istr('ACCEPT-LANGUAGE') +ACCEPT_RANGES = istr('ACCEPT-RANGES') +ACCESS_CONTROL_MAX_AGE = istr('ACCESS-CONTROL-MAX-AGE') +ACCESS_CONTROL_ALLOW_CREDENTIALS = istr('ACCESS-CONTROL-ALLOW-CREDENTIALS') +ACCESS_CONTROL_ALLOW_HEADERS = istr('ACCESS-CONTROL-ALLOW-HEADERS') +ACCESS_CONTROL_ALLOW_METHODS = istr('ACCESS-CONTROL-ALLOW-METHODS') +ACCESS_CONTROL_ALLOW_ORIGIN = istr('ACCESS-CONTROL-ALLOW-ORIGIN') +ACCESS_CONTROL_EXPOSE_HEADERS = istr('ACCESS-CONTROL-EXPOSE-HEADERS') +ACCESS_CONTROL_REQUEST_HEADERS = istr('ACCESS-CONTROL-REQUEST-HEADERS') +ACCESS_CONTROL_REQUEST_METHOD = istr('ACCESS-CONTROL-REQUEST-METHOD') +AGE = istr('AGE') +ALLOW = istr('ALLOW') +AUTHORIZATION = istr('AUTHORIZATION') +CACHE_CONTROL = istr('CACHE-CONTROL') +CONNECTION = istr('CONNECTION') +CONTENT_DISPOSITION = istr('CONTENT-DISPOSITION') +CONTENT_ENCODING = istr('CONTENT-ENCODING') +CONTENT_LANGUAGE = istr('CONTENT-LANGUAGE') +CONTENT_LENGTH = istr('CONTENT-LENGTH') +CONTENT_LOCATION = istr('CONTENT-LOCATION') +CONTENT_MD5 = istr('CONTENT-MD5') +CONTENT_RANGE = istr('CONTENT-RANGE') +CONTENT_TRANSFER_ENCODING = istr('CONTENT-TRANSFER-ENCODING') +CONTENT_TYPE = istr('CONTENT-TYPE') +COOKIE = istr('COOKIE') +DATE = istr('DATE') +DESTINATION = istr('DESTINATION') +DIGEST = istr('DIGEST') +ETAG = istr('ETAG') +EXPECT = istr('EXPECT') +EXPIRES = istr('EXPIRES') +FROM = istr('FROM') +HOST = istr('HOST') +IF_MATCH = istr('IF-MATCH') +IF_MODIFIED_SINCE = istr('IF-MODIFIED-SINCE') +IF_NONE_MATCH = istr('IF-NONE-MATCH') +IF_RANGE = istr('IF-RANGE') +IF_UNMODIFIED_SINCE = istr('IF-UNMODIFIED-SINCE') +KEEP_ALIVE = istr('KEEP-ALIVE') +LAST_EVENT_ID = istr('LAST-EVENT-ID') +LAST_MODIFIED = istr('LAST-MODIFIED') +LINK = istr('LINK') +LOCATION = istr('LOCATION') +MAX_FORWARDS = istr('MAX-FORWARDS') +ORIGIN = istr('ORIGIN') +PRAGMA = istr('PRAGMA') +PROXY_AUTHENTICATE = istr('PROXY_AUTHENTICATE') +PROXY_AUTHORIZATION = istr('PROXY-AUTHORIZATION') +RANGE = istr('RANGE') +REFERER = istr('REFERER') +RETRY_AFTER = istr('RETRY-AFTER') +SEC_WEBSOCKET_ACCEPT = istr('SEC-WEBSOCKET-ACCEPT') +SEC_WEBSOCKET_VERSION = istr('SEC-WEBSOCKET-VERSION') +SEC_WEBSOCKET_PROTOCOL = istr('SEC-WEBSOCKET-PROTOCOL') +SEC_WEBSOCKET_KEY = istr('SEC-WEBSOCKET-KEY') +SEC_WEBSOCKET_KEY1 = istr('SEC-WEBSOCKET-KEY1') +SERVER = istr('SERVER') +SET_COOKIE = istr('SET-COOKIE') +TE = istr('TE') +TRAILER = istr('TRAILER') +TRANSFER_ENCODING = istr('TRANSFER-ENCODING') +UPGRADE = istr('UPGRADE') +WEBSOCKET = istr('WEBSOCKET') +URI = istr('URI') +USER_AGENT = istr('USER-AGENT') +VARY = istr('VARY') +VIA = istr('VIA') +WANT_DIGEST = istr('WANT-DIGEST') +WARNING = istr('WARNING') +WWW_AUTHENTICATE = istr('WWW-AUTHENTICATE') diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index e518e703d7d..712b2db228c 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -15,7 +15,7 @@ from pathlib import Path from urllib.parse import quote, urlencode, urlsplit -import multidict +from multidict import istr, MultiDict, MultiDictProxy from . import hdrs from .abc import AbstractCookieJar @@ -119,7 +119,7 @@ def add_field(self, name, value, *, content_type=None, filename=None, if filename is None and content_transfer_encoding is None: filename = name - type_options = multidict.MultiDict({'name': name}) + type_options = MultiDict({'name': name}) if filename is not None and not isinstance(filename, str): raise TypeError('filename must be an instance of str. ' 'Got: %s' % filename) @@ -155,9 +155,7 @@ def add_fields(self, *fields): k = guess_filename(rec, 'unknown') self.add_field(k, rec) - elif isinstance(rec, - (multidict.MultiDictProxy, - multidict.MultiDict)): + elif isinstance(rec, (MultiDictProxy, MultiDict)): to_add.extend(rec.items()) elif isinstance(rec, (list, tuple)) and len(rec) == 2: @@ -331,17 +329,17 @@ def compile_format(self, log_format): @staticmethod def _format_e(key, args): - return (args[1] or {}).get(multidict.upstr(key), '-') + return (args[1] or {}).get(istr(key), '-') @staticmethod def _format_i(key, args): if not args[0]: return '(no headers)' - return args[0].headers.get(multidict.upstr(key), '-') + return args[0].headers.get(istr(key), '-') @staticmethod def _format_o(key, args): - return args[2].headers.get(multidict.upstr(key), '-') + return args[2].headers.get(istr(key), '-') @staticmethod def _format_a(args): diff --git a/aiohttp/protocol.py b/aiohttp/protocol.py index 6214d0e7e7a..50b4e0cb69b 100644 --- a/aiohttp/protocol.py +++ b/aiohttp/protocol.py @@ -9,7 +9,7 @@ import zlib from abc import abstractmethod, ABC from wsgiref.handlers import format_date_time -from multidict import CIMultiDict, upstr +from multidict import CIMultiDict, istr import aiohttp from . import errors, hdrs @@ -608,7 +608,7 @@ def add_header(self, name, value): 'Header {!r} should have string value, got {!r}'.format( name, value) - name = upstr(name) + name = istr(name) value = value.strip() if name == hdrs.CONTENT_LENGTH: diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 02ef30134e1..ecccd4c1559 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -14,8 +14,6 @@ from urllib.parse import urlencode, unquote from types import MappingProxyType -from multidict import upstr - from . import hdrs from .abc import AbstractRouter, AbstractMatchInfo, AbstractView from .file_sender import FileSender @@ -80,7 +78,7 @@ def __init__(self, method, handler, *, assert asyncio.iscoroutinefunction(expect_handler), \ 'Coroutine is expected, got {!r}'.format(expect_handler) - method = upstr(method) + method = method.upper() if method not in self.METHODS: raise ValueError("{} is not allowed HTTP method".format(method)) @@ -743,28 +741,28 @@ def add_get(self, *args, **kwargs): """ Shortcut for add_route with method GET """ - return self.add_route('GET', *args, **kwargs) + return self.add_route(hdrs.METH_GET, *args, **kwargs) def add_post(self, *args, **kwargs): """ Shortcut for add_route with method POST """ - return self.add_route('POST', *args, **kwargs) + return self.add_route(hdrs.METH_POST, *args, **kwargs) def add_put(self, *args, **kwargs): """ Shortcut for add_route with method PUT """ - return self.add_route('PUT', *args, **kwargs) + return self.add_route(hdrs.METH_PUT, *args, **kwargs) def add_patch(self, *args, **kwargs): """ Shortcut for add_route with method PATCH """ - return self.add_route('PATCH', *args, **kwargs) + return self.add_route(hdrs.METH_PATCH, *args, **kwargs) def add_delete(self, *args, **kwargs): """ Shortcut for add_route with method DELETE """ - return self.add_route('DELETE', *args, **kwargs) + return self.add_route(hdrs.METH_DELETE, *args, **kwargs) diff --git a/setup.py b/setup.py index 2c0680e484d..0e44c8f0e62 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ def build_extension(self, ext): raise RuntimeError('Unable to determine version.') -install_requires = ['chardet', 'multidict>=1.1.0,<2'] +install_requires = ['chardet', 'multidict>=2.0'] if sys.version_info < (3, 4, 1): raise RuntimeError("aiohttp requires Python 3.4.1+") diff --git a/tests/test_websocket_handshake.py b/tests/test_websocket_handshake.py index 6a59767fd68..efffceffd77 100644 --- a/tests/test_websocket_handshake.py +++ b/tests/test_websocket_handshake.py @@ -23,12 +23,12 @@ def message(): def gen_ws_headers(protocols=''): key = base64.b64encode(os.urandom(16)).decode() - hdrs = [('UPGRADE', 'websocket'), - ('CONNECTION', 'upgrade'), - ('SEC-WEBSOCKET-VERSION', '13'), - ('SEC-WEBSOCKET-KEY', key)] + hdrs = [('Upgrade', 'websocket'), + ('Connection', 'upgrade'), + ('Sec-Websocket-Version', '13'), + ('Sec-Websocket-Key', key)] if protocols: - hdrs += [('SEC-WEBSOCKET-PROTOCOL', protocols)] + hdrs += [('Sec-Websocket-Protocol', protocols)] return hdrs, key @@ -43,45 +43,45 @@ def test_no_upgrade(message, transport): def test_no_connection(message, transport): - message.headers.extend([('UPGRADE', 'websocket'), - ('CONNECTION', 'keep-alive')]) + message.headers.extend([('Upgrade', 'websocket'), + ('Connection', 'keep-alive')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) def test_protocol_version(message, transport): - message.headers.extend([('UPGRADE', 'websocket'), - ('CONNECTION', 'upgrade')]) + message.headers.extend([('Upgrade', 'websocket'), + ('Connection', 'upgrade')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) - message.headers.extend([('UPGRADE', 'websocket'), - ('CONNECTION', 'upgrade'), - ('SEC-WEBSOCKET-VERSION', '1')]) + message.headers.extend([('Upgrade', 'websocket'), + ('Connection', 'upgrade'), + ('Sec-Websocket-Version', '1')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) def test_protocol_key(message, transport): - message.headers.extend([('UPGRADE', 'websocket'), - ('CONNECTION', 'upgrade'), - ('SEC-WEBSOCKET-VERSION', '13')]) + message.headers.extend([('Upgrade', 'websocket'), + ('Connection', 'upgrade'), + ('Sec-Websocket-Version', '13')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) - message.headers.extend([('UPGRADE', 'websocket'), - ('CONNECTION', 'upgrade'), - ('SEC-WEBSOCKET-VERSION', '13'), - ('SEC-WEBSOCKET-KEY', '123')]) + message.headers.extend([('Upgrade', 'websocket'), + ('Connection', 'upgrade'), + ('Sec-Websocket-Version', '13'), + ('Sec-Websocket-Key', '123')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) sec_key = base64.b64encode(os.urandom(2)) - message.headers.extend([('UPGRADE', 'websocket'), - ('CONNECTION', 'upgrade'), - ('SEC-WEBSOCKET-VERSION', '13'), - ('SEC-WEBSOCKET-KEY', sec_key.decode())]) + message.headers.extend([('Upgrade', 'websocket'), + ('Connection', 'upgrade'), + ('Sec-Websocket-Version', '13'), + ('Sec-Websocket-Key', sec_key.decode())]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) @@ -98,7 +98,7 @@ def test_handshake(message, transport): key = base64.b64encode( hashlib.sha1(sec_key.encode() + websocket.WS_KEY).digest()) headers = dict(headers) - assert headers['SEC-WEBSOCKET-ACCEPT'] == key.decode() + assert headers['Sec-Websocket-Accept'] == key.decode() def test_handshake_protocol(message, transport): @@ -114,7 +114,7 @@ def test_handshake_protocol(message, transport): # also test if we reply with the protocol resp_headers = dict(resp_headers) - assert resp_headers['SEC-WEBSOCKET-PROTOCOL'] == proto + assert resp_headers['Sec-Websocket-Protocol'] == proto def test_handshake_protocol_agreement(message, transport): From 2f6a5e16afc1dce000723228a61c26dcb70848e5 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:44:23 +0200 Subject: [PATCH 02/14] Fix response tests --- tests/test_client_response.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_client_response.py b/tests/test_client_response.py index 5dcd0817c9e..ff8156abd92 100644 --- a/tests/test_client_response.py +++ b/tests/test_client_response.py @@ -133,7 +133,7 @@ def side_effect(*args, **kwargs): fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut self.response.headers = { - 'CONTENT-TYPE': 'application/json;charset=cp1251'} + 'Content-Type': 'application/json;charset=cp1251'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect @@ -147,7 +147,7 @@ def side_effect(*args, **kwargs): fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut self.response.headers = { - 'CONTENT-TYPE': 'application/json'} + 'Content-Type': 'application/json'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect self.response._get_encoding = mock.Mock() @@ -163,7 +163,7 @@ def side_effect(*args, **kwargs): fut = helpers.create_future(self.loop) fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut - self.response.headers = {'CONTENT-TYPE': 'application/json'} + self.response.headers = {'Content-Type': 'application/json'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect @@ -178,7 +178,7 @@ def side_effect(*args, **kwargs): fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut self.response.headers = { - 'CONTENT-TYPE': 'application/json;charset=cp1251'} + 'Content-Type': 'application/json;charset=cp1251'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect @@ -192,7 +192,7 @@ def side_effect(*args, **kwargs): fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut self.response.headers = { - 'CONTENT-TYPE': 'application/json;charset=cp1251'} + 'Content-Type': 'application/json;charset=cp1251'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect @@ -202,7 +202,7 @@ def side_effect(*args, **kwargs): def test_json_custom_loader(self): self.response.headers = { - 'CONTENT-TYPE': 'application/json;charset=cp1251'} + 'Content-Type': 'application/json;charset=cp1251'} self.response._content = b'data' def custom(content): @@ -214,7 +214,7 @@ def custom(content): @mock.patch('aiohttp.client_reqrep.client_logger') def test_json_no_content(self, m_log): self.response.headers = { - 'CONTENT-TYPE': 'data/octet-stream'} + 'Content-Type': 'data/octet-stream'} self.response._content = b'' res = self.loop.run_until_complete(self.response.json()) @@ -229,7 +229,7 @@ def side_effect(*args, **kwargs): fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut self.response.headers = { - 'CONTENT-TYPE': 'application/json;charset=utf8'} + 'Content-Type': 'application/json;charset=utf8'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect self.response._get_encoding = mock.Mock() @@ -245,7 +245,7 @@ def side_effect(*args, **kwargs): fut = helpers.create_future(self.loop) fut.set_result('{"тест": "пройден"}'.encode('cp1251')) return fut - self.response.headers = {'CONTENT-TYPE': 'application/json'} + self.response.headers = {'Content-Type': 'application/json'} content = self.response.content = mock.Mock() content.read.side_effect = side_effect @@ -266,7 +266,7 @@ class MyResponse(ClientResponse): def test_get_encoding_unknown(self, m_chardet): m_chardet.detect.return_value = {'encoding': None} - self.response.headers = {'CONTENT-TYPE': 'application/json'} + self.response.headers = {'Content-Type': 'application/json'} self.assertEqual(self.response._get_encoding(), 'utf-8') def test_raise_for_status_2xx(self): From 66ff04aa9d215ab98989511546fe6b717c0560a0 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:46:59 +0200 Subject: [PATCH 03/14] Fix request tests --- tests/test_client_request.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_client_request.py b/tests/test_client_request.py index 53fc577a51c..4d3b8a7b942 100644 --- a/tests/test_client_request.py +++ b/tests/test_client_request.py @@ -458,7 +458,7 @@ def test_content_type_auto_header_bytes(self): def test_content_type_skip_auto_header_bytes(self): req = ClientRequest('post', 'http://python.org', data=b'hey you', - skip_auto_headers={'CONTENT-TYPE'}, + skip_auto_headers={'Content-Type'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertNotIn('CONTENT-TYPE', req.headers) @@ -466,7 +466,7 @@ def test_content_type_skip_auto_header_bytes(self): def test_content_type_skip_auto_header_form(self): req = ClientRequest('post', 'http://python.org', data={'hey': 'you'}, - loop=self.loop, skip_auto_headers={'CONTENT-TYPE'}) + loop=self.loop, skip_auto_headers={'Content-Type'}) resp = req.send(self.transport, self.protocol) self.assertNotIn('CONTENT-TYPE', req.headers) resp.close() @@ -474,7 +474,7 @@ def test_content_type_skip_auto_header_form(self): def test_content_type_auto_header_content_length_no_skip(self): req = ClientRequest('get', 'http://python.org', data=io.BytesIO(b'hey'), - skip_auto_headers={'CONTENT-LENGTH'}, + skip_auto_headers={'Content-Length'}, loop=self.loop) resp = req.send(self.transport, self.protocol) self.assertEqual(req.headers.get('CONTENT-LENGTH'), '3') From 151771fe8a3c00ee9f0fc15a123d9e3f6bf4a377 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:49:24 +0200 Subject: [PATCH 04/14] Fix proxy tests --- tests/test_proxy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_proxy.py b/tests/test_proxy.py index f97cc95d15b..3c8afa486f0 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -65,7 +65,7 @@ def test_connect(self, ClientRequestMock): ClientRequestMock.assert_called_with( 'GET', 'http://proxy.example.com', auth=None, - headers={'HOST': 'www.python.org'}, + headers={'Host': 'www.python.org'}, loop=loop_mock) def test_proxy_auth(self): @@ -524,6 +524,6 @@ def test_connect(self, ClientRequestMock): ClientRequestMock.assert_called_with( 'GET', 'http://proxy.example.com', auth=None, - headers={'HOST': 'www.python.org'}, + headers={'Host': 'www.python.org'}, loop=loop_mock) conn.close() From dc407234c3e6c01b1f64b3c6883fb1dcd98a51bd Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:50:44 +0200 Subject: [PATCH 05/14] Fix web exceptions tests --- tests/test_web_exceptions.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_web_exceptions.py b/tests/test_web_exceptions.py index 846f0a849c6..14327fc3c3d 100644 --- a/tests/test_web_exceptions.py +++ b/tests/test_web_exceptions.py @@ -55,10 +55,10 @@ def test_HTTPOk(buf, request): yield from resp.write_eof() txt = buf.decode('utf8') assert re.match(('HTTP/1.1 200 OK\r\n' - 'CONTENT-TYPE: text/plain; charset=utf-8\r\n' - 'CONTENT-LENGTH: 7\r\n' - 'DATE: .+\r\n' - 'SERVER: .+\r\n\r\n' + 'Content-Type: text/plain; charset=utf-8\r\n' + 'Content-Length: 7\r\n' + 'Date: .+\r\n' + 'Server: .+\r\n\r\n' '200: OK'), txt) @@ -91,11 +91,11 @@ def test_HTTPFound(buf, request): yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 302 Found\r\n' - 'CONTENT-TYPE: text/plain; charset=utf-8\r\n' - 'CONTENT-LENGTH: 10\r\n' - 'LOCATION: /redirect\r\n' - 'DATE: .+\r\n' - 'SERVER: .+\r\n\r\n' + 'Content-Type: text/plain; charset=utf-8\r\n' + 'Content-Length: 10\r\n' + 'Location: /redirect\r\n' + 'Date: .+\r\n' + 'Server: .+\r\n\r\n' '302: Found', txt) @@ -117,11 +117,11 @@ def test_HTTPMethodNotAllowed(buf, request): yield from resp.write_eof() txt = buf.decode('utf8') assert re.match('HTTP/1.1 405 Method Not Allowed\r\n' - 'CONTENT-TYPE: text/plain; charset=utf-8\r\n' - 'CONTENT-LENGTH: 23\r\n' - 'ALLOW: POST,PUT\r\n' - 'DATE: .+\r\n' - 'SERVER: .+\r\n\r\n' + 'Content-Type: text/plain; charset=utf-8\r\n' + 'Content-Length: 23\r\n' + 'Allow: POST,PUT\r\n' + 'Date: .+\r\n' + 'Server: .+\r\n\r\n' '405: Method Not Allowed', txt) From df713c575a1744bee44c59474a2e8c36e44e3302 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:51:50 +0200 Subject: [PATCH 06/14] Fix server tests --- tests/test_server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_server.py b/tests/test_server.py index 6ffae5a285a..f6f30aad74c 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -255,7 +255,7 @@ def test_handle_error(srv): content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert b'HTTP/1.1 404 Not Found' in content - assert b'X-SERVER: asyncio' in content + assert b'X-Server: asyncio' in content assert not srv._keep_alive @@ -274,7 +274,7 @@ def test_handle_error__utf(make_srv): content = b''.join( [c[1][0] for c in list(srv.writer.write.mock_calls)]) assert b'HTTP/1.1 500 Internal Server Error' in content - assert b'CONTENT-TYPE: text/html; charset=utf-8' in content + assert b'Content-Type: text/html; charset=utf-8' in content pattern = escape("raise RuntimeError('что-то пошло не так')") assert pattern.encode('utf-8') in content assert not srv._keep_alive From 27435f744a4dc6dbe5c37f1eb712454f2d2c7503 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:55:50 +0200 Subject: [PATCH 07/14] Fix web response tests --- tests/test_web_response.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_web_response.py b/tests/test_web_response.py index 34cc8e2472a..1b2e496ddd7 100644 --- a/tests/test_web_response.py +++ b/tests/test_web_response.py @@ -814,8 +814,8 @@ def append(data): yield from resp.prepare(req) yield from resp.write_eof() txt = buf.decode('utf8') - assert re.match('HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 0\r\n' - 'DATE: .+\r\nSERVER: .+\r\n\r\n', txt) + assert re.match('HTTP/1.1 200 OK\r\nContent-Length: 0\r\n' + 'Date: .+\r\nServer: .+\r\n\r\n', txt) @pytest.mark.run_loop @@ -836,8 +836,8 @@ def append(data): yield from resp.prepare(req) yield from resp.write_eof() txt = buf.decode('utf8') - assert re.match('HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 4\r\n' - 'DATE: .+\r\nSERVER: .+\r\n\r\ndata', txt) + assert re.match('HTTP/1.1 200 OK\r\nContent-Length: 4\r\n' + 'Date: .+\r\nServer: .+\r\n\r\ndata', txt) @pytest.mark.run_loop @@ -859,9 +859,9 @@ def append(data): yield from resp.prepare(req) yield from resp.write_eof() txt = buf.decode('utf8') - assert re.match('HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 0\r\n' - 'SET-COOKIE: name=value\r\n' - 'DATE: .+\r\nSERVER: .+\r\n\r\n', txt) + assert re.match('HTTP/1.1 200 OK\r\nContent-Length: 0\r\n' + 'Set-Cookie: name=value\r\n' + 'Date: .+\r\nServer: .+\r\n\r\n', txt) def test_set_text_with_content_type(): From d26e2d09ea13b9689d8d757e347da035352c7e33 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 17:59:17 +0200 Subject: [PATCH 08/14] Fix web request tests --- tests/test_web_request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_web_request.py b/tests/test_web_request.py index e15bd1b5c01..940ff238cad 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -46,7 +46,7 @@ def test_ctor(make_request, warning): assert req._reader is reader assert req._writer is writer assert req.headers == headers - assert req.raw_headers == ((b'FOO', b'bar'),) + assert req.raw_headers == ((b'Foo', b'bar'),) def test_doubleslashes(make_request): @@ -232,4 +232,4 @@ def test_https_scheme_by_secure_proxy_ssl_header_false_test(make_request): def test_raw_headers(make_request): req = make_request('GET', '/', headers=CIMultiDict({'X-HEADER': 'aaa'})) - assert req.raw_headers == ((b'X-HEADER', b'aaa'),) + assert req.raw_headers == ((b'X-Header', b'aaa'),) From 0c9046cf3a4827d4bc6dcbe0013cf35d8483c7ab Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 18:10:10 +0200 Subject: [PATCH 09/14] Fix protocol tests --- aiohttp/protocol.py | 2 +- tests/test_protocol.py | 30 ++++++++++++------------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/aiohttp/protocol.py b/aiohttp/protocol.py index 50b4e0cb69b..95398c2626b 100644 --- a/aiohttp/protocol.py +++ b/aiohttp/protocol.py @@ -115,7 +115,7 @@ def parse_headers(self, lines): bvalue = bvalue.strip() - name = bname.decode('utf-8', 'surrogateescape') + name = istr(bname.decode('utf-8', 'surrogateescape')) value = bvalue.decode('utf-8', 'surrogateescape') # keep-alive and encoding diff --git a/tests/test_protocol.py b/tests/test_protocol.py index c66b668d79a..ab6be241703 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -90,7 +90,7 @@ def test_add_header(transport): assert [] == list(msg.headers) msg.add_header('content-type', 'plain/html') - assert [('CONTENT-TYPE', 'plain/html')] == list(msg.headers.items()) + assert [('Content-Type', 'plain/html')] == list(msg.headers.items()) def test_add_header_with_spaces(transport): @@ -98,7 +98,7 @@ def test_add_header_with_spaces(transport): assert [] == list(msg.headers) msg.add_header('content-type', ' plain/html ') - assert [('CONTENT-TYPE', 'plain/html')] == list(msg.headers.items()) + assert [('Content-Type', 'plain/html')] == list(msg.headers.items()) def test_add_header_non_ascii(transport): @@ -125,7 +125,7 @@ def test_add_headers(transport): assert [] == list(msg.headers) msg.add_headers(('content-type', 'plain/html')) - assert [('CONTENT-TYPE', 'plain/html')] == list(msg.headers.items()) + assert [('Content-Type', 'plain/html')] == list(msg.headers.items()) def test_add_headers_length(transport): @@ -151,7 +151,7 @@ def test_add_headers_upgrade_websocket(transport): assert [] == list(msg.headers) msg.add_headers(('upgrade', 'websocket')) - assert [('UPGRADE', 'websocket')] == list(msg.headers.items()) + assert [('Upgrade', 'websocket')] == list(msg.headers.items()) def test_add_headers_connection_keepalive(transport): @@ -201,15 +201,13 @@ def test_default_headers_chunked(transport): msg = protocol.Response(transport, 200) msg._add_default_headers() - headers = [r for r, _ in msg.headers.items()] - assert 'TRANSFER-ENCODING' not in headers + assert 'TRANSFER-ENCODING' not in msg.headers msg = protocol.Response(transport, 200) msg.enable_chunked_encoding() msg.send_headers() - headers = [r for r, _ in msg.headers.items()] - assert 'TRANSFER-ENCODING' in headers + assert 'TRANSFER-ENCODING' in msg.headers def test_default_headers_connection_upgrade(transport): @@ -217,8 +215,7 @@ def test_default_headers_connection_upgrade(transport): msg.upgrade = True msg._add_default_headers() - headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] - assert [('CONNECTION', 'upgrade')] == headers + assert msg.headers['Connection'] == 'upgrade' def test_default_headers_connection_close(transport): @@ -226,8 +223,7 @@ def test_default_headers_connection_close(transport): msg.force_close() msg._add_default_headers() - headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] - assert [('CONNECTION', 'close')] == headers + assert msg.headers['Connection'] == 'close' def test_default_headers_connection_keep_alive_http_10(transport): @@ -236,8 +232,7 @@ def test_default_headers_connection_keep_alive_http_10(transport): msg.keepalive = True msg._add_default_headers() - headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] - assert [('CONNECTION', 'keep-alive')] == headers + assert msg.headers['Connection'] == 'keep-alive' def test_default_headers_connection_keep_alive_11(transport): @@ -246,8 +241,7 @@ def test_default_headers_connection_keep_alive_11(transport): msg.keepalive = True msg._add_default_headers() - headers = [r for r in msg.headers.items() if r[0] == 'CONNECTION'] - assert 'CONNECTION' not in headers + assert 'Connection' not in msg.headers def test_send_headers(transport): @@ -262,7 +256,7 @@ def test_send_headers(transport): content = b''.join([arg[1][0] for arg in list(write.mock_calls)]) assert content.startswith(b'HTTP/1.1 200 OK\r\n') - assert b'CONTENT-TYPE: plain/html' in content + assert b'Content-Type: plain/html' in content assert msg.headers_sent assert msg.is_headers_sent() # cleanup @@ -281,7 +275,7 @@ def test_send_headers_non_ascii(transport): content = b''.join([arg[1][0] for arg in list(write.mock_calls)]) assert content.startswith(b'HTTP/1.1 200 OK\r\n') - assert b'X-HEADER: \xd1\x82\xd0\xb5\xd0\xba\xd1\x81\xd1\x82' in content + assert b'X-Header: \xd1\x82\xd0\xb5\xd0\xba\xd1\x81\xd1\x82' in content assert msg.headers_sent assert msg.is_headers_sent() # cleanup From afc8fbef7b6e18235abc4fc449d96e7ded450747 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 18:12:39 +0200 Subject: [PATCH 10/14] Fix multipart tests --- tests/test_multipart.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_multipart.py b/tests/test_multipart.py index d31e9b81421..5bfcccfe3ae 100644 --- a/tests/test_multipart.py +++ b/tests/test_multipart.py @@ -830,13 +830,13 @@ def test_serialize_multipart(self): multipart.append_json({'test': 'passed'}) self.assertEqual( [b'--:\r\n', - b'CONTENT-TYPE: text/plain; charset=utf-8\r\n' - b'CONTENT-LENGTH: 11', + b'Content-Type: text/plain; charset=utf-8\r\n' + b'Content-Length: 11', b'\r\n\r\n', b'foo-bar-baz', b'\r\n', b'--:\r\n', - b'CONTENT-TYPE: application/json', + b'Content-Type: application/json', b'\r\n\r\n', b'{"test": "passed"}', b'\r\n', @@ -856,8 +856,8 @@ def test_serialize_with_content_encoding_gzip(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_ENCODING: 'gzip'}) stream = part.serialize() - self.assertEqual(b'CONTENT-ENCODING: gzip\r\n' - b'CONTENT-TYPE: text/plain; charset=utf-8', + self.assertEqual(b'Content-Encoding: gzip\r\n' + b'Content-Type: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) @@ -872,8 +872,8 @@ def test_serialize_with_content_encoding_deflate(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_ENCODING: 'deflate'}) stream = part.serialize() - self.assertEqual(b'CONTENT-ENCODING: deflate\r\n' - b'CONTENT-TYPE: text/plain; charset=utf-8', + self.assertEqual(b'Content-Encoding: deflate\r\n' + b'Content-Type: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) @@ -886,9 +886,9 @@ def test_serialize_with_content_encoding_identity(self): part = aiohttp.multipart.BodyPartWriter( thing, {CONTENT_ENCODING: 'identity'}) stream = part.serialize() - self.assertEqual(b'CONTENT-ENCODING: identity\r\n' - b'CONTENT-TYPE: application/octet-stream\r\n' - b'CONTENT-LENGTH: 16', + self.assertEqual(b'Content-Encoding: identity\r\n' + b'Content-Type: application/octet-stream\r\n' + b'Content-Length: 16', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) @@ -906,8 +906,8 @@ def test_serialize_with_content_transfer_encoding_base64(self): part = aiohttp.multipart.BodyPartWriter( 'Time to Relax!', {CONTENT_TRANSFER_ENCODING: 'base64'}) stream = part.serialize() - self.assertEqual(b'CONTENT-TRANSFER-ENCODING: base64\r\n' - b'CONTENT-TYPE: text/plain; charset=utf-8', + self.assertEqual(b'Content-Transfer-Encoding: base64\r\n' + b'Content-Type: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) @@ -922,8 +922,8 @@ def test_serialize_io_with_content_transfer_encoding_base64(self): {CONTENT_TRANSFER_ENCODING: 'base64'}) part._chunk_size = 6 stream = part.serialize() - self.assertEqual(b'CONTENT-TRANSFER-ENCODING: base64\r\n' - b'CONTENT-TYPE: application/octet-stream', + self.assertEqual(b'Content-Transfer-Encoding: base64\r\n' + b'Content-Type: application/octet-stream', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) @@ -937,8 +937,8 @@ def test_serialize_with_content_transfer_encoding_quote_printable(self): part = aiohttp.multipart.BodyPartWriter( 'Привет, мир!', {CONTENT_TRANSFER_ENCODING: 'quoted-printable'}) stream = part.serialize() - self.assertEqual(b'CONTENT-TRANSFER-ENCODING: quoted-printable\r\n' - b'CONTENT-TYPE: text/plain; charset=utf-8', + self.assertEqual(b'Content-Transfer-Encoding: quoted-printable\r\n' + b'Content-Type: text/plain; charset=utf-8', next(stream)) self.assertEqual(b'\r\n\r\n', next(stream)) From 17c012095bc13a49ca6db74cbfd82f8d072e20bb Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 18:16:26 +0200 Subject: [PATCH 11/14] Fix http parser tests --- tests/test_http_parser.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index 66193fd93c1..6255d27fb90 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -26,7 +26,8 @@ def test_parse_headers(self): hdrs) self.assertEqual(list(headers.items()), - [('TEST', 'line\r\n continue'), ('TEST2', 'data')]) + [('Test', 'line\r\n continue'), + ('Test2', 'data')]) self.assertEqual(raw_headers, [(b'TEST', b'line\r\n continue'), (b'TEST2', b'data')]) @@ -42,8 +43,8 @@ def test_parse_headers_multi(self): hdrs) self.assertEqual(list(headers.items()), - [('SET-COOKIE', 'c1=cookie1'), - ('SET-COOKIE', 'c2=cookie2')]) + [('Set-Cookie', 'c1=cookie1'), + ('Set-Cookie', 'c2=cookie2')]) self.assertEqual(raw_headers, [(b'SET-COOKIE', b'c1=cookie1'), (b'SET-COOKIE', b'c2=cookie2')]) From 468178c61b87ac95c370197be752e64048bfcd39 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 18:22:52 +0200 Subject: [PATCH 12/14] Fix helpers tests --- aiohttp/helpers.py | 10 ++++++---- tests/test_helpers.py | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index 712b2db228c..0242b1518ec 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -15,7 +15,7 @@ from pathlib import Path from urllib.parse import quote, urlencode, urlsplit -from multidict import istr, MultiDict, MultiDictProxy +from multidict import MultiDict, MultiDictProxy from . import hdrs from .abc import AbstractCookieJar @@ -329,17 +329,19 @@ def compile_format(self, log_format): @staticmethod def _format_e(key, args): - return (args[1] or {}).get(istr(key), '-') + return (args[1] or {}).get(key, '-') @staticmethod def _format_i(key, args): if not args[0]: return '(no headers)' - return args[0].headers.get(istr(key), '-') + # suboptimal, make istr(key) once + return args[0].headers.get(key, '-') @staticmethod def _format_o(key, args): - return args[2].headers.get(istr(key), '-') + # suboptimal, make istr(key) once + return args[2].headers.get(key, '-') @staticmethod def _format_a(args): diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 4368b4229fd..c4f2dbbd245 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -165,9 +165,9 @@ def test_access_logger_dicts(): log_format = '%{User-Agent}i %{Content-Length}o %{SPAM}e %{None}i' mock_logger = mock.Mock() access_logger = helpers.AccessLogger(mock_logger, log_format) - message = mock.Mock(headers={"USER-AGENT": "Mock/1.0"}, version=(1, 1)) + message = mock.Mock(headers={"User-Agent": "Mock/1.0"}, version=(1, 1)) environ = {"SPAM": "EGGS"} - response = mock.Mock(headers={"CONTENT-LENGTH": 123}) + response = mock.Mock(headers={"Content-Length": 123}) transport = mock.Mock() transport.get_extra_info.return_value = ("127.0.0.2", 1234) access_logger.log(message, environ, response, transport, 0.0) From aabf2badb1f0153bbbd950a1d817f75d9a8de9aa Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 18:45:10 +0200 Subject: [PATCH 13/14] Fix fuctional test --- aiohttp/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohttp/test_utils.py b/aiohttp/test_utils.py index 825661ada83..6fc37dcdf76 100644 --- a/aiohttp/test_utils.py +++ b/aiohttp/test_utils.py @@ -83,7 +83,7 @@ def handle_request(self, message, payload): return for hdr, val in message.headers.items(): - if (hdr == 'EXPECT') and (val == '100-continue'): + if (hdr.upper() == 'EXPECT') and (val == '100-continue'): self.transport.write(b'HTTP/1.0 100 Continue\r\n\r\n') break From 012362d9cf6cedfc4713a4f6e6cee735894fe213 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 29 Jul 2016 18:48:12 +0200 Subject: [PATCH 14/14] Don't perform extra conversions --- aiohttp/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aiohttp/client.py b/aiohttp/client.py index 7230b7999ed..a4e525037b8 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -158,7 +158,6 @@ def _request(self, method, url, *, redirects = 0 history = [] - method = method.upper() # Merge with default headers and transform to CIMultiDict headers = self._prepare_headers(headers)