{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"A non-blocking, single-threaded HTTP server.\n\nTypical applications have little direct interaction with the `HTTPServer`\nclass except to start a server at the beginning of the process\n(and even that is often done indirectly via `tornado.web.Application.listen`).\n\n.. versionchanged:: 4.0\n\n   The ``HTTPRequest`` class that used to live in this module has been moved\n   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function\n\nimport socket\n\nfrom tornado.escape import native_str\nfrom tornado.http1connection import HTTP1ServerConnection, HTTP1ConnectionParameters\nfrom tornado import gen\nfrom tornado import httputil\nfrom tornado import iostream\nfrom tornado import netutil\nfrom tornado.tcpserver import TCPServer\nfrom tornado.util import Configurable\n\n\nclass HTTPServer(TCPServer, Configurable,\n                 httputil.HTTPServerConnectionDelegate):\n    r\"\"\"A non-blocking, single-threaded HTTP server.\n\n    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,\n    or, for backwards compatibility, a callback that takes an\n    `.HTTPServerRequest` as an argument. The delegate is usually a\n    `tornado.web.Application`.\n\n    `HTTPServer` supports keep-alive connections by default\n    (automatically for HTTP/1.1, or for HTTP/1.0 when the client\n    requests ``Connection: keep-alive``).\n\n    If ``xheaders`` is ``True``, we support the\n    ``X-Real-Ip``/``X-Forwarded-For`` and\n    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the\n    remote IP and URI scheme/protocol for all requests.  These headers\n    are useful when running Tornado behind a reverse proxy or load\n    balancer.  The ``protocol`` argument can also be set to ``https``\n    if Tornado is run behind an SSL-decoding proxy that does not set one of\n    the supported ``xheaders``.\n\n    By default, when parsing the ``X-Forwarded-For`` header, Tornado will\n    select the last (i.e., the closest) address on the list of hosts as the\n    remote host IP address.  To select the next server in the chain, a list of\n    trusted downstream hosts may be passed as the ``trusted_downstream``\n    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``\n    header.\n\n    To make this server serve SSL traffic, send the ``ssl_options`` keyword\n    argument with an `ssl.SSLContext` object. For compatibility with older\n    versions of Python ``ssl_options`` may also be a dictionary of keyword\n    arguments for the `ssl.wrap_socket` method.::\n\n       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)\n       ssl_ctx.load_cert_chain(os.path.join(data_dir, \"mydomain.crt\"),\n                               os.path.join(data_dir, \"mydomain.key\"))\n       HTTPServer(application, ssl_options=ssl_ctx)\n\n    `HTTPServer` initialization follows one of three patterns (the\n    initialization methods are defined on `tornado.tcpserver.TCPServer`):\n\n    1. `~tornado.tcpserver.TCPServer.listen`: simple single-process::\n\n            server = HTTPServer(app)\n            server.listen(8888)\n            IOLoop.current().start()\n\n       In many cases, `tornado.web.Application.listen` can be used to avoid\n       the need to explicitly create the `HTTPServer`.\n\n    2. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:\n       simple multi-process::\n\n            server = HTTPServer(app)\n            server.bind(8888)\n            server.start(0)  # Forks multiple sub-processes\n            IOLoop.current().start()\n\n       When using this interface, an `.IOLoop` must *not* be passed\n       to the `HTTPServer` constructor.  `~.TCPServer.start` will always start\n       the server on the default singleton `.IOLoop`.\n\n    3. `~tornado.tcpserver.TCPServer.add_sockets`: advanced multi-process::\n\n            sockets = tornado.netutil.bind_sockets(8888)\n            tornado.process.fork_processes(0)\n            server = HTTPServer(app)\n            server.add_sockets(sockets)\n            IOLoop.current().start()\n\n       The `~.TCPServer.add_sockets` interface is more complicated,\n       but it can be used with `tornado.process.fork_processes` to\n       give you more flexibility in when the fork happens.\n       `~.TCPServer.add_sockets` can also be used in single-process\n       servers if you want to create your listening sockets in some\n       way other than `tornado.netutil.bind_sockets`.\n\n    .. versionchanged:: 4.0\n       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,\n       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``\n       arguments.  Added support for `.HTTPServerConnectionDelegate`\n       instances as ``request_callback``.\n\n    .. versionchanged:: 4.1\n       `.HTTPServerConnectionDelegate.start_request` is now called with\n       two arguments ``(server_conn, request_conn)`` (in accordance with the\n       documentation) instead of one ``(request_conn)``.\n\n    .. versionchanged:: 4.2\n       `HTTPServer` is now a subclass of `tornado.util.Configurable`.\n\n    .. versionchanged:: 4.5\n       Added the ``trusted_downstream`` argument.\n\n    .. versionchanged:: 5.0\n       The ``io_loop`` argument has been removed.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        # Ignore args to __init__; real initialization belongs in\n        # initialize since we're Configurable. (there's something\n        # weird in initialization order between this class,\n        # Configurable, and TCPServer so we can't leave __init__ out\n        # completely)\n        pass\n\n    def initialize(self, request_callback, no_keep_alive=False,\n                   xheaders=False, ssl_options=None, protocol=None,\n                   decompress_request=False,\n                   chunk_size=None, max_header_size=None,\n                   idle_connection_timeout=None, body_timeout=None,\n                   max_body_size=None, max_buffer_size=None,\n                   trusted_downstream=None):\n        self.request_callback = request_callback\n        self.xheaders = xheaders\n        self.protocol = protocol\n        self.conn_params = HTTP1ConnectionParameters(\n            decompress=decompress_request,\n            chunk_size=chunk_size,\n            max_header_size=max_header_size,\n            header_timeout=idle_connection_timeout or 3600,\n            max_body_size=max_body_size,\n            body_timeout=body_timeout,\n            no_keep_alive=no_keep_alive)\n        TCPServer.__init__(self, ssl_options=ssl_options,\n                           max_buffer_size=max_buffer_size,\n                           read_chunk_size=chunk_size)\n        self._connections = set()\n        self.trusted_downstream = trusted_downstream\n\n    @classmethod\n    def configurable_base(cls):\n        return HTTPServer\n\n    @classmethod\n    def configurable_default(cls):\n        return HTTPServer\n\n    @gen.coroutine\n    def close_all_connections(self):\n        while self._connections:\n            # Peek at an arbitrary element of the set\n            conn = next(iter(self._connections))\n            yield conn.close()\n\n    def handle_stream(self, stream, address):\n        context = _HTTPRequestContext(stream, address,\n                                      self.protocol,\n                                      self.trusted_downstream)\n        conn = HTTP1ServerConnection(\n            stream, self.conn_params, context)\n        self._connections.add(conn)\n        conn.start_serving(self)\n\n    def start_request(self, server_conn, request_conn):\n        if isinstance(self.request_callback, httputil.HTTPServerConnectionDelegate):\n            delegate = self.request_callback.start_request(server_conn, request_conn)\n        else:\n            delegate = _CallableAdapter(self.request_callback, request_conn)\n\n        if self.xheaders:\n            delegate = _ProxyAdapter(delegate, request_conn)\n\n        return delegate\n\n    def on_close(self, server_conn):\n        self._connections.remove(server_conn)\n\n\nclass _CallableAdapter(httputil.HTTPMessageDelegate):\n    def __init__(self, request_callback, request_conn):\n        self.connection = request_conn\n        self.request_callback = request_callback\n        self.request = None\n        self.delegate = None\n        self._chunks = []\n\n    def headers_received(self, start_line, headers):\n        self.request = httputil.HTTPServerRequest(\n            connection=self.connection, start_line=start_line,\n            headers=headers)\n\n    def data_received(self, chunk):\n        self._chunks.append(chunk)\n\n    def finish(self):\n        self.request.body = b''.join(self._chunks)\n        self.request._parse_body()\n        self.request_callback(self.request)\n\n    def on_connection_close(self):\n        self._chunks = None\n\n\nclass _HTTPRequestContext(object):\n    def __init__(self, stream, address, protocol, trusted_downstream=None):\n        self.address = address\n        # Save the socket's address family now so we know how to\n        # interpret self.address even after the stream is closed\n        # and its socket attribute replaced with None.\n        if stream.socket is not None:\n            self.address_family = stream.socket.family\n        else:\n            self.address_family = None\n        # In HTTPServerRequest we want an IP, not a full socket address.\n        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and\n                address is not None):\n            self.remote_ip = address[0]\n        else:\n            # Unix (or other) socket; fake the remote address.\n            self.remote_ip = '0.0.0.0'\n        if protocol:\n            self.protocol = protocol\n        elif isinstance(stream, iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n        self._orig_remote_ip = self.remote_ip\n        self._orig_protocol = self.protocol\n        self.trusted_downstream = set(trusted_downstream or [])\n\n    def __str__(self):\n        if self.address_family in (socket.AF_INET, socket.AF_INET6):\n            return self.remote_ip\n        elif isinstance(self.address, bytes):\n            # Python 3 with the -bb option warns about str(bytes),\n            # so convert it explicitly.\n            # Unix socket addresses are str on mac but bytes on linux.\n            return native_str(self.address)\n        else:\n            return str(self.address)\n\n    def _apply_xheaders(self, headers):\n        \"\"\"Rewrite the ``remote_ip`` and ``protocol`` fields.\"\"\"\n        # Squid uses X-Forwarded-For, others use X-Real-Ip\n        ip = headers.get(\"X-Forwarded-For\", self.remote_ip)\n        # Skip trusted downstream hosts in X-Forwarded-For list\n        for ip in (cand.strip() for cand in reversed(ip.split(','))):\n            if ip not in self.trusted_downstream:\n                break\n        ip = headers.get(\"X-Real-Ip\", ip)\n        if netutil.is_valid_ip(ip):\n            self.remote_ip = ip\n        # AWS uses X-Forwarded-Proto\n        proto_header = headers.get(\n            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",\n                                    self.protocol))\n        if proto_header in (\"http\", \"https\"):\n            self.protocol = proto_header\n\n    def _unapply_xheaders(self):\n        \"\"\"Undo changes from `_apply_xheaders`.\n\n        Xheaders are per-request so they should not leak to the next\n        request on the same connection.\n        \"\"\"\n        self.remote_ip = self._orig_remote_ip\n        self.protocol = self._orig_protocol\n\n\nclass _ProxyAdapter(httputil.HTTPMessageDelegate):\n    def __init__(self, delegate, request_conn):\n        self.connection = request_conn\n        self.delegate = delegate\n\n    def headers_received(self, start_line, headers):\n        self.connection.context._apply_xheaders(headers)\n        return self.delegate.headers_received(start_line, headers)\n\n    def data_received(self, chunk):\n        return self.delegate.data_received(chunk)\n\n    def finish(self):\n        self.delegate.finish()\n        self._cleanup()\n\n    def on_connection_close(self):\n        self.delegate.on_connection_close()\n        self._cleanup()\n\n    def _cleanup(self):\n        self.connection.context._unapply_xheaders()\n\n\nHTTPRequest = httputil.HTTPServerRequest\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"A non-blocking, single-threaded HTTP server.\n\nTypical applications have little direct interaction with the `HTTPServer`\nclass except to start a server at the beginning of the process\n(and even that is often done indirectly via `tornado.web.Application.listen`).\n\n.. versionchanged:: 4.0\n\n   The ``HTTPRequest`` class that used to live in this module has been moved\n   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function\n\nimport socket\n\nfrom tornado.escape import native_str\nfrom tornado.http1connection import HTTP1ServerConnection, HTTP1ConnectionParameters\nfrom tornado import gen\nfrom tornado import httputil\nfrom tornado import iostream\nfrom tornado import netutil\nfrom tornado.tcpserver import TCPServer\nfrom tornado.util import Configurable\n\n\nclass HTTPServer(TCPServer, Configurable,\n                 httputil.HTTPServerConnectionDelegate):\n    r\"\"\"A non-blocking, single-threaded HTTP server.\n\n    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,\n    or, for backwards compatibility, a callback that takes an\n    `.HTTPServerRequest` as an argument. The delegate is usually a\n    `tornado.web.Application`.\n\n    `HTTPServer` supports keep-alive connections by default\n    (automatically for HTTP/1.1, or for HTTP/1.0 when the client\n    requests ``Connection: keep-alive``).\n\n    If ``xheaders`` is ``True``, we support the\n    ``X-Real-Ip``/``X-Forwarded-For`` and\n    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the\n    remote IP and URI scheme/protocol for all requests.  These headers\n    are useful when running Tornado behind a reverse proxy or load\n    balancer.  The ``protocol`` argument can also be set to ``https``\n    if Tornado is run behind an SSL-decoding proxy that does not set one of\n    the supported ``xheaders``.\n\n    By default, when parsing the ``X-Forwarded-For`` header, Tornado will\n    select the last (i.e., the closest) address on the list of hosts as the\n    remote host IP address.  To select the next server in the chain, a list of\n    trusted downstream hosts may be passed as the ``trusted_downstream``\n    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``\n    header.\n\n    To make this server serve SSL traffic, send the ``ssl_options`` keyword\n    argument with an `ssl.SSLContext` object. For compatibility with older\n    versions of Python ``ssl_options`` may also be a dictionary of keyword\n    arguments for the `ssl.wrap_socket` method.::\n\n       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)\n       ssl_ctx.load_cert_chain(os.path.join(data_dir, \"mydomain.crt\"),\n                               os.path.join(data_dir, \"mydomain.key\"))\n       HTTPServer(application, ssl_options=ssl_ctx)\n\n    `HTTPServer` initialization follows one of three patterns (the\n    initialization methods are defined on `tornado.tcpserver.TCPServer`):\n\n    1. `~tornado.tcpserver.TCPServer.listen`: simple single-process::\n\n            server = HTTPServer(app)\n            server.listen(8888)\n            IOLoop.current().start()\n\n       In many cases, `tornado.web.Application.listen` can be used to avoid\n       the need to explicitly create the `HTTPServer`.\n\n    2. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:\n       simple multi-process::\n\n            server = HTTPServer(app)\n            server.bind(8888)\n            server.start(0)  # Forks multiple sub-processes\n            IOLoop.current().start()\n\n       When using this interface, an `.IOLoop` must *not* be passed\n       to the `HTTPServer` constructor.  `~.TCPServer.start` will always start\n       the server on the default singleton `.IOLoop`.\n\n    3. `~tornado.tcpserver.TCPServer.add_sockets`: advanced multi-process::\n\n            sockets = tornado.netutil.bind_sockets(8888)\n            tornado.process.fork_processes(0)\n            server = HTTPServer(app)\n            server.add_sockets(sockets)\n            IOLoop.current().start()\n\n       The `~.TCPServer.add_sockets` interface is more complicated,\n       but it can be used with `tornado.process.fork_processes` to\n       give you more flexibility in when the fork happens.\n       `~.TCPServer.add_sockets` can also be used in single-process\n       servers if you want to create your listening sockets in some\n       way other than `tornado.netutil.bind_sockets`.\n\n    .. versionchanged:: 4.0\n       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,\n       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``\n       arguments.  Added support for `.HTTPServerConnectionDelegate`\n       instances as ``request_callback``.\n\n    .. versionchanged:: 4.1\n       `.HTTPServerConnectionDelegate.start_request` is now called with\n       two arguments ``(server_conn, request_conn)`` (in accordance with the\n       documentation) instead of one ``(request_conn)``.\n\n    .. versionchanged:: 4.2\n       `HTTPServer` is now a subclass of `tornado.util.Configurable`.\n\n    .. versionchanged:: 4.5\n       Added the ``trusted_downstream`` argument.\n\n    .. versionchanged:: 5.0\n       The ``io_loop`` argument has been removed.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        # Ignore args to __init__; real initialization belongs in\n        # initialize since we're Configurable. (there's something\n        # weird in initialization order between this class,\n        # Configurable, and TCPServer so we can't leave __init__ out\n        # completely)\n        pass\n\n    def initialize(self, request_callback, no_keep_alive=False,\n                   xheaders=False, ssl_options=None, protocol=None,\n                   decompress_request=False,\n                   chunk_size=None, max_header_size=None,\n                   idle_connection_timeout=None, body_timeout=None,\n                   max_body_size=None, max_buffer_size=None,\n                   trusted_downstream=None):\n        self.request_callback = request_callback\n        self.xheaders = xheaders\n        self.protocol = protocol\n        self.conn_params = HTTP1ConnectionParameters(\n            decompress=decompress_request,\n            chunk_size=chunk_size,\n            max_header_size=max_header_size,\n            header_timeout=idle_connection_timeout or 3600,\n            max_body_size=max_body_size,\n            body_timeout=body_timeout,\n            no_keep_alive=no_keep_alive)\n        TCPServer.__init__(self, ssl_options=ssl_options,\n                           max_buffer_size=max_buffer_size,\n                           read_chunk_size=chunk_size)\n        self._connections = set()\n        self.trusted_downstream = trusted_downstream\n\n    @classmethod\n    def configurable_base(cls):\n        return HTTPServer\n\n    @classmethod\n    def configurable_default(cls):\n        return HTTPServer\n\n    @gen.coroutine\n    def close_all_connections(self):\n        while self._connections:\n            # Peek at an arbitrary element of the set\n            conn = next(iter(self._connections))\n            yield conn.close()\n\n    def handle_stream(self, stream, address):\n        context = _HTTPRequestContext(stream, address,\n                                      self.protocol,\n                                      self.trusted_downstream)\n        conn = HTTP1ServerConnection(\n            stream, self.conn_params, context)\n        self._connections.add(conn)\n        conn.start_serving(self)\n\n    def start_request(self, server_conn, request_conn):\n        if isinstance(self.request_callback, httputil.HTTPServerConnectionDelegate):\n            delegate = self.request_callback.start_request(server_conn, request_conn)\n        else:\n            delegate = _CallableAdapter(self.request_callback, request_conn)\n\n        if self.xheaders:\n            delegate = _ProxyAdapter(delegate, request_conn)\n\n        return delegate\n\n    def on_close(self, server_conn):\n        self._connections.remove(server_conn)\n\n\nclass _CallableAdapter(httputil.HTTPMessageDelegate):\n    def __init__(self, request_callback, request_conn):\n        self.connection = request_conn\n        self.request_callback = request_callback\n        self.request = None\n        self.delegate = None\n        self._chunks = []\n\n    def headers_received(self, start_line, headers):\n        self.request = httputil.HTTPServerRequest(\n            connection=self.connection, start_line=start_line,\n            headers=headers)\n\n    def data_received(self, chunk):\n        self._chunks.append(chunk)\n\n    def finish(self):\n        self.request.body = b''.join(self._chunks)\n        self.request._parse_body()\n        self.request_callback(self.request)\n\n    def on_connection_close(self):\n        self._chunks = None\n\n\nclass _HTTPRequestContext(object):\n    def __init__(self, stream, address, protocol, trusted_downstream=None):\n        self.address = address\n        # Save the socket's address family now so we know how to\n        # interpret self.address even after the stream is closed\n        # and its socket attribute replaced with None.\n        if stream.socket is not None:\n            self.address_family = stream.socket.family\n        else:\n            self.address_family = None\n        # In HTTPServerRequest we want an IP, not a full socket address.\n        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and\n                address is not None):\n            self.remote_ip = address[0]\n        else:\n            # Unix (or other) socket; fake the remote address.\n            self.remote_ip = '0.0.0.0'\n        if protocol:\n            self.protocol = protocol\n        elif isinstance(stream, iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n        self._orig_remote_ip = self.remote_ip\n        self._orig_protocol = self.protocol\n        self.trusted_downstream = set(trusted_downstream or [])\n\n    def __str__(self):\n        if self.address_family in (socket.AF_INET, socket.AF_INET6):\n            return self.remote_ip\n        elif isinstance(self.address, bytes):\n            # Python 3 with the -bb option warns about str(bytes),\n            # so convert it explicitly.\n            # Unix socket addresses are str on mac but bytes on linux.\n            return native_str(self.address)\n        else:\n            return str(self.address)\n\n    def _apply_xheaders(self, headers):\n        \"\"\"Rewrite the ``remote_ip`` and ``protocol`` fields.\"\"\"\n        # Squid uses X-Forwarded-For, others use X-Real-Ip\n        ip = headers.get(\"X-Forwarded-For\", self.remote_ip)\n        # Skip trusted downstream hosts in X-Forwarded-For list\n        for ip in (cand.strip() for cand in reversed(ip.split(','))):\n            if ip not in self.trusted_downstream:\n                break\n        ip = headers.get(\"X-Real-Ip\", ip)\n        if netutil.is_valid_ip(ip):\n            self.remote_ip = ip\n        # AWS uses X-Forwarded-Proto\n        proto_header = headers.get(\n            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",\n                                    self.protocol))\n        if proto_header:\n            # use only the last proto entry if there is more than one\n            # TODO: support trusting mutiple layers of proxied protocol\n            proto_header = proto_header.split(',')[-1].strip()\n        if proto_header in (\"http\", \"https\"):\n            self.protocol = proto_header\n\n    def _unapply_xheaders(self):\n        \"\"\"Undo changes from `_apply_xheaders`.\n\n        Xheaders are per-request so they should not leak to the next\n        request on the same connection.\n        \"\"\"\n        self.remote_ip = self._orig_remote_ip\n        self.protocol = self._orig_protocol\n\n\nclass _ProxyAdapter(httputil.HTTPMessageDelegate):\n    def __init__(self, delegate, request_conn):\n        self.connection = request_conn\n        self.delegate = delegate\n\n    def headers_received(self, start_line, headers):\n        self.connection.context._apply_xheaders(headers)\n        return self.delegate.headers_received(start_line, headers)\n\n    def data_received(self, chunk):\n        return self.delegate.data_received(chunk)\n\n    def finish(self):\n        self.delegate.finish()\n        self._cleanup()\n\n    def on_connection_close(self):\n        self.delegate.on_connection_close()\n        self._cleanup()\n\n    def _cleanup(self):\n        self.connection.context._unapply_xheaders()\n\n\nHTTPRequest = httputil.HTTPServerRequest\n",
            "header": {
                "file": {
                    "path": "tornado/httpserver.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "8921a051",
                "new_commit_hash": "da755f84",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/httpserver.py"
            },
            "plus_file": {
                "path": "b/tornado/httpserver.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 287,
                            "length": 6
                        },
                        "new_range": {
                            "start": 287,
                            "length": 10
                        },
                        "section": "class _HTTPRequestContext(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        proto_header = headers.get(",
                                "type": "context"
                            },
                            {
                                "content": "            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",",
                                "type": "context"
                            },
                            {
                                "content": "                                    self.protocol))",
                                "type": "context"
                            },
                            {
                                "content": "        if proto_header:",
                                "type": "added"
                            },
                            {
                                "content": "            # use only the last proto entry if there is more than one",
                                "type": "added"
                            },
                            {
                                "content": "            # TODO: support trusting mutiple layers of proxied protocol",
                                "type": "added"
                            },
                            {
                                "content": "            proto_header = proto_header.split(',')[-1].strip()",
                                "type": "added"
                            },
                            {
                                "content": "        if proto_header in (\"http\", \"https\"):",
                                "type": "context"
                            },
                            {
                                "content": "            self.protocol = proto_header",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/httpserver.py",
                            "type": "class",
                            "name": "_HTTPRequestContext",
                            "content": "class _HTTPRequestContext(object):\n    def __init__(self, stream, address, protocol, trusted_downstream=None):\n        self.address = address\n        # Save the socket's address family now so we know how to\n        # interpret self.address even after the stream is closed\n        # and its socket attribute replaced with None.\n        if stream.socket is not None:\n            self.address_family = stream.socket.family\n        else:\n            self.address_family = None\n        # In HTTPServerRequest we want an IP, not a full socket address.\n        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and\n                address is not None):\n            self.remote_ip = address[0]\n        else:\n            # Unix (or other) socket; fake the remote address.\n            self.remote_ip = '0.0.0.0'\n        if protocol:\n            self.protocol = protocol\n        elif isinstance(stream, iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n        self._orig_remote_ip = self.remote_ip\n        self._orig_protocol = self.protocol\n        self.trusted_downstream = set(trusted_downstream or [])\n\n    def __str__(self):\n        if self.address_family in (socket.AF_INET, socket.AF_INET6):\n            return self.remote_ip\n        elif isinstance(self.address, bytes):\n            # Python 3 with the -bb option warns about str(bytes),\n            # so convert it explicitly.\n            # Unix socket addresses are str on mac but bytes on linux.\n            return native_str(self.address)\n        else:\n            return str(self.address)\n\n    def _apply_xheaders(self, headers):\n        \"\"\"Rewrite the ``remote_ip`` and ``protocol`` fields.\"\"\"\n        # Squid uses X-Forwarded-For, others use X-Real-Ip\n        ip = headers.get(\"X-Forwarded-For\", self.remote_ip)\n        # Skip trusted downstream hosts in X-Forwarded-For list\n        for ip in (cand.strip() for cand in reversed(ip.split(','))):\n            if ip not in self.trusted_downstream:\n                break\n        ip = headers.get(\"X-Real-Ip\", ip)\n        if netutil.is_valid_ip(ip):\n            self.remote_ip = ip\n        # AWS uses X-Forwarded-Proto\n        proto_header = headers.get(\n            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",\n                                    self.protocol))\n        if proto_header:\n            # use only the last proto entry if there is more than one\n            # TODO: support trusting mutiple layers of proxied protocol\n            proto_header = proto_header.split(',')[-1].strip()\n        if proto_header in (\"http\", \"https\"):\n            self.protocol = proto_header\n\n    def _unapply_xheaders(self):\n        \"\"\"Undo changes from `_apply_xheaders`.\n\n        Xheaders are per-request so they should not leak to the next\n        request on the same connection.\n        \"\"\"\n        self.remote_ip = self._orig_remote_ip\n        self.protocol = self._orig_protocol",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 237,
                            "end_lineno": 304,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/httpserver.py",
                            "type": "method",
                            "name": "_HTTPRequestContext._apply_xheaders",
                            "content": "class _HTTPRequestContext(object):\n    def __init__(self, stream, address, protocol, trusted_downstream=None):\n        self.address = address\n        # Save the socket's address family now so we know how to\n        # interpret self.address even after the stream is closed\n        # and its socket attribute replaced with None.\n        if stream.socket is not None:\n            self.address_family = stream.socket.family\n        else:\n            self.address_family = None\n        # In HTTPServerRequest we want an IP, not a full socket address.\n        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and\n                address is not None):\n            self.remote_ip = address[0]\n        else:\n            # Unix (or other) socket; fake the remote address.\n            self.remote_ip = '0.0.0.0'\n        if protocol:\n            self.protocol = protocol\n        elif isinstance(stream, iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n        self._orig_remote_ip = self.remote_ip\n        self._orig_protocol = self.protocol\n        self.trusted_downstream = set(trusted_downstream or [])\n\n    def __str__(self):\n        if self.address_family in (socket.AF_INET, socket.AF_INET6):\n            return self.remote_ip\n        elif isinstance(self.address, bytes):\n            # Python 3 with the -bb option warns about str(bytes),\n            # so convert it explicitly.\n            # Unix socket addresses are str on mac but bytes on linux.\n            return native_str(self.address)\n        else:\n            return str(self.address)\n\n    def _apply_xheaders(self, headers):\n        \"\"\"Rewrite the ``remote_ip`` and ``protocol`` fields.\"\"\"\n        # Squid uses X-Forwarded-For, others use X-Real-Ip\n        ip = headers.get(\"X-Forwarded-For\", self.remote_ip)\n        # Skip trusted downstream hosts in X-Forwarded-For list\n        for ip in (cand.strip() for cand in reversed(ip.split(','))):\n            if ip not in self.trusted_downstream:\n                break\n        ip = headers.get(\"X-Real-Ip\", ip)\n        if netutil.is_valid_ip(ip):\n            self.remote_ip = ip\n        # AWS uses X-Forwarded-Proto\n        proto_header = headers.get(\n            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",\n                                    self.protocol))\n        if proto_header:\n            # use only the last proto entry if there is more than one\n            # TODO: support trusting mutiple layers of proxied protocol\n            proto_header = proto_header.split(',')[-1].strip()\n        if proto_header in (\"http\", \"https\"):\n            self.protocol = proto_header\n\n    def _unapply_xheaders(self):\n        \"\"\"Undo changes from `_apply_xheaders`.\n\n        Xheaders are per-request so they should not leak to the next\n        request on the same connection.\n        \"\"\"\n        self.remote_ip = self._orig_remote_ip\n        self.protocol = self._orig_protocol",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 275,
                            "end_lineno": 295,
                            "parent": {
                                "file_name": "tornado/httpserver.py",
                                "type": "class",
                                "name": "_HTTPRequestContext",
                                "content": "class _HTTPRequestContext(object):\n    def __init__(self, stream, address, protocol, trusted_downstream=None):\n        self.address = address\n        # Save the socket's address family now so we know how to\n        # interpret self.address even after the stream is closed\n        # and its socket attribute replaced with None.\n        if stream.socket is not None:\n            self.address_family = stream.socket.family\n        else:\n            self.address_family = None\n        # In HTTPServerRequest we want an IP, not a full socket address.\n        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and\n                address is not None):\n            self.remote_ip = address[0]\n        else:\n            # Unix (or other) socket; fake the remote address.\n            self.remote_ip = '0.0.0.0'\n        if protocol:\n            self.protocol = protocol\n        elif isinstance(stream, iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n        self._orig_remote_ip = self.remote_ip\n        self._orig_protocol = self.protocol\n        self.trusted_downstream = set(trusted_downstream or [])\n\n    def __str__(self):\n        if self.address_family in (socket.AF_INET, socket.AF_INET6):\n            return self.remote_ip\n        elif isinstance(self.address, bytes):\n            # Python 3 with the -bb option warns about str(bytes),\n            # so convert it explicitly.\n            # Unix socket addresses are str on mac but bytes on linux.\n            return native_str(self.address)\n        else:\n            return str(self.address)\n\n    def _apply_xheaders(self, headers):\n        \"\"\"Rewrite the ``remote_ip`` and ``protocol`` fields.\"\"\"\n        # Squid uses X-Forwarded-For, others use X-Real-Ip\n        ip = headers.get(\"X-Forwarded-For\", self.remote_ip)\n        # Skip trusted downstream hosts in X-Forwarded-For list\n        for ip in (cand.strip() for cand in reversed(ip.split(','))):\n            if ip not in self.trusted_downstream:\n                break\n        ip = headers.get(\"X-Real-Ip\", ip)\n        if netutil.is_valid_ip(ip):\n            self.remote_ip = ip\n        # AWS uses X-Forwarded-Proto\n        proto_header = headers.get(\n            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",\n                                    self.protocol))\n        if proto_header:\n            # use only the last proto entry if there is more than one\n            # TODO: support trusting mutiple layers of proxied protocol\n            proto_header = proto_header.split(',')[-1].strip()\n        if proto_header in (\"http\", \"https\"):\n            self.protocol = proto_header\n\n    def _unapply_xheaders(self):\n        \"\"\"Undo changes from `_apply_xheaders`.\n\n        Xheaders are per-request so they should not leak to the next\n        request on the same connection.\n        \"\"\"\n        self.remote_ip = self._orig_remote_ip\n        self.protocol = self._orig_protocol",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 237,
                                "end_lineno": 304,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#!/usr/bin/env python\n\n\nfrom __future__ import absolute_import, division, print_function\nfrom tornado import netutil\nfrom tornado.escape import json_decode, json_encode, utf8, _unicode, recursive_unicode, native_str\nfrom tornado import gen\nfrom tornado.http1connection import HTTP1Connection\nfrom tornado.httpserver import HTTPServer\nfrom tornado.httputil import HTTPHeaders, HTTPMessageDelegate, HTTPServerConnectionDelegate, ResponseStartLine\nfrom tornado.iostream import IOStream\nfrom tornado.log import gen_log\nfrom tornado.netutil import ssl_options_to_context\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog, gen_test\nfrom tornado.test.util import unittest, skipOnTravis\nfrom tornado.web import Application, RequestHandler, asynchronous, stream_request_body\nfrom contextlib import closing\nimport datetime\nimport gzip\nimport os\nimport shutil\nimport socket\nimport ssl\nimport sys\nimport tempfile\nfrom io import BytesIO\n\n\ndef read_stream_body(stream, callback):\n    \"\"\"Reads an HTTP response from `stream` and runs callback with its\n    start_line, headers and body.\"\"\"\n    chunks = []\n\n    class Delegate(HTTPMessageDelegate):\n        def headers_received(self, start_line, headers):\n            self.headers = headers\n            self.start_line = start_line\n\n        def data_received(self, chunk):\n            chunks.append(chunk)\n\n        def finish(self):\n            conn.detach()\n            callback((self.start_line, self.headers, b''.join(chunks)))\n    conn = HTTP1Connection(stream, True)\n    conn.read_response(Delegate())\n\n\nclass HandlerBaseTestCase(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', self.__class__.Handler)])\n\n    def fetch_json(self, *args, **kwargs):\n        response = self.fetch(*args, **kwargs)\n        response.rethrow()\n        return json_decode(response.body)\n\n\nclass HelloWorldRequestHandler(RequestHandler):\n    def initialize(self, protocol=\"http\"):\n        self.expected_protocol = protocol\n\n    def get(self):\n        if self.request.protocol != self.expected_protocol:\n            raise Exception(\"unexpected protocol\")\n        self.finish(\"Hello world\")\n\n    def post(self):\n        self.finish(\"Got %d bytes in POST\" % len(self.request.body))\n\n\n# In pre-1.0 versions of openssl, SSLv23 clients always send SSLv2\n# ClientHello messages, which are rejected by SSLv3 and TLSv1\n# servers.  Note that while the OPENSSL_VERSION_INFO was formally\n# introduced in python3.2, it was present but undocumented in\n# python 2.7\nskipIfOldSSL = unittest.skipIf(\n    getattr(ssl, 'OPENSSL_VERSION_INFO', (0, 0)) < (1, 0),\n    \"old version of ssl module and/or openssl\")\n\n\nclass BaseSSLTest(AsyncHTTPSTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler,\n                             dict(protocol=\"https\"))])\n\n\nclass SSLTestMixin(object):\n    def get_ssl_options(self):\n        return dict(ssl_version=self.get_ssl_version(),  # type: ignore\n                    **AsyncHTTPSTestCase.get_ssl_options())\n\n    def get_ssl_version(self):\n        raise NotImplementedError()\n\n    def test_ssl(self):\n        response = self.fetch('/')\n        self.assertEqual(response.body, b\"Hello world\")\n\n    def test_large_post(self):\n        response = self.fetch('/',\n                              method='POST',\n                              body='A' * 5000)\n        self.assertEqual(response.body, b\"Got 5000 bytes in POST\")\n\n    def test_non_ssl_request(self):\n        # Make sure the server closes the connection when it gets a non-ssl\n        # connection, rather than waiting for a timeout or otherwise\n        # misbehaving.\n        with ExpectLog(gen_log, '(SSL Error|uncaught exception)'):\n            with ExpectLog(gen_log, 'Uncaught exception', required=False):\n                self.http_client.fetch(\n                    self.get_url(\"/\").replace('https:', 'http:'),\n                    self.stop,\n                    request_timeout=3600,\n                    connect_timeout=3600)\n                response = self.wait()\n        self.assertEqual(response.code, 599)\n\n    def test_error_logging(self):\n        # No stack traces are logged for SSL errors.\n        with ExpectLog(gen_log, 'SSL Error') as expect_log:\n            self.http_client.fetch(\n                self.get_url(\"/\").replace(\"https:\", \"http:\"),\n                self.stop)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n        self.assertFalse(expect_log.logged_stack)\n\n# Python's SSL implementation differs significantly between versions.\n# For example, SSLv3 and TLSv1 throw an exception if you try to read\n# from the socket before the handshake is complete, but the default\n# of SSLv23 allows it.\n\n\nclass SSLv23Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_SSLv23\n\n\n@skipIfOldSSL\nclass SSLv3Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_SSLv3\n\n\n@skipIfOldSSL\nclass TLSv1Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_TLSv1\n\n\nclass SSLContextTest(BaseSSLTest, SSLTestMixin):\n    def get_ssl_options(self):\n        context = ssl_options_to_context(\n            AsyncHTTPSTestCase.get_ssl_options(self))\n        assert isinstance(context, ssl.SSLContext)\n        return context\n\n\nclass BadSSLOptionsTest(unittest.TestCase):\n    def test_missing_arguments(self):\n        application = Application()\n        self.assertRaises(KeyError, HTTPServer, application, ssl_options={\n            \"keyfile\": \"/__missing__.crt\",\n        })\n\n    def test_missing_key(self):\n        \"\"\"A missing SSL key should cause an immediate exception.\"\"\"\n\n        application = Application()\n        module_dir = os.path.dirname(__file__)\n        existing_certificate = os.path.join(module_dir, 'test.crt')\n        existing_key = os.path.join(module_dir, 'test.key')\n\n        self.assertRaises((ValueError, IOError),\n                          HTTPServer, application, ssl_options={\n                              \"certfile\": \"/__mising__.crt\",\n        })\n        self.assertRaises((ValueError, IOError),\n                          HTTPServer, application, ssl_options={\n                              \"certfile\": existing_certificate,\n                              \"keyfile\": \"/__missing__.key\"\n        })\n\n        # This actually works because both files exist\n        HTTPServer(application, ssl_options={\n                   \"certfile\": existing_certificate,\n                   \"keyfile\": existing_key,\n                   })\n\n\nclass MultipartTestHandler(RequestHandler):\n    def post(self):\n        self.finish({\"header\": self.request.headers[\"X-Header-Encoding-Test\"],\n                     \"argument\": self.get_argument(\"argument\"),\n                     \"filename\": self.request.files[\"files\"][0].filename,\n                     \"filebody\": _unicode(self.request.files[\"files\"][0][\"body\"]),\n                     })\n\n\n# This test is also called from wsgi_test\nclass HTTPConnectionTest(AsyncHTTPTestCase):\n    def get_handlers(self):\n        return [(\"/multipart\", MultipartTestHandler),\n                (\"/hello\", HelloWorldRequestHandler)]\n\n    def get_app(self):\n        return Application(self.get_handlers())\n\n    def raw_fetch(self, headers, body, newline=b\"\\r\\n\"):\n        with closing(IOStream(socket.socket())) as stream:\n            stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n            self.wait()\n            stream.write(\n                newline.join(headers +\n                             [utf8(\"Content-Length: %d\" % len(body))]) +\n                newline + newline + body)\n            read_stream_body(stream, self.stop)\n            start_line, headers, body = self.wait()\n            return body\n\n    def test_multipart_form(self):\n        # Encodings here are tricky:  Headers are latin1, bodies can be\n        # anything (we use utf8 by default).\n        response = self.raw_fetch([\n            b\"POST /multipart HTTP/1.0\",\n            b\"Content-Type: multipart/form-data; boundary=1234567890\",\n            b\"X-Header-encoding-test: \\xe9\",\n        ],\n            b\"\\r\\n\".join([\n                b\"Content-Disposition: form-data; name=argument\",\n                b\"\",\n                u\"\\u00e1\".encode(\"utf-8\"),\n                b\"--1234567890\",\n                u'Content-Disposition: form-data; name=\"files\"; filename=\"\\u00f3\"'.encode(\"utf8\"),\n                b\"\",\n                u\"\\u00fa\".encode(\"utf-8\"),\n                b\"--1234567890--\",\n                b\"\",\n            ]))\n        data = json_decode(response)\n        self.assertEqual(u\"\\u00e9\", data[\"header\"])\n        self.assertEqual(u\"\\u00e1\", data[\"argument\"])\n        self.assertEqual(u\"\\u00f3\", data[\"filename\"])\n        self.assertEqual(u\"\\u00fa\", data[\"filebody\"])\n\n    def test_newlines(self):\n        # We support both CRLF and bare LF as line separators.\n        for newline in (b\"\\r\\n\", b\"\\n\"):\n            response = self.raw_fetch([b\"GET /hello HTTP/1.0\"], b\"\",\n                                      newline=newline)\n            self.assertEqual(response, b'Hello world')\n\n    def test_100_continue(self):\n        # Run through a 100-continue interaction by hand:\n        # When given Expect: 100-continue, we get a 100 response after the\n        # headers, and then the real response after the body.\n        stream = IOStream(socket.socket())\n        stream.connect((\"127.0.0.1\", self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"\\r\\n\".join([b\"POST /hello HTTP/1.1\",\n                                   b\"Content-Length: 1024\",\n                                   b\"Expect: 100-continue\",\n                                   b\"Connection: close\",\n                                   b\"\\r\\n\"]), callback=self.stop)\n        self.wait()\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.1 100 \"), data)\n        stream.write(b\"a\" * 1024)\n        stream.read_until(b\"\\r\\n\", self.stop)\n        first_line = self.wait()\n        self.assertTrue(first_line.startswith(b\"HTTP/1.1 200\"), first_line)\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        header_data = self.wait()\n        headers = HTTPHeaders.parse(native_str(header_data.decode('latin1')))\n        stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Got 1024 bytes in POST\")\n        stream.close()\n\n\nclass EchoHandler(RequestHandler):\n    def get(self):\n        self.write(recursive_unicode(self.request.arguments))\n\n    def post(self):\n        self.write(recursive_unicode(self.request.arguments))\n\n\nclass TypeCheckHandler(RequestHandler):\n    def prepare(self):\n        self.errors = {}\n        fields = [\n            ('method', str),\n            ('uri', str),\n            ('version', str),\n            ('remote_ip', str),\n            ('protocol', str),\n            ('host', str),\n            ('path', str),\n            ('query', str),\n        ]\n        for field, expected_type in fields:\n            self.check_type(field, getattr(self.request, field), expected_type)\n\n        self.check_type('header_key', list(self.request.headers.keys())[0], str)\n        self.check_type('header_value', list(self.request.headers.values())[0], str)\n\n        self.check_type('cookie_key', list(self.request.cookies.keys())[0], str)\n        self.check_type('cookie_value', list(self.request.cookies.values())[0].value, str)\n        # secure cookies\n\n        self.check_type('arg_key', list(self.request.arguments.keys())[0], str)\n        self.check_type('arg_value', list(self.request.arguments.values())[0][0], bytes)\n\n    def post(self):\n        self.check_type('body', self.request.body, bytes)\n        self.write(self.errors)\n\n    def get(self):\n        self.write(self.errors)\n\n    def check_type(self, name, obj, expected_type):\n        actual_type = type(obj)\n        if expected_type != actual_type:\n            self.errors[name] = \"expected %s, got %s\" % (expected_type,\n                                                         actual_type)\n\n\nclass HTTPServerTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([(\"/echo\", EchoHandler),\n                            (\"/typecheck\", TypeCheckHandler),\n                            (\"//doubleslash\", EchoHandler),\n                            ])\n\n    def test_query_string_encoding(self):\n        response = self.fetch(\"/echo?foo=%C3%A9\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\\u00e9\"]})\n\n    def test_empty_query_string(self):\n        response = self.fetch(\"/echo?foo=&foo=\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\", u\"\"]})\n\n    def test_empty_post_parameters(self):\n        response = self.fetch(\"/echo\", method=\"POST\", body=\"foo=&bar=\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\"], u\"bar\": [u\"\"]})\n\n    def test_types(self):\n        headers = {\"Cookie\": \"foo=bar\"}\n        response = self.fetch(\"/typecheck?foo=bar\", headers=headers)\n        data = json_decode(response.body)\n        self.assertEqual(data, {})\n\n        response = self.fetch(\"/typecheck\", method=\"POST\", body=\"foo=bar\", headers=headers)\n        data = json_decode(response.body)\n        self.assertEqual(data, {})\n\n    def test_double_slash(self):\n        # urlparse.urlsplit (which tornado.httpserver used to use\n        # incorrectly) would parse paths beginning with \"//\" as\n        # protocol-relative urls.\n        response = self.fetch(\"//doubleslash\")\n        self.assertEqual(200, response.code)\n        self.assertEqual(json_decode(response.body), {})\n\n    def test_malformed_body(self):\n        # parse_qs is pretty forgiving, but it will fail on python 3\n        # if the data is not utf8.  On python 2 parse_qs will work,\n        # but then the recursive_unicode call in EchoHandler will\n        # fail.\n        if str is bytes:\n            return\n        with ExpectLog(gen_log, 'Invalid x-www-form-urlencoded body'):\n            response = self.fetch(\n                '/echo', method=\"POST\",\n                headers={'Content-Type': 'application/x-www-form-urlencoded'},\n                body=b'\\xe9')\n        self.assertEqual(200, response.code)\n        self.assertEqual(b'{}', response.body)\n\n\nclass HTTPServerRawTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([\n            ('/echo', EchoHandler),\n        ])\n\n    def setUp(self):\n        super(HTTPServerRawTest, self).setUp()\n        self.stream = IOStream(socket.socket())\n        self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n\n    def tearDown(self):\n        self.stream.close()\n        super(HTTPServerRawTest, self).tearDown()\n\n    def test_empty_request(self):\n        self.stream.close()\n        self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)\n        self.wait()\n\n    def test_malformed_first_line_response(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP request line'):\n            self.stream.write(b'asdf\\r\\n\\r\\n')\n            read_stream_body(self.stream, self.stop)\n            start_line, headers, response = self.wait()\n            self.assertEqual('HTTP/1.1', start_line.version)\n            self.assertEqual(400, start_line.code)\n            self.assertEqual('Bad Request', start_line.reason)\n\n    def test_malformed_first_line_log(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP request line'):\n            self.stream.write(b'asdf\\r\\n\\r\\n')\n            # TODO: need an async version of ExpectLog so we don't need\n            # hard-coded timeouts here.\n            self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),\n                                     self.stop)\n            self.wait()\n\n    def test_malformed_headers(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP headers'):\n            self.stream.write(b'GET / HTTP/1.0\\r\\nasdf\\r\\n\\r\\n')\n            self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),\n                                     self.stop)\n            self.wait()\n\n    def test_chunked_request_body(self):\n        # Chunked requests are not widely supported and we don't have a way\n        # to generate them in AsyncHTTPClient, but HTTPServer will read them.\n        self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nTransfer-Encoding: chunked\nContent-Type: application/x-www-form-urlencoded\n\n4\nfoo=\n3\nbar\n0\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n        read_stream_body(self.stream, self.stop)\n        start_line, headers, response = self.wait()\n        self.assertEqual(json_decode(response), {u'foo': [u'bar']})\n\n    def test_chunked_request_uppercase(self):\n        # As per RFC 2616 section 3.6, \"Transfer-Encoding\" header's value is\n        # case-insensitive.\n        self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nTransfer-Encoding: Chunked\nContent-Type: application/x-www-form-urlencoded\n\n4\nfoo=\n3\nbar\n0\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n        read_stream_body(self.stream, self.stop)\n        start_line, headers, response = self.wait()\n        self.assertEqual(json_decode(response), {u'foo': [u'bar']})\n\n    def test_invalid_content_length(self):\n        with ExpectLog(gen_log, '.*Only integer Content-Length is allowed'):\n            self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nContent-Length: foo\n\nbar\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n            self.stream.read_until_close(self.stop)\n            self.wait()\n\n\nclass XHeaderTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(remote_ip=self.request.remote_ip,\n                            remote_protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(xheaders=True, trusted_downstream=['5.5.5.5'])\n\n    def test_ip_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_ip\"], \"127.0.0.1\")\n\n        valid_ipv4 = {\"X-Real-IP\": \"4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_host = {\"X-Real-IP\": \"www.google.com\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n    def test_trusted_downstream(self):\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4, 5.5.5.5\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n    def test_scheme_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"http\")\n\n        https_scheme = {\"X-Scheme\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_scheme)[\"remote_protocol\"],\n            \"https\")\n\n        https_forwarded = {\"X-Forwarded-Proto\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n\nclass SSLXHeaderTest(AsyncHTTPSTestCase, HandlerBaseTestCase):\n    def get_app(self):\n        return Application([('/', XHeaderTest.Handler)])\n\n    def get_httpserver_options(self):\n        output = super(SSLXHeaderTest, self).get_httpserver_options()\n        output['xheaders'] = True\n        return output\n\n    def test_request_without_xprotocol(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n\n        http_scheme = {\"X-Scheme\": \"http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_scheme)[\"remote_protocol\"], \"http\")\n\n        bad_scheme = {\"X-Scheme\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_scheme)[\"remote_protocol\"], \"https\")\n\n\nclass ManualProtocolTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(protocol='https')\n\n    def test_manual_protocol(self):\n        self.assertEqual(self.fetch_json('/')['protocol'], 'https')\n\n\n@unittest.skipIf(not hasattr(socket, 'AF_UNIX') or sys.platform == 'cygwin',\n                 \"unix sockets not supported on this platform\")\nclass UnixSocketTest(AsyncTestCase):\n    \"\"\"HTTPServers can listen on Unix sockets too.\n\n    Why would you want to do this?  Nginx can proxy to backends listening\n    on unix sockets, for one thing (and managing a namespace for unix\n    sockets can be easier than managing a bunch of TCP port numbers).\n\n    Unfortunately, there's no way to specify a unix socket in a url for\n    an HTTP client, so we have to test this by hand.\n    \"\"\"\n    def setUp(self):\n        super(UnixSocketTest, self).setUp()\n        self.tmpdir = tempfile.mkdtemp()\n        self.sockfile = os.path.join(self.tmpdir, \"test.sock\")\n        sock = netutil.bind_unix_socket(self.sockfile)\n        app = Application([(\"/hello\", HelloWorldRequestHandler)])\n        self.server = HTTPServer(app)\n        self.server.add_socket(sock)\n        self.stream = IOStream(socket.socket(socket.AF_UNIX))\n        self.stream.connect(self.sockfile, self.stop)\n        self.wait()\n\n    def tearDown(self):\n        self.stream.close()\n        self.io_loop.run_sync(self.server.close_all_connections)\n        self.server.stop()\n        shutil.rmtree(self.tmpdir)\n        super(UnixSocketTest, self).tearDown()\n\n    def test_unix_socket(self):\n        self.stream.write(b\"GET /hello HTTP/1.0\\r\\n\\r\\n\")\n        self.stream.read_until(b\"\\r\\n\", self.stop)\n        response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.1 200 OK\\r\\n\")\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        headers = HTTPHeaders.parse(self.wait().decode('latin1'))\n        self.stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Hello world\")\n\n    def test_unix_socket_bad_request(self):\n        # Unix sockets don't have remote addresses so they just return an\n        # empty string.\n        with ExpectLog(gen_log, \"Malformed HTTP message from\"):\n            self.stream.write(b\"garbage\\r\\n\\r\\n\")\n            self.stream.read_until_close(self.stop)\n            response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.1 400 Bad Request\\r\\n\\r\\n\")\n\n\nclass KeepAliveTest(AsyncHTTPTestCase):\n    \"\"\"Tests various scenarios for HTTP 1.1 keep-alive support.\n\n    These tests don't use AsyncHTTPClient because we want to control\n    connection reuse and closing.\n    \"\"\"\n    def get_app(self):\n        class HelloHandler(RequestHandler):\n            def get(self):\n                self.finish('Hello world')\n\n            def post(self):\n                self.finish('Hello world')\n\n        class LargeHandler(RequestHandler):\n            def get(self):\n                # 512KB should be bigger than the socket buffers so it will\n                # be written out in chunks.\n                self.write(''.join(chr(i % 256) * 1024 for i in range(512)))\n\n        class FinishOnCloseHandler(RequestHandler):\n            @asynchronous\n            def get(self):\n                self.flush()\n\n            def on_connection_close(self):\n                # This is not very realistic, but finishing the request\n                # from the close callback has the right timing to mimic\n                # some errors seen in the wild.\n                self.finish('closed')\n\n        return Application([('/', HelloHandler),\n                            ('/large', LargeHandler),\n                            ('/finish_on_close', FinishOnCloseHandler)])\n\n    def setUp(self):\n        super(KeepAliveTest, self).setUp()\n        self.http_version = b'HTTP/1.1'\n\n    def tearDown(self):\n        # We just closed the client side of the socket; let the IOLoop run\n        # once to make sure the server side got the message.\n        self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)\n        self.wait()\n\n        if hasattr(self, 'stream'):\n            self.stream.close()\n        super(KeepAliveTest, self).tearDown()\n\n    # The next few methods are a crude manual http client\n    def connect(self):\n        self.stream = IOStream(socket.socket())\n        self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n\n    def read_headers(self):\n        self.stream.read_until(b'\\r\\n', self.stop)\n        first_line = self.wait()\n        self.assertTrue(first_line.startswith(b'HTTP/1.1 200'), first_line)\n        self.stream.read_until(b'\\r\\n\\r\\n', self.stop)\n        header_bytes = self.wait()\n        headers = HTTPHeaders.parse(header_bytes.decode('latin1'))\n        return headers\n\n    def read_response(self):\n        self.headers = self.read_headers()\n        self.stream.read_bytes(int(self.headers['Content-Length']), self.stop)\n        body = self.wait()\n        self.assertEqual(b'Hello world', body)\n\n    def close(self):\n        self.stream.close()\n        del self.stream\n\n    def test_two_requests(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.close()\n\n    def test_request_close(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\nConnection: close\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.read_until_close(callback=self.stop)\n        data = self.wait()\n        self.assertTrue(not data)\n        self.assertEqual(self.headers['Connection'], 'close')\n        self.close()\n\n    # keepalive is supported for http 1.0 too, but it's opt-in\n    def test_http10(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.read_until_close(callback=self.stop)\n        data = self.wait()\n        self.assertTrue(not data)\n        self.assertTrue('Connection' not in self.headers)\n        self.close()\n\n    def test_http10_keepalive(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n    def test_http10_keepalive_extra_crlf(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n    def test_pipelined_requests(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\nGET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.read_response()\n        self.close()\n\n    def test_pipelined_cancel(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\nGET / HTTP/1.1\\r\\n\\r\\n')\n        # only read once\n        self.read_response()\n        self.close()\n\n    def test_cancel_during_download(self):\n        self.connect()\n        self.stream.write(b'GET /large HTTP/1.1\\r\\n\\r\\n')\n        self.read_headers()\n        self.stream.read_bytes(1024, self.stop)\n        self.wait()\n        self.close()\n\n    def test_finish_while_closed(self):\n        self.connect()\n        self.stream.write(b'GET /finish_on_close HTTP/1.1\\r\\n\\r\\n')\n        self.read_headers()\n        self.close()\n\n    def test_keepalive_chunked(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'POST / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n'\n                          b'Transfer-Encoding: chunked\\r\\n'\n                          b'\\r\\n0\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n\nclass GzipBaseTest(object):\n    def get_app(self):\n        return Application([('/', EchoHandler)])\n\n    def post_gzip(self, body):\n        bytesio = BytesIO()\n        gzip_file = gzip.GzipFile(mode='w', fileobj=bytesio)\n        gzip_file.write(utf8(body))\n        gzip_file.close()\n        compressed_body = bytesio.getvalue()\n        return self.fetch('/', method='POST', body=compressed_body,\n                          headers={'Content-Encoding': 'gzip'})\n\n    def test_uncompressed(self):\n        response = self.fetch('/', method='POST', body='foo=bar')\n        self.assertEquals(json_decode(response.body), {u'foo': [u'bar']})\n\n\nclass GzipTest(GzipBaseTest, AsyncHTTPTestCase):\n    def get_httpserver_options(self):\n        return dict(decompress_request=True)\n\n    def test_gzip(self):\n        response = self.post_gzip('foo=bar')\n        self.assertEquals(json_decode(response.body), {u'foo': [u'bar']})\n\n\nclass GzipUnsupportedTest(GzipBaseTest, AsyncHTTPTestCase):\n    def test_gzip_unsupported(self):\n        # Gzip support is opt-in; without it the server fails to parse\n        # the body (but parsing form bodies is currently just a log message,\n        # not a fatal error).\n        with ExpectLog(gen_log, \"Unsupported Content-Encoding\"):\n            response = self.post_gzip('foo=bar')\n        self.assertEquals(json_decode(response.body), {})\n\n\nclass StreamingChunkSizeTest(AsyncHTTPTestCase):\n    # 50 characters long, and repetitive so it can be compressed.\n    BODY = b'01234567890123456789012345678901234567890123456789'\n    CHUNK_SIZE = 16\n\n    def get_http_client(self):\n        # body_producer doesn't work on curl_httpclient, so override the\n        # configured AsyncHTTPClient implementation.\n        return SimpleAsyncHTTPClient()\n\n    def get_httpserver_options(self):\n        return dict(chunk_size=self.CHUNK_SIZE, decompress_request=True)\n\n    class MessageDelegate(HTTPMessageDelegate):\n        def __init__(self, connection):\n            self.connection = connection\n\n        def headers_received(self, start_line, headers):\n            self.chunk_lengths = []\n\n        def data_received(self, chunk):\n            self.chunk_lengths.append(len(chunk))\n\n        def finish(self):\n            response_body = utf8(json_encode(self.chunk_lengths))\n            self.connection.write_headers(\n                ResponseStartLine('HTTP/1.1', 200, 'OK'),\n                HTTPHeaders({'Content-Length': str(len(response_body))}))\n            self.connection.write(response_body)\n            self.connection.finish()\n\n    def get_app(self):\n        class App(HTTPServerConnectionDelegate):\n            def start_request(self, server_conn, request_conn):\n                return StreamingChunkSizeTest.MessageDelegate(request_conn)\n        return App()\n\n    def fetch_chunk_sizes(self, **kwargs):\n        response = self.fetch('/', method='POST', **kwargs)\n        response.rethrow()\n        chunks = json_decode(response.body)\n        self.assertEqual(len(self.BODY), sum(chunks))\n        for chunk_size in chunks:\n            self.assertLessEqual(chunk_size, self.CHUNK_SIZE,\n                                 'oversized chunk: ' + str(chunks))\n            self.assertGreater(chunk_size, 0,\n                               'empty chunk: ' + str(chunks))\n        return chunks\n\n    def compress(self, body):\n        bytesio = BytesIO()\n        gzfile = gzip.GzipFile(mode='w', fileobj=bytesio)\n        gzfile.write(body)\n        gzfile.close()\n        compressed = bytesio.getvalue()\n        if len(compressed) >= len(body):\n            raise Exception(\"body did not shrink when compressed\")\n        return compressed\n\n    def test_regular_body(self):\n        chunks = self.fetch_chunk_sizes(body=self.BODY)\n        # Without compression we know exactly what to expect.\n        self.assertEqual([16, 16, 16, 2], chunks)\n\n    def test_compressed_body(self):\n        self.fetch_chunk_sizes(body=self.compress(self.BODY),\n                               headers={'Content-Encoding': 'gzip'})\n        # Compression creates irregular boundaries so the assertions\n        # in fetch_chunk_sizes are as specific as we can get.\n\n    def test_chunked_body(self):\n        def body_producer(write):\n            write(self.BODY[:20])\n            write(self.BODY[20:])\n        chunks = self.fetch_chunk_sizes(body_producer=body_producer)\n        # HTTP chunk boundaries translate to application-visible breaks\n        self.assertEqual([16, 4, 16, 14], chunks)\n\n    def test_chunked_compressed(self):\n        compressed = self.compress(self.BODY)\n        self.assertGreater(len(compressed), 20)\n\n        def body_producer(write):\n            write(compressed[:20])\n            write(compressed[20:])\n        self.fetch_chunk_sizes(body_producer=body_producer,\n                               headers={'Content-Encoding': 'gzip'})\n\n\nclass MaxHeaderSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler)])\n\n    def get_httpserver_options(self):\n        return dict(max_header_size=1024)\n\n    def test_small_headers(self):\n        response = self.fetch(\"/\", headers={'X-Filler': 'a' * 100})\n        response.rethrow()\n        self.assertEqual(response.body, b\"Hello world\")\n\n    def test_large_headers(self):\n        with ExpectLog(gen_log, \"Unsatisfiable read\", required=False):\n            response = self.fetch(\"/\", headers={'X-Filler': 'a' * 1000})\n        # 431 is \"Request Header Fields Too Large\", defined in RFC\n        # 6585. However, many implementations just close the\n        # connection in this case, resulting in a 599.\n        self.assertIn(response.code, (431, 599))\n\n\n@skipOnTravis\nclass IdleTimeoutTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler)])\n\n    def get_httpserver_options(self):\n        return dict(idle_connection_timeout=0.1)\n\n    def setUp(self):\n        super(IdleTimeoutTest, self).setUp()\n        self.streams = []\n\n    def tearDown(self):\n        super(IdleTimeoutTest, self).tearDown()\n        for stream in self.streams:\n            stream.close()\n\n    def connect(self):\n        stream = IOStream(socket.socket())\n        stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n        self.streams.append(stream)\n        return stream\n\n    def test_unused_connection(self):\n        stream = self.connect()\n        stream.set_close_callback(self.stop)\n        self.wait()\n\n    def test_idle_after_use(self):\n        stream = self.connect()\n        stream.set_close_callback(lambda: self.stop(\"closed\"))\n\n        # Use the connection twice to make sure keep-alives are working\n        for i in range(2):\n            stream.write(b\"GET / HTTP/1.1\\r\\n\\r\\n\")\n            stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n            self.wait()\n            stream.read_bytes(11, self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"Hello world\")\n\n        # Now let the timeout trigger and close the connection.\n        data = self.wait()\n        self.assertEqual(data, \"closed\")\n\n\nclass BodyLimitsTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class BufferedHandler(RequestHandler):\n            def put(self):\n                self.write(str(len(self.request.body)))\n\n        @stream_request_body\n        class StreamingHandler(RequestHandler):\n            def initialize(self):\n                self.bytes_read = 0\n\n            def prepare(self):\n                if 'expected_size' in self.request.arguments:\n                    self.request.connection.set_max_body_size(\n                        int(self.get_argument('expected_size')))\n                if 'body_timeout' in self.request.arguments:\n                    self.request.connection.set_body_timeout(\n                        float(self.get_argument('body_timeout')))\n\n            def data_received(self, data):\n                self.bytes_read += len(data)\n\n            def put(self):\n                self.write(str(self.bytes_read))\n\n        return Application([('/buffered', BufferedHandler),\n                            ('/streaming', StreamingHandler)])\n\n    def get_httpserver_options(self):\n        return dict(body_timeout=3600, max_body_size=4096)\n\n    def get_http_client(self):\n        # body_producer doesn't work on curl_httpclient, so override the\n        # configured AsyncHTTPClient implementation.\n        return SimpleAsyncHTTPClient()\n\n    def test_small_body(self):\n        response = self.fetch('/buffered', method='PUT', body=b'a' * 4096)\n        self.assertEqual(response.body, b'4096')\n        response = self.fetch('/streaming', method='PUT', body=b'a' * 4096)\n        self.assertEqual(response.body, b'4096')\n\n    def test_large_body_buffered(self):\n        with ExpectLog(gen_log, '.*Content-Length too long'):\n            response = self.fetch('/buffered', method='PUT', body=b'a' * 10240)\n        self.assertEqual(response.code, 400)\n\n    def test_large_body_buffered_chunked(self):\n        with ExpectLog(gen_log, '.*chunked body too large'):\n            response = self.fetch('/buffered', method='PUT',\n                                  body_producer=lambda write: write(b'a' * 10240))\n        # this test is flaky on windows; accept 400 (expected) or 599\n        self.assertIn(response.code, [400, 599])\n\n    def test_large_body_streaming(self):\n        with ExpectLog(gen_log, '.*Content-Length too long'):\n            response = self.fetch('/streaming', method='PUT', body=b'a' * 10240)\n        self.assertEqual(response.code, 400)\n\n    def test_large_body_streaming_chunked(self):\n        with ExpectLog(gen_log, '.*chunked body too large'):\n            response = self.fetch('/streaming', method='PUT',\n                                  body_producer=lambda write: write(b'a' * 10240))\n        # this test is flaky on windows; accept 400 (expected) or 599\n        self.assertIn(response.code, [400, 599])\n\n    def test_large_body_streaming_override(self):\n        response = self.fetch('/streaming?expected_size=10240', method='PUT',\n                              body=b'a' * 10240)\n        self.assertEqual(response.body, b'10240')\n\n    def test_large_body_streaming_chunked_override(self):\n        response = self.fetch('/streaming?expected_size=10240', method='PUT',\n                              body_producer=lambda write: write(b'a' * 10240))\n        self.assertEqual(response.body, b'10240')\n\n    @gen_test\n    def test_timeout(self):\n        stream = IOStream(socket.socket())\n        try:\n            yield stream.connect(('127.0.0.1', self.get_http_port()))\n            # Use a raw stream because AsyncHTTPClient won't let us read a\n            # response without finishing a body.\n            stream.write(b'PUT /streaming?body_timeout=0.1 HTTP/1.0\\r\\n'\n                         b'Content-Length: 42\\r\\n\\r\\n')\n            with ExpectLog(gen_log, 'Timeout reading body'):\n                response = yield stream.read_until_close()\n            self.assertEqual(response, b'')\n        finally:\n            stream.close()\n\n    @gen_test\n    def test_body_size_override_reset(self):\n        # The max_body_size override is reset between requests.\n        stream = IOStream(socket.socket())\n        try:\n            yield stream.connect(('127.0.0.1', self.get_http_port()))\n            # Use a raw stream so we can make sure it's all on one connection.\n            stream.write(b'PUT /streaming?expected_size=10240 HTTP/1.1\\r\\n'\n                         b'Content-Length: 10240\\r\\n\\r\\n')\n            stream.write(b'a' * 10240)\n            start_line, headers, response = yield gen.Task(read_stream_body, stream)\n            self.assertEqual(response, b'10240')\n            # Without the ?expected_size parameter, we get the old default value\n            stream.write(b'PUT /streaming HTTP/1.1\\r\\n'\n                         b'Content-Length: 10240\\r\\n\\r\\n')\n            with ExpectLog(gen_log, '.*Content-Length too long'):\n                data = yield stream.read_until_close()\n            self.assertEqual(data, b'HTTP/1.1 400 Bad Request\\r\\n\\r\\n')\n        finally:\n            stream.close()\n\n\nclass LegacyInterfaceTest(AsyncHTTPTestCase):\n    def get_app(self):\n        # The old request_callback interface does not implement the\n        # delegate interface, and writes its response via request.write\n        # instead of request.connection.write_headers.\n        def handle_request(request):\n            self.http1 = request.version.startswith(\"HTTP/1.\")\n            if not self.http1:\n                # This test will be skipped if we're using HTTP/2,\n                # so just close it out cleanly using the modern interface.\n                request.connection.write_headers(\n                    ResponseStartLine('', 200, 'OK'),\n                    HTTPHeaders())\n                request.connection.finish()\n                return\n            message = b\"Hello world\"\n            request.write(utf8(\"HTTP/1.1 200 OK\\r\\n\"\n                               \"Content-Length: %d\\r\\n\\r\\n\" % len(message)))\n            request.write(message)\n            request.finish()\n        return handle_request\n\n    def test_legacy_interface(self):\n        response = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(response.body, b\"Hello world\")\n",
            "new_file_content": "#!/usr/bin/env python\n\n\nfrom __future__ import absolute_import, division, print_function\nfrom tornado import netutil\nfrom tornado.escape import json_decode, json_encode, utf8, _unicode, recursive_unicode, native_str\nfrom tornado import gen\nfrom tornado.http1connection import HTTP1Connection\nfrom tornado.httpserver import HTTPServer\nfrom tornado.httputil import HTTPHeaders, HTTPMessageDelegate, HTTPServerConnectionDelegate, ResponseStartLine\nfrom tornado.iostream import IOStream\nfrom tornado.log import gen_log\nfrom tornado.netutil import ssl_options_to_context\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog, gen_test\nfrom tornado.test.util import unittest, skipOnTravis\nfrom tornado.web import Application, RequestHandler, asynchronous, stream_request_body\nfrom contextlib import closing\nimport datetime\nimport gzip\nimport os\nimport shutil\nimport socket\nimport ssl\nimport sys\nimport tempfile\nfrom io import BytesIO\n\n\ndef read_stream_body(stream, callback):\n    \"\"\"Reads an HTTP response from `stream` and runs callback with its\n    start_line, headers and body.\"\"\"\n    chunks = []\n\n    class Delegate(HTTPMessageDelegate):\n        def headers_received(self, start_line, headers):\n            self.headers = headers\n            self.start_line = start_line\n\n        def data_received(self, chunk):\n            chunks.append(chunk)\n\n        def finish(self):\n            conn.detach()\n            callback((self.start_line, self.headers, b''.join(chunks)))\n    conn = HTTP1Connection(stream, True)\n    conn.read_response(Delegate())\n\n\nclass HandlerBaseTestCase(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', self.__class__.Handler)])\n\n    def fetch_json(self, *args, **kwargs):\n        response = self.fetch(*args, **kwargs)\n        response.rethrow()\n        return json_decode(response.body)\n\n\nclass HelloWorldRequestHandler(RequestHandler):\n    def initialize(self, protocol=\"http\"):\n        self.expected_protocol = protocol\n\n    def get(self):\n        if self.request.protocol != self.expected_protocol:\n            raise Exception(\"unexpected protocol\")\n        self.finish(\"Hello world\")\n\n    def post(self):\n        self.finish(\"Got %d bytes in POST\" % len(self.request.body))\n\n\n# In pre-1.0 versions of openssl, SSLv23 clients always send SSLv2\n# ClientHello messages, which are rejected by SSLv3 and TLSv1\n# servers.  Note that while the OPENSSL_VERSION_INFO was formally\n# introduced in python3.2, it was present but undocumented in\n# python 2.7\nskipIfOldSSL = unittest.skipIf(\n    getattr(ssl, 'OPENSSL_VERSION_INFO', (0, 0)) < (1, 0),\n    \"old version of ssl module and/or openssl\")\n\n\nclass BaseSSLTest(AsyncHTTPSTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler,\n                             dict(protocol=\"https\"))])\n\n\nclass SSLTestMixin(object):\n    def get_ssl_options(self):\n        return dict(ssl_version=self.get_ssl_version(),  # type: ignore\n                    **AsyncHTTPSTestCase.get_ssl_options())\n\n    def get_ssl_version(self):\n        raise NotImplementedError()\n\n    def test_ssl(self):\n        response = self.fetch('/')\n        self.assertEqual(response.body, b\"Hello world\")\n\n    def test_large_post(self):\n        response = self.fetch('/',\n                              method='POST',\n                              body='A' * 5000)\n        self.assertEqual(response.body, b\"Got 5000 bytes in POST\")\n\n    def test_non_ssl_request(self):\n        # Make sure the server closes the connection when it gets a non-ssl\n        # connection, rather than waiting for a timeout or otherwise\n        # misbehaving.\n        with ExpectLog(gen_log, '(SSL Error|uncaught exception)'):\n            with ExpectLog(gen_log, 'Uncaught exception', required=False):\n                self.http_client.fetch(\n                    self.get_url(\"/\").replace('https:', 'http:'),\n                    self.stop,\n                    request_timeout=3600,\n                    connect_timeout=3600)\n                response = self.wait()\n        self.assertEqual(response.code, 599)\n\n    def test_error_logging(self):\n        # No stack traces are logged for SSL errors.\n        with ExpectLog(gen_log, 'SSL Error') as expect_log:\n            self.http_client.fetch(\n                self.get_url(\"/\").replace(\"https:\", \"http:\"),\n                self.stop)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n        self.assertFalse(expect_log.logged_stack)\n\n# Python's SSL implementation differs significantly between versions.\n# For example, SSLv3 and TLSv1 throw an exception if you try to read\n# from the socket before the handshake is complete, but the default\n# of SSLv23 allows it.\n\n\nclass SSLv23Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_SSLv23\n\n\n@skipIfOldSSL\nclass SSLv3Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_SSLv3\n\n\n@skipIfOldSSL\nclass TLSv1Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_TLSv1\n\n\nclass SSLContextTest(BaseSSLTest, SSLTestMixin):\n    def get_ssl_options(self):\n        context = ssl_options_to_context(\n            AsyncHTTPSTestCase.get_ssl_options(self))\n        assert isinstance(context, ssl.SSLContext)\n        return context\n\n\nclass BadSSLOptionsTest(unittest.TestCase):\n    def test_missing_arguments(self):\n        application = Application()\n        self.assertRaises(KeyError, HTTPServer, application, ssl_options={\n            \"keyfile\": \"/__missing__.crt\",\n        })\n\n    def test_missing_key(self):\n        \"\"\"A missing SSL key should cause an immediate exception.\"\"\"\n\n        application = Application()\n        module_dir = os.path.dirname(__file__)\n        existing_certificate = os.path.join(module_dir, 'test.crt')\n        existing_key = os.path.join(module_dir, 'test.key')\n\n        self.assertRaises((ValueError, IOError),\n                          HTTPServer, application, ssl_options={\n                              \"certfile\": \"/__mising__.crt\",\n        })\n        self.assertRaises((ValueError, IOError),\n                          HTTPServer, application, ssl_options={\n                              \"certfile\": existing_certificate,\n                              \"keyfile\": \"/__missing__.key\"\n        })\n\n        # This actually works because both files exist\n        HTTPServer(application, ssl_options={\n                   \"certfile\": existing_certificate,\n                   \"keyfile\": existing_key,\n                   })\n\n\nclass MultipartTestHandler(RequestHandler):\n    def post(self):\n        self.finish({\"header\": self.request.headers[\"X-Header-Encoding-Test\"],\n                     \"argument\": self.get_argument(\"argument\"),\n                     \"filename\": self.request.files[\"files\"][0].filename,\n                     \"filebody\": _unicode(self.request.files[\"files\"][0][\"body\"]),\n                     })\n\n\n# This test is also called from wsgi_test\nclass HTTPConnectionTest(AsyncHTTPTestCase):\n    def get_handlers(self):\n        return [(\"/multipart\", MultipartTestHandler),\n                (\"/hello\", HelloWorldRequestHandler)]\n\n    def get_app(self):\n        return Application(self.get_handlers())\n\n    def raw_fetch(self, headers, body, newline=b\"\\r\\n\"):\n        with closing(IOStream(socket.socket())) as stream:\n            stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n            self.wait()\n            stream.write(\n                newline.join(headers +\n                             [utf8(\"Content-Length: %d\" % len(body))]) +\n                newline + newline + body)\n            read_stream_body(stream, self.stop)\n            start_line, headers, body = self.wait()\n            return body\n\n    def test_multipart_form(self):\n        # Encodings here are tricky:  Headers are latin1, bodies can be\n        # anything (we use utf8 by default).\n        response = self.raw_fetch([\n            b\"POST /multipart HTTP/1.0\",\n            b\"Content-Type: multipart/form-data; boundary=1234567890\",\n            b\"X-Header-encoding-test: \\xe9\",\n        ],\n            b\"\\r\\n\".join([\n                b\"Content-Disposition: form-data; name=argument\",\n                b\"\",\n                u\"\\u00e1\".encode(\"utf-8\"),\n                b\"--1234567890\",\n                u'Content-Disposition: form-data; name=\"files\"; filename=\"\\u00f3\"'.encode(\"utf8\"),\n                b\"\",\n                u\"\\u00fa\".encode(\"utf-8\"),\n                b\"--1234567890--\",\n                b\"\",\n            ]))\n        data = json_decode(response)\n        self.assertEqual(u\"\\u00e9\", data[\"header\"])\n        self.assertEqual(u\"\\u00e1\", data[\"argument\"])\n        self.assertEqual(u\"\\u00f3\", data[\"filename\"])\n        self.assertEqual(u\"\\u00fa\", data[\"filebody\"])\n\n    def test_newlines(self):\n        # We support both CRLF and bare LF as line separators.\n        for newline in (b\"\\r\\n\", b\"\\n\"):\n            response = self.raw_fetch([b\"GET /hello HTTP/1.0\"], b\"\",\n                                      newline=newline)\n            self.assertEqual(response, b'Hello world')\n\n    def test_100_continue(self):\n        # Run through a 100-continue interaction by hand:\n        # When given Expect: 100-continue, we get a 100 response after the\n        # headers, and then the real response after the body.\n        stream = IOStream(socket.socket())\n        stream.connect((\"127.0.0.1\", self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"\\r\\n\".join([b\"POST /hello HTTP/1.1\",\n                                   b\"Content-Length: 1024\",\n                                   b\"Expect: 100-continue\",\n                                   b\"Connection: close\",\n                                   b\"\\r\\n\"]), callback=self.stop)\n        self.wait()\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.1 100 \"), data)\n        stream.write(b\"a\" * 1024)\n        stream.read_until(b\"\\r\\n\", self.stop)\n        first_line = self.wait()\n        self.assertTrue(first_line.startswith(b\"HTTP/1.1 200\"), first_line)\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        header_data = self.wait()\n        headers = HTTPHeaders.parse(native_str(header_data.decode('latin1')))\n        stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Got 1024 bytes in POST\")\n        stream.close()\n\n\nclass EchoHandler(RequestHandler):\n    def get(self):\n        self.write(recursive_unicode(self.request.arguments))\n\n    def post(self):\n        self.write(recursive_unicode(self.request.arguments))\n\n\nclass TypeCheckHandler(RequestHandler):\n    def prepare(self):\n        self.errors = {}\n        fields = [\n            ('method', str),\n            ('uri', str),\n            ('version', str),\n            ('remote_ip', str),\n            ('protocol', str),\n            ('host', str),\n            ('path', str),\n            ('query', str),\n        ]\n        for field, expected_type in fields:\n            self.check_type(field, getattr(self.request, field), expected_type)\n\n        self.check_type('header_key', list(self.request.headers.keys())[0], str)\n        self.check_type('header_value', list(self.request.headers.values())[0], str)\n\n        self.check_type('cookie_key', list(self.request.cookies.keys())[0], str)\n        self.check_type('cookie_value', list(self.request.cookies.values())[0].value, str)\n        # secure cookies\n\n        self.check_type('arg_key', list(self.request.arguments.keys())[0], str)\n        self.check_type('arg_value', list(self.request.arguments.values())[0][0], bytes)\n\n    def post(self):\n        self.check_type('body', self.request.body, bytes)\n        self.write(self.errors)\n\n    def get(self):\n        self.write(self.errors)\n\n    def check_type(self, name, obj, expected_type):\n        actual_type = type(obj)\n        if expected_type != actual_type:\n            self.errors[name] = \"expected %s, got %s\" % (expected_type,\n                                                         actual_type)\n\n\nclass HTTPServerTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([(\"/echo\", EchoHandler),\n                            (\"/typecheck\", TypeCheckHandler),\n                            (\"//doubleslash\", EchoHandler),\n                            ])\n\n    def test_query_string_encoding(self):\n        response = self.fetch(\"/echo?foo=%C3%A9\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\\u00e9\"]})\n\n    def test_empty_query_string(self):\n        response = self.fetch(\"/echo?foo=&foo=\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\", u\"\"]})\n\n    def test_empty_post_parameters(self):\n        response = self.fetch(\"/echo\", method=\"POST\", body=\"foo=&bar=\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\"], u\"bar\": [u\"\"]})\n\n    def test_types(self):\n        headers = {\"Cookie\": \"foo=bar\"}\n        response = self.fetch(\"/typecheck?foo=bar\", headers=headers)\n        data = json_decode(response.body)\n        self.assertEqual(data, {})\n\n        response = self.fetch(\"/typecheck\", method=\"POST\", body=\"foo=bar\", headers=headers)\n        data = json_decode(response.body)\n        self.assertEqual(data, {})\n\n    def test_double_slash(self):\n        # urlparse.urlsplit (which tornado.httpserver used to use\n        # incorrectly) would parse paths beginning with \"//\" as\n        # protocol-relative urls.\n        response = self.fetch(\"//doubleslash\")\n        self.assertEqual(200, response.code)\n        self.assertEqual(json_decode(response.body), {})\n\n    def test_malformed_body(self):\n        # parse_qs is pretty forgiving, but it will fail on python 3\n        # if the data is not utf8.  On python 2 parse_qs will work,\n        # but then the recursive_unicode call in EchoHandler will\n        # fail.\n        if str is bytes:\n            return\n        with ExpectLog(gen_log, 'Invalid x-www-form-urlencoded body'):\n            response = self.fetch(\n                '/echo', method=\"POST\",\n                headers={'Content-Type': 'application/x-www-form-urlencoded'},\n                body=b'\\xe9')\n        self.assertEqual(200, response.code)\n        self.assertEqual(b'{}', response.body)\n\n\nclass HTTPServerRawTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([\n            ('/echo', EchoHandler),\n        ])\n\n    def setUp(self):\n        super(HTTPServerRawTest, self).setUp()\n        self.stream = IOStream(socket.socket())\n        self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n\n    def tearDown(self):\n        self.stream.close()\n        super(HTTPServerRawTest, self).tearDown()\n\n    def test_empty_request(self):\n        self.stream.close()\n        self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)\n        self.wait()\n\n    def test_malformed_first_line_response(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP request line'):\n            self.stream.write(b'asdf\\r\\n\\r\\n')\n            read_stream_body(self.stream, self.stop)\n            start_line, headers, response = self.wait()\n            self.assertEqual('HTTP/1.1', start_line.version)\n            self.assertEqual(400, start_line.code)\n            self.assertEqual('Bad Request', start_line.reason)\n\n    def test_malformed_first_line_log(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP request line'):\n            self.stream.write(b'asdf\\r\\n\\r\\n')\n            # TODO: need an async version of ExpectLog so we don't need\n            # hard-coded timeouts here.\n            self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),\n                                     self.stop)\n            self.wait()\n\n    def test_malformed_headers(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP headers'):\n            self.stream.write(b'GET / HTTP/1.0\\r\\nasdf\\r\\n\\r\\n')\n            self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),\n                                     self.stop)\n            self.wait()\n\n    def test_chunked_request_body(self):\n        # Chunked requests are not widely supported and we don't have a way\n        # to generate them in AsyncHTTPClient, but HTTPServer will read them.\n        self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nTransfer-Encoding: chunked\nContent-Type: application/x-www-form-urlencoded\n\n4\nfoo=\n3\nbar\n0\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n        read_stream_body(self.stream, self.stop)\n        start_line, headers, response = self.wait()\n        self.assertEqual(json_decode(response), {u'foo': [u'bar']})\n\n    def test_chunked_request_uppercase(self):\n        # As per RFC 2616 section 3.6, \"Transfer-Encoding\" header's value is\n        # case-insensitive.\n        self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nTransfer-Encoding: Chunked\nContent-Type: application/x-www-form-urlencoded\n\n4\nfoo=\n3\nbar\n0\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n        read_stream_body(self.stream, self.stop)\n        start_line, headers, response = self.wait()\n        self.assertEqual(json_decode(response), {u'foo': [u'bar']})\n\n    def test_invalid_content_length(self):\n        with ExpectLog(gen_log, '.*Only integer Content-Length is allowed'):\n            self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nContent-Length: foo\n\nbar\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n            self.stream.read_until_close(self.stop)\n            self.wait()\n\n\nclass XHeaderTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(remote_ip=self.request.remote_ip,\n                            remote_protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(xheaders=True, trusted_downstream=['5.5.5.5'])\n\n    def test_ip_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_ip\"], \"127.0.0.1\")\n\n        valid_ipv4 = {\"X-Real-IP\": \"4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_host = {\"X-Real-IP\": \"www.google.com\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n    def test_trusted_downstream(self):\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4, 5.5.5.5\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n    def test_scheme_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"http\")\n\n        https_scheme = {\"X-Scheme\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_scheme)[\"remote_protocol\"],\n            \"https\")\n\n        https_forwarded = {\"X-Forwarded-Proto\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        https_multi_forwarded = {\"X-Forwarded-Proto\": \"https , http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_multi_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n        http_multi_forwarded = {\"X-Forwarded-Proto\": \"http,https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_multi_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n\nclass SSLXHeaderTest(AsyncHTTPSTestCase, HandlerBaseTestCase):\n    def get_app(self):\n        return Application([('/', XHeaderTest.Handler)])\n\n    def get_httpserver_options(self):\n        output = super(SSLXHeaderTest, self).get_httpserver_options()\n        output['xheaders'] = True\n        return output\n\n    def test_request_without_xprotocol(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n\n        http_scheme = {\"X-Scheme\": \"http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_scheme)[\"remote_protocol\"], \"http\")\n\n        bad_scheme = {\"X-Scheme\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_scheme)[\"remote_protocol\"], \"https\")\n\n\nclass ManualProtocolTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(protocol='https')\n\n    def test_manual_protocol(self):\n        self.assertEqual(self.fetch_json('/')['protocol'], 'https')\n\n\n@unittest.skipIf(not hasattr(socket, 'AF_UNIX') or sys.platform == 'cygwin',\n                 \"unix sockets not supported on this platform\")\nclass UnixSocketTest(AsyncTestCase):\n    \"\"\"HTTPServers can listen on Unix sockets too.\n\n    Why would you want to do this?  Nginx can proxy to backends listening\n    on unix sockets, for one thing (and managing a namespace for unix\n    sockets can be easier than managing a bunch of TCP port numbers).\n\n    Unfortunately, there's no way to specify a unix socket in a url for\n    an HTTP client, so we have to test this by hand.\n    \"\"\"\n    def setUp(self):\n        super(UnixSocketTest, self).setUp()\n        self.tmpdir = tempfile.mkdtemp()\n        self.sockfile = os.path.join(self.tmpdir, \"test.sock\")\n        sock = netutil.bind_unix_socket(self.sockfile)\n        app = Application([(\"/hello\", HelloWorldRequestHandler)])\n        self.server = HTTPServer(app)\n        self.server.add_socket(sock)\n        self.stream = IOStream(socket.socket(socket.AF_UNIX))\n        self.stream.connect(self.sockfile, self.stop)\n        self.wait()\n\n    def tearDown(self):\n        self.stream.close()\n        self.io_loop.run_sync(self.server.close_all_connections)\n        self.server.stop()\n        shutil.rmtree(self.tmpdir)\n        super(UnixSocketTest, self).tearDown()\n\n    def test_unix_socket(self):\n        self.stream.write(b\"GET /hello HTTP/1.0\\r\\n\\r\\n\")\n        self.stream.read_until(b\"\\r\\n\", self.stop)\n        response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.1 200 OK\\r\\n\")\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        headers = HTTPHeaders.parse(self.wait().decode('latin1'))\n        self.stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Hello world\")\n\n    def test_unix_socket_bad_request(self):\n        # Unix sockets don't have remote addresses so they just return an\n        # empty string.\n        with ExpectLog(gen_log, \"Malformed HTTP message from\"):\n            self.stream.write(b\"garbage\\r\\n\\r\\n\")\n            self.stream.read_until_close(self.stop)\n            response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.1 400 Bad Request\\r\\n\\r\\n\")\n\n\nclass KeepAliveTest(AsyncHTTPTestCase):\n    \"\"\"Tests various scenarios for HTTP 1.1 keep-alive support.\n\n    These tests don't use AsyncHTTPClient because we want to control\n    connection reuse and closing.\n    \"\"\"\n    def get_app(self):\n        class HelloHandler(RequestHandler):\n            def get(self):\n                self.finish('Hello world')\n\n            def post(self):\n                self.finish('Hello world')\n\n        class LargeHandler(RequestHandler):\n            def get(self):\n                # 512KB should be bigger than the socket buffers so it will\n                # be written out in chunks.\n                self.write(''.join(chr(i % 256) * 1024 for i in range(512)))\n\n        class FinishOnCloseHandler(RequestHandler):\n            @asynchronous\n            def get(self):\n                self.flush()\n\n            def on_connection_close(self):\n                # This is not very realistic, but finishing the request\n                # from the close callback has the right timing to mimic\n                # some errors seen in the wild.\n                self.finish('closed')\n\n        return Application([('/', HelloHandler),\n                            ('/large', LargeHandler),\n                            ('/finish_on_close', FinishOnCloseHandler)])\n\n    def setUp(self):\n        super(KeepAliveTest, self).setUp()\n        self.http_version = b'HTTP/1.1'\n\n    def tearDown(self):\n        # We just closed the client side of the socket; let the IOLoop run\n        # once to make sure the server side got the message.\n        self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)\n        self.wait()\n\n        if hasattr(self, 'stream'):\n            self.stream.close()\n        super(KeepAliveTest, self).tearDown()\n\n    # The next few methods are a crude manual http client\n    def connect(self):\n        self.stream = IOStream(socket.socket())\n        self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n\n    def read_headers(self):\n        self.stream.read_until(b'\\r\\n', self.stop)\n        first_line = self.wait()\n        self.assertTrue(first_line.startswith(b'HTTP/1.1 200'), first_line)\n        self.stream.read_until(b'\\r\\n\\r\\n', self.stop)\n        header_bytes = self.wait()\n        headers = HTTPHeaders.parse(header_bytes.decode('latin1'))\n        return headers\n\n    def read_response(self):\n        self.headers = self.read_headers()\n        self.stream.read_bytes(int(self.headers['Content-Length']), self.stop)\n        body = self.wait()\n        self.assertEqual(b'Hello world', body)\n\n    def close(self):\n        self.stream.close()\n        del self.stream\n\n    def test_two_requests(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.close()\n\n    def test_request_close(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\nConnection: close\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.read_until_close(callback=self.stop)\n        data = self.wait()\n        self.assertTrue(not data)\n        self.assertEqual(self.headers['Connection'], 'close')\n        self.close()\n\n    # keepalive is supported for http 1.0 too, but it's opt-in\n    def test_http10(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.read_until_close(callback=self.stop)\n        data = self.wait()\n        self.assertTrue(not data)\n        self.assertTrue('Connection' not in self.headers)\n        self.close()\n\n    def test_http10_keepalive(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n    def test_http10_keepalive_extra_crlf(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n    def test_pipelined_requests(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\nGET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.read_response()\n        self.close()\n\n    def test_pipelined_cancel(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\nGET / HTTP/1.1\\r\\n\\r\\n')\n        # only read once\n        self.read_response()\n        self.close()\n\n    def test_cancel_during_download(self):\n        self.connect()\n        self.stream.write(b'GET /large HTTP/1.1\\r\\n\\r\\n')\n        self.read_headers()\n        self.stream.read_bytes(1024, self.stop)\n        self.wait()\n        self.close()\n\n    def test_finish_while_closed(self):\n        self.connect()\n        self.stream.write(b'GET /finish_on_close HTTP/1.1\\r\\n\\r\\n')\n        self.read_headers()\n        self.close()\n\n    def test_keepalive_chunked(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'POST / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n'\n                          b'Transfer-Encoding: chunked\\r\\n'\n                          b'\\r\\n0\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n\nclass GzipBaseTest(object):\n    def get_app(self):\n        return Application([('/', EchoHandler)])\n\n    def post_gzip(self, body):\n        bytesio = BytesIO()\n        gzip_file = gzip.GzipFile(mode='w', fileobj=bytesio)\n        gzip_file.write(utf8(body))\n        gzip_file.close()\n        compressed_body = bytesio.getvalue()\n        return self.fetch('/', method='POST', body=compressed_body,\n                          headers={'Content-Encoding': 'gzip'})\n\n    def test_uncompressed(self):\n        response = self.fetch('/', method='POST', body='foo=bar')\n        self.assertEquals(json_decode(response.body), {u'foo': [u'bar']})\n\n\nclass GzipTest(GzipBaseTest, AsyncHTTPTestCase):\n    def get_httpserver_options(self):\n        return dict(decompress_request=True)\n\n    def test_gzip(self):\n        response = self.post_gzip('foo=bar')\n        self.assertEquals(json_decode(response.body), {u'foo': [u'bar']})\n\n\nclass GzipUnsupportedTest(GzipBaseTest, AsyncHTTPTestCase):\n    def test_gzip_unsupported(self):\n        # Gzip support is opt-in; without it the server fails to parse\n        # the body (but parsing form bodies is currently just a log message,\n        # not a fatal error).\n        with ExpectLog(gen_log, \"Unsupported Content-Encoding\"):\n            response = self.post_gzip('foo=bar')\n        self.assertEquals(json_decode(response.body), {})\n\n\nclass StreamingChunkSizeTest(AsyncHTTPTestCase):\n    # 50 characters long, and repetitive so it can be compressed.\n    BODY = b'01234567890123456789012345678901234567890123456789'\n    CHUNK_SIZE = 16\n\n    def get_http_client(self):\n        # body_producer doesn't work on curl_httpclient, so override the\n        # configured AsyncHTTPClient implementation.\n        return SimpleAsyncHTTPClient()\n\n    def get_httpserver_options(self):\n        return dict(chunk_size=self.CHUNK_SIZE, decompress_request=True)\n\n    class MessageDelegate(HTTPMessageDelegate):\n        def __init__(self, connection):\n            self.connection = connection\n\n        def headers_received(self, start_line, headers):\n            self.chunk_lengths = []\n\n        def data_received(self, chunk):\n            self.chunk_lengths.append(len(chunk))\n\n        def finish(self):\n            response_body = utf8(json_encode(self.chunk_lengths))\n            self.connection.write_headers(\n                ResponseStartLine('HTTP/1.1', 200, 'OK'),\n                HTTPHeaders({'Content-Length': str(len(response_body))}))\n            self.connection.write(response_body)\n            self.connection.finish()\n\n    def get_app(self):\n        class App(HTTPServerConnectionDelegate):\n            def start_request(self, server_conn, request_conn):\n                return StreamingChunkSizeTest.MessageDelegate(request_conn)\n        return App()\n\n    def fetch_chunk_sizes(self, **kwargs):\n        response = self.fetch('/', method='POST', **kwargs)\n        response.rethrow()\n        chunks = json_decode(response.body)\n        self.assertEqual(len(self.BODY), sum(chunks))\n        for chunk_size in chunks:\n            self.assertLessEqual(chunk_size, self.CHUNK_SIZE,\n                                 'oversized chunk: ' + str(chunks))\n            self.assertGreater(chunk_size, 0,\n                               'empty chunk: ' + str(chunks))\n        return chunks\n\n    def compress(self, body):\n        bytesio = BytesIO()\n        gzfile = gzip.GzipFile(mode='w', fileobj=bytesio)\n        gzfile.write(body)\n        gzfile.close()\n        compressed = bytesio.getvalue()\n        if len(compressed) >= len(body):\n            raise Exception(\"body did not shrink when compressed\")\n        return compressed\n\n    def test_regular_body(self):\n        chunks = self.fetch_chunk_sizes(body=self.BODY)\n        # Without compression we know exactly what to expect.\n        self.assertEqual([16, 16, 16, 2], chunks)\n\n    def test_compressed_body(self):\n        self.fetch_chunk_sizes(body=self.compress(self.BODY),\n                               headers={'Content-Encoding': 'gzip'})\n        # Compression creates irregular boundaries so the assertions\n        # in fetch_chunk_sizes are as specific as we can get.\n\n    def test_chunked_body(self):\n        def body_producer(write):\n            write(self.BODY[:20])\n            write(self.BODY[20:])\n        chunks = self.fetch_chunk_sizes(body_producer=body_producer)\n        # HTTP chunk boundaries translate to application-visible breaks\n        self.assertEqual([16, 4, 16, 14], chunks)\n\n    def test_chunked_compressed(self):\n        compressed = self.compress(self.BODY)\n        self.assertGreater(len(compressed), 20)\n\n        def body_producer(write):\n            write(compressed[:20])\n            write(compressed[20:])\n        self.fetch_chunk_sizes(body_producer=body_producer,\n                               headers={'Content-Encoding': 'gzip'})\n\n\nclass MaxHeaderSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler)])\n\n    def get_httpserver_options(self):\n        return dict(max_header_size=1024)\n\n    def test_small_headers(self):\n        response = self.fetch(\"/\", headers={'X-Filler': 'a' * 100})\n        response.rethrow()\n        self.assertEqual(response.body, b\"Hello world\")\n\n    def test_large_headers(self):\n        with ExpectLog(gen_log, \"Unsatisfiable read\", required=False):\n            response = self.fetch(\"/\", headers={'X-Filler': 'a' * 1000})\n        # 431 is \"Request Header Fields Too Large\", defined in RFC\n        # 6585. However, many implementations just close the\n        # connection in this case, resulting in a 599.\n        self.assertIn(response.code, (431, 599))\n\n\n@skipOnTravis\nclass IdleTimeoutTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler)])\n\n    def get_httpserver_options(self):\n        return dict(idle_connection_timeout=0.1)\n\n    def setUp(self):\n        super(IdleTimeoutTest, self).setUp()\n        self.streams = []\n\n    def tearDown(self):\n        super(IdleTimeoutTest, self).tearDown()\n        for stream in self.streams:\n            stream.close()\n\n    def connect(self):\n        stream = IOStream(socket.socket())\n        stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n        self.streams.append(stream)\n        return stream\n\n    def test_unused_connection(self):\n        stream = self.connect()\n        stream.set_close_callback(self.stop)\n        self.wait()\n\n    def test_idle_after_use(self):\n        stream = self.connect()\n        stream.set_close_callback(lambda: self.stop(\"closed\"))\n\n        # Use the connection twice to make sure keep-alives are working\n        for i in range(2):\n            stream.write(b\"GET / HTTP/1.1\\r\\n\\r\\n\")\n            stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n            self.wait()\n            stream.read_bytes(11, self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"Hello world\")\n\n        # Now let the timeout trigger and close the connection.\n        data = self.wait()\n        self.assertEqual(data, \"closed\")\n\n\nclass BodyLimitsTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class BufferedHandler(RequestHandler):\n            def put(self):\n                self.write(str(len(self.request.body)))\n\n        @stream_request_body\n        class StreamingHandler(RequestHandler):\n            def initialize(self):\n                self.bytes_read = 0\n\n            def prepare(self):\n                if 'expected_size' in self.request.arguments:\n                    self.request.connection.set_max_body_size(\n                        int(self.get_argument('expected_size')))\n                if 'body_timeout' in self.request.arguments:\n                    self.request.connection.set_body_timeout(\n                        float(self.get_argument('body_timeout')))\n\n            def data_received(self, data):\n                self.bytes_read += len(data)\n\n            def put(self):\n                self.write(str(self.bytes_read))\n\n        return Application([('/buffered', BufferedHandler),\n                            ('/streaming', StreamingHandler)])\n\n    def get_httpserver_options(self):\n        return dict(body_timeout=3600, max_body_size=4096)\n\n    def get_http_client(self):\n        # body_producer doesn't work on curl_httpclient, so override the\n        # configured AsyncHTTPClient implementation.\n        return SimpleAsyncHTTPClient()\n\n    def test_small_body(self):\n        response = self.fetch('/buffered', method='PUT', body=b'a' * 4096)\n        self.assertEqual(response.body, b'4096')\n        response = self.fetch('/streaming', method='PUT', body=b'a' * 4096)\n        self.assertEqual(response.body, b'4096')\n\n    def test_large_body_buffered(self):\n        with ExpectLog(gen_log, '.*Content-Length too long'):\n            response = self.fetch('/buffered', method='PUT', body=b'a' * 10240)\n        self.assertEqual(response.code, 400)\n\n    def test_large_body_buffered_chunked(self):\n        with ExpectLog(gen_log, '.*chunked body too large'):\n            response = self.fetch('/buffered', method='PUT',\n                                  body_producer=lambda write: write(b'a' * 10240))\n        # this test is flaky on windows; accept 400 (expected) or 599\n        self.assertIn(response.code, [400, 599])\n\n    def test_large_body_streaming(self):\n        with ExpectLog(gen_log, '.*Content-Length too long'):\n            response = self.fetch('/streaming', method='PUT', body=b'a' * 10240)\n        self.assertEqual(response.code, 400)\n\n    def test_large_body_streaming_chunked(self):\n        with ExpectLog(gen_log, '.*chunked body too large'):\n            response = self.fetch('/streaming', method='PUT',\n                                  body_producer=lambda write: write(b'a' * 10240))\n        # this test is flaky on windows; accept 400 (expected) or 599\n        self.assertIn(response.code, [400, 599])\n\n    def test_large_body_streaming_override(self):\n        response = self.fetch('/streaming?expected_size=10240', method='PUT',\n                              body=b'a' * 10240)\n        self.assertEqual(response.body, b'10240')\n\n    def test_large_body_streaming_chunked_override(self):\n        response = self.fetch('/streaming?expected_size=10240', method='PUT',\n                              body_producer=lambda write: write(b'a' * 10240))\n        self.assertEqual(response.body, b'10240')\n\n    @gen_test\n    def test_timeout(self):\n        stream = IOStream(socket.socket())\n        try:\n            yield stream.connect(('127.0.0.1', self.get_http_port()))\n            # Use a raw stream because AsyncHTTPClient won't let us read a\n            # response without finishing a body.\n            stream.write(b'PUT /streaming?body_timeout=0.1 HTTP/1.0\\r\\n'\n                         b'Content-Length: 42\\r\\n\\r\\n')\n            with ExpectLog(gen_log, 'Timeout reading body'):\n                response = yield stream.read_until_close()\n            self.assertEqual(response, b'')\n        finally:\n            stream.close()\n\n    @gen_test\n    def test_body_size_override_reset(self):\n        # The max_body_size override is reset between requests.\n        stream = IOStream(socket.socket())\n        try:\n            yield stream.connect(('127.0.0.1', self.get_http_port()))\n            # Use a raw stream so we can make sure it's all on one connection.\n            stream.write(b'PUT /streaming?expected_size=10240 HTTP/1.1\\r\\n'\n                         b'Content-Length: 10240\\r\\n\\r\\n')\n            stream.write(b'a' * 10240)\n            start_line, headers, response = yield gen.Task(read_stream_body, stream)\n            self.assertEqual(response, b'10240')\n            # Without the ?expected_size parameter, we get the old default value\n            stream.write(b'PUT /streaming HTTP/1.1\\r\\n'\n                         b'Content-Length: 10240\\r\\n\\r\\n')\n            with ExpectLog(gen_log, '.*Content-Length too long'):\n                data = yield stream.read_until_close()\n            self.assertEqual(data, b'HTTP/1.1 400 Bad Request\\r\\n\\r\\n')\n        finally:\n            stream.close()\n\n\nclass LegacyInterfaceTest(AsyncHTTPTestCase):\n    def get_app(self):\n        # The old request_callback interface does not implement the\n        # delegate interface, and writes its response via request.write\n        # instead of request.connection.write_headers.\n        def handle_request(request):\n            self.http1 = request.version.startswith(\"HTTP/1.\")\n            if not self.http1:\n                # This test will be skipped if we're using HTTP/2,\n                # so just close it out cleanly using the modern interface.\n                request.connection.write_headers(\n                    ResponseStartLine('', 200, 'OK'),\n                    HTTPHeaders())\n                request.connection.finish()\n                return\n            message = b\"Hello world\"\n            request.write(utf8(\"HTTP/1.1 200 OK\\r\\n\"\n                               \"Content-Length: %d\\r\\n\\r\\n\" % len(message)))\n            request.write(message)\n            request.finish()\n        return handle_request\n\n    def test_legacy_interface(self):\n        response = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(response.body, b\"Hello world\")\n",
            "header": {
                "file": {
                    "path": "tornado/test/httpserver_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "2f9e9094",
                "new_commit_hash": "1b128602",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/httpserver_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/httpserver_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 550,
                            "length": 6
                        },
                        "new_range": {
                            "start": 550,
                            "length": 16
                        },
                        "section": "class XHeaderTest(HandlerBaseTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],",
                                "type": "context"
                            },
                            {
                                "content": "            \"https\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        https_multi_forwarded = {\"X-Forwarded-Proto\": \"https , http\"}",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "added"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=https_multi_forwarded)[\"remote_protocol\"],",
                                "type": "added"
                            },
                            {
                                "content": "            \"http\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        http_multi_forwarded = {\"X-Forwarded-Proto\": \"http,https\"}",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "added"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=http_multi_forwarded)[\"remote_protocol\"],",
                                "type": "added"
                            },
                            {
                                "content": "            \"https\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "context"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/httpserver_test.py",
                            "type": "method",
                            "name": "XHeaderTest.test_scheme_headers",
                            "content": "class XHeaderTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(remote_ip=self.request.remote_ip,\n                            remote_protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(xheaders=True, trusted_downstream=['5.5.5.5'])\n\n    def test_ip_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_ip\"], \"127.0.0.1\")\n\n        valid_ipv4 = {\"X-Real-IP\": \"4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_host = {\"X-Real-IP\": \"www.google.com\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n    def test_trusted_downstream(self):\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4, 5.5.5.5\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n    def test_scheme_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"http\")\n\n        https_scheme = {\"X-Scheme\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_scheme)[\"remote_protocol\"],\n            \"https\")\n\n        https_forwarded = {\"X-Forwarded-Proto\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        https_multi_forwarded = {\"X-Forwarded-Proto\": \"https , http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_multi_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n        http_multi_forwarded = {\"X-Forwarded-Proto\": \"http,https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_multi_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],\n            \"http\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 540,
                            "end_lineno": 566,
                            "parent": {
                                "file_name": "tornado/test/httpserver_test.py",
                                "type": "class",
                                "name": "XHeaderTest",
                                "content": "class XHeaderTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(remote_ip=self.request.remote_ip,\n                            remote_protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(xheaders=True, trusted_downstream=['5.5.5.5'])\n\n    def test_ip_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_ip\"], \"127.0.0.1\")\n\n        valid_ipv4 = {\"X-Real-IP\": \"4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_host = {\"X-Real-IP\": \"www.google.com\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n    def test_trusted_downstream(self):\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4, 5.5.5.5\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n    def test_scheme_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"http\")\n\n        https_scheme = {\"X-Scheme\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_scheme)[\"remote_protocol\"],\n            \"https\")\n\n        https_forwarded = {\"X-Forwarded-Proto\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        https_multi_forwarded = {\"X-Forwarded-Proto\": \"https , http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_multi_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n        http_multi_forwarded = {\"X-Forwarded-Proto\": \"http,https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_multi_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],\n            \"http\")",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 486,
                                "end_lineno": 566,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/httpserver_test.py",
                            "type": "class",
                            "name": "XHeaderTest",
                            "content": "class XHeaderTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(remote_ip=self.request.remote_ip,\n                            remote_protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(xheaders=True, trusted_downstream=['5.5.5.5'])\n\n    def test_ip_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_ip\"], \"127.0.0.1\")\n\n        valid_ipv4 = {\"X-Real-IP\": \"4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_host = {\"X-Real-IP\": \"www.google.com\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n    def test_trusted_downstream(self):\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4, 5.5.5.5\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n    def test_scheme_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"http\")\n\n        https_scheme = {\"X-Scheme\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_scheme)[\"remote_protocol\"],\n            \"https\")\n\n        https_forwarded = {\"X-Forwarded-Proto\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        https_multi_forwarded = {\"X-Forwarded-Proto\": \"https , http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_multi_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n        http_multi_forwarded = {\"X-Forwarded-Proto\": \"http,https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_multi_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],\n            \"http\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 486,
                            "end_lineno": 566,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "5fcfb4277514ff82e2d3b17a24a26ed505b8d453^",
    "new_commit_hash": "5fcfb4277514ff82e2d3b17a24a26ed505b8d453",
    "commit_message": "handle multiple values in X-Forwarded-Proto (#2162)",
    "commit_date": "2017-11-15T22:21:52-05:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "5fcfb4277514ff82e2d3b17a24a26ed505b8d453",
    "test_file_codes": [
        "#!/usr/bin/env python\n\n\nfrom __future__ import absolute_import, division, print_function\nfrom tornado import netutil\nfrom tornado.escape import json_decode, json_encode, utf8, _unicode, recursive_unicode, native_str\nfrom tornado import gen\nfrom tornado.http1connection import HTTP1Connection\nfrom tornado.httpserver import HTTPServer\nfrom tornado.httputil import HTTPHeaders, HTTPMessageDelegate, HTTPServerConnectionDelegate, ResponseStartLine\nfrom tornado.iostream import IOStream\nfrom tornado.log import gen_log\nfrom tornado.netutil import ssl_options_to_context\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog, gen_test\nfrom tornado.test.util import unittest, skipOnTravis\nfrom tornado.web import Application, RequestHandler, asynchronous, stream_request_body\nfrom contextlib import closing\nimport datetime\nimport gzip\nimport os\nimport shutil\nimport socket\nimport ssl\nimport sys\nimport tempfile\nfrom io import BytesIO\n\n\ndef read_stream_body(stream, callback):\n    \"\"\"Reads an HTTP response from `stream` and runs callback with its\n    start_line, headers and body.\"\"\"\n    chunks = []\n\n    class Delegate(HTTPMessageDelegate):\n        def headers_received(self, start_line, headers):\n            self.headers = headers\n            self.start_line = start_line\n\n        def data_received(self, chunk):\n            chunks.append(chunk)\n\n        def finish(self):\n            conn.detach()\n            callback((self.start_line, self.headers, b''.join(chunks)))\n    conn = HTTP1Connection(stream, True)\n    conn.read_response(Delegate())\n\n\nclass HandlerBaseTestCase(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', self.__class__.Handler)])\n\n    def fetch_json(self, *args, **kwargs):\n        response = self.fetch(*args, **kwargs)\n        response.rethrow()\n        return json_decode(response.body)\n\n\nclass HelloWorldRequestHandler(RequestHandler):\n    def initialize(self, protocol=\"http\"):\n        self.expected_protocol = protocol\n\n    def get(self):\n        if self.request.protocol != self.expected_protocol:\n            raise Exception(\"unexpected protocol\")\n        self.finish(\"Hello world\")\n\n    def post(self):\n        self.finish(\"Got %d bytes in POST\" % len(self.request.body))\n\n\n# In pre-1.0 versions of openssl, SSLv23 clients always send SSLv2\n# ClientHello messages, which are rejected by SSLv3 and TLSv1\n# servers.  Note that while the OPENSSL_VERSION_INFO was formally\n# introduced in python3.2, it was present but undocumented in\n# python 2.7\nskipIfOldSSL = unittest.skipIf(\n    getattr(ssl, 'OPENSSL_VERSION_INFO', (0, 0)) < (1, 0),\n    \"old version of ssl module and/or openssl\")\n\n\nclass BaseSSLTest(AsyncHTTPSTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler,\n                             dict(protocol=\"https\"))])\n\n\nclass SSLTestMixin(object):\n    def get_ssl_options(self):\n        return dict(ssl_version=self.get_ssl_version(),  # type: ignore\n                    **AsyncHTTPSTestCase.get_ssl_options())\n\n    def get_ssl_version(self):\n        raise NotImplementedError()\n\n    def test_ssl(self):\n        response = self.fetch('/')\n        self.assertEqual(response.body, b\"Hello world\")\n\n    def test_large_post(self):\n        response = self.fetch('/',\n                              method='POST',\n                              body='A' * 5000)\n        self.assertEqual(response.body, b\"Got 5000 bytes in POST\")\n\n    def test_non_ssl_request(self):\n        # Make sure the server closes the connection when it gets a non-ssl\n        # connection, rather than waiting for a timeout or otherwise\n        # misbehaving.\n        with ExpectLog(gen_log, '(SSL Error|uncaught exception)'):\n            with ExpectLog(gen_log, 'Uncaught exception', required=False):\n                self.http_client.fetch(\n                    self.get_url(\"/\").replace('https:', 'http:'),\n                    self.stop,\n                    request_timeout=3600,\n                    connect_timeout=3600)\n                response = self.wait()\n        self.assertEqual(response.code, 599)\n\n    def test_error_logging(self):\n        # No stack traces are logged for SSL errors.\n        with ExpectLog(gen_log, 'SSL Error') as expect_log:\n            self.http_client.fetch(\n                self.get_url(\"/\").replace(\"https:\", \"http:\"),\n                self.stop)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n        self.assertFalse(expect_log.logged_stack)\n\n# Python's SSL implementation differs significantly between versions.\n# For example, SSLv3 and TLSv1 throw an exception if you try to read\n# from the socket before the handshake is complete, but the default\n# of SSLv23 allows it.\n\n\nclass SSLv23Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_SSLv23\n\n\n@skipIfOldSSL\nclass SSLv3Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_SSLv3\n\n\n@skipIfOldSSL\nclass TLSv1Test(BaseSSLTest, SSLTestMixin):\n    def get_ssl_version(self):\n        return ssl.PROTOCOL_TLSv1\n\n\nclass SSLContextTest(BaseSSLTest, SSLTestMixin):\n    def get_ssl_options(self):\n        context = ssl_options_to_context(\n            AsyncHTTPSTestCase.get_ssl_options(self))\n        assert isinstance(context, ssl.SSLContext)\n        return context\n\n\nclass BadSSLOptionsTest(unittest.TestCase):\n    def test_missing_arguments(self):\n        application = Application()\n        self.assertRaises(KeyError, HTTPServer, application, ssl_options={\n            \"keyfile\": \"/__missing__.crt\",\n        })\n\n    def test_missing_key(self):\n        \"\"\"A missing SSL key should cause an immediate exception.\"\"\"\n\n        application = Application()\n        module_dir = os.path.dirname(__file__)\n        existing_certificate = os.path.join(module_dir, 'test.crt')\n        existing_key = os.path.join(module_dir, 'test.key')\n\n        self.assertRaises((ValueError, IOError),\n                          HTTPServer, application, ssl_options={\n                              \"certfile\": \"/__mising__.crt\",\n        })\n        self.assertRaises((ValueError, IOError),\n                          HTTPServer, application, ssl_options={\n                              \"certfile\": existing_certificate,\n                              \"keyfile\": \"/__missing__.key\"\n        })\n\n        # This actually works because both files exist\n        HTTPServer(application, ssl_options={\n                   \"certfile\": existing_certificate,\n                   \"keyfile\": existing_key,\n                   })\n\n\nclass MultipartTestHandler(RequestHandler):\n    def post(self):\n        self.finish({\"header\": self.request.headers[\"X-Header-Encoding-Test\"],\n                     \"argument\": self.get_argument(\"argument\"),\n                     \"filename\": self.request.files[\"files\"][0].filename,\n                     \"filebody\": _unicode(self.request.files[\"files\"][0][\"body\"]),\n                     })\n\n\n# This test is also called from wsgi_test\nclass HTTPConnectionTest(AsyncHTTPTestCase):\n    def get_handlers(self):\n        return [(\"/multipart\", MultipartTestHandler),\n                (\"/hello\", HelloWorldRequestHandler)]\n\n    def get_app(self):\n        return Application(self.get_handlers())\n\n    def raw_fetch(self, headers, body, newline=b\"\\r\\n\"):\n        with closing(IOStream(socket.socket())) as stream:\n            stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n            self.wait()\n            stream.write(\n                newline.join(headers +\n                             [utf8(\"Content-Length: %d\" % len(body))]) +\n                newline + newline + body)\n            read_stream_body(stream, self.stop)\n            start_line, headers, body = self.wait()\n            return body\n\n    def test_multipart_form(self):\n        # Encodings here are tricky:  Headers are latin1, bodies can be\n        # anything (we use utf8 by default).\n        response = self.raw_fetch([\n            b\"POST /multipart HTTP/1.0\",\n            b\"Content-Type: multipart/form-data; boundary=1234567890\",\n            b\"X-Header-encoding-test: \\xe9\",\n        ],\n            b\"\\r\\n\".join([\n                b\"Content-Disposition: form-data; name=argument\",\n                b\"\",\n                u\"\\u00e1\".encode(\"utf-8\"),\n                b\"--1234567890\",\n                u'Content-Disposition: form-data; name=\"files\"; filename=\"\\u00f3\"'.encode(\"utf8\"),\n                b\"\",\n                u\"\\u00fa\".encode(\"utf-8\"),\n                b\"--1234567890--\",\n                b\"\",\n            ]))\n        data = json_decode(response)\n        self.assertEqual(u\"\\u00e9\", data[\"header\"])\n        self.assertEqual(u\"\\u00e1\", data[\"argument\"])\n        self.assertEqual(u\"\\u00f3\", data[\"filename\"])\n        self.assertEqual(u\"\\u00fa\", data[\"filebody\"])\n\n    def test_newlines(self):\n        # We support both CRLF and bare LF as line separators.\n        for newline in (b\"\\r\\n\", b\"\\n\"):\n            response = self.raw_fetch([b\"GET /hello HTTP/1.0\"], b\"\",\n                                      newline=newline)\n            self.assertEqual(response, b'Hello world')\n\n    def test_100_continue(self):\n        # Run through a 100-continue interaction by hand:\n        # When given Expect: 100-continue, we get a 100 response after the\n        # headers, and then the real response after the body.\n        stream = IOStream(socket.socket())\n        stream.connect((\"127.0.0.1\", self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"\\r\\n\".join([b\"POST /hello HTTP/1.1\",\n                                   b\"Content-Length: 1024\",\n                                   b\"Expect: 100-continue\",\n                                   b\"Connection: close\",\n                                   b\"\\r\\n\"]), callback=self.stop)\n        self.wait()\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.1 100 \"), data)\n        stream.write(b\"a\" * 1024)\n        stream.read_until(b\"\\r\\n\", self.stop)\n        first_line = self.wait()\n        self.assertTrue(first_line.startswith(b\"HTTP/1.1 200\"), first_line)\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        header_data = self.wait()\n        headers = HTTPHeaders.parse(native_str(header_data.decode('latin1')))\n        stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Got 1024 bytes in POST\")\n        stream.close()\n\n\nclass EchoHandler(RequestHandler):\n    def get(self):\n        self.write(recursive_unicode(self.request.arguments))\n\n    def post(self):\n        self.write(recursive_unicode(self.request.arguments))\n\n\nclass TypeCheckHandler(RequestHandler):\n    def prepare(self):\n        self.errors = {}\n        fields = [\n            ('method', str),\n            ('uri', str),\n            ('version', str),\n            ('remote_ip', str),\n            ('protocol', str),\n            ('host', str),\n            ('path', str),\n            ('query', str),\n        ]\n        for field, expected_type in fields:\n            self.check_type(field, getattr(self.request, field), expected_type)\n\n        self.check_type('header_key', list(self.request.headers.keys())[0], str)\n        self.check_type('header_value', list(self.request.headers.values())[0], str)\n\n        self.check_type('cookie_key', list(self.request.cookies.keys())[0], str)\n        self.check_type('cookie_value', list(self.request.cookies.values())[0].value, str)\n        # secure cookies\n\n        self.check_type('arg_key', list(self.request.arguments.keys())[0], str)\n        self.check_type('arg_value', list(self.request.arguments.values())[0][0], bytes)\n\n    def post(self):\n        self.check_type('body', self.request.body, bytes)\n        self.write(self.errors)\n\n    def get(self):\n        self.write(self.errors)\n\n    def check_type(self, name, obj, expected_type):\n        actual_type = type(obj)\n        if expected_type != actual_type:\n            self.errors[name] = \"expected %s, got %s\" % (expected_type,\n                                                         actual_type)\n\n\nclass HTTPServerTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([(\"/echo\", EchoHandler),\n                            (\"/typecheck\", TypeCheckHandler),\n                            (\"//doubleslash\", EchoHandler),\n                            ])\n\n    def test_query_string_encoding(self):\n        response = self.fetch(\"/echo?foo=%C3%A9\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\\u00e9\"]})\n\n    def test_empty_query_string(self):\n        response = self.fetch(\"/echo?foo=&foo=\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\", u\"\"]})\n\n    def test_empty_post_parameters(self):\n        response = self.fetch(\"/echo\", method=\"POST\", body=\"foo=&bar=\")\n        data = json_decode(response.body)\n        self.assertEqual(data, {u\"foo\": [u\"\"], u\"bar\": [u\"\"]})\n\n    def test_types(self):\n        headers = {\"Cookie\": \"foo=bar\"}\n        response = self.fetch(\"/typecheck?foo=bar\", headers=headers)\n        data = json_decode(response.body)\n        self.assertEqual(data, {})\n\n        response = self.fetch(\"/typecheck\", method=\"POST\", body=\"foo=bar\", headers=headers)\n        data = json_decode(response.body)\n        self.assertEqual(data, {})\n\n    def test_double_slash(self):\n        # urlparse.urlsplit (which tornado.httpserver used to use\n        # incorrectly) would parse paths beginning with \"//\" as\n        # protocol-relative urls.\n        response = self.fetch(\"//doubleslash\")\n        self.assertEqual(200, response.code)\n        self.assertEqual(json_decode(response.body), {})\n\n    def test_malformed_body(self):\n        # parse_qs is pretty forgiving, but it will fail on python 3\n        # if the data is not utf8.  On python 2 parse_qs will work,\n        # but then the recursive_unicode call in EchoHandler will\n        # fail.\n        if str is bytes:\n            return\n        with ExpectLog(gen_log, 'Invalid x-www-form-urlencoded body'):\n            response = self.fetch(\n                '/echo', method=\"POST\",\n                headers={'Content-Type': 'application/x-www-form-urlencoded'},\n                body=b'\\xe9')\n        self.assertEqual(200, response.code)\n        self.assertEqual(b'{}', response.body)\n\n\nclass HTTPServerRawTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([\n            ('/echo', EchoHandler),\n        ])\n\n    def setUp(self):\n        super(HTTPServerRawTest, self).setUp()\n        self.stream = IOStream(socket.socket())\n        self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n\n    def tearDown(self):\n        self.stream.close()\n        super(HTTPServerRawTest, self).tearDown()\n\n    def test_empty_request(self):\n        self.stream.close()\n        self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)\n        self.wait()\n\n    def test_malformed_first_line_response(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP request line'):\n            self.stream.write(b'asdf\\r\\n\\r\\n')\n            read_stream_body(self.stream, self.stop)\n            start_line, headers, response = self.wait()\n            self.assertEqual('HTTP/1.1', start_line.version)\n            self.assertEqual(400, start_line.code)\n            self.assertEqual('Bad Request', start_line.reason)\n\n    def test_malformed_first_line_log(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP request line'):\n            self.stream.write(b'asdf\\r\\n\\r\\n')\n            # TODO: need an async version of ExpectLog so we don't need\n            # hard-coded timeouts here.\n            self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),\n                                     self.stop)\n            self.wait()\n\n    def test_malformed_headers(self):\n        with ExpectLog(gen_log, '.*Malformed HTTP headers'):\n            self.stream.write(b'GET / HTTP/1.0\\r\\nasdf\\r\\n\\r\\n')\n            self.io_loop.add_timeout(datetime.timedelta(seconds=0.05),\n                                     self.stop)\n            self.wait()\n\n    def test_chunked_request_body(self):\n        # Chunked requests are not widely supported and we don't have a way\n        # to generate them in AsyncHTTPClient, but HTTPServer will read them.\n        self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nTransfer-Encoding: chunked\nContent-Type: application/x-www-form-urlencoded\n\n4\nfoo=\n3\nbar\n0\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n        read_stream_body(self.stream, self.stop)\n        start_line, headers, response = self.wait()\n        self.assertEqual(json_decode(response), {u'foo': [u'bar']})\n\n    def test_chunked_request_uppercase(self):\n        # As per RFC 2616 section 3.6, \"Transfer-Encoding\" header's value is\n        # case-insensitive.\n        self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nTransfer-Encoding: Chunked\nContent-Type: application/x-www-form-urlencoded\n\n4\nfoo=\n3\nbar\n0\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n        read_stream_body(self.stream, self.stop)\n        start_line, headers, response = self.wait()\n        self.assertEqual(json_decode(response), {u'foo': [u'bar']})\n\n    def test_invalid_content_length(self):\n        with ExpectLog(gen_log, '.*Only integer Content-Length is allowed'):\n            self.stream.write(b\"\"\"\\\nPOST /echo HTTP/1.1\nContent-Length: foo\n\nbar\n\n\"\"\".replace(b\"\\n\", b\"\\r\\n\"))\n            self.stream.read_until_close(self.stop)\n            self.wait()\n\n\nclass XHeaderTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(remote_ip=self.request.remote_ip,\n                            remote_protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(xheaders=True, trusted_downstream=['5.5.5.5'])\n\n    def test_ip_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_ip\"], \"127.0.0.1\")\n\n        valid_ipv4 = {\"X-Real-IP\": \"4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],\n            \"2620:0:1cfe:face:b00c::3\")\n\n        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n        invalid_host = {\"X-Real-IP\": \"www.google.com\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],\n            \"127.0.0.1\")\n\n    def test_trusted_downstream(self):\n\n        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4, 5.5.5.5\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],\n            \"4.4.4.4\")\n\n    def test_scheme_headers(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"http\")\n\n        https_scheme = {\"X-Scheme\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_scheme)[\"remote_protocol\"],\n            \"https\")\n\n        https_forwarded = {\"X-Forwarded-Proto\": \"https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        https_multi_forwarded = {\"X-Forwarded-Proto\": \"https , http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=https_multi_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n        http_multi_forwarded = {\"X-Forwarded-Proto\": \"http,https\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_multi_forwarded)[\"remote_protocol\"],\n            \"https\")\n\n        bad_forwarded = {\"X-Forwarded-Proto\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_forwarded)[\"remote_protocol\"],\n            \"http\")\n\n\nclass SSLXHeaderTest(AsyncHTTPSTestCase, HandlerBaseTestCase):\n    def get_app(self):\n        return Application([('/', XHeaderTest.Handler)])\n\n    def get_httpserver_options(self):\n        output = super(SSLXHeaderTest, self).get_httpserver_options()\n        output['xheaders'] = True\n        return output\n\n    def test_request_without_xprotocol(self):\n        self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n\n        http_scheme = {\"X-Scheme\": \"http\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=http_scheme)[\"remote_protocol\"], \"http\")\n\n        bad_scheme = {\"X-Scheme\": \"unknown\"}\n        self.assertEqual(\n            self.fetch_json(\"/\", headers=bad_scheme)[\"remote_protocol\"], \"https\")\n\n\nclass ManualProtocolTest(HandlerBaseTestCase):\n    class Handler(RequestHandler):\n        def get(self):\n            self.write(dict(protocol=self.request.protocol))\n\n    def get_httpserver_options(self):\n        return dict(protocol='https')\n\n    def test_manual_protocol(self):\n        self.assertEqual(self.fetch_json('/')['protocol'], 'https')\n\n\n@unittest.skipIf(not hasattr(socket, 'AF_UNIX') or sys.platform == 'cygwin',\n                 \"unix sockets not supported on this platform\")\nclass UnixSocketTest(AsyncTestCase):\n    \"\"\"HTTPServers can listen on Unix sockets too.\n\n    Why would you want to do this?  Nginx can proxy to backends listening\n    on unix sockets, for one thing (and managing a namespace for unix\n    sockets can be easier than managing a bunch of TCP port numbers).\n\n    Unfortunately, there's no way to specify a unix socket in a url for\n    an HTTP client, so we have to test this by hand.\n    \"\"\"\n    def setUp(self):\n        super(UnixSocketTest, self).setUp()\n        self.tmpdir = tempfile.mkdtemp()\n        self.sockfile = os.path.join(self.tmpdir, \"test.sock\")\n        sock = netutil.bind_unix_socket(self.sockfile)\n        app = Application([(\"/hello\", HelloWorldRequestHandler)])\n        self.server = HTTPServer(app)\n        self.server.add_socket(sock)\n        self.stream = IOStream(socket.socket(socket.AF_UNIX))\n        self.stream.connect(self.sockfile, self.stop)\n        self.wait()\n\n    def tearDown(self):\n        self.stream.close()\n        self.io_loop.run_sync(self.server.close_all_connections)\n        self.server.stop()\n        shutil.rmtree(self.tmpdir)\n        super(UnixSocketTest, self).tearDown()\n\n    def test_unix_socket(self):\n        self.stream.write(b\"GET /hello HTTP/1.0\\r\\n\\r\\n\")\n        self.stream.read_until(b\"\\r\\n\", self.stop)\n        response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.1 200 OK\\r\\n\")\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        headers = HTTPHeaders.parse(self.wait().decode('latin1'))\n        self.stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Hello world\")\n\n    def test_unix_socket_bad_request(self):\n        # Unix sockets don't have remote addresses so they just return an\n        # empty string.\n        with ExpectLog(gen_log, \"Malformed HTTP message from\"):\n            self.stream.write(b\"garbage\\r\\n\\r\\n\")\n            self.stream.read_until_close(self.stop)\n            response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.1 400 Bad Request\\r\\n\\r\\n\")\n\n\nclass KeepAliveTest(AsyncHTTPTestCase):\n    \"\"\"Tests various scenarios for HTTP 1.1 keep-alive support.\n\n    These tests don't use AsyncHTTPClient because we want to control\n    connection reuse and closing.\n    \"\"\"\n    def get_app(self):\n        class HelloHandler(RequestHandler):\n            def get(self):\n                self.finish('Hello world')\n\n            def post(self):\n                self.finish('Hello world')\n\n        class LargeHandler(RequestHandler):\n            def get(self):\n                # 512KB should be bigger than the socket buffers so it will\n                # be written out in chunks.\n                self.write(''.join(chr(i % 256) * 1024 for i in range(512)))\n\n        class FinishOnCloseHandler(RequestHandler):\n            @asynchronous\n            def get(self):\n                self.flush()\n\n            def on_connection_close(self):\n                # This is not very realistic, but finishing the request\n                # from the close callback has the right timing to mimic\n                # some errors seen in the wild.\n                self.finish('closed')\n\n        return Application([('/', HelloHandler),\n                            ('/large', LargeHandler),\n                            ('/finish_on_close', FinishOnCloseHandler)])\n\n    def setUp(self):\n        super(KeepAliveTest, self).setUp()\n        self.http_version = b'HTTP/1.1'\n\n    def tearDown(self):\n        # We just closed the client side of the socket; let the IOLoop run\n        # once to make sure the server side got the message.\n        self.io_loop.add_timeout(datetime.timedelta(seconds=0.001), self.stop)\n        self.wait()\n\n        if hasattr(self, 'stream'):\n            self.stream.close()\n        super(KeepAliveTest, self).tearDown()\n\n    # The next few methods are a crude manual http client\n    def connect(self):\n        self.stream = IOStream(socket.socket())\n        self.stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n\n    def read_headers(self):\n        self.stream.read_until(b'\\r\\n', self.stop)\n        first_line = self.wait()\n        self.assertTrue(first_line.startswith(b'HTTP/1.1 200'), first_line)\n        self.stream.read_until(b'\\r\\n\\r\\n', self.stop)\n        header_bytes = self.wait()\n        headers = HTTPHeaders.parse(header_bytes.decode('latin1'))\n        return headers\n\n    def read_response(self):\n        self.headers = self.read_headers()\n        self.stream.read_bytes(int(self.headers['Content-Length']), self.stop)\n        body = self.wait()\n        self.assertEqual(b'Hello world', body)\n\n    def close(self):\n        self.stream.close()\n        del self.stream\n\n    def test_two_requests(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.close()\n\n    def test_request_close(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\nConnection: close\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.read_until_close(callback=self.stop)\n        data = self.wait()\n        self.assertTrue(not data)\n        self.assertEqual(self.headers['Connection'], 'close')\n        self.close()\n\n    # keepalive is supported for http 1.0 too, but it's opt-in\n    def test_http10(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\n\\r\\n')\n        self.read_response()\n        self.stream.read_until_close(callback=self.stop)\n        data = self.wait()\n        self.assertTrue(not data)\n        self.assertTrue('Connection' not in self.headers)\n        self.close()\n\n    def test_http10_keepalive(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n    def test_http10_keepalive_extra_crlf(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n    def test_pipelined_requests(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\nGET / HTTP/1.1\\r\\n\\r\\n')\n        self.read_response()\n        self.read_response()\n        self.close()\n\n    def test_pipelined_cancel(self):\n        self.connect()\n        self.stream.write(b'GET / HTTP/1.1\\r\\n\\r\\nGET / HTTP/1.1\\r\\n\\r\\n')\n        # only read once\n        self.read_response()\n        self.close()\n\n    def test_cancel_during_download(self):\n        self.connect()\n        self.stream.write(b'GET /large HTTP/1.1\\r\\n\\r\\n')\n        self.read_headers()\n        self.stream.read_bytes(1024, self.stop)\n        self.wait()\n        self.close()\n\n    def test_finish_while_closed(self):\n        self.connect()\n        self.stream.write(b'GET /finish_on_close HTTP/1.1\\r\\n\\r\\n')\n        self.read_headers()\n        self.close()\n\n    def test_keepalive_chunked(self):\n        self.http_version = b'HTTP/1.0'\n        self.connect()\n        self.stream.write(b'POST / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n'\n                          b'Transfer-Encoding: chunked\\r\\n'\n                          b'\\r\\n0\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\n        self.assertEqual(self.headers['Connection'], 'Keep-Alive')\n        self.close()\n\n\nclass GzipBaseTest(object):\n    def get_app(self):\n        return Application([('/', EchoHandler)])\n\n    def post_gzip(self, body):\n        bytesio = BytesIO()\n        gzip_file = gzip.GzipFile(mode='w', fileobj=bytesio)\n        gzip_file.write(utf8(body))\n        gzip_file.close()\n        compressed_body = bytesio.getvalue()\n        return self.fetch('/', method='POST', body=compressed_body,\n                          headers={'Content-Encoding': 'gzip'})\n\n    def test_uncompressed(self):\n        response = self.fetch('/', method='POST', body='foo=bar')\n        self.assertEquals(json_decode(response.body), {u'foo': [u'bar']})\n\n\nclass GzipTest(GzipBaseTest, AsyncHTTPTestCase):\n    def get_httpserver_options(self):\n        return dict(decompress_request=True)\n\n    def test_gzip(self):\n        response = self.post_gzip('foo=bar')\n        self.assertEquals(json_decode(response.body), {u'foo': [u'bar']})\n\n\nclass GzipUnsupportedTest(GzipBaseTest, AsyncHTTPTestCase):\n    def test_gzip_unsupported(self):\n        # Gzip support is opt-in; without it the server fails to parse\n        # the body (but parsing form bodies is currently just a log message,\n        # not a fatal error).\n        with ExpectLog(gen_log, \"Unsupported Content-Encoding\"):\n            response = self.post_gzip('foo=bar')\n        self.assertEquals(json_decode(response.body), {})\n\n\nclass StreamingChunkSizeTest(AsyncHTTPTestCase):\n    # 50 characters long, and repetitive so it can be compressed.\n    BODY = b'01234567890123456789012345678901234567890123456789'\n    CHUNK_SIZE = 16\n\n    def get_http_client(self):\n        # body_producer doesn't work on curl_httpclient, so override the\n        # configured AsyncHTTPClient implementation.\n        return SimpleAsyncHTTPClient()\n\n    def get_httpserver_options(self):\n        return dict(chunk_size=self.CHUNK_SIZE, decompress_request=True)\n\n    class MessageDelegate(HTTPMessageDelegate):\n        def __init__(self, connection):\n            self.connection = connection\n\n        def headers_received(self, start_line, headers):\n            self.chunk_lengths = []\n\n        def data_received(self, chunk):\n            self.chunk_lengths.append(len(chunk))\n\n        def finish(self):\n            response_body = utf8(json_encode(self.chunk_lengths))\n            self.connection.write_headers(\n                ResponseStartLine('HTTP/1.1', 200, 'OK'),\n                HTTPHeaders({'Content-Length': str(len(response_body))}))\n            self.connection.write(response_body)\n            self.connection.finish()\n\n    def get_app(self):\n        class App(HTTPServerConnectionDelegate):\n            def start_request(self, server_conn, request_conn):\n                return StreamingChunkSizeTest.MessageDelegate(request_conn)\n        return App()\n\n    def fetch_chunk_sizes(self, **kwargs):\n        response = self.fetch('/', method='POST', **kwargs)\n        response.rethrow()\n        chunks = json_decode(response.body)\n        self.assertEqual(len(self.BODY), sum(chunks))\n        for chunk_size in chunks:\n            self.assertLessEqual(chunk_size, self.CHUNK_SIZE,\n                                 'oversized chunk: ' + str(chunks))\n            self.assertGreater(chunk_size, 0,\n                               'empty chunk: ' + str(chunks))\n        return chunks\n\n    def compress(self, body):\n        bytesio = BytesIO()\n        gzfile = gzip.GzipFile(mode='w', fileobj=bytesio)\n        gzfile.write(body)\n        gzfile.close()\n        compressed = bytesio.getvalue()\n        if len(compressed) >= len(body):\n            raise Exception(\"body did not shrink when compressed\")\n        return compressed\n\n    def test_regular_body(self):\n        chunks = self.fetch_chunk_sizes(body=self.BODY)\n        # Without compression we know exactly what to expect.\n        self.assertEqual([16, 16, 16, 2], chunks)\n\n    def test_compressed_body(self):\n        self.fetch_chunk_sizes(body=self.compress(self.BODY),\n                               headers={'Content-Encoding': 'gzip'})\n        # Compression creates irregular boundaries so the assertions\n        # in fetch_chunk_sizes are as specific as we can get.\n\n    def test_chunked_body(self):\n        def body_producer(write):\n            write(self.BODY[:20])\n            write(self.BODY[20:])\n        chunks = self.fetch_chunk_sizes(body_producer=body_producer)\n        # HTTP chunk boundaries translate to application-visible breaks\n        self.assertEqual([16, 4, 16, 14], chunks)\n\n    def test_chunked_compressed(self):\n        compressed = self.compress(self.BODY)\n        self.assertGreater(len(compressed), 20)\n\n        def body_producer(write):\n            write(compressed[:20])\n            write(compressed[20:])\n        self.fetch_chunk_sizes(body_producer=body_producer,\n                               headers={'Content-Encoding': 'gzip'})\n\n\nclass MaxHeaderSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler)])\n\n    def get_httpserver_options(self):\n        return dict(max_header_size=1024)\n\n    def test_small_headers(self):\n        response = self.fetch(\"/\", headers={'X-Filler': 'a' * 100})\n        response.rethrow()\n        self.assertEqual(response.body, b\"Hello world\")\n\n    def test_large_headers(self):\n        with ExpectLog(gen_log, \"Unsatisfiable read\", required=False):\n            response = self.fetch(\"/\", headers={'X-Filler': 'a' * 1000})\n        # 431 is \"Request Header Fields Too Large\", defined in RFC\n        # 6585. However, many implementations just close the\n        # connection in this case, resulting in a 599.\n        self.assertIn(response.code, (431, 599))\n\n\n@skipOnTravis\nclass IdleTimeoutTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', HelloWorldRequestHandler)])\n\n    def get_httpserver_options(self):\n        return dict(idle_connection_timeout=0.1)\n\n    def setUp(self):\n        super(IdleTimeoutTest, self).setUp()\n        self.streams = []\n\n    def tearDown(self):\n        super(IdleTimeoutTest, self).tearDown()\n        for stream in self.streams:\n            stream.close()\n\n    def connect(self):\n        stream = IOStream(socket.socket())\n        stream.connect(('127.0.0.1', self.get_http_port()), self.stop)\n        self.wait()\n        self.streams.append(stream)\n        return stream\n\n    def test_unused_connection(self):\n        stream = self.connect()\n        stream.set_close_callback(self.stop)\n        self.wait()\n\n    def test_idle_after_use(self):\n        stream = self.connect()\n        stream.set_close_callback(lambda: self.stop(\"closed\"))\n\n        # Use the connection twice to make sure keep-alives are working\n        for i in range(2):\n            stream.write(b\"GET / HTTP/1.1\\r\\n\\r\\n\")\n            stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n            self.wait()\n            stream.read_bytes(11, self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"Hello world\")\n\n        # Now let the timeout trigger and close the connection.\n        data = self.wait()\n        self.assertEqual(data, \"closed\")\n\n\nclass BodyLimitsTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class BufferedHandler(RequestHandler):\n            def put(self):\n                self.write(str(len(self.request.body)))\n\n        @stream_request_body\n        class StreamingHandler(RequestHandler):\n            def initialize(self):\n                self.bytes_read = 0\n\n            def prepare(self):\n                if 'expected_size' in self.request.arguments:\n                    self.request.connection.set_max_body_size(\n                        int(self.get_argument('expected_size')))\n                if 'body_timeout' in self.request.arguments:\n                    self.request.connection.set_body_timeout(\n                        float(self.get_argument('body_timeout')))\n\n            def data_received(self, data):\n                self.bytes_read += len(data)\n\n            def put(self):\n                self.write(str(self.bytes_read))\n\n        return Application([('/buffered', BufferedHandler),\n                            ('/streaming', StreamingHandler)])\n\n    def get_httpserver_options(self):\n        return dict(body_timeout=3600, max_body_size=4096)\n\n    def get_http_client(self):\n        # body_producer doesn't work on curl_httpclient, so override the\n        # configured AsyncHTTPClient implementation.\n        return SimpleAsyncHTTPClient()\n\n    def test_small_body(self):\n        response = self.fetch('/buffered', method='PUT', body=b'a' * 4096)\n        self.assertEqual(response.body, b'4096')\n        response = self.fetch('/streaming', method='PUT', body=b'a' * 4096)\n        self.assertEqual(response.body, b'4096')\n\n    def test_large_body_buffered(self):\n        with ExpectLog(gen_log, '.*Content-Length too long'):\n            response = self.fetch('/buffered', method='PUT', body=b'a' * 10240)\n        self.assertEqual(response.code, 400)\n\n    def test_large_body_buffered_chunked(self):\n        with ExpectLog(gen_log, '.*chunked body too large'):\n            response = self.fetch('/buffered', method='PUT',\n                                  body_producer=lambda write: write(b'a' * 10240))\n        # this test is flaky on windows; accept 400 (expected) or 599\n        self.assertIn(response.code, [400, 599])\n\n    def test_large_body_streaming(self):\n        with ExpectLog(gen_log, '.*Content-Length too long'):\n            response = self.fetch('/streaming', method='PUT', body=b'a' * 10240)\n        self.assertEqual(response.code, 400)\n\n    def test_large_body_streaming_chunked(self):\n        with ExpectLog(gen_log, '.*chunked body too large'):\n            response = self.fetch('/streaming', method='PUT',\n                                  body_producer=lambda write: write(b'a' * 10240))\n        # this test is flaky on windows; accept 400 (expected) or 599\n        self.assertIn(response.code, [400, 599])\n\n    def test_large_body_streaming_override(self):\n        response = self.fetch('/streaming?expected_size=10240', method='PUT',\n                              body=b'a' * 10240)\n        self.assertEqual(response.body, b'10240')\n\n    def test_large_body_streaming_chunked_override(self):\n        response = self.fetch('/streaming?expected_size=10240', method='PUT',\n                              body_producer=lambda write: write(b'a' * 10240))\n        self.assertEqual(response.body, b'10240')\n\n    @gen_test\n    def test_timeout(self):\n        stream = IOStream(socket.socket())\n        try:\n            yield stream.connect(('127.0.0.1', self.get_http_port()))\n            # Use a raw stream because AsyncHTTPClient won't let us read a\n            # response without finishing a body.\n            stream.write(b'PUT /streaming?body_timeout=0.1 HTTP/1.0\\r\\n'\n                         b'Content-Length: 42\\r\\n\\r\\n')\n            with ExpectLog(gen_log, 'Timeout reading body'):\n                response = yield stream.read_until_close()\n            self.assertEqual(response, b'')\n        finally:\n            stream.close()\n\n    @gen_test\n    def test_body_size_override_reset(self):\n        # The max_body_size override is reset between requests.\n        stream = IOStream(socket.socket())\n        try:\n            yield stream.connect(('127.0.0.1', self.get_http_port()))\n            # Use a raw stream so we can make sure it's all on one connection.\n            stream.write(b'PUT /streaming?expected_size=10240 HTTP/1.1\\r\\n'\n                         b'Content-Length: 10240\\r\\n\\r\\n')\n            stream.write(b'a' * 10240)\n            start_line, headers, response = yield gen.Task(read_stream_body, stream)\n            self.assertEqual(response, b'10240')\n            # Without the ?expected_size parameter, we get the old default value\n            stream.write(b'PUT /streaming HTTP/1.1\\r\\n'\n                         b'Content-Length: 10240\\r\\n\\r\\n')\n            with ExpectLog(gen_log, '.*Content-Length too long'):\n                data = yield stream.read_until_close()\n            self.assertEqual(data, b'HTTP/1.1 400 Bad Request\\r\\n\\r\\n')\n        finally:\n            stream.close()\n\n\nclass LegacyInterfaceTest(AsyncHTTPTestCase):\n    def get_app(self):\n        # The old request_callback interface does not implement the\n        # delegate interface, and writes its response via request.write\n        # instead of request.connection.write_headers.\n        def handle_request(request):\n            self.http1 = request.version.startswith(\"HTTP/1.\")\n            if not self.http1:\n                # This test will be skipped if we're using HTTP/2,\n                # so just close it out cleanly using the modern interface.\n                request.connection.write_headers(\n                    ResponseStartLine('', 200, 'OK'),\n                    HTTPHeaders())\n                request.connection.finish()\n                return\n            message = b\"Hello world\"\n            request.write(utf8(\"HTTP/1.1 200 OK\\r\\n\"\n                               \"Content-Length: %d\\r\\n\\r\\n\" % len(message)))\n            request.write(message)\n            request.finish()\n        return handle_request\n\n    def test_legacy_interface(self):\n        response = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(response.body, b\"Hello world\")\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 770ms\nPrepared 1 package in 915ms\nInstalled 1 package in 0.75ms\n + tornado==5.0.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453)\nResolved 29 packages in 13ms\nInstalled 29 packages in 154ms\n + attrs==24.3.0\n + automat==24.8.1\n + cachetools==5.5.0\n + cffi==1.17.1\n + chardet==5.2.0\n + colorama==0.4.6\n + constantly==23.10.4\n + distlib==0.3.9\n + exceptiongroup==1.2.2\n + filelock==3.16.1\n + hyperlink==21.0.0\n + idna==3.10\n + incremental==24.7.2\n + iniconfig==2.0.0\n + packaging==24.2\n + platformdirs==4.3.6\n + pluggy==1.5.0\n + pycares==4.5.0\n + pycparser==2.22\n + pycurl==7.45.4\n + pyproject-api==1.8.0\n + pytest==8.3.4\n + setuptools==75.6.0\n + tomli==2.2.1\n + tox==4.23.2\n + twisted==24.11.0\n + typing-extensions==4.12.2\n + virtualenv==20.28.0\n + zope-interface==7.2\n",
    "new_commit_res_code": 1,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453\n.........................................................................\ncollected 73 items\n\n=================================== ERRORS =====================================\n__________ BadSSLOptionsTest.test_missing_key __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 188, in test_missing_key\n    HTTPServer(application, ssl_options={\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/util.py\", line 306, in __new__\n    instance.initialize(*args, **init_kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/httpserver.py\", line 167, in initialize\n    TCPServer.__init__(self, ssl_options=ssl_options,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 131, in __init__\n    raise ValueError('certfile \"%s\" does not exist' %\nValueError: certfile \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test.crt\" does not exist\n__________ BodyLimitsTest.test_body_size_override_reset __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 525, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/ioloop.py\", line 513, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/gen.py\", line 1084, in run\n    yielded = self.gen.send(value)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 215, in send\n    return self.__wrapped.send(val)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1123, in test_body_size_override_reset\n    data = yield stream.read_until_close()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_buffered __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1060, in test_large_body_buffered\n    response = self.fetch('/buffered', method='PUT', body=b'a' * 10240)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_buffered_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1065, in test_large_body_buffered_chunked\n    response = self.fetch('/buffered', method='PUT',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_streaming __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1072, in test_large_body_streaming\n    response = self.fetch('/streaming', method='PUT', body=b'a' * 10240)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_streaming_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1077, in test_large_body_streaming_chunked\n    response = self.fetch('/streaming', method='PUT',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 525, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/ioloop.py\", line 513, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/gen.py\", line 1084, in run\n    yielded = self.gen.send(value)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 215, in send\n    return self.__wrapped.send(val)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1102, in test_timeout\n    response = yield stream.read_until_close()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_invalid_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 483, in test_invalid_content_length\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_malformed_first_line_log __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 426, in test_malformed_first_line_log\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_malformed_first_line_response __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 417, in test_malformed_first_line_response\n    self.assertEqual('Bad Request', start_line.reason)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_malformed_headers __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 433, in test_malformed_headers\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ SSLContextTest.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLContextTest.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLContextTest.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLContextTest.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLXHeaderTest.test_request_without_xprotocol __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 579, in test_request_without_xprotocol\n    self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 55, in fetch_json\n    response = self.fetch(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 127, in test_error_logging\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 102, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 118, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 98, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 127, in test_error_logging\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 102, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 118, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 98, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 127, in test_error_logging\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 102, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 118, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 98, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ UnixSocketTest.test_unix_socket_bad_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 650, in test_unix_socket_bad_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BadSSLOptionsTest::test_missing_arguments\nERROR r2e_tests.test_1::BadSSLOptionsTest::test_missing_key\nERROR r2e_tests.test_1::BodyLimitsTest::test_body_size_override_reset\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_buffered\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_buffered_chunked\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming_chunked\nPASSED r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming_chunked_override\nPASSED r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming_override\nPASSED r2e_tests.test_1::BodyLimitsTest::test_small_body\nERROR r2e_tests.test_1::BodyLimitsTest::test_timeout\nPASSED r2e_tests.test_1::GzipTest::test_gzip\nPASSED r2e_tests.test_1::GzipTest::test_uncompressed\nPASSED r2e_tests.test_1::GzipUnsupportedTest::test_gzip_unsupported\nPASSED r2e_tests.test_1::GzipUnsupportedTest::test_uncompressed\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_100_continue\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_multipart_form\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_newlines\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_chunked_request_body\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_chunked_request_uppercase\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_empty_request\nERROR r2e_tests.test_1::HTTPServerRawTest::test_invalid_content_length\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_first_line_log\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_first_line_response\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_headers\nPASSED r2e_tests.test_1::HTTPServerTest::test_double_slash\nPASSED r2e_tests.test_1::HTTPServerTest::test_empty_post_parameters\nPASSED r2e_tests.test_1::HTTPServerTest::test_empty_query_string\nPASSED r2e_tests.test_1::HTTPServerTest::test_malformed_body\nPASSED r2e_tests.test_1::HTTPServerTest::test_query_string_encoding\nPASSED r2e_tests.test_1::HTTPServerTest::test_types\nPASSED r2e_tests.test_1::IdleTimeoutTest::test_idle_after_use\nPASSED r2e_tests.test_1::IdleTimeoutTest::test_unused_connection\nPASSED r2e_tests.test_1::KeepAliveTest::test_cancel_during_download\nPASSED r2e_tests.test_1::KeepAliveTest::test_finish_while_closed\nPASSED r2e_tests.test_1::KeepAliveTest::test_http10\nPASSED r2e_tests.test_1::KeepAliveTest::test_http10_keepalive\nPASSED r2e_tests.test_1::KeepAliveTest::test_http10_keepalive_extra_crlf\nPASSED r2e_tests.test_1::KeepAliveTest::test_keepalive_chunked\nPASSED r2e_tests.test_1::KeepAliveTest::test_pipelined_cancel\nPASSED r2e_tests.test_1::KeepAliveTest::test_pipelined_requests\nPASSED r2e_tests.test_1::KeepAliveTest::test_request_close\nPASSED r2e_tests.test_1::KeepAliveTest::test_two_requests\nPASSED r2e_tests.test_1::LegacyInterfaceTest::test_legacy_interface\nPASSED r2e_tests.test_1::ManualProtocolTest::test_manual_protocol\nPASSED r2e_tests.test_1::MaxHeaderSizeTest::test_large_headers\nPASSED r2e_tests.test_1::MaxHeaderSizeTest::test_small_headers\nERROR r2e_tests.test_1::SSLContextTest::test_error_logging\nERROR r2e_tests.test_1::SSLContextTest::test_large_post\nERROR r2e_tests.test_1::SSLContextTest::test_non_ssl_request\nERROR r2e_tests.test_1::SSLContextTest::test_ssl\nERROR r2e_tests.test_1::SSLXHeaderTest::test_request_without_xprotocol\nERROR r2e_tests.test_1::SSLv23Test::test_error_logging\nERROR r2e_tests.test_1::SSLv23Test::test_large_post\nERROR r2e_tests.test_1::SSLv23Test::test_non_ssl_request\nERROR r2e_tests.test_1::SSLv23Test::test_ssl\nERROR r2e_tests.test_1::SSLv3Test::test_error_logging\nERROR r2e_tests.test_1::SSLv3Test::test_large_post\nERROR r2e_tests.test_1::SSLv3Test::test_non_ssl_request\nERROR r2e_tests.test_1::SSLv3Test::test_ssl\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_chunked_body\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_chunked_compressed\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_compressed_body\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_regular_body\nERROR r2e_tests.test_1::TLSv1Test::test_error_logging\nERROR r2e_tests.test_1::TLSv1Test::test_large_post\nERROR r2e_tests.test_1::TLSv1Test::test_non_ssl_request\nERROR r2e_tests.test_1::TLSv1Test::test_ssl\nPASSED r2e_tests.test_1::UnixSocketTest::test_unix_socket\nERROR r2e_tests.test_1::UnixSocketTest::test_unix_socket_bad_request\nPASSED r2e_tests.test_1::XHeaderTest::test_ip_headers\nPASSED r2e_tests.test_1::XHeaderTest::test_scheme_headers\nPASSED r2e_tests.test_1::XHeaderTest::test_trusted_downstream\n=================== 29 errors, 44 passed in 0.72s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453\n.........................................................................\ncollected 73 items\n\n=================================== FAILURES ===================================\n__________ XHeaderTest.test_scheme_headers __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 559, in test_scheme_headers\n    self.assertEqual(\nAssertionError: 'http' != 'https'\n- http\n+ https\n?     +\n\n\n=================================== ERRORS =====================================\n__________ BadSSLOptionsTest.test_missing_key __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 188, in test_missing_key\n    HTTPServer(application, ssl_options={\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/util.py\", line 306, in __new__\n    instance.initialize(*args, **init_kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/httpserver.py\", line 167, in initialize\n    TCPServer.__init__(self, ssl_options=ssl_options,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 131, in __init__\n    raise ValueError('certfile \"%s\" does not exist' %\nValueError: certfile \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test.crt\" does not exist\n__________ BodyLimitsTest.test_body_size_override_reset __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 525, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/ioloop.py\", line 513, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/gen.py\", line 1084, in run\n    yielded = self.gen.send(value)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 215, in send\n    return self.__wrapped.send(val)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1123, in test_body_size_override_reset\n    data = yield stream.read_until_close()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_buffered __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1060, in test_large_body_buffered\n    response = self.fetch('/buffered', method='PUT', body=b'a' * 10240)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_buffered_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1065, in test_large_body_buffered_chunked\n    response = self.fetch('/buffered', method='PUT',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_streaming __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1072, in test_large_body_streaming\n    response = self.fetch('/streaming', method='PUT', body=b'a' * 10240)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_large_body_streaming_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1077, in test_large_body_streaming_chunked\n    response = self.fetch('/streaming', method='PUT',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ BodyLimitsTest.test_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 525, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/ioloop.py\", line 513, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/gen.py\", line 1084, in run\n    yielded = self.gen.send(value)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 215, in send\n    return self.__wrapped.send(val)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 1102, in test_timeout\n    response = yield stream.read_until_close()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_invalid_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 483, in test_invalid_content_length\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_malformed_first_line_log __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 426, in test_malformed_first_line_log\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_malformed_first_line_response __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 417, in test_malformed_first_line_response\n    self.assertEqual('Bad Request', start_line.reason)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ HTTPServerRawTest.test_malformed_headers __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 433, in test_malformed_headers\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ SSLContextTest.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLContextTest.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLContextTest.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLContextTest.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 588, in run\n    self._callSetUp()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 547, in _callSetUp\n    self.setUp()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 371, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 378, in get_http_server\n    return HTTPServer(self._app, **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 442, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 156, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLXHeaderTest.test_request_without_xprotocol __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 579, in test_request_without_xprotocol\n    self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 55, in fetch_json\n    response = self.fetch(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 127, in test_error_logging\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 102, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 118, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv23Test.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 98, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 127, in test_error_logging\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 102, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 118, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ SSLv3Test.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 98, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 127, in test_error_logging\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_large_post __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 102, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_non_ssl_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 118, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TLSv1Test.test_ssl __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 98, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 401, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 326, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 262, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 4, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/stack_context.py\", line 316, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 252, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/tcpserver.py\", line 263, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 502, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/netutil.py\", line 477, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ UnixSocketTest.test_unix_socket_bad_request __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 124, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/r2e_tests/test_1.py\", line 650, in test_unix_socket_bad_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_5fcfb4277514ff82e2d3b17a24a26ed505b8d453/tornado/testing.py\", line 606, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BadSSLOptionsTest::test_missing_arguments\nERROR r2e_tests.test_1::BadSSLOptionsTest::test_missing_key\nERROR r2e_tests.test_1::BodyLimitsTest::test_body_size_override_reset\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_buffered\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_buffered_chunked\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming\nERROR r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming_chunked\nPASSED r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming_chunked_override\nPASSED r2e_tests.test_1::BodyLimitsTest::test_large_body_streaming_override\nPASSED r2e_tests.test_1::BodyLimitsTest::test_small_body\nERROR r2e_tests.test_1::BodyLimitsTest::test_timeout\nPASSED r2e_tests.test_1::GzipTest::test_gzip\nPASSED r2e_tests.test_1::GzipTest::test_uncompressed\nPASSED r2e_tests.test_1::GzipUnsupportedTest::test_gzip_unsupported\nPASSED r2e_tests.test_1::GzipUnsupportedTest::test_uncompressed\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_100_continue\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_multipart_form\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_newlines\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_chunked_request_body\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_chunked_request_uppercase\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_empty_request\nERROR r2e_tests.test_1::HTTPServerRawTest::test_invalid_content_length\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_first_line_log\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_first_line_response\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_headers\nPASSED r2e_tests.test_1::HTTPServerTest::test_double_slash\nPASSED r2e_tests.test_1::HTTPServerTest::test_empty_post_parameters\nPASSED r2e_tests.test_1::HTTPServerTest::test_empty_query_string\nPASSED r2e_tests.test_1::HTTPServerTest::test_malformed_body\nPASSED r2e_tests.test_1::HTTPServerTest::test_query_string_encoding\nPASSED r2e_tests.test_1::HTTPServerTest::test_types\nPASSED r2e_tests.test_1::IdleTimeoutTest::test_idle_after_use\nPASSED r2e_tests.test_1::IdleTimeoutTest::test_unused_connection\nPASSED r2e_tests.test_1::KeepAliveTest::test_cancel_during_download\nPASSED r2e_tests.test_1::KeepAliveTest::test_finish_while_closed\nPASSED r2e_tests.test_1::KeepAliveTest::test_http10\nPASSED r2e_tests.test_1::KeepAliveTest::test_http10_keepalive\nPASSED r2e_tests.test_1::KeepAliveTest::test_http10_keepalive_extra_crlf\nPASSED r2e_tests.test_1::KeepAliveTest::test_keepalive_chunked\nPASSED r2e_tests.test_1::KeepAliveTest::test_pipelined_cancel\nPASSED r2e_tests.test_1::KeepAliveTest::test_pipelined_requests\nPASSED r2e_tests.test_1::KeepAliveTest::test_request_close\nPASSED r2e_tests.test_1::KeepAliveTest::test_two_requests\nPASSED r2e_tests.test_1::LegacyInterfaceTest::test_legacy_interface\nPASSED r2e_tests.test_1::ManualProtocolTest::test_manual_protocol\nPASSED r2e_tests.test_1::MaxHeaderSizeTest::test_large_headers\nPASSED r2e_tests.test_1::MaxHeaderSizeTest::test_small_headers\nERROR r2e_tests.test_1::SSLContextTest::test_error_logging\nERROR r2e_tests.test_1::SSLContextTest::test_large_post\nERROR r2e_tests.test_1::SSLContextTest::test_non_ssl_request\nERROR r2e_tests.test_1::SSLContextTest::test_ssl\nERROR r2e_tests.test_1::SSLXHeaderTest::test_request_without_xprotocol\nERROR r2e_tests.test_1::SSLv23Test::test_error_logging\nERROR r2e_tests.test_1::SSLv23Test::test_large_post\nERROR r2e_tests.test_1::SSLv23Test::test_non_ssl_request\nERROR r2e_tests.test_1::SSLv23Test::test_ssl\nERROR r2e_tests.test_1::SSLv3Test::test_error_logging\nERROR r2e_tests.test_1::SSLv3Test::test_large_post\nERROR r2e_tests.test_1::SSLv3Test::test_non_ssl_request\nERROR r2e_tests.test_1::SSLv3Test::test_ssl\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_chunked_body\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_chunked_compressed\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_compressed_body\nPASSED r2e_tests.test_1::StreamingChunkSizeTest::test_regular_body\nERROR r2e_tests.test_1::TLSv1Test::test_error_logging\nERROR r2e_tests.test_1::TLSv1Test::test_large_post\nERROR r2e_tests.test_1::TLSv1Test::test_non_ssl_request\nERROR r2e_tests.test_1::TLSv1Test::test_ssl\nPASSED r2e_tests.test_1::UnixSocketTest::test_unix_socket\nERROR r2e_tests.test_1::UnixSocketTest::test_unix_socket_bad_request\nPASSED r2e_tests.test_1::XHeaderTest::test_ip_headers\nFAILED r2e_tests.test_1::XHeaderTest::test_scheme_headers\nPASSED r2e_tests.test_1::XHeaderTest::test_trusted_downstream\n=================== 1 failed, 29 errors, 43 passed in 0.70s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/httpserver.py tornado/test/httpserver_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
**[ISSUE]**

**Title:** Incorrect Protocol Detection with Multiple X-Forwarded-Proto Values

**Description:**
When a request includes multiple values in the `X-Forwarded-Proto` header, the server fails to correctly determine the intended protocol. Specifically, the server does not properly parse and prioritize the protocol values, leading to incorrect protocol settings.

**Example Buggy Code:**
```python
headers = {"X-Forwarded-Proto": "https, http"}
response = make_request("/", headers=headers)
print(response["remote_protocol"])  # Expected to be "http"
```
In this example, the `X-Forwarded-Proto` header contains both "https" and "http". The expected behavior is for the server to use the last value ("http") to set the protocol. However, the server fails to do so correctly.

**Expected Behavior:**
When multiple values are present in the `X-Forwarded-Proto` header, the server should parse the header and use the last protocol specified (e.g., "http") to set the `remote_protocol`. This ensures that the server accurately reflects the intended protocol of the client request.

**Actual Behavior:**
The server does not correctly parse multiple values in the `X-Forwarded-Proto` header, resulting in incorrect protocol detection. Instead of using the last specified protocol ("http"), the server may retain the first value ("https") or fail to set the protocol appropriately, leading to potential mismatches and errors in handling the request.

**[/ISSUE]**
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/httpserver.py
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""A non-blocking, single-threaded HTTP server.

Typical applications have little direct interaction with the `HTTPServer`
class except to start a server at the beginning of the process
(and even that is often done indirectly via `tornado.web.Application.listen`).

.. versionchanged:: 4.0

   The ``HTTPRequest`` class that used to live in this module has been moved
   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.
"""

from __future__ import absolute_import, division, print_function

import socket

from tornado.escape import native_str
from tornado.http1connection import HTTP1ServerConnection, HTTP1ConnectionParameters
from tornado import gen
from tornado import httputil
from tornado import iostream
from tornado import netutil
from tornado.tcpserver import TCPServer
from tornado.util import Configurable


class HTTPServer(TCPServer, Configurable,
                 httputil.HTTPServerConnectionDelegate):
    r"""A non-blocking, single-threaded HTTP server.

    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,
    or, for backwards compatibility, a callback that takes an
    `.HTTPServerRequest` as an argument. The delegate is usually a
    `tornado.web.Application`.

    `HTTPServer` supports keep-alive connections by default
    (automatically for HTTP/1.1, or for HTTP/1.0 when the client
    requests ``Connection: keep-alive``).

    If ``xheaders`` is ``True``, we support the
    ``X-Real-Ip``/``X-Forwarded-For`` and
    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the
    remote IP and URI scheme/protocol for all requests.  These headers
    are useful when running Tornado behind a reverse proxy or load
    balancer.  The ``protocol`` argument can also be set to ``https``
    if Tornado is run behind an SSL-decoding proxy that does not set one of
    the supported ``xheaders``.

    By default, when parsing the ``X-Forwarded-For`` header, Tornado will
    select the last (i.e., the closest) address on the list of hosts as the
    remote host IP address.  To select the next server in the chain, a list of
    trusted downstream hosts may be passed as the ``trusted_downstream``
    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``
    header.

    To make this server serve SSL traffic, send the ``ssl_options`` keyword
    argument with an `ssl.SSLContext` object. For compatibility with older
    versions of Python ``ssl_options`` may also be a dictionary of keyword
    arguments for the `ssl.wrap_socket` method.::

       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
       ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                               os.path.join(data_dir, "mydomain.key"))
       HTTPServer(application, ssl_options=ssl_ctx)

    `HTTPServer` initialization follows one of three patterns (the
    initialization methods are defined on `tornado.tcpserver.TCPServer`):

    1. `~tornado.tcpserver.TCPServer.listen`: simple single-process::

            server = HTTPServer(app)
            server.listen(8888)
            IOLoop.current().start()

       In many cases, `tornado.web.Application.listen` can be used to avoid
       the need to explicitly create the `HTTPServer`.

    2. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:
       simple multi-process::

            server = HTTPServer(app)
            server.bind(8888)
            server.start(0)  # Forks multiple sub-processes
            IOLoop.current().start()

       When using this interface, an `.IOLoop` must *not* be passed
       to the `HTTPServer` constructor.  `~.TCPServer.start` will always start
       the server on the default singleton `.IOLoop`.

    3. `~tornado.tcpserver.TCPServer.add_sockets`: advanced multi-process::

            sockets = tornado.netutil.bind_sockets(8888)
            tornado.process.fork_processes(0)
            server = HTTPServer(app)
            server.add_sockets(sockets)
            IOLoop.current().start()

       The `~.TCPServer.add_sockets` interface is more complicated,
       but it can be used with `tornado.process.fork_processes` to
       give you more flexibility in when the fork happens.
       `~.TCPServer.add_sockets` can also be used in single-process
       servers if you want to create your listening sockets in some
       way other than `tornado.netutil.bind_sockets`.

    .. versionchanged:: 4.0
       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,
       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``
       arguments.  Added support for `.HTTPServerConnectionDelegate`
       instances as ``request_callback``.

    .. versionchanged:: 4.1
       `.HTTPServerConnectionDelegate.start_request` is now called with
       two arguments ``(server_conn, request_conn)`` (in accordance with the
       documentation) instead of one ``(request_conn)``.

    .. versionchanged:: 4.2
       `HTTPServer` is now a subclass of `tornado.util.Configurable`.

    .. versionchanged:: 4.5
       Added the ``trusted_downstream`` argument.

    .. versionchanged:: 5.0
       The ``io_loop`` argument has been removed.
    """
    def __init__(self, *args, **kwargs):
        # Ignore args to __init__; real initialization belongs in
        # initialize since we're Configurable. (there's something
        # weird in initialization order between this class,
        # Configurable, and TCPServer so we can't leave __init__ out
        # completely)
        pass

    def initialize(self, request_callback, no_keep_alive=False,
                   xheaders=False, ssl_options=None, protocol=None,
                   decompress_request=False,
                   chunk_size=None, max_header_size=None,
                   idle_connection_timeout=None, body_timeout=None,
                   max_body_size=None, max_buffer_size=None,
                   trusted_downstream=None):
        self.request_callback = request_callback
        self.xheaders = xheaders
        self.protocol = protocol
        self.conn_params = HTTP1ConnectionParameters(
            decompress=decompress_request,
            chunk_size=chunk_size,
            max_header_size=max_header_size,
            header_timeout=idle_connection_timeout or 3600,
            max_body_size=max_body_size,
            body_timeout=body_timeout,
            no_keep_alive=no_keep_alive)
        TCPServer.__init__(self, ssl_options=ssl_options,
                           max_buffer_size=max_buffer_size,
                           read_chunk_size=chunk_size)
        self._connections = set()
        self.trusted_downstream = trusted_downstream

    @classmethod
    def configurable_base(cls):
        return HTTPServer

    @classmethod
    def configurable_default(cls):
        return HTTPServer

    @gen.coroutine
    def close_all_connections(self):
        while self._connections:
            # Peek at an arbitrary element of the set
            conn = next(iter(self._connections))
            yield conn.close()

    def handle_stream(self, stream, address):
        context = _HTTPRequestContext(stream, address,
                                      self.protocol,
                                      self.trusted_downstream)
        conn = HTTP1ServerConnection(
            stream, self.conn_params, context)
        self._connections.add(conn)
        conn.start_serving(self)

    def start_request(self, server_conn, request_conn):
        if isinstance(self.request_callback, httputil.HTTPServerConnectionDelegate):
            delegate = self.request_callback.start_request(server_conn, request_conn)
        else:
            delegate = _CallableAdapter(self.request_callback, request_conn)

        if self.xheaders:
            delegate = _ProxyAdapter(delegate, request_conn)

        return delegate

    def on_close(self, server_conn):
        self._connections.remove(server_conn)


class _CallableAdapter(httputil.HTTPMessageDelegate):
    def __init__(self, request_callback, request_conn):
        self.connection = request_conn
        self.request_callback = request_callback
        self.request = None
        self.delegate = None
        self._chunks = []

    def headers_received(self, start_line, headers):
        self.request = httputil.HTTPServerRequest(
            connection=self.connection, start_line=start_line,
            headers=headers)

    def data_received(self, chunk):
        self._chunks.append(chunk)

    def finish(self):
        self.request.body = b''.join(self._chunks)
        self.request._parse_body()
        self.request_callback(self.request)

    def on_connection_close(self):
        self._chunks = None


class _HTTPRequestContext(object):
    def __init__(self, stream, address, protocol, trusted_downstream=None):
        self.address = address
        # Save the socket's address family now so we know how to
        # interpret self.address even after the stream is closed
        # and its socket attribute replaced with None.
        if stream.socket is not None:
            self.address_family = stream.socket.family
        else:
            self.address_family = None
        # In HTTPServerRequest we want an IP, not a full socket address.
        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and
                address is not None):
            self.remote_ip = address[0]
        else:
            # Unix (or other) socket; fake the remote address.
            self.remote_ip = '0.0.0.0'
        if protocol:
            self.protocol = protocol
        elif isinstance(stream, iostream.SSLIOStream):
            self.protocol = "https"
        else:
            self.protocol = "http"
        self._orig_remote_ip = self.remote_ip
        self._orig_protocol = self.protocol
        self.trusted_downstream = set(trusted_downstream or [])

    def __str__(self):
        if self.address_family in (socket.AF_INET, socket.AF_INET6):
            return self.remote_ip
        elif isinstance(self.address, bytes):
            # Python 3 with the -bb option warns about str(bytes),
            # so convert it explicitly.
            # Unix socket addresses are str on mac but bytes on linux.
            return native_str(self.address)
        else:
            return str(self.address)

    def _apply_xheaders(self, headers):
        """Rewrite the ``remote_ip`` and ``protocol`` fields."""
        # Squid uses X-Forwarded-For, others use X-Real-Ip
        ip = headers.get("X-Forwarded-For", self.remote_ip)
        # Skip trusted downstream hosts in X-Forwarded-For list
        for ip in (cand.strip() for cand in reversed(ip.split(','))):
            if ip not in self.trusted_downstream:
                break
        ip = headers.get("X-Real-Ip", ip)
        if netutil.is_valid_ip(ip):
            self.remote_ip = ip
        # AWS uses X-Forwarded-Proto
        proto_header = headers.get(
            "X-Scheme", headers.get("X-Forwarded-Proto",
                                    self.protocol))
        if proto_header in ("http", "https"):
            self.protocol = proto_header

    def _unapply_xheaders(self):
        """Undo changes from `_apply_xheaders`.

        Xheaders are per-request so they should not leak to the next
        request on the same connection.
        """
        self.remote_ip = self._orig_remote_ip
        self.protocol = self._orig_protocol


class _ProxyAdapter(httputil.HTTPMessageDelegate):
    def __init__(self, delegate, request_conn):
        self.connection = request_conn
        self.delegate = delegate

    def headers_received(self, start_line, headers):
        self.connection.context._apply_xheaders(headers)
        return self.delegate.headers_received(start_line, headers)

    def data_received(self, chunk):
        return self.delegate.data_received(chunk)

    def finish(self):
        self.delegate.finish()
        self._cleanup()

    def on_connection_close(self):
        self.delegate.on_connection_close()
        self._cleanup()

    def _cleanup(self):
        self.connection.context._unapply_xheaders()


HTTPRequest = httputil.HTTPServerRequest

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
**[ISSUE]**

**Title:** Incorrect Protocol Detection with Multiple X-Forwarded-Proto Values

**Description:**
When a request includes multiple values in the `X-Forwarded-Proto` header, the server fails to correctly determine the intended protocol. Specifically, the server does not properly parse and prioritize the protocol values, leading to incorrect protocol settings.

**Example Buggy Code:**
```python
headers = {"X-Forwarded-Proto": "https, http"}
response = make_request("/", headers=headers)
print(response["remote_protocol"])  # Expected to be "http"
```
In this example, the `X-Forwarded-Proto` header contains both "https" and "http". The expected behavior is for the server to use the last value ("http") to set the protocol. However, the server fails to do so correctly.

**Expected Behavior:**
When multiple values are present in the `X-Forwarded-Proto` header, the server should parse the header and use the last protocol specified (e.g., "http") to set the `remote_protocol`. This ensures that the server accurately reflects the intended protocol of the client request.

**Actual Behavior:**
The server does not correctly parse multiple values in the `X-Forwarded-Proto` header, resulting in incorrect protocol detection. Instead of using the last specified protocol ("http"), the server may retain the first value ("https") or fail to set the protocol appropriately, leading to potential mismatches and errors in handling the request.

**[/ISSUE]**
{
    "BadSSLOptionsTest.test_missing_arguments": "PASSED",
    "BadSSLOptionsTest.test_missing_key": "ERROR",
    "BodyLimitsTest.test_body_size_override_reset": "ERROR",
    "BodyLimitsTest.test_large_body_buffered": "ERROR",
    "BodyLimitsTest.test_large_body_buffered_chunked": "ERROR",
    "BodyLimitsTest.test_large_body_streaming": "ERROR",
    "BodyLimitsTest.test_large_body_streaming_chunked": "ERROR",
    "BodyLimitsTest.test_large_body_streaming_chunked_override": "PASSED",
    "BodyLimitsTest.test_large_body_streaming_override": "PASSED",
    "BodyLimitsTest.test_small_body": "PASSED",
    "BodyLimitsTest.test_timeout": "ERROR",
    "GzipTest.test_gzip": "PASSED",
    "GzipTest.test_uncompressed": "PASSED",
    "GzipUnsupportedTest.test_gzip_unsupported": "PASSED",
    "GzipUnsupportedTest.test_uncompressed": "PASSED",
    "HTTPConnectionTest.test_100_continue": "PASSED",
    "HTTPConnectionTest.test_multipart_form": "PASSED",
    "HTTPConnectionTest.test_newlines": "PASSED",
    "HTTPServerRawTest.test_chunked_request_body": "PASSED",
    "HTTPServerRawTest.test_chunked_request_uppercase": "PASSED",
    "HTTPServerRawTest.test_empty_request": "PASSED",
    "HTTPServerRawTest.test_invalid_content_length": "ERROR",
    "HTTPServerRawTest.test_malformed_first_line_log": "ERROR",
    "HTTPServerRawTest.test_malformed_first_line_response": "ERROR",
    "HTTPServerRawTest.test_malformed_headers": "ERROR",
    "HTTPServerTest.test_double_slash": "PASSED",
    "HTTPServerTest.test_empty_post_parameters": "PASSED",
    "HTTPServerTest.test_empty_query_string": "PASSED",
    "HTTPServerTest.test_malformed_body": "PASSED",
    "HTTPServerTest.test_query_string_encoding": "PASSED",
    "HTTPServerTest.test_types": "PASSED",
    "IdleTimeoutTest.test_idle_after_use": "PASSED",
    "IdleTimeoutTest.test_unused_connection": "PASSED",
    "KeepAliveTest.test_cancel_during_download": "PASSED",
    "KeepAliveTest.test_finish_while_closed": "PASSED",
    "KeepAliveTest.test_http10": "PASSED",
    "KeepAliveTest.test_http10_keepalive": "PASSED",
    "KeepAliveTest.test_http10_keepalive_extra_crlf": "PASSED",
    "KeepAliveTest.test_keepalive_chunked": "PASSED",
    "KeepAliveTest.test_pipelined_cancel": "PASSED",
    "KeepAliveTest.test_pipelined_requests": "PASSED",
    "KeepAliveTest.test_request_close": "PASSED",
    "KeepAliveTest.test_two_requests": "PASSED",
    "LegacyInterfaceTest.test_legacy_interface": "PASSED",
    "ManualProtocolTest.test_manual_protocol": "PASSED",
    "MaxHeaderSizeTest.test_large_headers": "PASSED",
    "MaxHeaderSizeTest.test_small_headers": "PASSED",
    "SSLContextTest.test_error_logging": "ERROR",
    "SSLContextTest.test_large_post": "ERROR",
    "SSLContextTest.test_non_ssl_request": "ERROR",
    "SSLContextTest.test_ssl": "ERROR",
    "SSLXHeaderTest.test_request_without_xprotocol": "ERROR",
    "SSLv23Test.test_error_logging": "ERROR",
    "SSLv23Test.test_large_post": "ERROR",
    "SSLv23Test.test_non_ssl_request": "ERROR",
    "SSLv23Test.test_ssl": "ERROR",
    "SSLv3Test.test_error_logging": "ERROR",
    "SSLv3Test.test_large_post": "ERROR",
    "SSLv3Test.test_non_ssl_request": "ERROR",
    "SSLv3Test.test_ssl": "ERROR",
    "StreamingChunkSizeTest.test_chunked_body": "PASSED",
    "StreamingChunkSizeTest.test_chunked_compressed": "PASSED",
    "StreamingChunkSizeTest.test_compressed_body": "PASSED",
    "StreamingChunkSizeTest.test_regular_body": "PASSED",
    "TLSv1Test.test_error_logging": "ERROR",
    "TLSv1Test.test_large_post": "ERROR",
    "TLSv1Test.test_non_ssl_request": "ERROR",
    "TLSv1Test.test_ssl": "ERROR",
    "UnixSocketTest.test_unix_socket": "PASSED",
    "UnixSocketTest.test_unix_socket_bad_request": "ERROR",
    "XHeaderTest.test_ip_headers": "PASSED",
    "XHeaderTest.test_scheme_headers": "PASSED",
    "XHeaderTest.test_trusted_downstream": "PASSED"
}
diff --git a/tornado/httpserver.py b/tornado/httpserver.py
index 8921a051..da755f84 100644
--- a/tornado/httpserver.py
+++ b/tornado/httpserver.py
@@ -287,6 +287,10 @@ class _HTTPRequestContext(object):
         proto_header = headers.get(
             "X-Scheme", headers.get("X-Forwarded-Proto",
                                     self.protocol))
+        if proto_header:
+            # use only the last proto entry if there is more than one
+            # TODO: support trusting mutiple layers of proxied protocol
+            proto_header = proto_header.split(',')[-1].strip()
         if proto_header in ("http", "https"):
             self.protocol = proto_header
 

{"tornado/httpserver.py": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"A non-blocking, single-threaded HTTP server.\n\nTypical applications have little direct interaction with the `HTTPServer`\nclass except to start a server at the beginning of the process\n(and even that is often done indirectly via `tornado.web.Application.listen`).\n\n.. versionchanged:: 4.0\n\n   The ``HTTPRequest`` class that used to live in this module has been moved\n   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function\n\nimport socket\n\nfrom tornado.escape import native_str\nfrom tornado.http1connection import HTTP1ServerConnection, HTTP1ConnectionParameters\nfrom tornado import gen\nfrom tornado import httputil\nfrom tornado import iostream\nfrom tornado import netutil\nfrom tornado.tcpserver import TCPServer\nfrom tornado.util import Configurable\n\n\nclass HTTPServer(TCPServer, Configurable,\n                 httputil.HTTPServerConnectionDelegate):\n    r\"\"\"A non-blocking, single-threaded HTTP server.\n\n    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,\n    or, for backwards compatibility, a callback that takes an\n    `.HTTPServerRequest` as an argument. The delegate is usually a\n    `tornado.web.Application`.\n\n    `HTTPServer` supports keep-alive connections by default\n    (automatically for HTTP/1.1, or for HTTP/1.0 when the client\n    requests ``Connection: keep-alive``).\n\n    If ``xheaders`` is ``True``, we support the\n    ``X-Real-Ip``/``X-Forwarded-For`` and\n    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the\n    remote IP and URI scheme/protocol for all requests.  These headers\n    are useful when running Tornado behind a reverse proxy or load\n    balancer.  The ``protocol`` argument can also be set to ``https``\n    if Tornado is run behind an SSL-decoding proxy that does not set one of\n    the supported ``xheaders``.\n\n    By default, when parsing the ``X-Forwarded-For`` header, Tornado will\n    select the last (i.e., the closest) address on the list of hosts as the\n    remote host IP address.  To select the next server in the chain, a list of\n    trusted downstream hosts may be passed as the ``trusted_downstream``\n    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``\n    header.\n\n    To make this server serve SSL traffic, send the ``ssl_options`` keyword\n    argument with an `ssl.SSLContext` object. For compatibility with older\n    versions of Python ``ssl_options`` may also be a dictionary of keyword\n    arguments for the `ssl.wrap_socket` method.::\n\n       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)\n       ssl_ctx.load_cert_chain(os.path.join(data_dir, \"mydomain.crt\"),\n                               os.path.join(data_dir, \"mydomain.key\"))\n       HTTPServer(application, ssl_options=ssl_ctx)\n\n    `HTTPServer` initialization follows one of three patterns (the\n    initialization methods are defined on `tornado.tcpserver.TCPServer`):\n\n    1. `~tornado.tcpserver.TCPServer.listen`: simple single-process::\n\n            server = HTTPServer(app)\n            server.listen(8888)\n            IOLoop.current().start()\n\n       In many cases, `tornado.web.Application.listen` can be used to avoid\n       the need to explicitly create the `HTTPServer`.\n\n    2. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:\n       simple multi-process::\n\n            server = HTTPServer(app)\n            server.bind(8888)\n            server.start(0)  # Forks multiple sub-processes\n            IOLoop.current().start()\n\n       When using this interface, an `.IOLoop` must *not* be passed\n       to the `HTTPServer` constructor.  `~.TCPServer.start` will always start\n       the server on the default singleton `.IOLoop`.\n\n    3. `~tornado.tcpserver.TCPServer.add_sockets`: advanced multi-process::\n\n            sockets = tornado.netutil.bind_sockets(8888)\n            tornado.process.fork_processes(0)\n            server = HTTPServer(app)\n            server.add_sockets(sockets)\n            IOLoop.current().start()\n\n       The `~.TCPServer.add_sockets` interface is more complicated,\n       but it can be used with `tornado.process.fork_processes` to\n       give you more flexibility in when the fork happens.\n       `~.TCPServer.add_sockets` can also be used in single-process\n       servers if you want to create your listening sockets in some\n       way other than `tornado.netutil.bind_sockets`.\n\n    .. versionchanged:: 4.0\n       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,\n       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``\n       arguments.  Added support for `.HTTPServerConnectionDelegate`\n       instances as ``request_callback``.\n\n    .. versionchanged:: 4.1\n       `.HTTPServerConnectionDelegate.start_request` is now called with\n       two arguments ``(server_conn, request_conn)`` (in accordance with the\n       documentation) instead of one ``(request_conn)``.\n\n    .. versionchanged:: 4.2\n       `HTTPServer` is now a subclass of `tornado.util.Configurable`.\n\n    .. versionchanged:: 4.5\n       Added the ``trusted_downstream`` argument.\n\n    .. versionchanged:: 5.0\n       The ``io_loop`` argument has been removed.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        # Ignore args to __init__; real initialization belongs in\n        # initialize since we're Configurable. (there's something\n        # weird in initialization order between this class,\n        # Configurable, and TCPServer so we can't leave __init__ out\n        # completely)\n        pass\n\n    def initialize(self, request_callback, no_keep_alive=False,\n                   xheaders=False, ssl_options=None, protocol=None,\n                   decompress_request=False,\n                   chunk_size=None, max_header_size=None,\n                   idle_connection_timeout=None, body_timeout=None,\n                   max_body_size=None, max_buffer_size=None,\n                   trusted_downstream=None):\n        self.request_callback = request_callback\n        self.xheaders = xheaders\n        self.protocol = protocol\n        self.conn_params = HTTP1ConnectionParameters(\n            decompress=decompress_request,\n            chunk_size=chunk_size,\n            max_header_size=max_header_size,\n            header_timeout=idle_connection_timeout or 3600,\n            max_body_size=max_body_size,\n            body_timeout=body_timeout,\n            no_keep_alive=no_keep_alive)\n        TCPServer.__init__(self, ssl_options=ssl_options,\n                           max_buffer_size=max_buffer_size,\n                           read_chunk_size=chunk_size)\n        self._connections = set()\n        self.trusted_downstream = trusted_downstream\n\n    @classmethod\n    def configurable_base(cls):\n        return HTTPServer\n\n    @classmethod\n    def configurable_default(cls):\n        return HTTPServer\n\n    @gen.coroutine\n    def close_all_connections(self):\n        while self._connections:\n            # Peek at an arbitrary element of the set\n            conn = next(iter(self._connections))\n            yield conn.close()\n\n    def handle_stream(self, stream, address):\n        context = _HTTPRequestContext(stream, address,\n                                      self.protocol,\n                                      self.trusted_downstream)\n        conn = HTTP1ServerConnection(\n            stream, self.conn_params, context)\n        self._connections.add(conn)\n        conn.start_serving(self)\n\n    def start_request(self, server_conn, request_conn):\n        if isinstance(self.request_callback, httputil.HTTPServerConnectionDelegate):\n            delegate = self.request_callback.start_request(server_conn, request_conn)\n        else:\n            delegate = _CallableAdapter(self.request_callback, request_conn)\n\n        if self.xheaders:\n            delegate = _ProxyAdapter(delegate, request_conn)\n\n        return delegate\n\n    def on_close(self, server_conn):\n        self._connections.remove(server_conn)\n\n\nclass _CallableAdapter(httputil.HTTPMessageDelegate):\n    def __init__(self, request_callback, request_conn):\n        self.connection = request_conn\n        self.request_callback = request_callback\n        self.request = None\n        self.delegate = None\n        self._chunks = []\n\n    def headers_received(self, start_line, headers):\n        self.request = httputil.HTTPServerRequest(\n            connection=self.connection, start_line=start_line,\n            headers=headers)\n\n    def data_received(self, chunk):\n        self._chunks.append(chunk)\n\n    def finish(self):\n        self.request.body = b''.join(self._chunks)\n        self.request._parse_body()\n        self.request_callback(self.request)\n\n    def on_connection_close(self):\n        self._chunks = None\n\n\nclass _HTTPRequestContext(object):\n    def __init__(self, stream, address, protocol, trusted_downstream=None):\n        self.address = address\n        # Save the socket's address family now so we know how to\n        # interpret self.address even after the stream is closed\n        # and its socket attribute replaced with None.\n        if stream.socket is not None:\n            self.address_family = stream.socket.family\n        else:\n            self.address_family = None\n        # In HTTPServerRequest we want an IP, not a full socket address.\n        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and\n                address is not None):\n            self.remote_ip = address[0]\n        else:\n            # Unix (or other) socket; fake the remote address.\n            self.remote_ip = '0.0.0.0'\n        if protocol:\n            self.protocol = protocol\n        elif isinstance(stream, iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n        self._orig_remote_ip = self.remote_ip\n        self._orig_protocol = self.protocol\n        self.trusted_downstream = set(trusted_downstream or [])\n\n    def __str__(self):\n        if self.address_family in (socket.AF_INET, socket.AF_INET6):\n            return self.remote_ip\n        elif isinstance(self.address, bytes):\n            # Python 3 with the -bb option warns about str(bytes),\n            # so convert it explicitly.\n            # Unix socket addresses are str on mac but bytes on linux.\n            return native_str(self.address)\n        else:\n            return str(self.address)\n\n    def _apply_xheaders(self, headers):\n        \"\"\"Rewrite the ``remote_ip`` and ``protocol`` fields.\"\"\"\n        # Squid uses X-Forwarded-For, others use X-Real-Ip\n        ip = headers.get(\"X-Forwarded-For\", self.remote_ip)\n        # Skip trusted downstream hosts in X-Forwarded-For list\n        for ip in (cand.strip() for cand in reversed(ip.split(','))):\n            if ip not in self.trusted_downstream:\n                break\n        ip = headers.get(\"X-Real-Ip\", ip)\n        if netutil.is_valid_ip(ip):\n            self.remote_ip = ip\n        # AWS uses X-Forwarded-Proto\n        proto_header = headers.get(\n            \"X-Scheme\", headers.get(\"X-Forwarded-Proto\",\n                                    self.protocol))\n        if proto_header in (\"http\", \"https\"):\n            self.protocol = proto_header\n\n    def _unapply_xheaders(self):\n        \"\"\"Undo changes from `_apply_xheaders`.\n\n        Xheaders are per-request so they should not leak to the next\n        request on the same connection.\n        \"\"\"\n        self.remote_ip = self._orig_remote_ip\n        self.protocol = self._orig_protocol\n\n\nclass _ProxyAdapter(httputil.HTTPMessageDelegate):\n    def __init__(self, delegate, request_conn):\n        self.connection = request_conn\n        self.delegate = delegate\n\n    def headers_received(self, start_line, headers):\n        self.connection.context._apply_xheaders(headers)\n        return self.delegate.headers_received(start_line, headers)\n\n    def data_received(self, chunk):\n        return self.delegate.data_received(chunk)\n\n    def finish(self):\n        self.delegate.finish()\n        self._cleanup()\n\n    def on_connection_close(self):\n        self.delegate.on_connection_close()\n        self._cleanup()\n\n    def _cleanup(self):\n        self.connection.context._unapply_xheaders()\n\n\nHTTPRequest = httputil.HTTPServerRequest\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
**[ISSUE]**

**Title:** Incorrect Protocol Detection with Multiple X-Forwarded-Proto Values

**Description:**
When a request includes multiple values in the `X-Forwarded-Proto` header, the server fails to correctly determine the intended protocol. Specifically, the server does not properly parse and prioritize the protocol values, leading to incorrect protocol settings.

**Example Buggy Code:**
```python
headers = {"X-Forwarded-Proto": "https, http"}
response = make_request("/", headers=headers)
print(response["remote_protocol"])  # Expected to be "http"
```
In this example, the `X-Forwarded-Proto` header contains both "https" and "http". The expected behavior is for the server to use the last value ("http") to set the protocol. However, the server fails to do so correctly.

**Expected Behavior:**
When multiple values are present in the `X-Forwarded-Proto` header, the server should parse the header and use the last protocol specified (e.g., "http") to set the `remote_protocol`. This ensures that the server accurately reflects the intended protocol of the client request.

**Actual Behavior:**
The server does not correctly parse multiple values in the `X-Forwarded-Proto` header, resulting in incorrect protocol detection. Instead of using the last specified protocol ("http"), the server may retain the first value ("https") or fail to set the protocol appropriately, leading to potential mismatches and errors in handling the request.

**[/ISSUE]**
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/httpserver.py
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""A non-blocking, single-threaded HTTP server.

Typical applications have little direct interaction with the `HTTPServer`
class except to start a server at the beginning of the process
(and even that is often done indirectly via `tornado.web.Application.listen`).

.. versionchanged:: 4.0

   The ``HTTPRequest`` class that used to live in this module has been moved
   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.
"""

from __future__ import absolute_import, division, print_function

import socket

from tornado.escape import native_str
from tornado.http1connection import HTTP1ServerConnection, HTTP1ConnectionParameters
from tornado import gen
from tornado import httputil
from tornado import iostream
from tornado import netutil
from tornado.tcpserver import TCPServer
from tornado.util import Configurable


class HTTPServer(TCPServer, Configurable,
                 httputil.HTTPServerConnectionDelegate):
    r"""A non-blocking, single-threaded HTTP server.

    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,
    or, for backwards compatibility, a callback that takes an
    `.HTTPServerRequest` as an argument. The delegate is usually a
    `tornado.web.Application`.

    `HTTPServer` supports keep-alive connections by default
    (automatically for HTTP/1.1, or for HTTP/1.0 when the client
    requests ``Connection: keep-alive``).

    If ``xheaders`` is ``True``, we support the
    ``X-Real-Ip``/``X-Forwarded-For`` and
    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the
    remote IP and URI scheme/protocol for all requests.  These headers
    are useful when running Tornado behind a reverse proxy or load
    balancer.  The ``protocol`` argument can also be set to ``https``
    if Tornado is run behind an SSL-decoding proxy that does not set one of
    the supported ``xheaders``.

    By default, when parsing the ``X-Forwarded-For`` header, Tornado will
    select the last (i.e., the closest) address on the list of hosts as the
    remote host IP address.  To select the next server in the chain, a list of
    trusted downstream hosts may be passed as the ``trusted_downstream``
    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``
    header.

    To make this server serve SSL traffic, send the ``ssl_options`` keyword
    argument with an `ssl.SSLContext` object. For compatibility with older
    versions of Python ``ssl_options`` may also be a dictionary of keyword
    arguments for the `ssl.wrap_socket` method.::

       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
       ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                               os.path.join(data_dir, "mydomain.key"))
       HTTPServer(application, ssl_options=ssl_ctx)

    `HTTPServer` initialization follows one of three patterns (the
    initialization methods are defined on `tornado.tcpserver.TCPServer`):

    1. `~tornado.tcpserver.TCPServer.listen`: simple single-process::

            server = HTTPServer(app)
            server.listen(8888)
            IOLoop.current().start()

       In many cases, `tornado.web.Application.listen` can be used to avoid
       the need to explicitly create the `HTTPServer`.

    2. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:
       simple multi-process::

            server = HTTPServer(app)
            server.bind(8888)
            server.start(0)  # Forks multiple sub-processes
            IOLoop.current().start()

       When using this interface, an `.IOLoop` must *not* be passed
       to the `HTTPServer` constructor.  `~.TCPServer.start` will always start
       the server on the default singleton `.IOLoop`.

    3. `~tornado.tcpserver.TCPServer.add_sockets`: advanced multi-process::

            sockets = tornado.netutil.bind_sockets(8888)
            tornado.process.fork_processes(0)
            server = HTTPServer(app)
            server.add_sockets(sockets)
            IOLoop.current().start()

       The `~.TCPServer.add_sockets` interface is more complicated,
       but it can be used with `tornado.process.fork_processes` to
       give you more flexibility in when the fork happens.
       `~.TCPServer.add_sockets` can also be used in single-process
       servers if you want to create your listening sockets in some
       way other than `tornado.netutil.bind_sockets`.

    .. versionchanged:: 4.0
       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,
       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``
       arguments.  Added support for `.HTTPServerConnectionDelegate`
       instances as ``request_callback``.

    .. versionchanged:: 4.1
       `.HTTPServerConnectionDelegate.start_request` is now called with
       two arguments ``(server_conn, request_conn)`` (in accordance with the
       documentation) instead of one ``(request_conn)``.

    .. versionchanged:: 4.2
       `HTTPServer` is now a subclass of `tornado.util.Configurable`.

    .. versionchanged:: 4.5
       Added the ``trusted_downstream`` argument.

    .. versionchanged:: 5.0
       The ``io_loop`` argument has been removed.
    """
    def __init__(self, *args, **kwargs):
        # Ignore args to __init__; real initialization belongs in
        # initialize since we're Configurable. (there's something
        # weird in initialization order between this class,
        # Configurable, and TCPServer so we can't leave __init__ out
        # completely)
        pass

    def initialize(self, request_callback, no_keep_alive=False,
                   xheaders=False, ssl_options=None, protocol=None,
                   decompress_request=False,
                   chunk_size=None, max_header_size=None,
                   idle_connection_timeout=None, body_timeout=None,
                   max_body_size=None, max_buffer_size=None,
                   trusted_downstream=None):
        self.request_callback = request_callback
        self.xheaders = xheaders
        self.protocol = protocol
        self.conn_params = HTTP1ConnectionParameters(
            decompress=decompress_request,
            chunk_size=chunk_size,
            max_header_size=max_header_size,
            header_timeout=idle_connection_timeout or 3600,
            max_body_size=max_body_size,
            body_timeout=body_timeout,
            no_keep_alive=no_keep_alive)
        TCPServer.__init__(self, ssl_options=ssl_options,
                           max_buffer_size=max_buffer_size,
                           read_chunk_size=chunk_size)
        self._connections = set()
        self.trusted_downstream = trusted_downstream

    @classmethod
    def configurable_base(cls):
        return HTTPServer

    @classmethod
    def configurable_default(cls):
        return HTTPServer

    @gen.coroutine
    def close_all_connections(self):
        while self._connections:
            # Peek at an arbitrary element of the set
            conn = next(iter(self._connections))
            yield conn.close()

    def handle_stream(self, stream, address):
        context = _HTTPRequestContext(stream, address,
                                      self.protocol,
                                      self.trusted_downstream)
        conn = HTTP1ServerConnection(
            stream, self.conn_params, context)
        self._connections.add(conn)
        conn.start_serving(self)

    def start_request(self, server_conn, request_conn):
        if isinstance(self.request_callback, httputil.HTTPServerConnectionDelegate):
            delegate = self.request_callback.start_request(server_conn, request_conn)
        else:
            delegate = _CallableAdapter(self.request_callback, request_conn)

        if self.xheaders:
            delegate = _ProxyAdapter(delegate, request_conn)

        return delegate

    def on_close(self, server_conn):
        self._connections.remove(server_conn)


class _CallableAdapter(httputil.HTTPMessageDelegate):
    def __init__(self, request_callback, request_conn):
        self.connection = request_conn
        self.request_callback = request_callback
        self.request = None
        self.delegate = None
        self._chunks = []

    def headers_received(self, start_line, headers):
        self.request = httputil.HTTPServerRequest(
            connection=self.connection, start_line=start_line,
            headers=headers)

    def data_received(self, chunk):
        self._chunks.append(chunk)

    def finish(self):
        self.request.body = b''.join(self._chunks)
        self.request._parse_body()
        self.request_callback(self.request)

    def on_connection_close(self):
        self._chunks = None


class _HTTPRequestContext(object):
    def __init__(self, stream, address, protocol, trusted_downstream=None):
        self.address = address
        # Save the socket's address family now so we know how to
        # interpret self.address even after the stream is closed
        # and its socket attribute replaced with None.
        if stream.socket is not None:
            self.address_family = stream.socket.family
        else:
            self.address_family = None
        # In HTTPServerRequest we want an IP, not a full socket address.
        if (self.address_family in (socket.AF_INET, socket.AF_INET6) and
                address is not None):
            self.remote_ip = address[0]
        else:
            # Unix (or other) socket; fake the remote address.
            self.remote_ip = '0.0.0.0'
        if protocol:
            self.protocol = protocol
        elif isinstance(stream, iostream.SSLIOStream):
            self.protocol = "https"
        else:
            self.protocol = "http"
        self._orig_remote_ip = self.remote_ip
        self._orig_protocol = self.protocol
        self.trusted_downstream = set(trusted_downstream or [])

    def __str__(self):
        if self.address_family in (socket.AF_INET, socket.AF_INET6):
            return self.remote_ip
        elif isinstance(self.address, bytes):
            # Python 3 with the -bb option warns about str(bytes),
            # so convert it explicitly.
            # Unix socket addresses are str on mac but bytes on linux.
            return native_str(self.address)
        else:
            return str(self.address)

    def _apply_xheaders(self, headers):
        """Rewrite the ``remote_ip`` and ``protocol`` fields."""
        # Squid uses X-Forwarded-For, others use X-Real-Ip
        ip = headers.get("X-Forwarded-For", self.remote_ip)
        # Skip trusted downstream hosts in X-Forwarded-For list
        for ip in (cand.strip() for cand in reversed(ip.split(','))):
            if ip not in self.trusted_downstream:
                break
        ip = headers.get("X-Real-Ip", ip)
        if netutil.is_valid_ip(ip):
            self.remote_ip = ip
        # AWS uses X-Forwarded-Proto
        proto_header = headers.get(
            "X-Scheme", headers.get("X-Forwarded-Proto",
                                    self.protocol))
        if proto_header in ("http", "https"):
            self.protocol = proto_header

    def _unapply_xheaders(self):
        """Undo changes from `_apply_xheaders`.

        Xheaders are per-request so they should not leak to the next
        request on the same connection.
        """
        self.remote_ip = self._orig_remote_ip
        self.protocol = self._orig_protocol


class _ProxyAdapter(httputil.HTTPMessageDelegate):
    def __init__(self, delegate, request_conn):
        self.connection = request_conn
        self.delegate = delegate

    def headers_received(self, start_line, headers):
        self.connection.context._apply_xheaders(headers)
        return self.delegate.headers_received(start_line, headers)

    def data_received(self, chunk):
        return self.delegate.data_received(chunk)

    def finish(self):
        self.delegate.finish()
        self._cleanup()

    def on_connection_close(self):
        self.delegate.on_connection_close()
        self._cleanup()

    def _cleanup(self):
        self.connection.context._unapply_xheaders()


HTTPRequest = httputil.HTTPServerRequest

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user