{
    "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\nThis module also defines the `HTTPRequest` class which is exposed via\n`tornado.web.RequestHandler.request`.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport socket\nimport ssl\nimport time\n\nfrom tornado.escape import native_str, parse_qs_bytes\nfrom tornado import httputil\nfrom tornado import iostream\nfrom tornado.log import gen_log\nfrom tornado import netutil\nfrom tornado.tcpserver import TCPServer\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    import Cookie  # py2\nexcept ImportError:\n    import http.cookies as Cookie  # py3\n\n\nclass HTTPServer(TCPServer):\n    r\"\"\"A non-blocking, single-threaded HTTP server.\n\n    A server is defined by a request callback that takes an HTTPRequest\n    instance as an argument and writes a valid HTTP response with\n    `HTTPRequest.write`. `HTTPRequest.finish` finishes the request (but does\n    not necessarily close the connection in the case of HTTP/1.1 keep-alive\n    requests). A simple example server that echoes back the URI you\n    requested::\n\n        import tornado.httpserver\n        import tornado.ioloop\n\n        def handle_request(request):\n           message = \"You requested %s\\n\" % request.uri\n           request.write(\"HTTP/1.1 200 OK\\r\\nContent-Length: %d\\r\\n\\r\\n%s\" % (\n                         len(message), message))\n           request.finish()\n\n        http_server = tornado.httpserver.HTTPServer(handle_request)\n        http_server.listen(8888)\n        tornado.ioloop.IOLoop.instance().start()\n\n    `HTTPServer` is a very basic connection handler.  It parses the request\n    headers and body, but the request callback is responsible for producing\n    the response exactly as it will appear on the wire.  This affords\n    maximum flexibility for applications to implement whatever parts\n    of HTTP responses are required.\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``).  This means that the request\n    callback must generate a properly-framed response, using either\n    the ``Content-Length`` header or ``Transfer-Encoding: chunked``.\n    Applications that are unable to frame their responses properly\n    should instead return a ``Connection: close`` header in each\n    response and pass ``no_keep_alive=True`` to the `HTTPServer`\n    constructor.\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    To make this server serve SSL traffic, send the ``ssl_options`` dictionary\n    argument with the arguments required for the `ssl.wrap_socket` method,\n    including ``certfile`` and ``keyfile``.  (In Python 3.2+ you can pass\n    an `ssl.SSLContext` object instead of a dict)::\n\n       HTTPServer(applicaton, ssl_options={\n           \"certfile\": os.path.join(data_dir, \"mydomain.crt\"),\n           \"keyfile\": os.path.join(data_dir, \"mydomain.key\"),\n       })\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.instance().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.instance().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.instance().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    \"\"\"\n    def __init__(self, request_callback, no_keep_alive=False, io_loop=None,\n                 xheaders=False, ssl_options=None, protocol=None, **kwargs):\n        self.request_callback = request_callback\n        self.no_keep_alive = no_keep_alive\n        self.xheaders = xheaders\n        self.protocol = protocol\n        TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,\n                           **kwargs)\n\n    def handle_stream(self, stream, address):\n        HTTPConnection(stream, address, self.request_callback,\n                       self.no_keep_alive, self.xheaders, self.protocol)\n\n\nclass _BadRequestException(Exception):\n    \"\"\"Exception class for malformed HTTP requests.\"\"\"\n    pass\n\n\nclass HTTPConnection(object):\n    \"\"\"Handles a connection to an HTTP client, executing HTTP requests.\n\n    We parse HTTP headers and bodies, and execute the request callback\n    until the HTTP conection is closed.\n    \"\"\"\n    def __init__(self, stream, address, request_callback, no_keep_alive=False,\n                 xheaders=False, protocol=None):\n        self.stream = stream\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        self.address_family = stream.socket.family\n        self.request_callback = request_callback\n        self.no_keep_alive = no_keep_alive\n        self.xheaders = xheaders\n        self.protocol = protocol\n        self._request = None\n        self._request_finished = False\n        self._write_callback = None\n        self._close_callback = None\n        # Save stack context here, outside of any request.  This keeps\n        # contexts from one request from leaking into the next.\n        self._header_callback = stack_context.wrap(self._on_headers)\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self._header_callback)\n\n    def _clear_callbacks(self):\n        \"\"\"Clears the per-request callbacks.\n\n        This is run in between requests to allow the previous handler\n        to be garbage collected (and prevent spurious close callbacks),\n        and when the connection is closed (to break up cycles and\n        facilitate garbage collection in cpython).\n        \"\"\"\n        self._write_callback = None\n        self._close_callback = None\n\n    def set_close_callback(self, callback):\n        \"\"\"Sets a callback that will be run when the connection is closed.\n\n        Use this instead of accessing\n        `HTTPConnection.stream.set_close_callback\n        <.BaseIOStream.set_close_callback>` directly (which was the\n        recommended approach prior to Tornado 3.0).\n        \"\"\"\n        self._close_callback = stack_context.wrap(callback)\n        self.stream.set_close_callback(self._on_connection_close)\n\n    def _on_connection_close(self):\n        callback = self._close_callback\n        self._close_callback = None\n        callback()\n        # Delete any unfinished callbacks to break up reference cycles.\n        self._header_callback = None\n        self._clear_callbacks()\n\n    def close(self):\n        self.stream.close()\n        # Remove this reference to self, which would otherwise cause a\n        # cycle and delay garbage collection of this connection.\n        self._header_callback = None\n        self._clear_callbacks()\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes a chunk of output to the stream.\"\"\"\n        assert self._request, \"Request closed\"\n        if not self.stream.closed():\n            self._write_callback = stack_context.wrap(callback)\n            self.stream.write(chunk, self._on_write_complete)\n\n    def finish(self):\n        \"\"\"Finishes the request.\"\"\"\n        assert self._request, \"Request closed\"\n        self._request_finished = True\n        if not self.stream.writing():\n            self._finish_request()\n\n    def _on_write_complete(self):\n        if self._write_callback is not None:\n            callback = self._write_callback\n            self._write_callback = None\n            callback()\n        # _on_write_complete is enqueued on the IOLoop whenever the\n        # IOStream's write buffer becomes empty, but it's possible for\n        # another callback that runs on the IOLoop before it to\n        # simultaneously write more data and finish the request.  If\n        # there is still data in the IOStream, a future\n        # _on_write_complete will be responsible for calling\n        # _finish_request.\n        if self._request_finished and not self.stream.writing():\n            self._finish_request()\n\n    def _finish_request(self):\n        if self.no_keep_alive:\n            disconnect = True\n        else:\n            connection_header = self._request.headers.get(\"Connection\")\n            if connection_header is not None:\n                connection_header = connection_header.lower()\n            if self._request.supports_http_1_1():\n                disconnect = connection_header == \"close\"\n            elif (\"Content-Length\" in self._request.headers\n                    or self._request.method in (\"HEAD\", \"GET\")):\n                disconnect = connection_header != \"keep-alive\"\n            else:\n                disconnect = True\n        self._request = None\n        self._request_finished = False\n        self._clear_callbacks()\n        if disconnect:\n            self.close()\n            return\n        try:\n            # Use a try/except instead of checking stream.closed()\n            # directly, because in some cases the stream doesn't discover\n            # that it's closed until you try to read from it.\n            self.stream.read_until(b\"\\r\\n\\r\\n\", self._header_callback)\n        except iostream.StreamClosedError:\n            self.close()\n\n    def _on_headers(self, data):\n        try:\n            data = native_str(data.decode('latin1'))\n            eol = data.find(\"\\r\\n\")\n            start_line = data[:eol]\n            try:\n                method, uri, version = start_line.split(\" \")\n            except ValueError:\n                raise _BadRequestException(\"Malformed HTTP request line\")\n            if not version.startswith(\"HTTP/\"):\n                raise _BadRequestException(\"Malformed HTTP version in HTTP Request-Line\")\n            try:\n                headers = httputil.HTTPHeaders.parse(data[eol:])\n            except ValueError:\n                # Probably from split() if there was no ':' in the line\n                raise _BadRequestException(\"Malformed HTTP headers\")\n\n            # HTTPRequest wants an IP, not a full socket address\n            if self.address_family in (socket.AF_INET, socket.AF_INET6):\n                remote_ip = self.address[0]\n            else:\n                # Unix (or other) socket; fake the remote address\n                remote_ip = '0.0.0.0'\n\n            self._request = HTTPRequest(\n                connection=self, method=method, uri=uri, version=version,\n                headers=headers, remote_ip=remote_ip, protocol=self.protocol)\n\n            content_length = headers.get(\"Content-Length\")\n            if content_length:\n                content_length = int(content_length)\n                if content_length > self.stream.max_buffer_size:\n                    raise _BadRequestException(\"Content-Length too long\")\n                if headers.get(\"Expect\") == \"100-continue\":\n                    self.stream.write(b\"HTTP/1.1 100 (Continue)\\r\\n\\r\\n\")\n                self.stream.read_bytes(content_length, self._on_request_body)\n                return\n\n            self.request_callback(self._request)\n        except _BadRequestException as e:\n            gen_log.info(\"Malformed HTTP request from %s: %s\",\n                         self.address[0], e)\n            self.close()\n            return\n\n    def _on_request_body(self, data):\n        self._request.body = data\n        if self._request.method in (\"POST\", \"PATCH\", \"PUT\"):\n            httputil.parse_body_arguments(\n                self._request.headers.get(\"Content-Type\", \"\"), data,\n                self._request.arguments, self._request.files)\n        self.request_callback(self._request)\n\n\nclass HTTPRequest(object):\n    \"\"\"A single HTTP request.\n\n    All attributes are type `str` unless otherwise noted.\n\n    .. attribute:: method\n\n       HTTP request method, e.g. \"GET\" or \"POST\"\n\n    .. attribute:: uri\n\n       The requested uri.\n\n    .. attribute:: path\n\n       The path portion of `uri`\n\n    .. attribute:: query\n\n       The query portion of `uri`\n\n    .. attribute:: version\n\n       HTTP version specified in request, e.g. \"HTTP/1.1\"\n\n    .. attribute:: headers\n\n       `.HTTPHeaders` dictionary-like object for request headers.  Acts like\n       a case-insensitive dictionary with additional methods for repeated\n       headers.\n\n    .. attribute:: body\n\n       Request body, if present, as a byte string.\n\n    .. attribute:: remote_ip\n\n       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,\n       will pass along the real IP address provided by a load balancer\n       in the ``X-Real-Ip`` header\n\n    .. attribute:: protocol\n\n       The protocol used, either \"http\" or \"https\".  If ``HTTPServer.xheaders``\n       is set, will pass along the protocol used by a load balancer if\n       reported via an ``X-Scheme`` header.\n\n    .. attribute:: host\n\n       The requested hostname, usually taken from the ``Host`` header.\n\n    .. attribute:: arguments\n\n       GET/POST arguments are available in the arguments property, which\n       maps arguments names to lists of values (to support multiple values\n       for individual names). Names are of type `str`, while arguments\n       are byte strings.  Note that this is different from\n       `.RequestHandler.get_argument`, which returns argument values as\n       unicode strings.\n\n    .. attribute:: files\n\n       File uploads are available in the files property, which maps file\n       names to lists of `.HTTPFile`.\n\n    .. attribute:: connection\n\n       An HTTP request is attached to a single HTTP connection, which can\n       be accessed through the \"connection\" attribute. Since connections\n       are typically kept open in HTTP/1.1, multiple requests can be handled\n       sequentially on a single connection.\n    \"\"\"\n    def __init__(self, method, uri, version=\"HTTP/1.0\", headers=None,\n                 body=None, remote_ip=None, protocol=None, host=None,\n                 files=None, connection=None):\n        self.method = method\n        self.uri = uri\n        self.version = version\n        self.headers = headers or httputil.HTTPHeaders()\n        self.body = body or \"\"\n\n        # set remote IP and protocol\n        self.remote_ip = remote_ip\n        if protocol:\n            self.protocol = protocol\n        elif connection and isinstance(connection.stream,\n                                       iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n\n        # xheaders can override the defaults\n        if connection and connection.xheaders:\n            # Squid uses X-Forwarded-For, others use X-Real-Ip\n            ip = self.headers.get(\n                \"X-Real-Ip\", self.headers.get(\"X-Forwarded-For\", self.remote_ip))\n            if netutil.is_valid_ip(ip):\n                self.remote_ip = ip\n            # AWS uses X-Forwarded-Proto\n            proto = self.headers.get(\n                \"X-Scheme\", self.headers.get(\"X-Forwarded-Proto\", self.protocol))\n            if proto in (\"http\", \"https\"):\n                self.protocol = proto\n\n\n        self.host = host or self.headers.get(\"Host\") or \"127.0.0.1\"\n        self.files = files or {}\n        self.connection = connection\n        self._start_time = time.time()\n        self._finish_time = None\n\n        self.path, sep, self.query = uri.partition('?')\n        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)\n\n    def supports_http_1_1(self):\n        \"\"\"Returns True if this request supports HTTP/1.1 semantics\"\"\"\n        return self.version == \"HTTP/1.1\"\n\n    @property\n    def cookies(self):\n        \"\"\"A dictionary of Cookie.Morsel objects.\"\"\"\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookie.SimpleCookie()\n            if \"Cookie\" in self.headers:\n                try:\n                    self._cookies.load(\n                        native_str(self.headers[\"Cookie\"]))\n                except Exception:\n                    self._cookies = {}\n        return self._cookies\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes the given chunk to the response stream.\"\"\"\n        assert isinstance(chunk, bytes_type)\n        self.connection.write(chunk, callback=callback)\n\n    def finish(self):\n        \"\"\"Finishes this HTTP request on the open connection.\"\"\"\n        self.connection.finish()\n        self._finish_time = time.time()\n\n    def full_url(self):\n        \"\"\"Reconstructs the full URL for this request.\"\"\"\n        return self.protocol + \"://\" + self.host + self.uri\n\n    def request_time(self):\n        \"\"\"Returns the amount of time it took for this request to execute.\"\"\"\n        if self._finish_time is None:\n            return time.time() - self._start_time\n        else:\n            return self._finish_time - self._start_time\n\n    def get_ssl_certificate(self, binary_form=False):\n        \"\"\"Returns the client's SSL certificate, if any.\n\n        To use client certificates, the HTTPServer must have been constructed\n        with cert_reqs set in ssl_options, e.g.::\n\n            server = HTTPServer(app,\n                ssl_options=dict(\n                    certfile=\"foo.crt\",\n                    keyfile=\"foo.key\",\n                    cert_reqs=ssl.CERT_REQUIRED,\n                    ca_certs=\"cacert.crt\"))\n\n        By default, the return value is a dictionary (or None, if no\n        client certificate is present).  If ``binary_form`` is true, a\n        DER-encoded form of the certificate is returned instead.  See\n        SSLSocket.getpeercert() in the standard library for more\n        details.\n        http://docs.python.org/library/ssl.html#sslsocket-objects\n        \"\"\"\n        try:\n            return self.connection.stream.socket.getpeercert(\n                binary_form=binary_form)\n        except ssl.SSLError:\n            return None\n\n    def __repr__(self):\n        attrs = (\"protocol\", \"host\", \"method\", \"uri\", \"version\", \"remote_ip\",\n                 \"body\")\n        args = \", \".join([\"%s=%r\" % (n, getattr(self, n)) for n in attrs])\n        return \"%s(%s, headers=%s)\" % (\n            self.__class__.__name__, args, dict(self.headers))\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\nThis module also defines the `HTTPRequest` class which is exposed via\n`tornado.web.RequestHandler.request`.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport socket\nimport ssl\nimport time\n\nfrom tornado.escape import native_str, parse_qs_bytes\nfrom tornado import httputil\nfrom tornado import iostream\nfrom tornado.log import gen_log\nfrom tornado import netutil\nfrom tornado.tcpserver import TCPServer\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    import Cookie  # py2\nexcept ImportError:\n    import http.cookies as Cookie  # py3\n\n\nclass HTTPServer(TCPServer):\n    r\"\"\"A non-blocking, single-threaded HTTP server.\n\n    A server is defined by a request callback that takes an HTTPRequest\n    instance as an argument and writes a valid HTTP response with\n    `HTTPRequest.write`. `HTTPRequest.finish` finishes the request (but does\n    not necessarily close the connection in the case of HTTP/1.1 keep-alive\n    requests). A simple example server that echoes back the URI you\n    requested::\n\n        import tornado.httpserver\n        import tornado.ioloop\n\n        def handle_request(request):\n           message = \"You requested %s\\n\" % request.uri\n           request.write(\"HTTP/1.1 200 OK\\r\\nContent-Length: %d\\r\\n\\r\\n%s\" % (\n                         len(message), message))\n           request.finish()\n\n        http_server = tornado.httpserver.HTTPServer(handle_request)\n        http_server.listen(8888)\n        tornado.ioloop.IOLoop.instance().start()\n\n    `HTTPServer` is a very basic connection handler.  It parses the request\n    headers and body, but the request callback is responsible for producing\n    the response exactly as it will appear on the wire.  This affords\n    maximum flexibility for applications to implement whatever parts\n    of HTTP responses are required.\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``).  This means that the request\n    callback must generate a properly-framed response, using either\n    the ``Content-Length`` header or ``Transfer-Encoding: chunked``.\n    Applications that are unable to frame their responses properly\n    should instead return a ``Connection: close`` header in each\n    response and pass ``no_keep_alive=True`` to the `HTTPServer`\n    constructor.\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    To make this server serve SSL traffic, send the ``ssl_options`` dictionary\n    argument with the arguments required for the `ssl.wrap_socket` method,\n    including ``certfile`` and ``keyfile``.  (In Python 3.2+ you can pass\n    an `ssl.SSLContext` object instead of a dict)::\n\n       HTTPServer(applicaton, ssl_options={\n           \"certfile\": os.path.join(data_dir, \"mydomain.crt\"),\n           \"keyfile\": os.path.join(data_dir, \"mydomain.key\"),\n       })\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.instance().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.instance().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.instance().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    \"\"\"\n    def __init__(self, request_callback, no_keep_alive=False, io_loop=None,\n                 xheaders=False, ssl_options=None, protocol=None, **kwargs):\n        self.request_callback = request_callback\n        self.no_keep_alive = no_keep_alive\n        self.xheaders = xheaders\n        self.protocol = protocol\n        TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,\n                           **kwargs)\n\n    def handle_stream(self, stream, address):\n        HTTPConnection(stream, address, self.request_callback,\n                       self.no_keep_alive, self.xheaders, self.protocol)\n\n\nclass _BadRequestException(Exception):\n    \"\"\"Exception class for malformed HTTP requests.\"\"\"\n    pass\n\n\nclass HTTPConnection(object):\n    \"\"\"Handles a connection to an HTTP client, executing HTTP requests.\n\n    We parse HTTP headers and bodies, and execute the request callback\n    until the HTTP conection is closed.\n    \"\"\"\n    def __init__(self, stream, address, request_callback, no_keep_alive=False,\n                 xheaders=False, protocol=None):\n        self.stream = stream\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        self.address_family = stream.socket.family\n        self.request_callback = request_callback\n        self.no_keep_alive = no_keep_alive\n        self.xheaders = xheaders\n        self.protocol = protocol\n        self._request = None\n        self._request_finished = False\n        self._write_callback = None\n        self._close_callback = None\n        # Save stack context here, outside of any request.  This keeps\n        # contexts from one request from leaking into the next.\n        self._header_callback = stack_context.wrap(self._on_headers)\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self._header_callback)\n\n    def _clear_callbacks(self):\n        \"\"\"Clears the per-request callbacks.\n\n        This is run in between requests to allow the previous handler\n        to be garbage collected (and prevent spurious close callbacks),\n        and when the connection is closed (to break up cycles and\n        facilitate garbage collection in cpython).\n        \"\"\"\n        self._write_callback = None\n        self._close_callback = None\n\n    def set_close_callback(self, callback):\n        \"\"\"Sets a callback that will be run when the connection is closed.\n\n        Use this instead of accessing\n        `HTTPConnection.stream.set_close_callback\n        <.BaseIOStream.set_close_callback>` directly (which was the\n        recommended approach prior to Tornado 3.0).\n        \"\"\"\n        self._close_callback = stack_context.wrap(callback)\n        self.stream.set_close_callback(self._on_connection_close)\n\n    def _on_connection_close(self):\n        callback = self._close_callback\n        self._close_callback = None\n        callback()\n        # Delete any unfinished callbacks to break up reference cycles.\n        self._header_callback = None\n        self._clear_callbacks()\n\n    def close(self):\n        self.stream.close()\n        # Remove this reference to self, which would otherwise cause a\n        # cycle and delay garbage collection of this connection.\n        self._header_callback = None\n        self._clear_callbacks()\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes a chunk of output to the stream.\"\"\"\n        assert self._request, \"Request closed\"\n        if not self.stream.closed():\n            self._write_callback = stack_context.wrap(callback)\n            self.stream.write(chunk, self._on_write_complete)\n\n    def finish(self):\n        \"\"\"Finishes the request.\"\"\"\n        assert self._request, \"Request closed\"\n        self._request_finished = True\n        if not self.stream.writing():\n            self._finish_request()\n\n    def _on_write_complete(self):\n        if self._write_callback is not None:\n            callback = self._write_callback\n            self._write_callback = None\n            callback()\n        # _on_write_complete is enqueued on the IOLoop whenever the\n        # IOStream's write buffer becomes empty, but it's possible for\n        # another callback that runs on the IOLoop before it to\n        # simultaneously write more data and finish the request.  If\n        # there is still data in the IOStream, a future\n        # _on_write_complete will be responsible for calling\n        # _finish_request.\n        if self._request_finished and not self.stream.writing():\n            self._finish_request()\n\n    def _finish_request(self):\n        if self.no_keep_alive:\n            disconnect = True\n        else:\n            connection_header = self._request.headers.get(\"Connection\")\n            if connection_header is not None:\n                connection_header = connection_header.lower()\n            if self._request.supports_http_1_1():\n                disconnect = connection_header == \"close\"\n            elif (\"Content-Length\" in self._request.headers\n                    or self._request.method in (\"HEAD\", \"GET\")):\n                disconnect = connection_header != \"keep-alive\"\n            else:\n                disconnect = True\n        self._request = None\n        self._request_finished = False\n        self._clear_callbacks()\n        if disconnect:\n            self.close()\n            return\n        try:\n            # Use a try/except instead of checking stream.closed()\n            # directly, because in some cases the stream doesn't discover\n            # that it's closed until you try to read from it.\n            self.stream.read_until(b\"\\r\\n\\r\\n\", self._header_callback)\n        except iostream.StreamClosedError:\n            self.close()\n\n    def _on_headers(self, data):\n        try:\n            data = native_str(data.decode('latin1'))\n            eol = data.find(\"\\r\\n\")\n            start_line = data[:eol]\n            try:\n                method, uri, version = start_line.split(\" \")\n            except ValueError:\n                raise _BadRequestException(\"Malformed HTTP request line\")\n            if not version.startswith(\"HTTP/\"):\n                raise _BadRequestException(\"Malformed HTTP version in HTTP Request-Line\")\n            try:\n                headers = httputil.HTTPHeaders.parse(data[eol:])\n            except ValueError:\n                # Probably from split() if there was no ':' in the line\n                raise _BadRequestException(\"Malformed HTTP headers\")\n\n            # HTTPRequest wants an IP, not a full socket address\n            if self.address_family in (socket.AF_INET, socket.AF_INET6):\n                remote_ip = self.address[0]\n            else:\n                # Unix (or other) socket; fake the remote address\n                remote_ip = '0.0.0.0'\n\n            self._request = HTTPRequest(\n                connection=self, method=method, uri=uri, version=version,\n                headers=headers, remote_ip=remote_ip, protocol=self.protocol)\n\n            content_length = headers.get(\"Content-Length\")\n            if content_length:\n                content_length = int(content_length)\n                if content_length > self.stream.max_buffer_size:\n                    raise _BadRequestException(\"Content-Length too long\")\n                if headers.get(\"Expect\") == \"100-continue\":\n                    self.stream.write(b\"HTTP/1.1 100 (Continue)\\r\\n\\r\\n\")\n                self.stream.read_bytes(content_length, self._on_request_body)\n                return\n\n            self.request_callback(self._request)\n        except _BadRequestException as e:\n            gen_log.info(\"Malformed HTTP request from %s: %s\",\n                         self.address[0], e)\n            self.close()\n            return\n\n    def _on_request_body(self, data):\n        self._request.body = data\n        if self._request.method in (\"POST\", \"PATCH\", \"PUT\"):\n            httputil.parse_body_arguments(\n                self._request.headers.get(\"Content-Type\", \"\"), data,\n                self._request.arguments, self._request.files)\n        self.request_callback(self._request)\n\n\nclass HTTPRequest(object):\n    \"\"\"A single HTTP request.\n\n    All attributes are type `str` unless otherwise noted.\n\n    .. attribute:: method\n\n       HTTP request method, e.g. \"GET\" or \"POST\"\n\n    .. attribute:: uri\n\n       The requested uri.\n\n    .. attribute:: path\n\n       The path portion of `uri`\n\n    .. attribute:: query\n\n       The query portion of `uri`\n\n    .. attribute:: version\n\n       HTTP version specified in request, e.g. \"HTTP/1.1\"\n\n    .. attribute:: headers\n\n       `.HTTPHeaders` dictionary-like object for request headers.  Acts like\n       a case-insensitive dictionary with additional methods for repeated\n       headers.\n\n    .. attribute:: body\n\n       Request body, if present, as a byte string.\n\n    .. attribute:: remote_ip\n\n       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,\n       will pass along the real IP address provided by a load balancer\n       in the ``X-Real-Ip`` header\n\n    .. attribute:: protocol\n\n       The protocol used, either \"http\" or \"https\".  If ``HTTPServer.xheaders``\n       is set, will pass along the protocol used by a load balancer if\n       reported via an ``X-Scheme`` header.\n\n    .. attribute:: host\n\n       The requested hostname, usually taken from the ``Host`` header.\n\n    .. attribute:: arguments\n\n       GET/POST arguments are available in the arguments property, which\n       maps arguments names to lists of values (to support multiple values\n       for individual names). Names are of type `str`, while arguments\n       are byte strings.  Note that this is different from\n       `.RequestHandler.get_argument`, which returns argument values as\n       unicode strings.\n\n    .. attribute:: files\n\n       File uploads are available in the files property, which maps file\n       names to lists of `.HTTPFile`.\n\n    .. attribute:: connection\n\n       An HTTP request is attached to a single HTTP connection, which can\n       be accessed through the \"connection\" attribute. Since connections\n       are typically kept open in HTTP/1.1, multiple requests can be handled\n       sequentially on a single connection.\n    \"\"\"\n    def __init__(self, method, uri, version=\"HTTP/1.0\", headers=None,\n                 body=None, remote_ip=None, protocol=None, host=None,\n                 files=None, connection=None):\n        self.method = method\n        self.uri = uri\n        self.version = version\n        self.headers = headers or httputil.HTTPHeaders()\n        self.body = body or \"\"\n\n        # set remote IP and protocol\n        self.remote_ip = remote_ip\n        if protocol:\n            self.protocol = protocol\n        elif connection and isinstance(connection.stream,\n                                       iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n\n        # xheaders can override the defaults\n        if connection and connection.xheaders:\n            # Squid uses X-Forwarded-For, others use X-Real-Ip\n            ip = self.headers.get(\"X-Forwarded-For\", self.remote_ip)\n            ip = ip.split(',')[-1].strip()\n            ip = self.headers.get(\n                \"X-Real-Ip\", ip)\n            if netutil.is_valid_ip(ip):\n                self.remote_ip = ip\n            # AWS uses X-Forwarded-Proto\n            proto = self.headers.get(\n                \"X-Scheme\", self.headers.get(\"X-Forwarded-Proto\", self.protocol))\n            if proto in (\"http\", \"https\"):\n                self.protocol = proto\n\n\n        self.host = host or self.headers.get(\"Host\") or \"127.0.0.1\"\n        self.files = files or {}\n        self.connection = connection\n        self._start_time = time.time()\n        self._finish_time = None\n\n        self.path, sep, self.query = uri.partition('?')\n        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)\n\n    def supports_http_1_1(self):\n        \"\"\"Returns True if this request supports HTTP/1.1 semantics\"\"\"\n        return self.version == \"HTTP/1.1\"\n\n    @property\n    def cookies(self):\n        \"\"\"A dictionary of Cookie.Morsel objects.\"\"\"\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookie.SimpleCookie()\n            if \"Cookie\" in self.headers:\n                try:\n                    self._cookies.load(\n                        native_str(self.headers[\"Cookie\"]))\n                except Exception:\n                    self._cookies = {}\n        return self._cookies\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes the given chunk to the response stream.\"\"\"\n        assert isinstance(chunk, bytes_type)\n        self.connection.write(chunk, callback=callback)\n\n    def finish(self):\n        \"\"\"Finishes this HTTP request on the open connection.\"\"\"\n        self.connection.finish()\n        self._finish_time = time.time()\n\n    def full_url(self):\n        \"\"\"Reconstructs the full URL for this request.\"\"\"\n        return self.protocol + \"://\" + self.host + self.uri\n\n    def request_time(self):\n        \"\"\"Returns the amount of time it took for this request to execute.\"\"\"\n        if self._finish_time is None:\n            return time.time() - self._start_time\n        else:\n            return self._finish_time - self._start_time\n\n    def get_ssl_certificate(self, binary_form=False):\n        \"\"\"Returns the client's SSL certificate, if any.\n\n        To use client certificates, the HTTPServer must have been constructed\n        with cert_reqs set in ssl_options, e.g.::\n\n            server = HTTPServer(app,\n                ssl_options=dict(\n                    certfile=\"foo.crt\",\n                    keyfile=\"foo.key\",\n                    cert_reqs=ssl.CERT_REQUIRED,\n                    ca_certs=\"cacert.crt\"))\n\n        By default, the return value is a dictionary (or None, if no\n        client certificate is present).  If ``binary_form`` is true, a\n        DER-encoded form of the certificate is returned instead.  See\n        SSLSocket.getpeercert() in the standard library for more\n        details.\n        http://docs.python.org/library/ssl.html#sslsocket-objects\n        \"\"\"\n        try:\n            return self.connection.stream.socket.getpeercert(\n                binary_form=binary_form)\n        except ssl.SSLError:\n            return None\n\n    def __repr__(self):\n        attrs = (\"protocol\", \"host\", \"method\", \"uri\", \"version\", \"remote_ip\",\n                 \"body\")\n        args = \", \".join([\"%s=%r\" % (n, getattr(self, n)) for n in attrs])\n        return \"%s(%s, headers=%s)\" % (\n            self.__class__.__name__, args, dict(self.headers))\n",
            "header": {
                "file": {
                    "path": "tornado/httpserver.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "16472fa4",
                "new_commit_hash": "f597737a",
                "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": 431,
                            "length": 8
                        },
                        "new_range": {
                            "start": 431,
                            "length": 10
                        },
                        "section": "class HTTPRequest(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        # xheaders can override the defaults",
                                "type": "context"
                            },
                            {
                                "content": "        if connection and connection.xheaders:",
                                "type": "context"
                            },
                            {
                                "content": "            # Squid uses X-Forwarded-For, others use X-Real-Ip",
                                "type": "context"
                            },
                            {
                                "content": "            ip = self.headers.get(\"X-Forwarded-For\", self.remote_ip)",
                                "type": "added"
                            },
                            {
                                "content": "            ip = ip.split(',')[-1].strip()",
                                "type": "added"
                            },
                            {
                                "content": "            ip = self.headers.get(",
                                "type": "context"
                            },
                            {
                                "content": "                \"X-Real-Ip\", self.headers.get(\"X-Forwarded-For\", self.remote_ip))",
                                "type": "deleted"
                            },
                            {
                                "content": "                \"X-Real-Ip\", ip)",
                                "type": "added"
                            },
                            {
                                "content": "            if netutil.is_valid_ip(ip):",
                                "type": "context"
                            },
                            {
                                "content": "                self.remote_ip = ip",
                                "type": "context"
                            },
                            {
                                "content": "            # AWS uses X-Forwarded-Proto",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/httpserver.py",
                            "type": "method",
                            "name": "HTTPRequest.__init__",
                            "content": "class HTTPRequest(object):\n    \"\"\"A single HTTP request.\n\n    All attributes are type `str` unless otherwise noted.\n\n    .. attribute:: method\n\n       HTTP request method, e.g. \"GET\" or \"POST\"\n\n    .. attribute:: uri\n\n       The requested uri.\n\n    .. attribute:: path\n\n       The path portion of `uri`\n\n    .. attribute:: query\n\n       The query portion of `uri`\n\n    .. attribute:: version\n\n       HTTP version specified in request, e.g. \"HTTP/1.1\"\n\n    .. attribute:: headers\n\n       `.HTTPHeaders` dictionary-like object for request headers.  Acts like\n       a case-insensitive dictionary with additional methods for repeated\n       headers.\n\n    .. attribute:: body\n\n       Request body, if present, as a byte string.\n\n    .. attribute:: remote_ip\n\n       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,\n       will pass along the real IP address provided by a load balancer\n       in the ``X-Real-Ip`` header\n\n    .. attribute:: protocol\n\n       The protocol used, either \"http\" or \"https\".  If ``HTTPServer.xheaders``\n       is set, will pass along the protocol used by a load balancer if\n       reported via an ``X-Scheme`` header.\n\n    .. attribute:: host\n\n       The requested hostname, usually taken from the ``Host`` header.\n\n    .. attribute:: arguments\n\n       GET/POST arguments are available in the arguments property, which\n       maps arguments names to lists of values (to support multiple values\n       for individual names). Names are of type `str`, while arguments\n       are byte strings.  Note that this is different from\n       `.RequestHandler.get_argument`, which returns argument values as\n       unicode strings.\n\n    .. attribute:: files\n\n       File uploads are available in the files property, which maps file\n       names to lists of `.HTTPFile`.\n\n    .. attribute:: connection\n\n       An HTTP request is attached to a single HTTP connection, which can\n       be accessed through the \"connection\" attribute. Since connections\n       are typically kept open in HTTP/1.1, multiple requests can be handled\n       sequentially on a single connection.\n    \"\"\"\n    def __init__(self, method, uri, version=\"HTTP/1.0\", headers=None,\n                 body=None, remote_ip=None, protocol=None, host=None,\n                 files=None, connection=None):\n        self.method = method\n        self.uri = uri\n        self.version = version\n        self.headers = headers or httputil.HTTPHeaders()\n        self.body = body or \"\"\n\n        # set remote IP and protocol\n        self.remote_ip = remote_ip\n        if protocol:\n            self.protocol = protocol\n        elif connection and isinstance(connection.stream,\n                                       iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n\n        # xheaders can override the defaults\n        if connection and connection.xheaders:\n            # Squid uses X-Forwarded-For, others use X-Real-Ip\n            ip = self.headers.get(\n                \"X-Real-Ip\", self.headers.get(\"X-Forwarded-For\", self.remote_ip))\n            if netutil.is_valid_ip(ip):\n                self.remote_ip = ip\n            # AWS uses X-Forwarded-Proto\n            proto = self.headers.get(\n                \"X-Scheme\", self.headers.get(\"X-Forwarded-Proto\", self.protocol))\n            if proto in (\"http\", \"https\"):\n                self.protocol = proto\n\n\n        self.host = host or self.headers.get(\"Host\") or \"127.0.0.1\"\n        self.files = files or {}\n        self.connection = connection\n        self._start_time = time.time()\n        self._finish_time = None\n\n        self.path, sep, self.query = uri.partition('?')\n        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)\n\n    def supports_http_1_1(self):\n        \"\"\"Returns True if this request supports HTTP/1.1 semantics\"\"\"\n        return self.version == \"HTTP/1.1\"\n\n    @property\n    def cookies(self):\n        \"\"\"A dictionary of Cookie.Morsel objects.\"\"\"\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookie.SimpleCookie()\n            if \"Cookie\" in self.headers:\n                try:\n                    self._cookies.load(\n                        native_str(self.headers[\"Cookie\"]))\n                except Exception:\n                    self._cookies = {}\n        return self._cookies\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes the given chunk to the response stream.\"\"\"\n        assert isinstance(chunk, bytes_type)\n        self.connection.write(chunk, callback=callback)\n\n    def finish(self):\n        \"\"\"Finishes this HTTP request on the open connection.\"\"\"\n        self.connection.finish()\n        self._finish_time = time.time()\n\n    def full_url(self):\n        \"\"\"Reconstructs the full URL for this request.\"\"\"\n        return self.protocol + \"://\" + self.host + self.uri\n\n    def request_time(self):\n        \"\"\"Returns the amount of time it took for this request to execute.\"\"\"\n        if self._finish_time is None:\n            return time.time() - self._start_time\n        else:\n            return self._finish_time - self._start_time\n\n    def get_ssl_certificate(self, binary_form=False):\n        \"\"\"Returns the client's SSL certificate, if any.\n\n        To use client certificates, the HTTPServer must have been constructed\n        with cert_reqs set in ssl_options, e.g.::\n\n            server = HTTPServer(app,\n                ssl_options=dict(\n                    certfile=\"foo.crt\",\n                    keyfile=\"foo.key\",\n                    cert_reqs=ssl.CERT_REQUIRED,\n                    ca_certs=\"cacert.crt\"))\n\n        By default, the return value is a dictionary (or None, if no\n        client certificate is present).  If ``binary_form`` is true, a\n        DER-encoded form of the certificate is returned instead.  See\n        SSLSocket.getpeercert() in the standard library for more\n        details.\n        http://docs.python.org/library/ssl.html#sslsocket-objects\n        \"\"\"\n        try:\n            return self.connection.stream.socket.getpeercert(\n                binary_form=binary_form)\n        except ssl.SSLError:\n            return None\n\n    def __repr__(self):\n        attrs = (\"protocol\", \"host\", \"method\", \"uri\", \"version\", \"remote_ip\",\n                 \"body\")\n        args = \", \".join([\"%s=%r\" % (n, getattr(self, n)) for n in attrs])\n        return \"%s(%s, headers=%s)\" % (\n            self.__class__.__name__, args, dict(self.headers))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 412,
                            "end_lineno": 452,
                            "parent": {
                                "file_name": "tornado/httpserver.py",
                                "type": "class",
                                "name": "HTTPRequest",
                                "content": "class HTTPRequest(object):\n    \"\"\"A single HTTP request.\n\n    All attributes are type `str` unless otherwise noted.\n\n    .. attribute:: method\n\n       HTTP request method, e.g. \"GET\" or \"POST\"\n\n    .. attribute:: uri\n\n       The requested uri.\n\n    .. attribute:: path\n\n       The path portion of `uri`\n\n    .. attribute:: query\n\n       The query portion of `uri`\n\n    .. attribute:: version\n\n       HTTP version specified in request, e.g. \"HTTP/1.1\"\n\n    .. attribute:: headers\n\n       `.HTTPHeaders` dictionary-like object for request headers.  Acts like\n       a case-insensitive dictionary with additional methods for repeated\n       headers.\n\n    .. attribute:: body\n\n       Request body, if present, as a byte string.\n\n    .. attribute:: remote_ip\n\n       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,\n       will pass along the real IP address provided by a load balancer\n       in the ``X-Real-Ip`` header\n\n    .. attribute:: protocol\n\n       The protocol used, either \"http\" or \"https\".  If ``HTTPServer.xheaders``\n       is set, will pass along the protocol used by a load balancer if\n       reported via an ``X-Scheme`` header.\n\n    .. attribute:: host\n\n       The requested hostname, usually taken from the ``Host`` header.\n\n    .. attribute:: arguments\n\n       GET/POST arguments are available in the arguments property, which\n       maps arguments names to lists of values (to support multiple values\n       for individual names). Names are of type `str`, while arguments\n       are byte strings.  Note that this is different from\n       `.RequestHandler.get_argument`, which returns argument values as\n       unicode strings.\n\n    .. attribute:: files\n\n       File uploads are available in the files property, which maps file\n       names to lists of `.HTTPFile`.\n\n    .. attribute:: connection\n\n       An HTTP request is attached to a single HTTP connection, which can\n       be accessed through the \"connection\" attribute. Since connections\n       are typically kept open in HTTP/1.1, multiple requests can be handled\n       sequentially on a single connection.\n    \"\"\"\n    def __init__(self, method, uri, version=\"HTTP/1.0\", headers=None,\n                 body=None, remote_ip=None, protocol=None, host=None,\n                 files=None, connection=None):\n        self.method = method\n        self.uri = uri\n        self.version = version\n        self.headers = headers or httputil.HTTPHeaders()\n        self.body = body or \"\"\n\n        # set remote IP and protocol\n        self.remote_ip = remote_ip\n        if protocol:\n            self.protocol = protocol\n        elif connection and isinstance(connection.stream,\n                                       iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n\n        # xheaders can override the defaults\n        if connection and connection.xheaders:\n            # Squid uses X-Forwarded-For, others use X-Real-Ip\n            ip = self.headers.get(\n                \"X-Real-Ip\", self.headers.get(\"X-Forwarded-For\", self.remote_ip))\n            if netutil.is_valid_ip(ip):\n                self.remote_ip = ip\n            # AWS uses X-Forwarded-Proto\n            proto = self.headers.get(\n                \"X-Scheme\", self.headers.get(\"X-Forwarded-Proto\", self.protocol))\n            if proto in (\"http\", \"https\"):\n                self.protocol = proto\n\n\n        self.host = host or self.headers.get(\"Host\") or \"127.0.0.1\"\n        self.files = files or {}\n        self.connection = connection\n        self._start_time = time.time()\n        self._finish_time = None\n\n        self.path, sep, self.query = uri.partition('?')\n        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)\n\n    def supports_http_1_1(self):\n        \"\"\"Returns True if this request supports HTTP/1.1 semantics\"\"\"\n        return self.version == \"HTTP/1.1\"\n\n    @property\n    def cookies(self):\n        \"\"\"A dictionary of Cookie.Morsel objects.\"\"\"\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookie.SimpleCookie()\n            if \"Cookie\" in self.headers:\n                try:\n                    self._cookies.load(\n                        native_str(self.headers[\"Cookie\"]))\n                except Exception:\n                    self._cookies = {}\n        return self._cookies\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes the given chunk to the response stream.\"\"\"\n        assert isinstance(chunk, bytes_type)\n        self.connection.write(chunk, callback=callback)\n\n    def finish(self):\n        \"\"\"Finishes this HTTP request on the open connection.\"\"\"\n        self.connection.finish()\n        self._finish_time = time.time()\n\n    def full_url(self):\n        \"\"\"Reconstructs the full URL for this request.\"\"\"\n        return self.protocol + \"://\" + self.host + self.uri\n\n    def request_time(self):\n        \"\"\"Returns the amount of time it took for this request to execute.\"\"\"\n        if self._finish_time is None:\n            return time.time() - self._start_time\n        else:\n            return self._finish_time - self._start_time\n\n    def get_ssl_certificate(self, binary_form=False):\n        \"\"\"Returns the client's SSL certificate, if any.\n\n        To use client certificates, the HTTPServer must have been constructed\n        with cert_reqs set in ssl_options, e.g.::\n\n            server = HTTPServer(app,\n                ssl_options=dict(\n                    certfile=\"foo.crt\",\n                    keyfile=\"foo.key\",\n                    cert_reqs=ssl.CERT_REQUIRED,\n                    ca_certs=\"cacert.crt\"))\n\n        By default, the return value is a dictionary (or None, if no\n        client certificate is present).  If ``binary_form`` is true, a\n        DER-encoded form of the certificate is returned instead.  See\n        SSLSocket.getpeercert() in the standard library for more\n        details.\n        http://docs.python.org/library/ssl.html#sslsocket-objects\n        \"\"\"\n        try:\n            return self.connection.stream.socket.getpeercert(\n                binary_form=binary_form)\n        except ssl.SSLError:\n            return None\n\n    def __repr__(self):\n        attrs = (\"protocol\", \"host\", \"method\", \"uri\", \"version\", \"remote_ip\",\n                 \"body\")\n        args = \", \".join([\"%s=%r\" % (n, getattr(self, n)) for n in attrs])\n        return \"%s(%s, headers=%s)\" % (\n            self.__class__.__name__, args, dict(self.headers))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 340,
                                "end_lineno": 523,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/httpserver.py",
                            "type": "class",
                            "name": "HTTPRequest",
                            "content": "class HTTPRequest(object):\n    \"\"\"A single HTTP request.\n\n    All attributes are type `str` unless otherwise noted.\n\n    .. attribute:: method\n\n       HTTP request method, e.g. \"GET\" or \"POST\"\n\n    .. attribute:: uri\n\n       The requested uri.\n\n    .. attribute:: path\n\n       The path portion of `uri`\n\n    .. attribute:: query\n\n       The query portion of `uri`\n\n    .. attribute:: version\n\n       HTTP version specified in request, e.g. \"HTTP/1.1\"\n\n    .. attribute:: headers\n\n       `.HTTPHeaders` dictionary-like object for request headers.  Acts like\n       a case-insensitive dictionary with additional methods for repeated\n       headers.\n\n    .. attribute:: body\n\n       Request body, if present, as a byte string.\n\n    .. attribute:: remote_ip\n\n       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,\n       will pass along the real IP address provided by a load balancer\n       in the ``X-Real-Ip`` header\n\n    .. attribute:: protocol\n\n       The protocol used, either \"http\" or \"https\".  If ``HTTPServer.xheaders``\n       is set, will pass along the protocol used by a load balancer if\n       reported via an ``X-Scheme`` header.\n\n    .. attribute:: host\n\n       The requested hostname, usually taken from the ``Host`` header.\n\n    .. attribute:: arguments\n\n       GET/POST arguments are available in the arguments property, which\n       maps arguments names to lists of values (to support multiple values\n       for individual names). Names are of type `str`, while arguments\n       are byte strings.  Note that this is different from\n       `.RequestHandler.get_argument`, which returns argument values as\n       unicode strings.\n\n    .. attribute:: files\n\n       File uploads are available in the files property, which maps file\n       names to lists of `.HTTPFile`.\n\n    .. attribute:: connection\n\n       An HTTP request is attached to a single HTTP connection, which can\n       be accessed through the \"connection\" attribute. Since connections\n       are typically kept open in HTTP/1.1, multiple requests can be handled\n       sequentially on a single connection.\n    \"\"\"\n    def __init__(self, method, uri, version=\"HTTP/1.0\", headers=None,\n                 body=None, remote_ip=None, protocol=None, host=None,\n                 files=None, connection=None):\n        self.method = method\n        self.uri = uri\n        self.version = version\n        self.headers = headers or httputil.HTTPHeaders()\n        self.body = body or \"\"\n\n        # set remote IP and protocol\n        self.remote_ip = remote_ip\n        if protocol:\n            self.protocol = protocol\n        elif connection and isinstance(connection.stream,\n                                       iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n\n        # xheaders can override the defaults\n        if connection and connection.xheaders:\n            # Squid uses X-Forwarded-For, others use X-Real-Ip\n            ip = self.headers.get(\n                \"X-Real-Ip\", self.headers.get(\"X-Forwarded-For\", self.remote_ip))\n            if netutil.is_valid_ip(ip):\n                self.remote_ip = ip\n            # AWS uses X-Forwarded-Proto\n            proto = self.headers.get(\n                \"X-Scheme\", self.headers.get(\"X-Forwarded-Proto\", self.protocol))\n            if proto in (\"http\", \"https\"):\n                self.protocol = proto\n\n\n        self.host = host or self.headers.get(\"Host\") or \"127.0.0.1\"\n        self.files = files or {}\n        self.connection = connection\n        self._start_time = time.time()\n        self._finish_time = None\n\n        self.path, sep, self.query = uri.partition('?')\n        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)\n\n    def supports_http_1_1(self):\n        \"\"\"Returns True if this request supports HTTP/1.1 semantics\"\"\"\n        return self.version == \"HTTP/1.1\"\n\n    @property\n    def cookies(self):\n        \"\"\"A dictionary of Cookie.Morsel objects.\"\"\"\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookie.SimpleCookie()\n            if \"Cookie\" in self.headers:\n                try:\n                    self._cookies.load(\n                        native_str(self.headers[\"Cookie\"]))\n                except Exception:\n                    self._cookies = {}\n        return self._cookies\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes the given chunk to the response stream.\"\"\"\n        assert isinstance(chunk, bytes_type)\n        self.connection.write(chunk, callback=callback)\n\n    def finish(self):\n        \"\"\"Finishes this HTTP request on the open connection.\"\"\"\n        self.connection.finish()\n        self._finish_time = time.time()\n\n    def full_url(self):\n        \"\"\"Reconstructs the full URL for this request.\"\"\"\n        return self.protocol + \"://\" + self.host + self.uri\n\n    def request_time(self):\n        \"\"\"Returns the amount of time it took for this request to execute.\"\"\"\n        if self._finish_time is None:\n            return time.time() - self._start_time\n        else:\n            return self._finish_time - self._start_time\n\n    def get_ssl_certificate(self, binary_form=False):\n        \"\"\"Returns the client's SSL certificate, if any.\n\n        To use client certificates, the HTTPServer must have been constructed\n        with cert_reqs set in ssl_options, e.g.::\n\n            server = HTTPServer(app,\n                ssl_options=dict(\n                    certfile=\"foo.crt\",\n                    keyfile=\"foo.key\",\n                    cert_reqs=ssl.CERT_REQUIRED,\n                    ca_certs=\"cacert.crt\"))\n\n        By default, the return value is a dictionary (or None, if no\n        client certificate is present).  If ``binary_form`` is true, a\n        DER-encoded form of the certificate is returned instead.  See\n        SSLSocket.getpeercert() in the standard library for more\n        details.\n        http://docs.python.org/library/ssl.html#sslsocket-objects\n        \"\"\"\n        try:\n            return self.connection.stream.socket.getpeercert(\n                binary_form=binary_form)\n        except ssl.SSLError:\n            return None\n\n    def __repr__(self):\n        attrs = (\"protocol\", \"host\", \"method\", \"uri\", \"version\", \"remote_ip\",\n                 \"body\")\n        args = \", \".join([\"%s=%r\" % (n, getattr(self, n)) for n in attrs])\n        return \"%s(%s, headers=%s)\" % (\n            self.__class__.__name__, args, dict(self.headers))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 340,
                            "end_lineno": 523,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#!/usr/bin/env python\n\n\nfrom __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import httpclient, simple_httpclient, netutil\nfrom tornado.escape import json_decode, utf8, _unicode, recursive_unicode, native_str\nfrom tornado.httpserver import HTTPServer\nfrom tornado.httputil import HTTPHeaders\nfrom tornado.iostream import IOStream\nfrom tornado.log import gen_log\nfrom tornado.netutil import ssl_options_to_context, Resolver\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog\nfrom tornado.test.util import unittest\nfrom tornado.util import u, bytes_type\nfrom tornado.web import Application, RequestHandler, asynchronous\nimport datetime\nimport os\nimport shutil\nimport socket\nimport ssl\nimport sys\nimport tempfile\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(),\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            self.http_client.fetch(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# 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\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\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\n        self.assertRaises(ValueError, HTTPServer, application, ssl_options={\n                          \"certfile\": \"/__mising__.crt\",\n                          })\n        self.assertRaises(ValueError, 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_certificate\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\nclass RawRequestHTTPConnection(simple_httpclient._HTTPConnection):\n    def set_request(self, request):\n        self.__next_request = request\n\n    def _on_connect(self):\n        self.stream.write(self.__next_request)\n        self.__next_request = None\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self._on_headers)\n\n# This test is also called from wsgi_test\n\n\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):\n        client = SimpleAsyncHTTPClient(self.io_loop)\n        conn = RawRequestHTTPConnection(\n            self.io_loop, client,\n            httpclient._RequestProxy(\n                httpclient.HTTPRequest(self.get_url(\"/\")),\n                dict(httpclient.HTTPRequest._DEFAULTS)),\n            None, self.stop,\n            1024 * 1024, Resolver(io_loop=self.io_loop))\n        conn.set_request(\n            b\"\\r\\n\".join(headers +\n                         [utf8(\"Content-Length: %d\\r\\n\" % len(body))]) +\n            b\"\\r\\n\" + body)\n        response = self.wait()\n        client.close()\n        response.rethrow()\n        return response\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.body)\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_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(), io_loop=self.io_loop)\n        stream.connect((\"localhost\", 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\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_type)\n\n    def post(self):\n        self.check_type('body', self.request.body, bytes_type)\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\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(('localhost', 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(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.01),\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.01),\n                                     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)\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_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        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_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_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\n    def tearDown(self):\n        shutil.rmtree(self.tmpdir)\n        super(UnixSocketTest, self).tearDown()\n\n    def test_unix_socket(self):\n        sockfile = os.path.join(self.tmpdir, \"test.sock\")\n        sock = netutil.bind_unix_socket(sockfile)\n        app = Application([(\"/hello\", HelloWorldRequestHandler)])\n        server = HTTPServer(app, io_loop=self.io_loop)\n        server.add_socket(sock)\n        stream = IOStream(socket.socket(socket.AF_UNIX), io_loop=self.io_loop)\n        stream.connect(sockfile, self.stop)\n        self.wait()\n        stream.write(b\"GET /hello HTTP/1.0\\r\\n\\r\\n\")\n        stream.read_until(b\"\\r\\n\", self.stop)\n        response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.0 200 OK\\r\\n\")\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        headers = HTTPHeaders.parse(self.wait().decode('latin1'))\n        stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Hello world\")\n        stream.close()\n        server.stop()\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        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(), io_loop=self.io_loop)\n        self.stream.connect(('localhost', 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(self.http_version + b' 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        headers = self.read_headers()\n        self.stream.read_bytes(int(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.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.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.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\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",
            "new_file_content": "#!/usr/bin/env python\n\n\nfrom __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import httpclient, simple_httpclient, netutil\nfrom tornado.escape import json_decode, utf8, _unicode, recursive_unicode, native_str\nfrom tornado.httpserver import HTTPServer\nfrom tornado.httputil import HTTPHeaders\nfrom tornado.iostream import IOStream\nfrom tornado.log import gen_log\nfrom tornado.netutil import ssl_options_to_context, Resolver\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog\nfrom tornado.test.util import unittest\nfrom tornado.util import u, bytes_type\nfrom tornado.web import Application, RequestHandler, asynchronous\nimport datetime\nimport os\nimport shutil\nimport socket\nimport ssl\nimport sys\nimport tempfile\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(),\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            self.http_client.fetch(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# 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\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\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\n        self.assertRaises(ValueError, HTTPServer, application, ssl_options={\n                          \"certfile\": \"/__mising__.crt\",\n                          })\n        self.assertRaises(ValueError, 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_certificate\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\nclass RawRequestHTTPConnection(simple_httpclient._HTTPConnection):\n    def set_request(self, request):\n        self.__next_request = request\n\n    def _on_connect(self):\n        self.stream.write(self.__next_request)\n        self.__next_request = None\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self._on_headers)\n\n# This test is also called from wsgi_test\n\n\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):\n        client = SimpleAsyncHTTPClient(self.io_loop)\n        conn = RawRequestHTTPConnection(\n            self.io_loop, client,\n            httpclient._RequestProxy(\n                httpclient.HTTPRequest(self.get_url(\"/\")),\n                dict(httpclient.HTTPRequest._DEFAULTS)),\n            None, self.stop,\n            1024 * 1024, Resolver(io_loop=self.io_loop))\n        conn.set_request(\n            b\"\\r\\n\".join(headers +\n                         [utf8(\"Content-Length: %d\\r\\n\" % len(body))]) +\n            b\"\\r\\n\" + body)\n        response = self.wait()\n        client.close()\n        response.rethrow()\n        return response\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.body)\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_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(), io_loop=self.io_loop)\n        stream.connect((\"localhost\", 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\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_type)\n\n    def post(self):\n        self.check_type('body', self.request.body, bytes_type)\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\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(('localhost', 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(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.01),\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.01),\n                                     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)\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_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\n    def tearDown(self):\n        shutil.rmtree(self.tmpdir)\n        super(UnixSocketTest, self).tearDown()\n\n    def test_unix_socket(self):\n        sockfile = os.path.join(self.tmpdir, \"test.sock\")\n        sock = netutil.bind_unix_socket(sockfile)\n        app = Application([(\"/hello\", HelloWorldRequestHandler)])\n        server = HTTPServer(app, io_loop=self.io_loop)\n        server.add_socket(sock)\n        stream = IOStream(socket.socket(socket.AF_UNIX), io_loop=self.io_loop)\n        stream.connect(sockfile, self.stop)\n        self.wait()\n        stream.write(b\"GET /hello HTTP/1.0\\r\\n\\r\\n\")\n        stream.read_until(b\"\\r\\n\", self.stop)\n        response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.0 200 OK\\r\\n\")\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        headers = HTTPHeaders.parse(self.wait().decode('latin1'))\n        stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Hello world\")\n        stream.close()\n        server.stop()\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        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(), io_loop=self.io_loop)\n        self.stream.connect(('localhost', 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(self.http_version + b' 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        headers = self.read_headers()\n        self.stream.read_bytes(int(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.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.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.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\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",
            "header": {
                "file": {
                    "path": "tornado/test/httpserver_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "ba23a15b",
                "new_commit_hash": "6f53c3af",
                "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": 397,
                            "length": 16
                        },
                        "new_range": {
                            "start": 397,
                            "length": 31
                        },
                        "section": "class XHeaderTest(HandlerBaseTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            self.fetch_json(\"/\", headers=valid_ipv4)[\"remote_ip\"],",
                                "type": "context"
                            },
                            {
                                "content": "            \"4.4.4.4\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        valid_ipv4_list = {\"X-Forwarded-For\": \"127.0.0.1, 4.4.4.4\"}",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "added"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=valid_ipv4_list)[\"remote_ip\"],",
                                "type": "added"
                            },
                            {
                                "content": "            \"4.4.4.4\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        valid_ipv6 = {\"X-Real-IP\": \"2620:0:1cfe:face:b00c::3\"}",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "context"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=valid_ipv6)[\"remote_ip\"],",
                                "type": "context"
                            },
                            {
                                "content": "            \"2620:0:1cfe:face:b00c::3\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        valid_ipv6_list = {\"X-Forwarded-For\": \"::1, 2620:0:1cfe:face:b00c::3\"}",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "added"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=valid_ipv6_list)[\"remote_ip\"],",
                                "type": "added"
                            },
                            {
                                "content": "            \"2620:0:1cfe:face:b00c::3\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        invalid_chars = {\"X-Real-IP\": \"4.4.4.4<script>\"}",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "context"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=invalid_chars)[\"remote_ip\"],",
                                "type": "context"
                            },
                            {
                                "content": "            \"127.0.0.1\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        invalid_chars_list = {\"X-Forwarded-For\": \"4.4.4.4, 5.5.5.5<script>\"}",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "added"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=invalid_chars_list)[\"remote_ip\"],",
                                "type": "added"
                            },
                            {
                                "content": "            \"127.0.0.1\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        invalid_host = {\"X-Real-IP\": \"www.google.com\"}",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(",
                                "type": "context"
                            },
                            {
                                "content": "            self.fetch_json(\"/\", headers=invalid_host)[\"remote_ip\"],",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "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)\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_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\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 383,
                            "end_lineno": 446,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/httpserver_test.py",
                            "type": "method",
                            "name": "XHeaderTest.test_ip_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)\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_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\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 392,
                            "end_lineno": 428,
                            "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)\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_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\")",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 383,
                                "end_lineno": 446,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "e23cbd4769b8a6e37abe80f849275559399c3aeb^",
    "new_commit_hash": "e23cbd4769b8a6e37abe80f849275559399c3aeb",
    "commit_message": "support ip lists in X-Forwarded-For headers",
    "commit_date": "2013-04-18T14:20:37-04:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "e23cbd4769b8a6e37abe80f849275559399c3aeb",
    "test_file_codes": [
        "#!/usr/bin/env python\n\n\nfrom __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import httpclient, simple_httpclient, netutil\nfrom tornado.escape import json_decode, utf8, _unicode, recursive_unicode, native_str\nfrom tornado.httpserver import HTTPServer\nfrom tornado.httputil import HTTPHeaders\nfrom tornado.iostream import IOStream\nfrom tornado.log import gen_log\nfrom tornado.netutil import ssl_options_to_context, Resolver\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog\nfrom tornado.test.util import unittest\nfrom tornado.util import u, bytes_type\nfrom tornado.web import Application, RequestHandler, asynchronous\nimport datetime\nimport os\nimport shutil\nimport socket\nimport ssl\nimport sys\nimport tempfile\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(),\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            self.http_client.fetch(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# 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\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\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\n        self.assertRaises(ValueError, HTTPServer, application, ssl_options={\n                          \"certfile\": \"/__mising__.crt\",\n                          })\n        self.assertRaises(ValueError, 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_certificate\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\nclass RawRequestHTTPConnection(simple_httpclient._HTTPConnection):\n    def set_request(self, request):\n        self.__next_request = request\n\n    def _on_connect(self):\n        self.stream.write(self.__next_request)\n        self.__next_request = None\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self._on_headers)\n\n# This test is also called from wsgi_test\n\n\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):\n        client = SimpleAsyncHTTPClient(self.io_loop)\n        conn = RawRequestHTTPConnection(\n            self.io_loop, client,\n            httpclient._RequestProxy(\n                httpclient.HTTPRequest(self.get_url(\"/\")),\n                dict(httpclient.HTTPRequest._DEFAULTS)),\n            None, self.stop,\n            1024 * 1024, Resolver(io_loop=self.io_loop))\n        conn.set_request(\n            b\"\\r\\n\".join(headers +\n                         [utf8(\"Content-Length: %d\\r\\n\" % len(body))]) +\n            b\"\\r\\n\" + body)\n        response = self.wait()\n        client.close()\n        response.rethrow()\n        return response\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.body)\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_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(), io_loop=self.io_loop)\n        stream.connect((\"localhost\", 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\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_type)\n\n    def post(self):\n        self.check_type('body', self.request.body, bytes_type)\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\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(('localhost', 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(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.01),\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.01),\n                                     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)\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_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\n    def tearDown(self):\n        shutil.rmtree(self.tmpdir)\n        super(UnixSocketTest, self).tearDown()\n\n    def test_unix_socket(self):\n        sockfile = os.path.join(self.tmpdir, \"test.sock\")\n        sock = netutil.bind_unix_socket(sockfile)\n        app = Application([(\"/hello\", HelloWorldRequestHandler)])\n        server = HTTPServer(app, io_loop=self.io_loop)\n        server.add_socket(sock)\n        stream = IOStream(socket.socket(socket.AF_UNIX), io_loop=self.io_loop)\n        stream.connect(sockfile, self.stop)\n        self.wait()\n        stream.write(b\"GET /hello HTTP/1.0\\r\\n\\r\\n\")\n        stream.read_until(b\"\\r\\n\", self.stop)\n        response = self.wait()\n        self.assertEqual(response, b\"HTTP/1.0 200 OK\\r\\n\")\n        stream.read_until(b\"\\r\\n\\r\\n\", self.stop)\n        headers = HTTPHeaders.parse(self.wait().decode('latin1'))\n        stream.read_bytes(int(headers[\"Content-Length\"]), self.stop)\n        body = self.wait()\n        self.assertEqual(body, b\"Hello world\")\n        stream.close()\n        server.stop()\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        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(), io_loop=self.io_loop)\n        self.stream.connect(('localhost', 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(self.http_version + b' 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        headers = self.read_headers()\n        self.stream.read_bytes(int(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.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.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.stream.write(b'GET / HTTP/1.0\\r\\nConnection: keep-alive\\r\\n\\r\\n')\n        self.read_response()\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",
        "#!/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 801ms\nPrepared 1 package in 585ms\nInstalled 1 package in 0.72ms\n + tornado==3.1.dev2 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb)\nResolved 29 packages in 13ms\nInstalled 29 packages in 25ms\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_e23cbd4769b8a6e37abe80f849275559399c3aeb\n.....................................\ncollected 37 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 150, in test_missing_key\n    HTTPServer(application, ssl_options={\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/httpserver.py\", line 152, in __init__\n    TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 98, in __init__\n    raise ValueError('certfile \"%s\" does not exist' %\nValueError: certfile \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test.crt\" does not exist\n__________ HTTPServerRawTest.test_malformed_first_line __________\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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 373, in test_malformed_first_line\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 466, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 380, in test_malformed_headers\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 466, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\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_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 271, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 279, in get_http_server\n    **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 339, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 121, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 271, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 279, in get_http_server\n    **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 339, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 121, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 271, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 279, in get_http_server\n    **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 339, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 121, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 459, in test_request_without_xprotocol\n    self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 31, in fetch_json\n    response = self.fetch(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 78, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 92, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 74, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 78, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 92, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 74, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 78, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 92, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 74, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BadSSLOptionsTest::test_missing_arguments\nERROR r2e_tests.test_1::BadSSLOptionsTest::test_missing_key\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_100_continue\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_multipart_form\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_empty_request\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_first_line\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_query_string_encoding\nPASSED r2e_tests.test_1::HTTPServerTest::test_types\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_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::ManualProtocolTest::test_manual_protocol\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_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_large_post\nERROR r2e_tests.test_1::SSLv3Test::test_non_ssl_request\nERROR r2e_tests.test_1::SSLv3Test::test_ssl\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\nPASSED r2e_tests.test_1::XHeaderTest::test_ip_headers\nPASSED r2e_tests.test_1::XHeaderTest::test_scheme_headers\n=================== 16 errors, 21 passed in 0.34s ===================\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_e23cbd4769b8a6e37abe80f849275559399c3aeb\n.....................................\ncollected 37 items\n\n=================================== FAILURES ===================================\n__________ XHeaderTest.test_ip_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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 401, in test_ip_headers\n    self.assertEqual(\nAssertionError: '127.0.0.1' != '4.4.4.4'\n- 127.0.0.1\n+ 4.4.4.4\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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 150, in test_missing_key\n    HTTPServer(application, ssl_options={\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/httpserver.py\", line 152, in __init__\n    TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 98, in __init__\n    raise ValueError('certfile \"%s\" does not exist' %\nValueError: certfile \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test.crt\" does not exist\n__________ HTTPServerRawTest.test_malformed_first_line __________\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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 373, in test_malformed_first_line\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 466, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 380, in test_malformed_headers\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 466, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\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_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 271, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 279, in get_http_server\n    **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 339, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 121, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 271, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 279, in get_http_server\n    **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 339, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 121, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 271, in setUp\n    self.http_server = self.get_http_server()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 279, in get_http_server\n    **self.get_httpserver_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 339, in get_httpserver_options\n    return dict(ssl_options=self.get_ssl_options())\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 121, in get_ssl_options\n    context = ssl_options_to_context(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 459, in test_request_without_xprotocol\n    self.assertEqual(self.fetch_json(\"/\")[\"remote_protocol\"], \"https\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 31, in fetch_json\n    response = self.fetch(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 78, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 92, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 74, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 78, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 92, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 74, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 78, in test_large_post\n    response = self.fetch('/',\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 92, in test_non_ssl_request\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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_e23cbd4769b8a6e37abe80f849275559399c3aeb/r2e_tests/test_1.py\", line 74, in test_ssl\n    response = self.fetch('/')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 296, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 235, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/testing.py\", line 180, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/stack_context.py\", line 252, in wrapped\n    fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 311, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e23cbd4769b8a6e37abe80f849275559399c3aeb/tornado/netutil.py\", line 292, 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\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BadSSLOptionsTest::test_missing_arguments\nERROR r2e_tests.test_1::BadSSLOptionsTest::test_missing_key\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_100_continue\nPASSED r2e_tests.test_1::HTTPConnectionTest::test_multipart_form\nPASSED r2e_tests.test_1::HTTPServerRawTest::test_empty_request\nERROR r2e_tests.test_1::HTTPServerRawTest::test_malformed_first_line\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_query_string_encoding\nPASSED r2e_tests.test_1::HTTPServerTest::test_types\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_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::ManualProtocolTest::test_manual_protocol\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_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_large_post\nERROR r2e_tests.test_1::SSLv3Test::test_non_ssl_request\nERROR r2e_tests.test_1::SSLv3Test::test_ssl\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\nFAILED r2e_tests.test_1::XHeaderTest::test_ip_headers\nPASSED r2e_tests.test_1::XHeaderTest::test_scheme_headers\n=================== 1 failed, 16 errors, 20 passed in 0.34s ===================\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 `remote_ip` Extraction with Multiple IPs in `X-Forwarded-For` Header

**Description:**
When a client sends an `X-Forwarded-For` header containing a list of IP addresses, the server fails to correctly extract the intended `remote_ip`. Instead of retrieving the last IP in the list, it incorrectly assigns the first IP or an unintended value.

**Example Buggy Code:**
```python
headers = {"X-Forwarded-For": "127.0.0.1, 4.4.4.4"}
response = fetch_json("/", headers=headers)
print(response["remote_ip"])  # Outputs: '127.0.0.1' instead of '4.4.4.4'
```

**Expected Behavior:**
The server should parse the `X-Forwarded-For` header and set `remote_ip` to the last IP address in the list (`"4.4.4.4"` in this case).

**Actual Behavior:**
The server incorrectly sets `remote_ip` to the first IP address in the `X-Forwarded-For` header (`"127.0.0.1"`), ignoring the subsequent IPs.

[/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`).

This module also defines the `HTTPRequest` class which is exposed via
`tornado.web.RequestHandler.request`.
"""

from __future__ import absolute_import, division, print_function, with_statement

import socket
import ssl
import time

from tornado.escape import native_str, parse_qs_bytes
from tornado import httputil
from tornado import iostream
from tornado.log import gen_log
from tornado import netutil
from tornado.tcpserver import TCPServer
from tornado import stack_context
from tornado.util import bytes_type

try:
    import Cookie  # py2
except ImportError:
    import http.cookies as Cookie  # py3


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

    A server is defined by a request callback that takes an HTTPRequest
    instance as an argument and writes a valid HTTP response with
    `HTTPRequest.write`. `HTTPRequest.finish` finishes the request (but does
    not necessarily close the connection in the case of HTTP/1.1 keep-alive
    requests). A simple example server that echoes back the URI you
    requested::

        import tornado.httpserver
        import tornado.ioloop

        def handle_request(request):
           message = "You requested %s\n" % request.uri
           request.write("HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s" % (
                         len(message), message))
           request.finish()

        http_server = tornado.httpserver.HTTPServer(handle_request)
        http_server.listen(8888)
        tornado.ioloop.IOLoop.instance().start()

    `HTTPServer` is a very basic connection handler.  It parses the request
    headers and body, but the request callback is responsible for producing
    the response exactly as it will appear on the wire.  This affords
    maximum flexibility for applications to implement whatever parts
    of HTTP responses are required.

    `HTTPServer` supports keep-alive connections by default
    (automatically for HTTP/1.1, or for HTTP/1.0 when the client
    requests ``Connection: keep-alive``).  This means that the request
    callback must generate a properly-framed response, using either
    the ``Content-Length`` header or ``Transfer-Encoding: chunked``.
    Applications that are unable to frame their responses properly
    should instead return a ``Connection: close`` header in each
    response and pass ``no_keep_alive=True`` to the `HTTPServer`
    constructor.

    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``.

    To make this server serve SSL traffic, send the ``ssl_options`` dictionary
    argument with the arguments required for the `ssl.wrap_socket` method,
    including ``certfile`` and ``keyfile``.  (In Python 3.2+ you can pass
    an `ssl.SSLContext` object instead of a dict)::

       HTTPServer(applicaton, ssl_options={
           "certfile": os.path.join(data_dir, "mydomain.crt"),
           "keyfile": os.path.join(data_dir, "mydomain.key"),
       })

    `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.instance().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.instance().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.instance().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`.

    """
    def __init__(self, request_callback, no_keep_alive=False, io_loop=None,
                 xheaders=False, ssl_options=None, protocol=None, **kwargs):
        self.request_callback = request_callback
        self.no_keep_alive = no_keep_alive
        self.xheaders = xheaders
        self.protocol = protocol
        TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,
                           **kwargs)

    def handle_stream(self, stream, address):
        HTTPConnection(stream, address, self.request_callback,
                       self.no_keep_alive, self.xheaders, self.protocol)


class _BadRequestException(Exception):
    """Exception class for malformed HTTP requests."""
    pass


class HTTPConnection(object):
    """Handles a connection to an HTTP client, executing HTTP requests.

    We parse HTTP headers and bodies, and execute the request callback
    until the HTTP conection is closed.
    """
    def __init__(self, stream, address, request_callback, no_keep_alive=False,
                 xheaders=False, protocol=None):
        self.stream = stream
        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.
        self.address_family = stream.socket.family
        self.request_callback = request_callback
        self.no_keep_alive = no_keep_alive
        self.xheaders = xheaders
        self.protocol = protocol
        self._request = None
        self._request_finished = False
        self._write_callback = None
        self._close_callback = None
        # Save stack context here, outside of any request.  This keeps
        # contexts from one request from leaking into the next.
        self._header_callback = stack_context.wrap(self._on_headers)
        self.stream.read_until(b"\r\n\r\n", self._header_callback)

    def _clear_callbacks(self):
        """Clears the per-request callbacks.

        This is run in between requests to allow the previous handler
        to be garbage collected (and prevent spurious close callbacks),
        and when the connection is closed (to break up cycles and
        facilitate garbage collection in cpython).
        """
        self._write_callback = None
        self._close_callback = None

    def set_close_callback(self, callback):
        """Sets a callback that will be run when the connection is closed.

        Use this instead of accessing
        `HTTPConnection.stream.set_close_callback
        <.BaseIOStream.set_close_callback>` directly (which was the
        recommended approach prior to Tornado 3.0).
        """
        self._close_callback = stack_context.wrap(callback)
        self.stream.set_close_callback(self._on_connection_close)

    def _on_connection_close(self):
        callback = self._close_callback
        self._close_callback = None
        callback()
        # Delete any unfinished callbacks to break up reference cycles.
        self._header_callback = None
        self._clear_callbacks()

    def close(self):
        self.stream.close()
        # Remove this reference to self, which would otherwise cause a
        # cycle and delay garbage collection of this connection.
        self._header_callback = None
        self._clear_callbacks()

    def write(self, chunk, callback=None):
        """Writes a chunk of output to the stream."""
        assert self._request, "Request closed"
        if not self.stream.closed():
            self._write_callback = stack_context.wrap(callback)
            self.stream.write(chunk, self._on_write_complete)

    def finish(self):
        """Finishes the request."""
        assert self._request, "Request closed"
        self._request_finished = True
        if not self.stream.writing():
            self._finish_request()

    def _on_write_complete(self):
        if self._write_callback is not None:
            callback = self._write_callback
            self._write_callback = None
            callback()
        # _on_write_complete is enqueued on the IOLoop whenever the
        # IOStream's write buffer becomes empty, but it's possible for
        # another callback that runs on the IOLoop before it to
        # simultaneously write more data and finish the request.  If
        # there is still data in the IOStream, a future
        # _on_write_complete will be responsible for calling
        # _finish_request.
        if self._request_finished and not self.stream.writing():
            self._finish_request()

    def _finish_request(self):
        if self.no_keep_alive:
            disconnect = True
        else:
            connection_header = self._request.headers.get("Connection")
            if connection_header is not None:
                connection_header = connection_header.lower()
            if self._request.supports_http_1_1():
                disconnect = connection_header == "close"
            elif ("Content-Length" in self._request.headers
                    or self._request.method in ("HEAD", "GET")):
                disconnect = connection_header != "keep-alive"
            else:
                disconnect = True
        self._request = None
        self._request_finished = False
        self._clear_callbacks()
        if disconnect:
            self.close()
            return
        try:
            # Use a try/except instead of checking stream.closed()
            # directly, because in some cases the stream doesn't discover
            # that it's closed until you try to read from it.
            self.stream.read_until(b"\r\n\r\n", self._header_callback)
        except iostream.StreamClosedError:
            self.close()

    def _on_headers(self, data):
        try:
            data = native_str(data.decode('latin1'))
            eol = data.find("\r\n")
            start_line = data[:eol]
            try:
                method, uri, version = start_line.split(" ")
            except ValueError:
                raise _BadRequestException("Malformed HTTP request line")
            if not version.startswith("HTTP/"):
                raise _BadRequestException("Malformed HTTP version in HTTP Request-Line")
            try:
                headers = httputil.HTTPHeaders.parse(data[eol:])
            except ValueError:
                # Probably from split() if there was no ':' in the line
                raise _BadRequestException("Malformed HTTP headers")

            # HTTPRequest wants an IP, not a full socket address
            if self.address_family in (socket.AF_INET, socket.AF_INET6):
                remote_ip = self.address[0]
            else:
                # Unix (or other) socket; fake the remote address
                remote_ip = '0.0.0.0'

            self._request = HTTPRequest(
                connection=self, method=method, uri=uri, version=version,
                headers=headers, remote_ip=remote_ip, protocol=self.protocol)

            content_length = headers.get("Content-Length")
            if content_length:
                content_length = int(content_length)
                if content_length > self.stream.max_buffer_size:
                    raise _BadRequestException("Content-Length too long")
                if headers.get("Expect") == "100-continue":
                    self.stream.write(b"HTTP/1.1 100 (Continue)\r\n\r\n")
                self.stream.read_bytes(content_length, self._on_request_body)
                return

            self.request_callback(self._request)
        except _BadRequestException as e:
            gen_log.info("Malformed HTTP request from %s: %s",
                         self.address[0], e)
            self.close()
            return

    def _on_request_body(self, data):
        self._request.body = data
        if self._request.method in ("POST", "PATCH", "PUT"):
            httputil.parse_body_arguments(
                self._request.headers.get("Content-Type", ""), data,
                self._request.arguments, self._request.files)
        self.request_callback(self._request)


class HTTPRequest(object):
    """A single HTTP request.

    All attributes are type `str` unless otherwise noted.

    .. attribute:: method

       HTTP request method, e.g. "GET" or "POST"

    .. attribute:: uri

       The requested uri.

    .. attribute:: path

       The path portion of `uri`

    .. attribute:: query

       The query portion of `uri`

    .. attribute:: version

       HTTP version specified in request, e.g. "HTTP/1.1"

    .. attribute:: headers

       `.HTTPHeaders` dictionary-like object for request headers.  Acts like
       a case-insensitive dictionary with additional methods for repeated
       headers.

    .. attribute:: body

       Request body, if present, as a byte string.

    .. attribute:: remote_ip

       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,
       will pass along the real IP address provided by a load balancer
       in the ``X-Real-Ip`` header

    .. attribute:: protocol

       The protocol used, either "http" or "https".  If ``HTTPServer.xheaders``
       is set, will pass along the protocol used by a load balancer if
       reported via an ``X-Scheme`` header.

    .. attribute:: host

       The requested hostname, usually taken from the ``Host`` header.

    .. attribute:: arguments

       GET/POST arguments are available in the arguments property, which
       maps arguments names to lists of values (to support multiple values
       for individual names). Names are of type `str`, while arguments
       are byte strings.  Note that this is different from
       `.RequestHandler.get_argument`, which returns argument values as
       unicode strings.

    .. attribute:: files

       File uploads are available in the files property, which maps file
       names to lists of `.HTTPFile`.

    .. attribute:: connection

       An HTTP request is attached to a single HTTP connection, which can
       be accessed through the "connection" attribute. Since connections
       are typically kept open in HTTP/1.1, multiple requests can be handled
       sequentially on a single connection.
    """
    def __init__(self, method, uri, version="HTTP/1.0", headers=None,
                 body=None, remote_ip=None, protocol=None, host=None,
                 files=None, connection=None):
        self.method = method
        self.uri = uri
        self.version = version
        self.headers = headers or httputil.HTTPHeaders()
        self.body = body or ""

        # set remote IP and protocol
        self.remote_ip = remote_ip
        if protocol:
            self.protocol = protocol
        elif connection and isinstance(connection.stream,
                                       iostream.SSLIOStream):
            self.protocol = "https"
        else:
            self.protocol = "http"

        # xheaders can override the defaults
        if connection and connection.xheaders:
            # Squid uses X-Forwarded-For, others use X-Real-Ip
            ip = self.headers.get(
                "X-Real-Ip", self.headers.get("X-Forwarded-For", self.remote_ip))
            if netutil.is_valid_ip(ip):
                self.remote_ip = ip
            # AWS uses X-Forwarded-Proto
            proto = self.headers.get(
                "X-Scheme", self.headers.get("X-Forwarded-Proto", self.protocol))
            if proto in ("http", "https"):
                self.protocol = proto


        self.host = host or self.headers.get("Host") or "127.0.0.1"
        self.files = files or {}
        self.connection = connection
        self._start_time = time.time()
        self._finish_time = None

        self.path, sep, self.query = uri.partition('?')
        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)

    def supports_http_1_1(self):
        """Returns True if this request supports HTTP/1.1 semantics"""
        return self.version == "HTTP/1.1"

    @property
    def cookies(self):
        """A dictionary of Cookie.Morsel objects."""
        if not hasattr(self, "_cookies"):
            self._cookies = Cookie.SimpleCookie()
            if "Cookie" in self.headers:
                try:
                    self._cookies.load(
                        native_str(self.headers["Cookie"]))
                except Exception:
                    self._cookies = {}
        return self._cookies

    def write(self, chunk, callback=None):
        """Writes the given chunk to the response stream."""
        assert isinstance(chunk, bytes_type)
        self.connection.write(chunk, callback=callback)

    def finish(self):
        """Finishes this HTTP request on the open connection."""
        self.connection.finish()
        self._finish_time = time.time()

    def full_url(self):
        """Reconstructs the full URL for this request."""
        return self.protocol + "://" + self.host + self.uri

    def request_time(self):
        """Returns the amount of time it took for this request to execute."""
        if self._finish_time is None:
            return time.time() - self._start_time
        else:
            return self._finish_time - self._start_time

    def get_ssl_certificate(self, binary_form=False):
        """Returns the client's SSL certificate, if any.

        To use client certificates, the HTTPServer must have been constructed
        with cert_reqs set in ssl_options, e.g.::

            server = HTTPServer(app,
                ssl_options=dict(
                    certfile="foo.crt",
                    keyfile="foo.key",
                    cert_reqs=ssl.CERT_REQUIRED,
                    ca_certs="cacert.crt"))

        By default, the return value is a dictionary (or None, if no
        client certificate is present).  If ``binary_form`` is true, a
        DER-encoded form of the certificate is returned instead.  See
        SSLSocket.getpeercert() in the standard library for more
        details.
        http://docs.python.org/library/ssl.html#sslsocket-objects
        """
        try:
            return self.connection.stream.socket.getpeercert(
                binary_form=binary_form)
        except ssl.SSLError:
            return None

    def __repr__(self):
        attrs = ("protocol", "host", "method", "uri", "version", "remote_ip",
                 "body")
        args = ", ".join(["%s=%r" % (n, getattr(self, n)) for n in attrs])
        return "%s(%s, headers=%s)" % (
            self.__class__.__name__, args, dict(self.headers))

```
--- 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 `remote_ip` Extraction with Multiple IPs in `X-Forwarded-For` Header

**Description:**
When a client sends an `X-Forwarded-For` header containing a list of IP addresses, the server fails to correctly extract the intended `remote_ip`. Instead of retrieving the last IP in the list, it incorrectly assigns the first IP or an unintended value.

**Example Buggy Code:**
```python
headers = {"X-Forwarded-For": "127.0.0.1, 4.4.4.4"}
response = fetch_json("/", headers=headers)
print(response["remote_ip"])  # Outputs: '127.0.0.1' instead of '4.4.4.4'
```

**Expected Behavior:**
The server should parse the `X-Forwarded-For` header and set `remote_ip` to the last IP address in the list (`"4.4.4.4"` in this case).

**Actual Behavior:**
The server incorrectly sets `remote_ip` to the first IP address in the `X-Forwarded-For` header (`"127.0.0.1"`), ignoring the subsequent IPs.

[/ISSUE]
{
    "BadSSLOptionsTest.test_missing_arguments": "PASSED",
    "BadSSLOptionsTest.test_missing_key": "ERROR",
    "HTTPConnectionTest.test_100_continue": "PASSED",
    "HTTPConnectionTest.test_multipart_form": "PASSED",
    "HTTPServerRawTest.test_empty_request": "PASSED",
    "HTTPServerRawTest.test_malformed_first_line": "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_query_string_encoding": "PASSED",
    "HTTPServerTest.test_types": "PASSED",
    "KeepAliveTest.test_cancel_during_download": "PASSED",
    "KeepAliveTest.test_finish_while_closed": "PASSED",
    "KeepAliveTest.test_http10": "PASSED",
    "KeepAliveTest.test_http10_keepalive": "PASSED",
    "KeepAliveTest.test_pipelined_cancel": "PASSED",
    "KeepAliveTest.test_pipelined_requests": "PASSED",
    "KeepAliveTest.test_request_close": "PASSED",
    "KeepAliveTest.test_two_requests": "PASSED",
    "ManualProtocolTest.test_manual_protocol": "PASSED",
    "SSLContextTest.test_large_post": "ERROR",
    "SSLContextTest.test_non_ssl_request": "ERROR",
    "SSLContextTest.test_ssl": "ERROR",
    "SSLXHeaderTest.test_request_without_xprotocol": "ERROR",
    "SSLv23Test.test_large_post": "ERROR",
    "SSLv23Test.test_non_ssl_request": "ERROR",
    "SSLv23Test.test_ssl": "ERROR",
    "SSLv3Test.test_large_post": "ERROR",
    "SSLv3Test.test_non_ssl_request": "ERROR",
    "SSLv3Test.test_ssl": "ERROR",
    "TLSv1Test.test_large_post": "ERROR",
    "TLSv1Test.test_non_ssl_request": "ERROR",
    "TLSv1Test.test_ssl": "ERROR",
    "UnixSocketTest.test_unix_socket": "PASSED",
    "XHeaderTest.test_ip_headers": "PASSED",
    "XHeaderTest.test_scheme_headers": "PASSED"
}
diff --git a/tornado/httpserver.py b/tornado/httpserver.py
index 16472fa4..f597737a 100644
--- a/tornado/httpserver.py
+++ b/tornado/httpserver.py
@@ -431,8 +431,10 @@ class HTTPRequest(object):
         # xheaders can override the defaults
         if connection and connection.xheaders:
             # Squid uses X-Forwarded-For, others use X-Real-Ip
+            ip = self.headers.get("X-Forwarded-For", self.remote_ip)
+            ip = ip.split(',')[-1].strip()
             ip = self.headers.get(
-                "X-Real-Ip", self.headers.get("X-Forwarded-For", self.remote_ip))
+                "X-Real-Ip", ip)
             if netutil.is_valid_ip(ip):
                 self.remote_ip = ip
             # AWS uses X-Forwarded-Proto

{"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\nThis module also defines the `HTTPRequest` class which is exposed via\n`tornado.web.RequestHandler.request`.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport socket\nimport ssl\nimport time\n\nfrom tornado.escape import native_str, parse_qs_bytes\nfrom tornado import httputil\nfrom tornado import iostream\nfrom tornado.log import gen_log\nfrom tornado import netutil\nfrom tornado.tcpserver import TCPServer\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    import Cookie  # py2\nexcept ImportError:\n    import http.cookies as Cookie  # py3\n\n\nclass HTTPServer(TCPServer):\n    r\"\"\"A non-blocking, single-threaded HTTP server.\n\n    A server is defined by a request callback that takes an HTTPRequest\n    instance as an argument and writes a valid HTTP response with\n    `HTTPRequest.write`. `HTTPRequest.finish` finishes the request (but does\n    not necessarily close the connection in the case of HTTP/1.1 keep-alive\n    requests). A simple example server that echoes back the URI you\n    requested::\n\n        import tornado.httpserver\n        import tornado.ioloop\n\n        def handle_request(request):\n           message = \"You requested %s\\n\" % request.uri\n           request.write(\"HTTP/1.1 200 OK\\r\\nContent-Length: %d\\r\\n\\r\\n%s\" % (\n                         len(message), message))\n           request.finish()\n\n        http_server = tornado.httpserver.HTTPServer(handle_request)\n        http_server.listen(8888)\n        tornado.ioloop.IOLoop.instance().start()\n\n    `HTTPServer` is a very basic connection handler.  It parses the request\n    headers and body, but the request callback is responsible for producing\n    the response exactly as it will appear on the wire.  This affords\n    maximum flexibility for applications to implement whatever parts\n    of HTTP responses are required.\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``).  This means that the request\n    callback must generate a properly-framed response, using either\n    the ``Content-Length`` header or ``Transfer-Encoding: chunked``.\n    Applications that are unable to frame their responses properly\n    should instead return a ``Connection: close`` header in each\n    response and pass ``no_keep_alive=True`` to the `HTTPServer`\n    constructor.\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    To make this server serve SSL traffic, send the ``ssl_options`` dictionary\n    argument with the arguments required for the `ssl.wrap_socket` method,\n    including ``certfile`` and ``keyfile``.  (In Python 3.2+ you can pass\n    an `ssl.SSLContext` object instead of a dict)::\n\n       HTTPServer(applicaton, ssl_options={\n           \"certfile\": os.path.join(data_dir, \"mydomain.crt\"),\n           \"keyfile\": os.path.join(data_dir, \"mydomain.key\"),\n       })\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.instance().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.instance().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.instance().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    \"\"\"\n    def __init__(self, request_callback, no_keep_alive=False, io_loop=None,\n                 xheaders=False, ssl_options=None, protocol=None, **kwargs):\n        self.request_callback = request_callback\n        self.no_keep_alive = no_keep_alive\n        self.xheaders = xheaders\n        self.protocol = protocol\n        TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,\n                           **kwargs)\n\n    def handle_stream(self, stream, address):\n        HTTPConnection(stream, address, self.request_callback,\n                       self.no_keep_alive, self.xheaders, self.protocol)\n\n\nclass _BadRequestException(Exception):\n    \"\"\"Exception class for malformed HTTP requests.\"\"\"\n    pass\n\n\nclass HTTPConnection(object):\n    \"\"\"Handles a connection to an HTTP client, executing HTTP requests.\n\n    We parse HTTP headers and bodies, and execute the request callback\n    until the HTTP conection is closed.\n    \"\"\"\n    def __init__(self, stream, address, request_callback, no_keep_alive=False,\n                 xheaders=False, protocol=None):\n        self.stream = stream\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        self.address_family = stream.socket.family\n        self.request_callback = request_callback\n        self.no_keep_alive = no_keep_alive\n        self.xheaders = xheaders\n        self.protocol = protocol\n        self._request = None\n        self._request_finished = False\n        self._write_callback = None\n        self._close_callback = None\n        # Save stack context here, outside of any request.  This keeps\n        # contexts from one request from leaking into the next.\n        self._header_callback = stack_context.wrap(self._on_headers)\n        self.stream.read_until(b\"\\r\\n\\r\\n\", self._header_callback)\n\n    def _clear_callbacks(self):\n        \"\"\"Clears the per-request callbacks.\n\n        This is run in between requests to allow the previous handler\n        to be garbage collected (and prevent spurious close callbacks),\n        and when the connection is closed (to break up cycles and\n        facilitate garbage collection in cpython).\n        \"\"\"\n        self._write_callback = None\n        self._close_callback = None\n\n    def set_close_callback(self, callback):\n        \"\"\"Sets a callback that will be run when the connection is closed.\n\n        Use this instead of accessing\n        `HTTPConnection.stream.set_close_callback\n        <.BaseIOStream.set_close_callback>` directly (which was the\n        recommended approach prior to Tornado 3.0).\n        \"\"\"\n        self._close_callback = stack_context.wrap(callback)\n        self.stream.set_close_callback(self._on_connection_close)\n\n    def _on_connection_close(self):\n        callback = self._close_callback\n        self._close_callback = None\n        callback()\n        # Delete any unfinished callbacks to break up reference cycles.\n        self._header_callback = None\n        self._clear_callbacks()\n\n    def close(self):\n        self.stream.close()\n        # Remove this reference to self, which would otherwise cause a\n        # cycle and delay garbage collection of this connection.\n        self._header_callback = None\n        self._clear_callbacks()\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes a chunk of output to the stream.\"\"\"\n        assert self._request, \"Request closed\"\n        if not self.stream.closed():\n            self._write_callback = stack_context.wrap(callback)\n            self.stream.write(chunk, self._on_write_complete)\n\n    def finish(self):\n        \"\"\"Finishes the request.\"\"\"\n        assert self._request, \"Request closed\"\n        self._request_finished = True\n        if not self.stream.writing():\n            self._finish_request()\n\n    def _on_write_complete(self):\n        if self._write_callback is not None:\n            callback = self._write_callback\n            self._write_callback = None\n            callback()\n        # _on_write_complete is enqueued on the IOLoop whenever the\n        # IOStream's write buffer becomes empty, but it's possible for\n        # another callback that runs on the IOLoop before it to\n        # simultaneously write more data and finish the request.  If\n        # there is still data in the IOStream, a future\n        # _on_write_complete will be responsible for calling\n        # _finish_request.\n        if self._request_finished and not self.stream.writing():\n            self._finish_request()\n\n    def _finish_request(self):\n        if self.no_keep_alive:\n            disconnect = True\n        else:\n            connection_header = self._request.headers.get(\"Connection\")\n            if connection_header is not None:\n                connection_header = connection_header.lower()\n            if self._request.supports_http_1_1():\n                disconnect = connection_header == \"close\"\n            elif (\"Content-Length\" in self._request.headers\n                    or self._request.method in (\"HEAD\", \"GET\")):\n                disconnect = connection_header != \"keep-alive\"\n            else:\n                disconnect = True\n        self._request = None\n        self._request_finished = False\n        self._clear_callbacks()\n        if disconnect:\n            self.close()\n            return\n        try:\n            # Use a try/except instead of checking stream.closed()\n            # directly, because in some cases the stream doesn't discover\n            # that it's closed until you try to read from it.\n            self.stream.read_until(b\"\\r\\n\\r\\n\", self._header_callback)\n        except iostream.StreamClosedError:\n            self.close()\n\n    def _on_headers(self, data):\n        try:\n            data = native_str(data.decode('latin1'))\n            eol = data.find(\"\\r\\n\")\n            start_line = data[:eol]\n            try:\n                method, uri, version = start_line.split(\" \")\n            except ValueError:\n                raise _BadRequestException(\"Malformed HTTP request line\")\n            if not version.startswith(\"HTTP/\"):\n                raise _BadRequestException(\"Malformed HTTP version in HTTP Request-Line\")\n            try:\n                headers = httputil.HTTPHeaders.parse(data[eol:])\n            except ValueError:\n                # Probably from split() if there was no ':' in the line\n                raise _BadRequestException(\"Malformed HTTP headers\")\n\n            # HTTPRequest wants an IP, not a full socket address\n            if self.address_family in (socket.AF_INET, socket.AF_INET6):\n                remote_ip = self.address[0]\n            else:\n                # Unix (or other) socket; fake the remote address\n                remote_ip = '0.0.0.0'\n\n            self._request = HTTPRequest(\n                connection=self, method=method, uri=uri, version=version,\n                headers=headers, remote_ip=remote_ip, protocol=self.protocol)\n\n            content_length = headers.get(\"Content-Length\")\n            if content_length:\n                content_length = int(content_length)\n                if content_length > self.stream.max_buffer_size:\n                    raise _BadRequestException(\"Content-Length too long\")\n                if headers.get(\"Expect\") == \"100-continue\":\n                    self.stream.write(b\"HTTP/1.1 100 (Continue)\\r\\n\\r\\n\")\n                self.stream.read_bytes(content_length, self._on_request_body)\n                return\n\n            self.request_callback(self._request)\n        except _BadRequestException as e:\n            gen_log.info(\"Malformed HTTP request from %s: %s\",\n                         self.address[0], e)\n            self.close()\n            return\n\n    def _on_request_body(self, data):\n        self._request.body = data\n        if self._request.method in (\"POST\", \"PATCH\", \"PUT\"):\n            httputil.parse_body_arguments(\n                self._request.headers.get(\"Content-Type\", \"\"), data,\n                self._request.arguments, self._request.files)\n        self.request_callback(self._request)\n\n\nclass HTTPRequest(object):\n    \"\"\"A single HTTP request.\n\n    All attributes are type `str` unless otherwise noted.\n\n    .. attribute:: method\n\n       HTTP request method, e.g. \"GET\" or \"POST\"\n\n    .. attribute:: uri\n\n       The requested uri.\n\n    .. attribute:: path\n\n       The path portion of `uri`\n\n    .. attribute:: query\n\n       The query portion of `uri`\n\n    .. attribute:: version\n\n       HTTP version specified in request, e.g. \"HTTP/1.1\"\n\n    .. attribute:: headers\n\n       `.HTTPHeaders` dictionary-like object for request headers.  Acts like\n       a case-insensitive dictionary with additional methods for repeated\n       headers.\n\n    .. attribute:: body\n\n       Request body, if present, as a byte string.\n\n    .. attribute:: remote_ip\n\n       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,\n       will pass along the real IP address provided by a load balancer\n       in the ``X-Real-Ip`` header\n\n    .. attribute:: protocol\n\n       The protocol used, either \"http\" or \"https\".  If ``HTTPServer.xheaders``\n       is set, will pass along the protocol used by a load balancer if\n       reported via an ``X-Scheme`` header.\n\n    .. attribute:: host\n\n       The requested hostname, usually taken from the ``Host`` header.\n\n    .. attribute:: arguments\n\n       GET/POST arguments are available in the arguments property, which\n       maps arguments names to lists of values (to support multiple values\n       for individual names). Names are of type `str`, while arguments\n       are byte strings.  Note that this is different from\n       `.RequestHandler.get_argument`, which returns argument values as\n       unicode strings.\n\n    .. attribute:: files\n\n       File uploads are available in the files property, which maps file\n       names to lists of `.HTTPFile`.\n\n    .. attribute:: connection\n\n       An HTTP request is attached to a single HTTP connection, which can\n       be accessed through the \"connection\" attribute. Since connections\n       are typically kept open in HTTP/1.1, multiple requests can be handled\n       sequentially on a single connection.\n    \"\"\"\n    def __init__(self, method, uri, version=\"HTTP/1.0\", headers=None,\n                 body=None, remote_ip=None, protocol=None, host=None,\n                 files=None, connection=None):\n        self.method = method\n        self.uri = uri\n        self.version = version\n        self.headers = headers or httputil.HTTPHeaders()\n        self.body = body or \"\"\n\n        # set remote IP and protocol\n        self.remote_ip = remote_ip\n        if protocol:\n            self.protocol = protocol\n        elif connection and isinstance(connection.stream,\n                                       iostream.SSLIOStream):\n            self.protocol = \"https\"\n        else:\n            self.protocol = \"http\"\n\n        # xheaders can override the defaults\n        if connection and connection.xheaders:\n            # Squid uses X-Forwarded-For, others use X-Real-Ip\n            ip = self.headers.get(\n                \"X-Real-Ip\", self.headers.get(\"X-Forwarded-For\", self.remote_ip))\n            if netutil.is_valid_ip(ip):\n                self.remote_ip = ip\n            # AWS uses X-Forwarded-Proto\n            proto = self.headers.get(\n                \"X-Scheme\", self.headers.get(\"X-Forwarded-Proto\", self.protocol))\n            if proto in (\"http\", \"https\"):\n                self.protocol = proto\n\n\n        self.host = host or self.headers.get(\"Host\") or \"127.0.0.1\"\n        self.files = files or {}\n        self.connection = connection\n        self._start_time = time.time()\n        self._finish_time = None\n\n        self.path, sep, self.query = uri.partition('?')\n        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)\n\n    def supports_http_1_1(self):\n        \"\"\"Returns True if this request supports HTTP/1.1 semantics\"\"\"\n        return self.version == \"HTTP/1.1\"\n\n    @property\n    def cookies(self):\n        \"\"\"A dictionary of Cookie.Morsel objects.\"\"\"\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookie.SimpleCookie()\n            if \"Cookie\" in self.headers:\n                try:\n                    self._cookies.load(\n                        native_str(self.headers[\"Cookie\"]))\n                except Exception:\n                    self._cookies = {}\n        return self._cookies\n\n    def write(self, chunk, callback=None):\n        \"\"\"Writes the given chunk to the response stream.\"\"\"\n        assert isinstance(chunk, bytes_type)\n        self.connection.write(chunk, callback=callback)\n\n    def finish(self):\n        \"\"\"Finishes this HTTP request on the open connection.\"\"\"\n        self.connection.finish()\n        self._finish_time = time.time()\n\n    def full_url(self):\n        \"\"\"Reconstructs the full URL for this request.\"\"\"\n        return self.protocol + \"://\" + self.host + self.uri\n\n    def request_time(self):\n        \"\"\"Returns the amount of time it took for this request to execute.\"\"\"\n        if self._finish_time is None:\n            return time.time() - self._start_time\n        else:\n            return self._finish_time - self._start_time\n\n    def get_ssl_certificate(self, binary_form=False):\n        \"\"\"Returns the client's SSL certificate, if any.\n\n        To use client certificates, the HTTPServer must have been constructed\n        with cert_reqs set in ssl_options, e.g.::\n\n            server = HTTPServer(app,\n                ssl_options=dict(\n                    certfile=\"foo.crt\",\n                    keyfile=\"foo.key\",\n                    cert_reqs=ssl.CERT_REQUIRED,\n                    ca_certs=\"cacert.crt\"))\n\n        By default, the return value is a dictionary (or None, if no\n        client certificate is present).  If ``binary_form`` is true, a\n        DER-encoded form of the certificate is returned instead.  See\n        SSLSocket.getpeercert() in the standard library for more\n        details.\n        http://docs.python.org/library/ssl.html#sslsocket-objects\n        \"\"\"\n        try:\n            return self.connection.stream.socket.getpeercert(\n                binary_form=binary_form)\n        except ssl.SSLError:\n            return None\n\n    def __repr__(self):\n        attrs = (\"protocol\", \"host\", \"method\", \"uri\", \"version\", \"remote_ip\",\n                 \"body\")\n        args = \", \".join([\"%s=%r\" % (n, getattr(self, n)) for n in attrs])\n        return \"%s(%s, headers=%s)\" % (\n            self.__class__.__name__, args, dict(self.headers))\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 `remote_ip` Extraction with Multiple IPs in `X-Forwarded-For` Header

**Description:**
When a client sends an `X-Forwarded-For` header containing a list of IP addresses, the server fails to correctly extract the intended `remote_ip`. Instead of retrieving the last IP in the list, it incorrectly assigns the first IP or an unintended value.

**Example Buggy Code:**
```python
headers = {"X-Forwarded-For": "127.0.0.1, 4.4.4.4"}
response = fetch_json("/", headers=headers)
print(response["remote_ip"])  # Outputs: '127.0.0.1' instead of '4.4.4.4'
```

**Expected Behavior:**
The server should parse the `X-Forwarded-For` header and set `remote_ip` to the last IP address in the list (`"4.4.4.4"` in this case).

**Actual Behavior:**
The server incorrectly sets `remote_ip` to the first IP address in the `X-Forwarded-For` header (`"127.0.0.1"`), ignoring the subsequent IPs.

[/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`).

This module also defines the `HTTPRequest` class which is exposed via
`tornado.web.RequestHandler.request`.
"""

from __future__ import absolute_import, division, print_function, with_statement

import socket
import ssl
import time

from tornado.escape import native_str, parse_qs_bytes
from tornado import httputil
from tornado import iostream
from tornado.log import gen_log
from tornado import netutil
from tornado.tcpserver import TCPServer
from tornado import stack_context
from tornado.util import bytes_type

try:
    import Cookie  # py2
except ImportError:
    import http.cookies as Cookie  # py3


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

    A server is defined by a request callback that takes an HTTPRequest
    instance as an argument and writes a valid HTTP response with
    `HTTPRequest.write`. `HTTPRequest.finish` finishes the request (but does
    not necessarily close the connection in the case of HTTP/1.1 keep-alive
    requests). A simple example server that echoes back the URI you
    requested::

        import tornado.httpserver
        import tornado.ioloop

        def handle_request(request):
           message = "You requested %s\n" % request.uri
           request.write("HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s" % (
                         len(message), message))
           request.finish()

        http_server = tornado.httpserver.HTTPServer(handle_request)
        http_server.listen(8888)
        tornado.ioloop.IOLoop.instance().start()

    `HTTPServer` is a very basic connection handler.  It parses the request
    headers and body, but the request callback is responsible for producing
    the response exactly as it will appear on the wire.  This affords
    maximum flexibility for applications to implement whatever parts
    of HTTP responses are required.

    `HTTPServer` supports keep-alive connections by default
    (automatically for HTTP/1.1, or for HTTP/1.0 when the client
    requests ``Connection: keep-alive``).  This means that the request
    callback must generate a properly-framed response, using either
    the ``Content-Length`` header or ``Transfer-Encoding: chunked``.
    Applications that are unable to frame their responses properly
    should instead return a ``Connection: close`` header in each
    response and pass ``no_keep_alive=True`` to the `HTTPServer`
    constructor.

    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``.

    To make this server serve SSL traffic, send the ``ssl_options`` dictionary
    argument with the arguments required for the `ssl.wrap_socket` method,
    including ``certfile`` and ``keyfile``.  (In Python 3.2+ you can pass
    an `ssl.SSLContext` object instead of a dict)::

       HTTPServer(applicaton, ssl_options={
           "certfile": os.path.join(data_dir, "mydomain.crt"),
           "keyfile": os.path.join(data_dir, "mydomain.key"),
       })

    `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.instance().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.instance().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.instance().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`.

    """
    def __init__(self, request_callback, no_keep_alive=False, io_loop=None,
                 xheaders=False, ssl_options=None, protocol=None, **kwargs):
        self.request_callback = request_callback
        self.no_keep_alive = no_keep_alive
        self.xheaders = xheaders
        self.protocol = protocol
        TCPServer.__init__(self, io_loop=io_loop, ssl_options=ssl_options,
                           **kwargs)

    def handle_stream(self, stream, address):
        HTTPConnection(stream, address, self.request_callback,
                       self.no_keep_alive, self.xheaders, self.protocol)


class _BadRequestException(Exception):
    """Exception class for malformed HTTP requests."""
    pass


class HTTPConnection(object):
    """Handles a connection to an HTTP client, executing HTTP requests.

    We parse HTTP headers and bodies, and execute the request callback
    until the HTTP conection is closed.
    """
    def __init__(self, stream, address, request_callback, no_keep_alive=False,
                 xheaders=False, protocol=None):
        self.stream = stream
        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.
        self.address_family = stream.socket.family
        self.request_callback = request_callback
        self.no_keep_alive = no_keep_alive
        self.xheaders = xheaders
        self.protocol = protocol
        self._request = None
        self._request_finished = False
        self._write_callback = None
        self._close_callback = None
        # Save stack context here, outside of any request.  This keeps
        # contexts from one request from leaking into the next.
        self._header_callback = stack_context.wrap(self._on_headers)
        self.stream.read_until(b"\r\n\r\n", self._header_callback)

    def _clear_callbacks(self):
        """Clears the per-request callbacks.

        This is run in between requests to allow the previous handler
        to be garbage collected (and prevent spurious close callbacks),
        and when the connection is closed (to break up cycles and
        facilitate garbage collection in cpython).
        """
        self._write_callback = None
        self._close_callback = None

    def set_close_callback(self, callback):
        """Sets a callback that will be run when the connection is closed.

        Use this instead of accessing
        `HTTPConnection.stream.set_close_callback
        <.BaseIOStream.set_close_callback>` directly (which was the
        recommended approach prior to Tornado 3.0).
        """
        self._close_callback = stack_context.wrap(callback)
        self.stream.set_close_callback(self._on_connection_close)

    def _on_connection_close(self):
        callback = self._close_callback
        self._close_callback = None
        callback()
        # Delete any unfinished callbacks to break up reference cycles.
        self._header_callback = None
        self._clear_callbacks()

    def close(self):
        self.stream.close()
        # Remove this reference to self, which would otherwise cause a
        # cycle and delay garbage collection of this connection.
        self._header_callback = None
        self._clear_callbacks()

    def write(self, chunk, callback=None):
        """Writes a chunk of output to the stream."""
        assert self._request, "Request closed"
        if not self.stream.closed():
            self._write_callback = stack_context.wrap(callback)
            self.stream.write(chunk, self._on_write_complete)

    def finish(self):
        """Finishes the request."""
        assert self._request, "Request closed"
        self._request_finished = True
        if not self.stream.writing():
            self._finish_request()

    def _on_write_complete(self):
        if self._write_callback is not None:
            callback = self._write_callback
            self._write_callback = None
            callback()
        # _on_write_complete is enqueued on the IOLoop whenever the
        # IOStream's write buffer becomes empty, but it's possible for
        # another callback that runs on the IOLoop before it to
        # simultaneously write more data and finish the request.  If
        # there is still data in the IOStream, a future
        # _on_write_complete will be responsible for calling
        # _finish_request.
        if self._request_finished and not self.stream.writing():
            self._finish_request()

    def _finish_request(self):
        if self.no_keep_alive:
            disconnect = True
        else:
            connection_header = self._request.headers.get("Connection")
            if connection_header is not None:
                connection_header = connection_header.lower()
            if self._request.supports_http_1_1():
                disconnect = connection_header == "close"
            elif ("Content-Length" in self._request.headers
                    or self._request.method in ("HEAD", "GET")):
                disconnect = connection_header != "keep-alive"
            else:
                disconnect = True
        self._request = None
        self._request_finished = False
        self._clear_callbacks()
        if disconnect:
            self.close()
            return
        try:
            # Use a try/except instead of checking stream.closed()
            # directly, because in some cases the stream doesn't discover
            # that it's closed until you try to read from it.
            self.stream.read_until(b"\r\n\r\n", self._header_callback)
        except iostream.StreamClosedError:
            self.close()

    def _on_headers(self, data):
        try:
            data = native_str(data.decode('latin1'))
            eol = data.find("\r\n")
            start_line = data[:eol]
            try:
                method, uri, version = start_line.split(" ")
            except ValueError:
                raise _BadRequestException("Malformed HTTP request line")
            if not version.startswith("HTTP/"):
                raise _BadRequestException("Malformed HTTP version in HTTP Request-Line")
            try:
                headers = httputil.HTTPHeaders.parse(data[eol:])
            except ValueError:
                # Probably from split() if there was no ':' in the line
                raise _BadRequestException("Malformed HTTP headers")

            # HTTPRequest wants an IP, not a full socket address
            if self.address_family in (socket.AF_INET, socket.AF_INET6):
                remote_ip = self.address[0]
            else:
                # Unix (or other) socket; fake the remote address
                remote_ip = '0.0.0.0'

            self._request = HTTPRequest(
                connection=self, method=method, uri=uri, version=version,
                headers=headers, remote_ip=remote_ip, protocol=self.protocol)

            content_length = headers.get("Content-Length")
            if content_length:
                content_length = int(content_length)
                if content_length > self.stream.max_buffer_size:
                    raise _BadRequestException("Content-Length too long")
                if headers.get("Expect") == "100-continue":
                    self.stream.write(b"HTTP/1.1 100 (Continue)\r\n\r\n")
                self.stream.read_bytes(content_length, self._on_request_body)
                return

            self.request_callback(self._request)
        except _BadRequestException as e:
            gen_log.info("Malformed HTTP request from %s: %s",
                         self.address[0], e)
            self.close()
            return

    def _on_request_body(self, data):
        self._request.body = data
        if self._request.method in ("POST", "PATCH", "PUT"):
            httputil.parse_body_arguments(
                self._request.headers.get("Content-Type", ""), data,
                self._request.arguments, self._request.files)
        self.request_callback(self._request)


class HTTPRequest(object):
    """A single HTTP request.

    All attributes are type `str` unless otherwise noted.

    .. attribute:: method

       HTTP request method, e.g. "GET" or "POST"

    .. attribute:: uri

       The requested uri.

    .. attribute:: path

       The path portion of `uri`

    .. attribute:: query

       The query portion of `uri`

    .. attribute:: version

       HTTP version specified in request, e.g. "HTTP/1.1"

    .. attribute:: headers

       `.HTTPHeaders` dictionary-like object for request headers.  Acts like
       a case-insensitive dictionary with additional methods for repeated
       headers.

    .. attribute:: body

       Request body, if present, as a byte string.

    .. attribute:: remote_ip

       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,
       will pass along the real IP address provided by a load balancer
       in the ``X-Real-Ip`` header

    .. attribute:: protocol

       The protocol used, either "http" or "https".  If ``HTTPServer.xheaders``
       is set, will pass along the protocol used by a load balancer if
       reported via an ``X-Scheme`` header.

    .. attribute:: host

       The requested hostname, usually taken from the ``Host`` header.

    .. attribute:: arguments

       GET/POST arguments are available in the arguments property, which
       maps arguments names to lists of values (to support multiple values
       for individual names). Names are of type `str`, while arguments
       are byte strings.  Note that this is different from
       `.RequestHandler.get_argument`, which returns argument values as
       unicode strings.

    .. attribute:: files

       File uploads are available in the files property, which maps file
       names to lists of `.HTTPFile`.

    .. attribute:: connection

       An HTTP request is attached to a single HTTP connection, which can
       be accessed through the "connection" attribute. Since connections
       are typically kept open in HTTP/1.1, multiple requests can be handled
       sequentially on a single connection.
    """
    def __init__(self, method, uri, version="HTTP/1.0", headers=None,
                 body=None, remote_ip=None, protocol=None, host=None,
                 files=None, connection=None):
        self.method = method
        self.uri = uri
        self.version = version
        self.headers = headers or httputil.HTTPHeaders()
        self.body = body or ""

        # set remote IP and protocol
        self.remote_ip = remote_ip
        if protocol:
            self.protocol = protocol
        elif connection and isinstance(connection.stream,
                                       iostream.SSLIOStream):
            self.protocol = "https"
        else:
            self.protocol = "http"

        # xheaders can override the defaults
        if connection and connection.xheaders:
            # Squid uses X-Forwarded-For, others use X-Real-Ip
            ip = self.headers.get(
                "X-Real-Ip", self.headers.get("X-Forwarded-For", self.remote_ip))
            if netutil.is_valid_ip(ip):
                self.remote_ip = ip
            # AWS uses X-Forwarded-Proto
            proto = self.headers.get(
                "X-Scheme", self.headers.get("X-Forwarded-Proto", self.protocol))
            if proto in ("http", "https"):
                self.protocol = proto


        self.host = host or self.headers.get("Host") or "127.0.0.1"
        self.files = files or {}
        self.connection = connection
        self._start_time = time.time()
        self._finish_time = None

        self.path, sep, self.query = uri.partition('?')
        self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)

    def supports_http_1_1(self):
        """Returns True if this request supports HTTP/1.1 semantics"""
        return self.version == "HTTP/1.1"

    @property
    def cookies(self):
        """A dictionary of Cookie.Morsel objects."""
        if not hasattr(self, "_cookies"):
            self._cookies = Cookie.SimpleCookie()
            if "Cookie" in self.headers:
                try:
                    self._cookies.load(
                        native_str(self.headers["Cookie"]))
                except Exception:
                    self._cookies = {}
        return self._cookies

    def write(self, chunk, callback=None):
        """Writes the given chunk to the response stream."""
        assert isinstance(chunk, bytes_type)
        self.connection.write(chunk, callback=callback)

    def finish(self):
        """Finishes this HTTP request on the open connection."""
        self.connection.finish()
        self._finish_time = time.time()

    def full_url(self):
        """Reconstructs the full URL for this request."""
        return self.protocol + "://" + self.host + self.uri

    def request_time(self):
        """Returns the amount of time it took for this request to execute."""
        if self._finish_time is None:
            return time.time() - self._start_time
        else:
            return self._finish_time - self._start_time

    def get_ssl_certificate(self, binary_form=False):
        """Returns the client's SSL certificate, if any.

        To use client certificates, the HTTPServer must have been constructed
        with cert_reqs set in ssl_options, e.g.::

            server = HTTPServer(app,
                ssl_options=dict(
                    certfile="foo.crt",
                    keyfile="foo.key",
                    cert_reqs=ssl.CERT_REQUIRED,
                    ca_certs="cacert.crt"))

        By default, the return value is a dictionary (or None, if no
        client certificate is present).  If ``binary_form`` is true, a
        DER-encoded form of the certificate is returned instead.  See
        SSLSocket.getpeercert() in the standard library for more
        details.
        http://docs.python.org/library/ssl.html#sslsocket-objects
        """
        try:
            return self.connection.stream.socket.getpeercert(
                binary_form=binary_form)
        except ssl.SSLError:
            return None

    def __repr__(self):
        attrs = ("protocol", "host", "method", "uri", "version", "remote_ip",
                 "body")
        args = ", ".join(["%s=%r" % (n, getattr(self, n)) for n in attrs])
        return "%s(%s, headers=%s)" % (
            self.__class__.__name__, args, dict(self.headers))

```
--- 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