We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
aiohttp filtering out "Authorization" header
Apparently aiohttp is filtering out the "Authorization" header in aiohttp.wsgi:69 in create_wsgi_environ.

This bug was found while using aiopyramid + jwtauth, you can find more details (and an example project) on https://github.com/housleyjk/aiopyramid/issues/14


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `aiohttp/wsgi.py`
Content:
```
1 """wsgi server.
2 
3 TODO:
4   * proxy protocol
5   * x-forward security
6   * wsgi file support (os.sendfile)
7 """
8 
9 import asyncio
10 import inspect
11 import io
12 import os
13 import sys
14 from urllib.parse import urlsplit
15 
16 import aiohttp
17 from aiohttp import server, hdrs
18 
19 __all__ = ('WSGIServerHttpProtocol',)
20 
21 
22 class WSGIServerHttpProtocol(server.ServerHttpProtocol):
23     """HTTP Server that implements the Python WSGI protocol.
24 
25     It uses 'wsgi.async' of 'True'. 'wsgi.input' can behave differently
26     depends on 'readpayload' constructor parameter. If readpayload is set to
27     True, wsgi server reads all incoming data into BytesIO object and
28     sends it as 'wsgi.input' environ var. If readpayload is set to false
29     'wsgi.input' is a StreamReader and application should read incoming
30     data with "yield from environ['wsgi.input'].read()". It defaults to False.
31     """
32 
33     SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '')
34 
35     def __init__(self, app, readpayload=False, is_ssl=False, *args, **kw):
36         super().__init__(*args, **kw)
37 
38         self.wsgi = app
39         self.is_ssl = is_ssl
40         self.readpayload = readpayload
41 
42     def create_wsgi_response(self, message):
43         return WsgiResponse(self.writer, message)
44 
45     def create_wsgi_environ(self, message, payload):
46         uri_parts = urlsplit(message.path)
47         url_scheme = 'https' if self.is_ssl else 'http'
48 
49         environ = {
50             'wsgi.input': payload,
51             'wsgi.errors': sys.stderr,
52             'wsgi.version': (1, 0),
53             'wsgi.async': True,
54             'wsgi.multithread': False,
55             'wsgi.multiprocess': False,
56             'wsgi.run_once': False,
57             'wsgi.file_wrapper': FileWrapper,
58             'wsgi.url_scheme': url_scheme,
59             'SERVER_SOFTWARE': aiohttp.HttpMessage.SERVER_SOFTWARE,
60             'REQUEST_METHOD': message.method,
61             'QUERY_STRING': uri_parts.query or '',
62             'RAW_URI': message.path,
63             'SERVER_PROTOCOL': 'HTTP/%s.%s' % message.version
64         }
65 
66         script_name = self.SCRIPT_NAME
67 
68         for hdr_name, hdr_value in message.headers.items():
69             if hdr_name == 'AUTHORIZATION':
70                 continue
71             elif hdr_name == 'SCRIPT_NAME':
72                 script_name = hdr_value
73             elif hdr_name == 'CONTENT-TYPE':
74                 environ['CONTENT_TYPE'] = hdr_value
75                 continue
76             elif hdr_name == 'CONTENT-LENGTH':
77                 environ['CONTENT_LENGTH'] = hdr_value
78                 continue
79 
80             key = 'HTTP_%s' % hdr_name.replace('-', '_')
81             if key in environ:
82                 hdr_value = '%s,%s' % (environ[key], hdr_value)
83 
84             environ[key] = hdr_value
85 
86         # authors should be aware that REMOTE_HOST and REMOTE_ADDR
87         # may not qualify the remote addr
88         # also SERVER_PORT variable MUST be set to the TCP/IP port number on
89         # which this request is received from the client.
90         # http://www.ietf.org/rfc/rfc3875
91 
92         remote = self.transport.get_extra_info('peername')
93         environ['REMOTE_ADDR'] = remote[0]
94         environ['REMOTE_PORT'] = remote[1]
95 
96         sockname = self.transport.get_extra_info('sockname')
97         environ['SERVER_PORT'] = str(sockname[1])
98         host = message.headers.get("HOST", None)
99         if host:
100             environ['SERVER_NAME'] = host.split(":")[0]
101         else:
102             environ['SERVER_NAME'] = sockname[0]
103 
104         path_info = uri_parts.path
105         if script_name:
106             path_info = path_info.split(script_name, 1)[-1]
107 
108         environ['PATH_INFO'] = path_info
109         environ['SCRIPT_NAME'] = script_name
110 
111         environ['async.reader'] = self.reader
112         environ['async.writer'] = self.writer
113 
114         return environ
115 
116     @asyncio.coroutine
117     def handle_request(self, message, payload):
118         """Handle a single HTTP request"""
119         now = self._loop.time()
120 
121         if self.readpayload:
122             wsgiinput = io.BytesIO()
123             wsgiinput.write((yield from payload.read()))
124             wsgiinput.seek(0)
125             payload = wsgiinput
126 
127         environ = self.create_wsgi_environ(message, payload)
128         response = self.create_wsgi_response(message)
129 
130         riter = self.wsgi(environ, response.start_response)
131         if isinstance(riter, asyncio.Future) or inspect.isgenerator(riter):
132             riter = yield from riter
133 
134         resp = response.response
135         try:
136             for item in riter:
137                 if isinstance(item, asyncio.Future):
138                     item = yield from item
139                 yield from resp.write(item)
140 
141             yield from resp.write_eof()
142         finally:
143             if hasattr(riter, 'close'):
144                 riter.close()
145 
146         if resp.keep_alive():
147             self.keep_alive(True)
148 
149         self.log_access(
150             message, environ, response.response, self._loop.time() - now)
151 
152 
153 class FileWrapper:
154     """Custom file wrapper."""
155 
156     def __init__(self, fobj, chunk_size=8192):
157         self.fobj = fobj
158         self.chunk_size = chunk_size
159         if hasattr(fobj, 'close'):
160             self.close = fobj.close
161 
162     def __iter__(self):
163         return self
164 
165     def __next__(self):
166         data = self.fobj.read(self.chunk_size)
167         if data:
168             return data
169         raise StopIteration
170 
171 
172 class WsgiResponse:
173     """Implementation of start_response() callable as specified by PEP 3333"""
174 
175     status = None
176 
177     HOP_HEADERS = {
178         hdrs.CONNECTION,
179         hdrs.KEEP_ALIVE,
180         hdrs.PROXY_AUTHENTICATE,
181         hdrs.PROXY_AUTHORIZATION,
182         hdrs.TE,
183         hdrs.TRAILER,
184         hdrs.TRANSFER_ENCODING,
185         hdrs.UPGRADE,
186     }
187 
188     def __init__(self, writer, message):
189         self.writer = writer
190         self.message = message
191 
192     def start_response(self, status, headers, exc_info=None):
193         if exc_info:
194             try:
195                 if self.status:
196                     raise exc_info[1]
197             finally:
198                 exc_info = None
199 
200         status_code = int(status.split(' ', 1)[0])
201 
202         self.status = status
203         resp = self.response = aiohttp.Response(
204             self.writer, status_code,
205             self.message.version, self.message.should_close)
206         resp.HOP_HEADERS = self.HOP_HEADERS
207         resp.add_headers(*headers)
208 
209         if resp.has_chunked_hdr:
210             resp.enable_chunked_encoding()
211 
212         # send headers immediately for websocket connection
213         if status_code == 101 and resp.upgrade and resp.websocket:
214             resp.send_headers()
215         else:
216             resp._send_headers = True
217         return self.response.write
218
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/aiohttp/wsgi.py b/aiohttp/wsgi.py
--- a/aiohttp/wsgi.py
+++ b/aiohttp/wsgi.py
@@ -66,9 +66,7 @@
         script_name = self.SCRIPT_NAME
 
         for hdr_name, hdr_value in message.headers.items():
-            if hdr_name == 'AUTHORIZATION':
-                continue
-            elif hdr_name == 'SCRIPT_NAME':
+            if hdr_name == 'SCRIPT_NAME':
                 script_name = hdr_value
             elif hdr_name == 'CONTENT-TYPE':
                 environ['CONTENT_TYPE'] = hdr_value

{"golden_diff": "diff --git a/aiohttp/wsgi.py b/aiohttp/wsgi.py\n--- a/aiohttp/wsgi.py\n+++ b/aiohttp/wsgi.py\n@@ -66,9 +66,7 @@\n         script_name = self.SCRIPT_NAME\n \n         for hdr_name, hdr_value in message.headers.items():\n-            if hdr_name == 'AUTHORIZATION':\n-                continue\n-            elif hdr_name == 'SCRIPT_NAME':\n+            if hdr_name == 'SCRIPT_NAME':\n                 script_name = hdr_value\n             elif hdr_name == 'CONTENT-TYPE':\n                 environ['CONTENT_TYPE'] = hdr_value\n", "issue": "aiohttp filtering out \"Authorization\" header\nApparently aiohttp is filtering out the \"Authorization\" header in aiohttp.wsgi:69 in create_wsgi_environ.\n\nThis bug was found while using aiopyramid + jwtauth, you can find more details (and an example project) on https://github.com/housleyjk/aiopyramid/issues/14\n\n", "before_files": [{"content": "\"\"\"wsgi server.\n\nTODO:\n  * proxy protocol\n  * x-forward security\n  * wsgi file support (os.sendfile)\n\"\"\"\n\nimport asyncio\nimport inspect\nimport io\nimport os\nimport sys\nfrom urllib.parse import urlsplit\n\nimport aiohttp\nfrom aiohttp import server, hdrs\n\n__all__ = ('WSGIServerHttpProtocol',)\n\n\nclass WSGIServerHttpProtocol(server.ServerHttpProtocol):\n    \"\"\"HTTP Server that implements the Python WSGI protocol.\n\n    It uses 'wsgi.async' of 'True'. 'wsgi.input' can behave differently\n    depends on 'readpayload' constructor parameter. If readpayload is set to\n    True, wsgi server reads all incoming data into BytesIO object and\n    sends it as 'wsgi.input' environ var. If readpayload is set to false\n    'wsgi.input' is a StreamReader and application should read incoming\n    data with \"yield from environ['wsgi.input'].read()\". It defaults to False.\n    \"\"\"\n\n    SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '')\n\n    def __init__(self, app, readpayload=False, is_ssl=False, *args, **kw):\n        super().__init__(*args, **kw)\n\n        self.wsgi = app\n        self.is_ssl = is_ssl\n        self.readpayload = readpayload\n\n    def create_wsgi_response(self, message):\n        return WsgiResponse(self.writer, message)\n\n    def create_wsgi_environ(self, message, payload):\n        uri_parts = urlsplit(message.path)\n        url_scheme = 'https' if self.is_ssl else 'http'\n\n        environ = {\n            'wsgi.input': payload,\n            'wsgi.errors': sys.stderr,\n            'wsgi.version': (1, 0),\n            'wsgi.async': True,\n            'wsgi.multithread': False,\n            'wsgi.multiprocess': False,\n            'wsgi.run_once': False,\n            'wsgi.file_wrapper': FileWrapper,\n            'wsgi.url_scheme': url_scheme,\n            'SERVER_SOFTWARE': aiohttp.HttpMessage.SERVER_SOFTWARE,\n            'REQUEST_METHOD': message.method,\n            'QUERY_STRING': uri_parts.query or '',\n            'RAW_URI': message.path,\n            'SERVER_PROTOCOL': 'HTTP/%s.%s' % message.version\n        }\n\n        script_name = self.SCRIPT_NAME\n\n        for hdr_name, hdr_value in message.headers.items():\n            if hdr_name == 'AUTHORIZATION':\n                continue\n            elif hdr_name == 'SCRIPT_NAME':\n                script_name = hdr_value\n            elif hdr_name == 'CONTENT-TYPE':\n                environ['CONTENT_TYPE'] = hdr_value\n                continue\n            elif hdr_name == 'CONTENT-LENGTH':\n                environ['CONTENT_LENGTH'] = hdr_value\n                continue\n\n            key = 'HTTP_%s' % hdr_name.replace('-', '_')\n            if key in environ:\n                hdr_value = '%s,%s' % (environ[key], hdr_value)\n\n            environ[key] = hdr_value\n\n        # authors should be aware that REMOTE_HOST and REMOTE_ADDR\n        # may not qualify the remote addr\n        # also SERVER_PORT variable MUST be set to the TCP/IP port number on\n        # which this request is received from the client.\n        # http://www.ietf.org/rfc/rfc3875\n\n        remote = self.transport.get_extra_info('peername')\n        environ['REMOTE_ADDR'] = remote[0]\n        environ['REMOTE_PORT'] = remote[1]\n\n        sockname = self.transport.get_extra_info('sockname')\n        environ['SERVER_PORT'] = str(sockname[1])\n        host = message.headers.get(\"HOST\", None)\n        if host:\n            environ['SERVER_NAME'] = host.split(\":\")[0]\n        else:\n            environ['SERVER_NAME'] = sockname[0]\n\n        path_info = uri_parts.path\n        if script_name:\n            path_info = path_info.split(script_name, 1)[-1]\n\n        environ['PATH_INFO'] = path_info\n        environ['SCRIPT_NAME'] = script_name\n\n        environ['async.reader'] = self.reader\n        environ['async.writer'] = self.writer\n\n        return environ\n\n    @asyncio.coroutine\n    def handle_request(self, message, payload):\n        \"\"\"Handle a single HTTP request\"\"\"\n        now = self._loop.time()\n\n        if self.readpayload:\n            wsgiinput = io.BytesIO()\n            wsgiinput.write((yield from payload.read()))\n            wsgiinput.seek(0)\n            payload = wsgiinput\n\n        environ = self.create_wsgi_environ(message, payload)\n        response = self.create_wsgi_response(message)\n\n        riter = self.wsgi(environ, response.start_response)\n        if isinstance(riter, asyncio.Future) or inspect.isgenerator(riter):\n            riter = yield from riter\n\n        resp = response.response\n        try:\n            for item in riter:\n                if isinstance(item, asyncio.Future):\n                    item = yield from item\n                yield from resp.write(item)\n\n            yield from resp.write_eof()\n        finally:\n            if hasattr(riter, 'close'):\n                riter.close()\n\n        if resp.keep_alive():\n            self.keep_alive(True)\n\n        self.log_access(\n            message, environ, response.response, self._loop.time() - now)\n\n\nclass FileWrapper:\n    \"\"\"Custom file wrapper.\"\"\"\n\n    def __init__(self, fobj, chunk_size=8192):\n        self.fobj = fobj\n        self.chunk_size = chunk_size\n        if hasattr(fobj, 'close'):\n            self.close = fobj.close\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        data = self.fobj.read(self.chunk_size)\n        if data:\n            return data\n        raise StopIteration\n\n\nclass WsgiResponse:\n    \"\"\"Implementation of start_response() callable as specified by PEP 3333\"\"\"\n\n    status = None\n\n    HOP_HEADERS = {\n        hdrs.CONNECTION,\n        hdrs.KEEP_ALIVE,\n        hdrs.PROXY_AUTHENTICATE,\n        hdrs.PROXY_AUTHORIZATION,\n        hdrs.TE,\n        hdrs.TRAILER,\n        hdrs.TRANSFER_ENCODING,\n        hdrs.UPGRADE,\n    }\n\n    def __init__(self, writer, message):\n        self.writer = writer\n        self.message = message\n\n    def start_response(self, status, headers, exc_info=None):\n        if exc_info:\n            try:\n                if self.status:\n                    raise exc_info[1]\n            finally:\n                exc_info = None\n\n        status_code = int(status.split(' ', 1)[0])\n\n        self.status = status\n        resp = self.response = aiohttp.Response(\n            self.writer, status_code,\n            self.message.version, self.message.should_close)\n        resp.HOP_HEADERS = self.HOP_HEADERS\n        resp.add_headers(*headers)\n\n        if resp.has_chunked_hdr:\n            resp.enable_chunked_encoding()\n\n        # send headers immediately for websocket connection\n        if status_code == 101 and resp.upgrade and resp.websocket:\n            resp.send_headers()\n        else:\n            resp._send_headers = True\n        return self.response.write\n", "path": "aiohttp/wsgi.py"}], "after_files": [{"content": "\"\"\"wsgi server.\n\nTODO:\n  * proxy protocol\n  * x-forward security\n  * wsgi file support (os.sendfile)\n\"\"\"\n\nimport asyncio\nimport inspect\nimport io\nimport os\nimport sys\nfrom urllib.parse import urlsplit\n\nimport aiohttp\nfrom aiohttp import server, hdrs\n\n__all__ = ('WSGIServerHttpProtocol',)\n\n\nclass WSGIServerHttpProtocol(server.ServerHttpProtocol):\n    \"\"\"HTTP Server that implements the Python WSGI protocol.\n\n    It uses 'wsgi.async' of 'True'. 'wsgi.input' can behave differently\n    depends on 'readpayload' constructor parameter. If readpayload is set to\n    True, wsgi server reads all incoming data into BytesIO object and\n    sends it as 'wsgi.input' environ var. If readpayload is set to false\n    'wsgi.input' is a StreamReader and application should read incoming\n    data with \"yield from environ['wsgi.input'].read()\". It defaults to False.\n    \"\"\"\n\n    SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '')\n\n    def __init__(self, app, readpayload=False, is_ssl=False, *args, **kw):\n        super().__init__(*args, **kw)\n\n        self.wsgi = app\n        self.is_ssl = is_ssl\n        self.readpayload = readpayload\n\n    def create_wsgi_response(self, message):\n        return WsgiResponse(self.writer, message)\n\n    def create_wsgi_environ(self, message, payload):\n        uri_parts = urlsplit(message.path)\n        url_scheme = 'https' if self.is_ssl else 'http'\n\n        environ = {\n            'wsgi.input': payload,\n            'wsgi.errors': sys.stderr,\n            'wsgi.version': (1, 0),\n            'wsgi.async': True,\n            'wsgi.multithread': False,\n            'wsgi.multiprocess': False,\n            'wsgi.run_once': False,\n            'wsgi.file_wrapper': FileWrapper,\n            'wsgi.url_scheme': url_scheme,\n            'SERVER_SOFTWARE': aiohttp.HttpMessage.SERVER_SOFTWARE,\n            'REQUEST_METHOD': message.method,\n            'QUERY_STRING': uri_parts.query or '',\n            'RAW_URI': message.path,\n            'SERVER_PROTOCOL': 'HTTP/%s.%s' % message.version\n        }\n\n        script_name = self.SCRIPT_NAME\n\n        for hdr_name, hdr_value in message.headers.items():\n            if hdr_name == 'SCRIPT_NAME':\n                script_name = hdr_value\n            elif hdr_name == 'CONTENT-TYPE':\n                environ['CONTENT_TYPE'] = hdr_value\n                continue\n            elif hdr_name == 'CONTENT-LENGTH':\n                environ['CONTENT_LENGTH'] = hdr_value\n                continue\n\n            key = 'HTTP_%s' % hdr_name.replace('-', '_')\n            if key in environ:\n                hdr_value = '%s,%s' % (environ[key], hdr_value)\n\n            environ[key] = hdr_value\n\n        # authors should be aware that REMOTE_HOST and REMOTE_ADDR\n        # may not qualify the remote addr\n        # also SERVER_PORT variable MUST be set to the TCP/IP port number on\n        # which this request is received from the client.\n        # http://www.ietf.org/rfc/rfc3875\n\n        remote = self.transport.get_extra_info('peername')\n        environ['REMOTE_ADDR'] = remote[0]\n        environ['REMOTE_PORT'] = remote[1]\n\n        sockname = self.transport.get_extra_info('sockname')\n        environ['SERVER_PORT'] = str(sockname[1])\n        host = message.headers.get(\"HOST\", None)\n        if host:\n            environ['SERVER_NAME'] = host.split(\":\")[0]\n        else:\n            environ['SERVER_NAME'] = sockname[0]\n\n        path_info = uri_parts.path\n        if script_name:\n            path_info = path_info.split(script_name, 1)[-1]\n\n        environ['PATH_INFO'] = path_info\n        environ['SCRIPT_NAME'] = script_name\n\n        environ['async.reader'] = self.reader\n        environ['async.writer'] = self.writer\n\n        return environ\n\n    @asyncio.coroutine\n    def handle_request(self, message, payload):\n        \"\"\"Handle a single HTTP request\"\"\"\n        now = self._loop.time()\n\n        if self.readpayload:\n            wsgiinput = io.BytesIO()\n            wsgiinput.write((yield from payload.read()))\n            wsgiinput.seek(0)\n            payload = wsgiinput\n\n        environ = self.create_wsgi_environ(message, payload)\n        response = self.create_wsgi_response(message)\n\n        riter = self.wsgi(environ, response.start_response)\n        if isinstance(riter, asyncio.Future) or inspect.isgenerator(riter):\n            riter = yield from riter\n\n        resp = response.response\n        try:\n            for item in riter:\n                if isinstance(item, asyncio.Future):\n                    item = yield from item\n                yield from resp.write(item)\n\n            yield from resp.write_eof()\n        finally:\n            if hasattr(riter, 'close'):\n                riter.close()\n\n        if resp.keep_alive():\n            self.keep_alive(True)\n\n        self.log_access(\n            message, environ, response.response, self._loop.time() - now)\n\n\nclass FileWrapper:\n    \"\"\"Custom file wrapper.\"\"\"\n\n    def __init__(self, fobj, chunk_size=8192):\n        self.fobj = fobj\n        self.chunk_size = chunk_size\n        if hasattr(fobj, 'close'):\n            self.close = fobj.close\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        data = self.fobj.read(self.chunk_size)\n        if data:\n            return data\n        raise StopIteration\n\n\nclass WsgiResponse:\n    \"\"\"Implementation of start_response() callable as specified by PEP 3333\"\"\"\n\n    status = None\n\n    HOP_HEADERS = {\n        hdrs.CONNECTION,\n        hdrs.KEEP_ALIVE,\n        hdrs.PROXY_AUTHENTICATE,\n        hdrs.PROXY_AUTHORIZATION,\n        hdrs.TE,\n        hdrs.TRAILER,\n        hdrs.TRANSFER_ENCODING,\n        hdrs.UPGRADE,\n    }\n\n    def __init__(self, writer, message):\n        self.writer = writer\n        self.message = message\n\n    def start_response(self, status, headers, exc_info=None):\n        if exc_info:\n            try:\n                if self.status:\n                    raise exc_info[1]\n            finally:\n                exc_info = None\n\n        status_code = int(status.split(' ', 1)[0])\n\n        self.status = status\n        resp = self.response = aiohttp.Response(\n            self.writer, status_code,\n            self.message.version, self.message.should_close)\n        resp.HOP_HEADERS = self.HOP_HEADERS\n        resp.add_headers(*headers)\n\n        if resp.has_chunked_hdr:\n            resp.enable_chunked_encoding()\n\n        # send headers immediately for websocket connection\n        if status_code == 101 and resp.upgrade and resp.websocket:\n            resp.send_headers()\n        else:\n            resp._send_headers = True\n        return self.response.write\n", "path": "aiohttp/wsgi.py"}]}