{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom tornado.escape import utf8, _unicode\nfrom tornado import gen\nfrom tornado.httpclient import HTTPResponse, HTTPError, AsyncHTTPClient, main, _RequestProxy\nfrom tornado import httputil\nfrom tornado.http1connection import HTTP1Connection, HTTP1ConnectionParameters\nfrom tornado.iostream import StreamClosedError\nfrom tornado.netutil import Resolver, OverrideResolver, _client_ssl_defaults\nfrom tornado.log import gen_log\nfrom tornado import stack_context\nfrom tornado.tcpclient import TCPClient\n\nimport base64\nimport collections\nimport copy\nimport functools\nimport re\nimport socket\nimport sys\nfrom io import BytesIO\n\n\ntry:\n    import urlparse  # py2\nexcept ImportError:\n    import urllib.parse as urlparse  # py3\n\ntry:\n    import ssl\nexcept ImportError:\n    # ssl is not available on Google App Engine.\n    ssl = None\n\ntry:\n    import certifi\nexcept ImportError:\n    certifi = None\n\n\ndef _default_ca_certs():\n    if certifi is None:\n        raise Exception(\"The 'certifi' package is required to use https \"\n                        \"in simple_httpclient\")\n    return certifi.where()\n\n\nclass SimpleAsyncHTTPClient(AsyncHTTPClient):\n    \"\"\"Non-blocking HTTP client with no external dependencies.\n\n    This class implements an HTTP 1.1 client on top of Tornado's IOStreams.\n    Some features found in the curl-based AsyncHTTPClient are not yet\n    supported.  In particular, proxies are not supported, connections\n    are not reused, and callers cannot select the network interface to be\n    used.\n    \"\"\"\n    def initialize(self, io_loop, max_clients=10,\n                   hostname_mapping=None, max_buffer_size=104857600,\n                   resolver=None, defaults=None, max_header_size=None,\n                   max_body_size=None):\n        \"\"\"Creates a AsyncHTTPClient.\n\n        Only a single AsyncHTTPClient instance exists per IOLoop\n        in order to provide limitations on the number of pending connections.\n        ``force_instance=True`` may be used to suppress this behavior.\n\n        Note that because of this implicit reuse, unless ``force_instance``\n        is used, only the first call to the constructor actually uses\n        its arguments. It is recommended to use the ``configure`` method\n        instead of the constructor to ensure that arguments take effect.\n\n        ``max_clients`` is the number of concurrent requests that can be\n        in progress; when this limit is reached additional requests will be\n        queued. Note that time spent waiting in this queue still counts\n        against the ``request_timeout``.\n\n        ``hostname_mapping`` is a dictionary mapping hostnames to IP addresses.\n        It can be used to make local DNS changes when modifying system-wide\n        settings like ``/etc/hosts`` is not possible or desirable (e.g. in\n        unittests).\n\n        ``max_buffer_size`` (default 100MB) is the number of bytes\n        that can be read into memory at once. ``max_body_size``\n        (defaults to ``max_buffer_size``) is the largest response body\n        that the client will accept.  Without a\n        ``streaming_callback``, the smaller of these two limits\n        applies; with a ``streaming_callback`` only ``max_body_size``\n        does.\n\n        .. versionchanged:: 4.2\n           Added the ``max_body_size`` argument.\n        \"\"\"\n        super(SimpleAsyncHTTPClient, self).initialize(io_loop,\n                                                      defaults=defaults)\n        self.max_clients = max_clients\n        self.queue = collections.deque()\n        self.active = {}\n        self.waiting = {}\n        self.max_buffer_size = max_buffer_size\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        # TCPClient could create a Resolver for us, but we have to do it\n        # ourselves to support hostname_mapping.\n        if resolver:\n            self.resolver = resolver\n            self.own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self.own_resolver = True\n        if hostname_mapping is not None:\n            self.resolver = OverrideResolver(resolver=self.resolver,\n                                             mapping=hostname_mapping)\n        self.tcp_client = TCPClient(resolver=self.resolver, io_loop=io_loop)\n\n    def close(self):\n        super(SimpleAsyncHTTPClient, self).close()\n        if self.own_resolver:\n            self.resolver.close()\n        self.tcp_client.close()\n\n    def fetch_impl(self, request, callback):\n        key = object()\n        self.queue.append((key, request, callback))\n        if not len(self.active) < self.max_clients:\n            timeout_handle = self.io_loop.add_timeout(\n                self.io_loop.time() + min(request.connect_timeout,\n                                          request.request_timeout),\n                functools.partial(self._on_timeout, key, \"in request queue\"))\n        else:\n            timeout_handle = None\n        self.waiting[key] = (request, callback, timeout_handle)\n        self._process_queue()\n        if self.queue:\n            gen_log.debug(\"max_clients limit reached, request queued. \"\n                          \"%d active, %d queued requests.\" % (\n                              len(self.active), len(self.queue)))\n\n    def _process_queue(self):\n        with stack_context.NullContext():\n            while self.queue and len(self.active) < self.max_clients:\n                key, request, callback = self.queue.popleft()\n                if key not in self.waiting:\n                    continue\n                self._remove_timeout(key)\n                self.active[key] = (request, callback)\n                release_callback = functools.partial(self._release_fetch, key)\n                self._handle_request(request, release_callback, callback)\n\n    def _connection_class(self):\n        return _HTTPConnection\n\n    def _handle_request(self, request, release_callback, final_callback):\n        self._connection_class()(\n            self.io_loop, self, request, release_callback,\n            final_callback, self.max_buffer_size, self.tcp_client,\n            self.max_header_size, self.max_body_size)\n\n    def _release_fetch(self, key):\n        del self.active[key]\n        self._process_queue()\n\n    def _remove_timeout(self, key):\n        if key in self.waiting:\n            request, callback, timeout_handle = self.waiting[key]\n            if timeout_handle is not None:\n                self.io_loop.remove_timeout(timeout_handle)\n            del self.waiting[key]\n\n    def _on_timeout(self, key, info=None):\n        \"\"\"Timeout callback of request.\n\n        Construct a timeout HTTPResponse when a timeout occurs.\n\n        :arg object key: A simple object to mark the request.\n        :info string key: More detailed timeout information.\n        \"\"\"\n        request, callback, timeout_handle = self.waiting[key]\n        self.queue.remove((key, request, callback))\n\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        timeout_response = HTTPResponse(\n            request, 599, error=HTTPError(599, error_message),\n            request_time=self.io_loop.time() - request.start_time)\n        self.io_loop.add_callback(callback, timeout_response)\n        del self.waiting[key]\n\n\nclass _HTTPConnection(httputil.HTTPMessageDelegate):\n    _SUPPORTED_METHODS = set([\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"])\n\n    def __init__(self, io_loop, client, request, release_callback,\n                 final_callback, max_buffer_size, tcp_client,\n                 max_header_size, max_body_size):\n        self.start_time = io_loop.time()\n        self.io_loop = io_loop\n        self.client = client\n        self.request = request\n        self.release_callback = release_callback\n        self.final_callback = final_callback\n        self.max_buffer_size = max_buffer_size\n        self.tcp_client = tcp_client\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        self.code = None\n        self.headers = None\n        self.chunks = []\n        self._decompressor = None\n        # Timeout handle returned by IOLoop.add_timeout\n        self._timeout = None\n        self._sockaddr = None\n        with stack_context.ExceptionStackContext(self._handle_exception):\n            self.parsed = urlparse.urlsplit(_unicode(self.request.url))\n            if self.parsed.scheme not in (\"http\", \"https\"):\n                raise ValueError(\"Unsupported url scheme: %s\" %\n                                 self.request.url)\n            # urlsplit results have hostname and port results, but they\n            # didn't support ipv6 literals until python 2.7.\n            netloc = self.parsed.netloc\n            if \"@\" in netloc:\n                userpass, _, netloc = netloc.rpartition(\"@\")\n            host, port = httputil.split_host_and_port(netloc)\n            if port is None:\n                port = 443 if self.parsed.scheme == \"https\" else 80\n            if re.match(r'^\\[.*\\]$', host):\n                # raw ipv6 addresses in urls are enclosed in brackets\n                host = host[1:-1]\n            self.parsed_hostname = host  # save final host for _on_connect\n\n            if request.allow_ipv6 is False:\n                af = socket.AF_INET\n            else:\n                af = socket.AF_UNSPEC\n\n            ssl_options = self._get_ssl_options(self.parsed.scheme)\n\n            timeout = min(self.request.connect_timeout, self.request.request_timeout)\n            if timeout:\n                self._timeout = self.io_loop.add_timeout(\n                    self.start_time + timeout,\n                    stack_context.wrap(functools.partial(self._on_timeout, \"while connecting\")))\n            self.tcp_client.connect(host, port, af=af,\n                                    ssl_options=ssl_options,\n                                    max_buffer_size=self.max_buffer_size,\n                                    callback=self._on_connect)\n\n    def _get_ssl_options(self, scheme):\n        if scheme == \"https\":\n            if self.request.ssl_options is not None:\n                return self.request.ssl_options\n            # If we are using the defaults, don't construct a\n            # new SSLContext.\n            if (self.request.validate_cert and\n                    self.request.ca_certs is None and\n                    self.request.client_cert is None and\n                    self.request.client_key is None):\n                return _client_ssl_defaults\n            ssl_options = {}\n            if self.request.validate_cert:\n                ssl_options[\"cert_reqs\"] = ssl.CERT_REQUIRED\n            if self.request.ca_certs is not None:\n                ssl_options[\"ca_certs\"] = self.request.ca_certs\n            elif not hasattr(ssl, 'create_default_context'):\n                # When create_default_context is present,\n                # we can omit the \"ca_certs\" parameter entirely,\n                # which avoids the dependency on \"certifi\" for py34.\n                ssl_options[\"ca_certs\"] = _default_ca_certs()\n            if self.request.client_key is not None:\n                ssl_options[\"keyfile\"] = self.request.client_key\n            if self.request.client_cert is not None:\n                ssl_options[\"certfile\"] = self.request.client_cert\n\n            # SSL interoperability is tricky.  We want to disable\n            # SSLv2 for security reasons; it wasn't disabled by default\n            # until openssl 1.0.  The best way to do this is to use\n            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python\n            # until 3.2.  Python 2.7 adds the ciphers argument, which\n            # can also be used to disable SSLv2.  As a last resort\n            # on python 2.6, we set ssl_version to TLSv1.  This is\n            # more narrow than we'd like since it also breaks\n            # compatibility with servers configured for SSLv3 only,\n            # but nearly all servers support both SSLv3 and TLSv1:\n            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html\n            if sys.version_info >= (2, 7):\n                # In addition to disabling SSLv2, we also exclude certain\n                # classes of insecure ciphers.\n                ssl_options[\"ciphers\"] = \"DEFAULT:!SSLv2:!EXPORT:!DES\"\n            else:\n                # This is really only necessary for pre-1.0 versions\n                # of openssl, but python 2.6 doesn't expose version\n                # information.\n                ssl_options[\"ssl_version\"] = ssl.PROTOCOL_TLSv1\n            return ssl_options\n        return None\n\n    def _on_timeout(self, info=None):\n        \"\"\"Timeout callback of _HTTPConnection instance.\n\n        Raise a timeout HTTPError when a timeout occurs.\n\n        :info string key: More detailed timeout information.\n        \"\"\"\n        self._timeout = None\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        if self.final_callback is not None:\n            raise HTTPError(599, error_message)\n\n    def _remove_timeout(self):\n        if self._timeout is not None:\n            self.io_loop.remove_timeout(self._timeout)\n            self._timeout = None\n\n    def _on_connect(self, stream):\n        if self.final_callback is None:\n            # final_callback is cleared if we've hit our timeout.\n            stream.close()\n            return\n        self.stream = stream\n        self.stream.set_close_callback(self.on_connection_close)\n        self._remove_timeout()\n        if self.final_callback is None:\n            return\n        if self.request.request_timeout:\n            self._timeout = self.io_loop.add_timeout(\n                self.start_time + self.request.request_timeout,\n                stack_context.wrap(functools.partial(self._on_timeout, \"while interacting\")))\n        if (self.request.method not in self._SUPPORTED_METHODS and\n                not self.request.allow_nonstandard_methods):\n            raise KeyError(\"unknown method %s\" % self.request.method)\n        for key in ('network_interface',\n                    'proxy_host', 'proxy_port',\n                    'proxy_username', 'proxy_password'):\n            if getattr(self.request, key, None):\n                raise NotImplementedError('%s not supported' % key)\n        if \"Connection\" not in self.request.headers:\n            self.request.headers[\"Connection\"] = \"close\"\n        if \"Host\" not in self.request.headers:\n            if '@' in self.parsed.netloc:\n                self.request.headers[\"Host\"] = self.parsed.netloc.rpartition('@')[-1]\n            else:\n                self.request.headers[\"Host\"] = self.parsed.netloc\n        username, password = None, None\n        if self.parsed.username is not None:\n            username, password = self.parsed.username, self.parsed.password\n        elif self.request.auth_username is not None:\n            username = self.request.auth_username\n            password = self.request.auth_password or ''\n        if username is not None:\n            if self.request.auth_mode not in (None, \"basic\"):\n                raise ValueError(\"unsupported auth_mode %s\",\n                                 self.request.auth_mode)\n            auth = utf8(username) + b\":\" + utf8(password)\n            self.request.headers[\"Authorization\"] = (b\"Basic \" +\n                                                     base64.b64encode(auth))\n        if self.request.user_agent:\n            self.request.headers[\"User-Agent\"] = self.request.user_agent\n        if not self.request.allow_nonstandard_methods:\n            # Some HTTP methods nearly always have bodies while others\n            # almost never do. Fail in this case unless the user has\n            # opted out of sanity checks with allow_nonstandard_methods.\n            body_expected = self.request.method in (\"POST\", \"PATCH\", \"PUT\")\n            body_present = (self.request.body is not None or\n                            self.request.body_producer is not None)\n            if ((body_expected and not body_present) or\n                    (body_present and not body_expected)):\n                raise ValueError(\n                    'Body must %sbe None for method %s (unless '\n                    'allow_nonstandard_methods is true)' %\n                    ('not ' if body_expected else '', self.request.method))\n        if self.request.expect_100_continue:\n            self.request.headers[\"Expect\"] = \"100-continue\"\n        if self.request.body is not None:\n            # When body_producer is used the caller is responsible for\n            # setting Content-Length (or else chunked encoding will be used).\n            self.request.headers[\"Content-Length\"] = str(len(\n                self.request.body))\n        if (self.request.method == \"POST\" and\n                \"Content-Type\" not in self.request.headers):\n            self.request.headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n        if self.request.decompress_response:\n            self.request.headers[\"Accept-Encoding\"] = \"gzip\"\n        req_path = ((self.parsed.path or '/') +\n                    (('?' + self.parsed.query) if self.parsed.query else ''))\n        self.connection = self._create_connection(stream)\n        start_line = httputil.RequestStartLine(self.request.method,\n                                               req_path, '')\n        self.connection.write_headers(start_line, self.request.headers)\n        if self.request.expect_100_continue:\n            self._read_response()\n        else:\n            self._write_body(True)\n\n    def _create_connection(self, stream):\n        stream.set_nodelay(True)\n        connection = HTTP1Connection(\n            stream, True,\n            HTTP1ConnectionParameters(\n                no_keep_alive=True,\n                max_header_size=self.max_header_size,\n                max_body_size=self.max_body_size,\n                decompress=self.request.decompress_response),\n            self._sockaddr)\n        return connection\n\n    def _write_body(self, start_read):\n        if self.request.body is not None:\n            self.connection.write(self.request.body)\n        elif self.request.body_producer is not None:\n            fut = self.request.body_producer(self.connection.write)\n            if fut is not None:\n                fut = gen.convert_yielded(fut)\n\n                def on_body_written(fut):\n                    fut.result()\n                    self.connection.finish()\n                    if start_read:\n                        self._read_response()\n                self.io_loop.add_future(fut, on_body_written)\n                return\n        self.connection.finish()\n        if start_read:\n            self._read_response()\n\n    def _read_response(self):\n        # Ensure that any exception raised in read_response ends up in our\n        # stack context.\n        self.io_loop.add_future(\n            self.connection.read_response(self),\n            lambda f: f.result())\n\n    def _release(self):\n        if self.release_callback is not None:\n            release_callback = self.release_callback\n            self.release_callback = None\n            release_callback()\n\n    def _run_callback(self, response):\n        self._release()\n        if self.final_callback is not None:\n            final_callback = self.final_callback\n            self.final_callback = None\n            self.io_loop.add_callback(final_callback, response)\n\n    def _handle_exception(self, typ, value, tb):\n        if self.final_callback:\n            self._remove_timeout()\n            if isinstance(value, StreamClosedError):\n                if value.real_error is None:\n                    value = HTTPError(599, \"Stream closed\")\n                else:\n                    value = value.real_error\n            self._run_callback(HTTPResponse(self.request, 599, error=value,\n                                            request_time=self.io_loop.time() - self.start_time,\n                                            ))\n\n            if hasattr(self, \"stream\"):\n                # TODO: this may cause a StreamClosedError to be raised\n                # by the connection's Future.  Should we cancel the\n                # connection more gracefully?\n                self.stream.close()\n            return True\n        else:\n            # If our callback has already been called, we are probably\n            # catching an exception that is not caused by us but rather\n            # some child of our callback. Rather than drop it on the floor,\n            # pass it along, unless it's just the stream being closed.\n            return isinstance(value, StreamClosedError)\n\n    def on_connection_close(self):\n        if self.final_callback is not None:\n            message = \"Connection closed\"\n            if self.stream.error:\n                raise self.stream.error\n            try:\n                raise HTTPError(599, message)\n            except HTTPError:\n                self._handle_exception(*sys.exc_info())\n\n    def headers_received(self, first_line, headers):\n        if self.request.expect_100_continue and first_line.code == 100:\n            self._write_body(False)\n            return\n        self.code = first_line.code\n        self.reason = first_line.reason\n        self.headers = headers\n\n        if self._should_follow_redirect():\n            return\n\n        if self.request.header_callback is not None:\n            # Reassemble the start line.\n            self.request.header_callback('%s %s %s\\r\\n' % first_line)\n            for k, v in self.headers.get_all():\n                self.request.header_callback(\"%s: %s\\r\\n\" % (k, v))\n            self.request.header_callback('\\r\\n')\n\n    def _should_follow_redirect(self):\n        return (self.request.follow_redirects and\n                self.request.max_redirects > 0 and\n                self.code in (301, 302, 303, 307))\n\n    def finish(self):\n        data = b''.join(self.chunks)\n        self._remove_timeout()\n        original_request = getattr(self.request, \"original_request\",\n                                   self.request)\n        if self._should_follow_redirect():\n            assert isinstance(self.request, _RequestProxy)\n            new_request = copy.copy(self.request.request)\n            new_request.url = urlparse.urljoin(self.request.url,\n                                               self.headers[\"Location\"])\n            new_request.max_redirects = self.request.max_redirects - 1\n            del new_request.headers[\"Host\"]\n            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4\n            # Client SHOULD make a GET request after a 303.\n            # According to the spec, 302 should be followed by the same\n            # method as the original request, but in practice browsers\n            # treat 302 the same as 303, and many servers use 302 for\n            # compatibility with pre-HTTP/1.1 user agents which don't\n            # understand the 303 status.\n            if self.code in (302, 303):\n                new_request.method = \"GET\"\n                new_request.body = None\n                for h in [\"Content-Length\", \"Content-Type\",\n                          \"Content-Encoding\", \"Transfer-Encoding\"]:\n                    try:\n                        del self.request.headers[h]\n                    except KeyError:\n                        pass\n            new_request.original_request = original_request\n            final_callback = self.final_callback\n            self.final_callback = None\n            self._release()\n            self.client.fetch(new_request, final_callback)\n            self._on_end_request()\n            return\n        if self.request.streaming_callback:\n            buffer = BytesIO()\n        else:\n            buffer = BytesIO(data)  # TODO: don't require one big string?\n        response = HTTPResponse(original_request,\n                                self.code, reason=getattr(self, 'reason', None),\n                                headers=self.headers,\n                                request_time=self.io_loop.time() - self.start_time,\n                                buffer=buffer,\n                                effective_url=self.request.url)\n        self._run_callback(response)\n        self._on_end_request()\n\n    def _on_end_request(self):\n        self.stream.close()\n\n    def data_received(self, chunk):\n        if self._should_follow_redirect():\n            # We're going to follow a redirect so just discard the body.\n            return\n        if self.request.streaming_callback is not None:\n            self.request.streaming_callback(chunk)\n        else:\n            self.chunks.append(chunk)\n\n\nif __name__ == \"__main__\":\n    AsyncHTTPClient.configure(SimpleAsyncHTTPClient)\n    main()\n",
            "new_file_content": "#!/usr/bin/env python\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom tornado.escape import utf8, _unicode\nfrom tornado import gen\nfrom tornado.httpclient import HTTPResponse, HTTPError, AsyncHTTPClient, main, _RequestProxy\nfrom tornado import httputil\nfrom tornado.http1connection import HTTP1Connection, HTTP1ConnectionParameters\nfrom tornado.iostream import StreamClosedError\nfrom tornado.netutil import Resolver, OverrideResolver, _client_ssl_defaults\nfrom tornado.log import gen_log\nfrom tornado import stack_context\nfrom tornado.tcpclient import TCPClient\n\nimport base64\nimport collections\nimport copy\nimport functools\nimport re\nimport socket\nimport sys\nfrom io import BytesIO\n\n\ntry:\n    import urlparse  # py2\nexcept ImportError:\n    import urllib.parse as urlparse  # py3\n\ntry:\n    import ssl\nexcept ImportError:\n    # ssl is not available on Google App Engine.\n    ssl = None\n\ntry:\n    import certifi\nexcept ImportError:\n    certifi = None\n\n\ndef _default_ca_certs():\n    if certifi is None:\n        raise Exception(\"The 'certifi' package is required to use https \"\n                        \"in simple_httpclient\")\n    return certifi.where()\n\n\nclass SimpleAsyncHTTPClient(AsyncHTTPClient):\n    \"\"\"Non-blocking HTTP client with no external dependencies.\n\n    This class implements an HTTP 1.1 client on top of Tornado's IOStreams.\n    Some features found in the curl-based AsyncHTTPClient are not yet\n    supported.  In particular, proxies are not supported, connections\n    are not reused, and callers cannot select the network interface to be\n    used.\n    \"\"\"\n    def initialize(self, io_loop, max_clients=10,\n                   hostname_mapping=None, max_buffer_size=104857600,\n                   resolver=None, defaults=None, max_header_size=None,\n                   max_body_size=None):\n        \"\"\"Creates a AsyncHTTPClient.\n\n        Only a single AsyncHTTPClient instance exists per IOLoop\n        in order to provide limitations on the number of pending connections.\n        ``force_instance=True`` may be used to suppress this behavior.\n\n        Note that because of this implicit reuse, unless ``force_instance``\n        is used, only the first call to the constructor actually uses\n        its arguments. It is recommended to use the ``configure`` method\n        instead of the constructor to ensure that arguments take effect.\n\n        ``max_clients`` is the number of concurrent requests that can be\n        in progress; when this limit is reached additional requests will be\n        queued. Note that time spent waiting in this queue still counts\n        against the ``request_timeout``.\n\n        ``hostname_mapping`` is a dictionary mapping hostnames to IP addresses.\n        It can be used to make local DNS changes when modifying system-wide\n        settings like ``/etc/hosts`` is not possible or desirable (e.g. in\n        unittests).\n\n        ``max_buffer_size`` (default 100MB) is the number of bytes\n        that can be read into memory at once. ``max_body_size``\n        (defaults to ``max_buffer_size``) is the largest response body\n        that the client will accept.  Without a\n        ``streaming_callback``, the smaller of these two limits\n        applies; with a ``streaming_callback`` only ``max_body_size``\n        does.\n\n        .. versionchanged:: 4.2\n           Added the ``max_body_size`` argument.\n        \"\"\"\n        super(SimpleAsyncHTTPClient, self).initialize(io_loop,\n                                                      defaults=defaults)\n        self.max_clients = max_clients\n        self.queue = collections.deque()\n        self.active = {}\n        self.waiting = {}\n        self.max_buffer_size = max_buffer_size\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        # TCPClient could create a Resolver for us, but we have to do it\n        # ourselves to support hostname_mapping.\n        if resolver:\n            self.resolver = resolver\n            self.own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self.own_resolver = True\n        if hostname_mapping is not None:\n            self.resolver = OverrideResolver(resolver=self.resolver,\n                                             mapping=hostname_mapping)\n        self.tcp_client = TCPClient(resolver=self.resolver, io_loop=io_loop)\n\n    def close(self):\n        super(SimpleAsyncHTTPClient, self).close()\n        if self.own_resolver:\n            self.resolver.close()\n        self.tcp_client.close()\n\n    def fetch_impl(self, request, callback):\n        key = object()\n        self.queue.append((key, request, callback))\n        if not len(self.active) < self.max_clients:\n            timeout_handle = self.io_loop.add_timeout(\n                self.io_loop.time() + min(request.connect_timeout,\n                                          request.request_timeout),\n                functools.partial(self._on_timeout, key, \"in request queue\"))\n        else:\n            timeout_handle = None\n        self.waiting[key] = (request, callback, timeout_handle)\n        self._process_queue()\n        if self.queue:\n            gen_log.debug(\"max_clients limit reached, request queued. \"\n                          \"%d active, %d queued requests.\" % (\n                              len(self.active), len(self.queue)))\n\n    def _process_queue(self):\n        with stack_context.NullContext():\n            while self.queue and len(self.active) < self.max_clients:\n                key, request, callback = self.queue.popleft()\n                if key not in self.waiting:\n                    continue\n                self._remove_timeout(key)\n                self.active[key] = (request, callback)\n                release_callback = functools.partial(self._release_fetch, key)\n                self._handle_request(request, release_callback, callback)\n\n    def _connection_class(self):\n        return _HTTPConnection\n\n    def _handle_request(self, request, release_callback, final_callback):\n        self._connection_class()(\n            self.io_loop, self, request, release_callback,\n            final_callback, self.max_buffer_size, self.tcp_client,\n            self.max_header_size, self.max_body_size)\n\n    def _release_fetch(self, key):\n        del self.active[key]\n        self._process_queue()\n\n    def _remove_timeout(self, key):\n        if key in self.waiting:\n            request, callback, timeout_handle = self.waiting[key]\n            if timeout_handle is not None:\n                self.io_loop.remove_timeout(timeout_handle)\n            del self.waiting[key]\n\n    def _on_timeout(self, key, info=None):\n        \"\"\"Timeout callback of request.\n\n        Construct a timeout HTTPResponse when a timeout occurs.\n\n        :arg object key: A simple object to mark the request.\n        :info string key: More detailed timeout information.\n        \"\"\"\n        request, callback, timeout_handle = self.waiting[key]\n        self.queue.remove((key, request, callback))\n\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        timeout_response = HTTPResponse(\n            request, 599, error=HTTPError(599, error_message),\n            request_time=self.io_loop.time() - request.start_time)\n        self.io_loop.add_callback(callback, timeout_response)\n        del self.waiting[key]\n\n\nclass _HTTPConnection(httputil.HTTPMessageDelegate):\n    _SUPPORTED_METHODS = set([\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"])\n\n    def __init__(self, io_loop, client, request, release_callback,\n                 final_callback, max_buffer_size, tcp_client,\n                 max_header_size, max_body_size):\n        self.start_time = io_loop.time()\n        self.io_loop = io_loop\n        self.client = client\n        self.request = request\n        self.release_callback = release_callback\n        self.final_callback = final_callback\n        self.max_buffer_size = max_buffer_size\n        self.tcp_client = tcp_client\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        self.code = None\n        self.headers = None\n        self.chunks = []\n        self._decompressor = None\n        # Timeout handle returned by IOLoop.add_timeout\n        self._timeout = None\n        self._sockaddr = None\n        with stack_context.ExceptionStackContext(self._handle_exception):\n            self.parsed = urlparse.urlsplit(_unicode(self.request.url))\n            if self.parsed.scheme not in (\"http\", \"https\"):\n                raise ValueError(\"Unsupported url scheme: %s\" %\n                                 self.request.url)\n            # urlsplit results have hostname and port results, but they\n            # didn't support ipv6 literals until python 2.7.\n            netloc = self.parsed.netloc\n            if \"@\" in netloc:\n                userpass, _, netloc = netloc.rpartition(\"@\")\n            host, port = httputil.split_host_and_port(netloc)\n            if port is None:\n                port = 443 if self.parsed.scheme == \"https\" else 80\n            if re.match(r'^\\[.*\\]$', host):\n                # raw ipv6 addresses in urls are enclosed in brackets\n                host = host[1:-1]\n            self.parsed_hostname = host  # save final host for _on_connect\n\n            if request.allow_ipv6 is False:\n                af = socket.AF_INET\n            else:\n                af = socket.AF_UNSPEC\n\n            ssl_options = self._get_ssl_options(self.parsed.scheme)\n\n            timeout = min(self.request.connect_timeout, self.request.request_timeout)\n            if timeout:\n                self._timeout = self.io_loop.add_timeout(\n                    self.start_time + timeout,\n                    stack_context.wrap(functools.partial(self._on_timeout, \"while connecting\")))\n            self.tcp_client.connect(host, port, af=af,\n                                    ssl_options=ssl_options,\n                                    max_buffer_size=self.max_buffer_size,\n                                    callback=self._on_connect)\n\n    def _get_ssl_options(self, scheme):\n        if scheme == \"https\":\n            if self.request.ssl_options is not None:\n                return self.request.ssl_options\n            # If we are using the defaults, don't construct a\n            # new SSLContext.\n            if (self.request.validate_cert and\n                    self.request.ca_certs is None and\n                    self.request.client_cert is None and\n                    self.request.client_key is None):\n                return _client_ssl_defaults\n            ssl_options = {}\n            if self.request.validate_cert:\n                ssl_options[\"cert_reqs\"] = ssl.CERT_REQUIRED\n            if self.request.ca_certs is not None:\n                ssl_options[\"ca_certs\"] = self.request.ca_certs\n            elif not hasattr(ssl, 'create_default_context'):\n                # When create_default_context is present,\n                # we can omit the \"ca_certs\" parameter entirely,\n                # which avoids the dependency on \"certifi\" for py34.\n                ssl_options[\"ca_certs\"] = _default_ca_certs()\n            if self.request.client_key is not None:\n                ssl_options[\"keyfile\"] = self.request.client_key\n            if self.request.client_cert is not None:\n                ssl_options[\"certfile\"] = self.request.client_cert\n\n            # SSL interoperability is tricky.  We want to disable\n            # SSLv2 for security reasons; it wasn't disabled by default\n            # until openssl 1.0.  The best way to do this is to use\n            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python\n            # until 3.2.  Python 2.7 adds the ciphers argument, which\n            # can also be used to disable SSLv2.  As a last resort\n            # on python 2.6, we set ssl_version to TLSv1.  This is\n            # more narrow than we'd like since it also breaks\n            # compatibility with servers configured for SSLv3 only,\n            # but nearly all servers support both SSLv3 and TLSv1:\n            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html\n            if sys.version_info >= (2, 7):\n                # In addition to disabling SSLv2, we also exclude certain\n                # classes of insecure ciphers.\n                ssl_options[\"ciphers\"] = \"DEFAULT:!SSLv2:!EXPORT:!DES\"\n            else:\n                # This is really only necessary for pre-1.0 versions\n                # of openssl, but python 2.6 doesn't expose version\n                # information.\n                ssl_options[\"ssl_version\"] = ssl.PROTOCOL_TLSv1\n            return ssl_options\n        return None\n\n    def _on_timeout(self, info=None):\n        \"\"\"Timeout callback of _HTTPConnection instance.\n\n        Raise a timeout HTTPError when a timeout occurs.\n\n        :info string key: More detailed timeout information.\n        \"\"\"\n        self._timeout = None\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        if self.final_callback is not None:\n            raise HTTPError(599, error_message)\n\n    def _remove_timeout(self):\n        if self._timeout is not None:\n            self.io_loop.remove_timeout(self._timeout)\n            self._timeout = None\n\n    def _on_connect(self, stream):\n        if self.final_callback is None:\n            # final_callback is cleared if we've hit our timeout.\n            stream.close()\n            return\n        self.stream = stream\n        self.stream.set_close_callback(self.on_connection_close)\n        self._remove_timeout()\n        if self.final_callback is None:\n            return\n        if self.request.request_timeout:\n            self._timeout = self.io_loop.add_timeout(\n                self.start_time + self.request.request_timeout,\n                stack_context.wrap(functools.partial(self._on_timeout, \"during request\")))\n        if (self.request.method not in self._SUPPORTED_METHODS and\n                not self.request.allow_nonstandard_methods):\n            raise KeyError(\"unknown method %s\" % self.request.method)\n        for key in ('network_interface',\n                    'proxy_host', 'proxy_port',\n                    'proxy_username', 'proxy_password'):\n            if getattr(self.request, key, None):\n                raise NotImplementedError('%s not supported' % key)\n        if \"Connection\" not in self.request.headers:\n            self.request.headers[\"Connection\"] = \"close\"\n        if \"Host\" not in self.request.headers:\n            if '@' in self.parsed.netloc:\n                self.request.headers[\"Host\"] = self.parsed.netloc.rpartition('@')[-1]\n            else:\n                self.request.headers[\"Host\"] = self.parsed.netloc\n        username, password = None, None\n        if self.parsed.username is not None:\n            username, password = self.parsed.username, self.parsed.password\n        elif self.request.auth_username is not None:\n            username = self.request.auth_username\n            password = self.request.auth_password or ''\n        if username is not None:\n            if self.request.auth_mode not in (None, \"basic\"):\n                raise ValueError(\"unsupported auth_mode %s\",\n                                 self.request.auth_mode)\n            auth = utf8(username) + b\":\" + utf8(password)\n            self.request.headers[\"Authorization\"] = (b\"Basic \" +\n                                                     base64.b64encode(auth))\n        if self.request.user_agent:\n            self.request.headers[\"User-Agent\"] = self.request.user_agent\n        if not self.request.allow_nonstandard_methods:\n            # Some HTTP methods nearly always have bodies while others\n            # almost never do. Fail in this case unless the user has\n            # opted out of sanity checks with allow_nonstandard_methods.\n            body_expected = self.request.method in (\"POST\", \"PATCH\", \"PUT\")\n            body_present = (self.request.body is not None or\n                            self.request.body_producer is not None)\n            if ((body_expected and not body_present) or\n                    (body_present and not body_expected)):\n                raise ValueError(\n                    'Body must %sbe None for method %s (unless '\n                    'allow_nonstandard_methods is true)' %\n                    ('not ' if body_expected else '', self.request.method))\n        if self.request.expect_100_continue:\n            self.request.headers[\"Expect\"] = \"100-continue\"\n        if self.request.body is not None:\n            # When body_producer is used the caller is responsible for\n            # setting Content-Length (or else chunked encoding will be used).\n            self.request.headers[\"Content-Length\"] = str(len(\n                self.request.body))\n        if (self.request.method == \"POST\" and\n                \"Content-Type\" not in self.request.headers):\n            self.request.headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n        if self.request.decompress_response:\n            self.request.headers[\"Accept-Encoding\"] = \"gzip\"\n        req_path = ((self.parsed.path or '/') +\n                    (('?' + self.parsed.query) if self.parsed.query else ''))\n        self.connection = self._create_connection(stream)\n        start_line = httputil.RequestStartLine(self.request.method,\n                                               req_path, '')\n        self.connection.write_headers(start_line, self.request.headers)\n        if self.request.expect_100_continue:\n            self._read_response()\n        else:\n            self._write_body(True)\n\n    def _create_connection(self, stream):\n        stream.set_nodelay(True)\n        connection = HTTP1Connection(\n            stream, True,\n            HTTP1ConnectionParameters(\n                no_keep_alive=True,\n                max_header_size=self.max_header_size,\n                max_body_size=self.max_body_size,\n                decompress=self.request.decompress_response),\n            self._sockaddr)\n        return connection\n\n    def _write_body(self, start_read):\n        if self.request.body is not None:\n            self.connection.write(self.request.body)\n        elif self.request.body_producer is not None:\n            fut = self.request.body_producer(self.connection.write)\n            if fut is not None:\n                fut = gen.convert_yielded(fut)\n\n                def on_body_written(fut):\n                    fut.result()\n                    self.connection.finish()\n                    if start_read:\n                        self._read_response()\n                self.io_loop.add_future(fut, on_body_written)\n                return\n        self.connection.finish()\n        if start_read:\n            self._read_response()\n\n    def _read_response(self):\n        # Ensure that any exception raised in read_response ends up in our\n        # stack context.\n        self.io_loop.add_future(\n            self.connection.read_response(self),\n            lambda f: f.result())\n\n    def _release(self):\n        if self.release_callback is not None:\n            release_callback = self.release_callback\n            self.release_callback = None\n            release_callback()\n\n    def _run_callback(self, response):\n        self._release()\n        if self.final_callback is not None:\n            final_callback = self.final_callback\n            self.final_callback = None\n            self.io_loop.add_callback(final_callback, response)\n\n    def _handle_exception(self, typ, value, tb):\n        if self.final_callback:\n            self._remove_timeout()\n            if isinstance(value, StreamClosedError):\n                if value.real_error is None:\n                    value = HTTPError(599, \"Stream closed\")\n                else:\n                    value = value.real_error\n            self._run_callback(HTTPResponse(self.request, 599, error=value,\n                                            request_time=self.io_loop.time() - self.start_time,\n                                            ))\n\n            if hasattr(self, \"stream\"):\n                # TODO: this may cause a StreamClosedError to be raised\n                # by the connection's Future.  Should we cancel the\n                # connection more gracefully?\n                self.stream.close()\n            return True\n        else:\n            # If our callback has already been called, we are probably\n            # catching an exception that is not caused by us but rather\n            # some child of our callback. Rather than drop it on the floor,\n            # pass it along, unless it's just the stream being closed.\n            return isinstance(value, StreamClosedError)\n\n    def on_connection_close(self):\n        if self.final_callback is not None:\n            message = \"Connection closed\"\n            if self.stream.error:\n                raise self.stream.error\n            try:\n                raise HTTPError(599, message)\n            except HTTPError:\n                self._handle_exception(*sys.exc_info())\n\n    def headers_received(self, first_line, headers):\n        if self.request.expect_100_continue and first_line.code == 100:\n            self._write_body(False)\n            return\n        self.code = first_line.code\n        self.reason = first_line.reason\n        self.headers = headers\n\n        if self._should_follow_redirect():\n            return\n\n        if self.request.header_callback is not None:\n            # Reassemble the start line.\n            self.request.header_callback('%s %s %s\\r\\n' % first_line)\n            for k, v in self.headers.get_all():\n                self.request.header_callback(\"%s: %s\\r\\n\" % (k, v))\n            self.request.header_callback('\\r\\n')\n\n    def _should_follow_redirect(self):\n        return (self.request.follow_redirects and\n                self.request.max_redirects > 0 and\n                self.code in (301, 302, 303, 307))\n\n    def finish(self):\n        data = b''.join(self.chunks)\n        self._remove_timeout()\n        original_request = getattr(self.request, \"original_request\",\n                                   self.request)\n        if self._should_follow_redirect():\n            assert isinstance(self.request, _RequestProxy)\n            new_request = copy.copy(self.request.request)\n            new_request.url = urlparse.urljoin(self.request.url,\n                                               self.headers[\"Location\"])\n            new_request.max_redirects = self.request.max_redirects - 1\n            del new_request.headers[\"Host\"]\n            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4\n            # Client SHOULD make a GET request after a 303.\n            # According to the spec, 302 should be followed by the same\n            # method as the original request, but in practice browsers\n            # treat 302 the same as 303, and many servers use 302 for\n            # compatibility with pre-HTTP/1.1 user agents which don't\n            # understand the 303 status.\n            if self.code in (302, 303):\n                new_request.method = \"GET\"\n                new_request.body = None\n                for h in [\"Content-Length\", \"Content-Type\",\n                          \"Content-Encoding\", \"Transfer-Encoding\"]:\n                    try:\n                        del self.request.headers[h]\n                    except KeyError:\n                        pass\n            new_request.original_request = original_request\n            final_callback = self.final_callback\n            self.final_callback = None\n            self._release()\n            self.client.fetch(new_request, final_callback)\n            self._on_end_request()\n            return\n        if self.request.streaming_callback:\n            buffer = BytesIO()\n        else:\n            buffer = BytesIO(data)  # TODO: don't require one big string?\n        response = HTTPResponse(original_request,\n                                self.code, reason=getattr(self, 'reason', None),\n                                headers=self.headers,\n                                request_time=self.io_loop.time() - self.start_time,\n                                buffer=buffer,\n                                effective_url=self.request.url)\n        self._run_callback(response)\n        self._on_end_request()\n\n    def _on_end_request(self):\n        self.stream.close()\n\n    def data_received(self, chunk):\n        if self._should_follow_redirect():\n            # We're going to follow a redirect so just discard the body.\n            return\n        if self.request.streaming_callback is not None:\n            self.request.streaming_callback(chunk)\n        else:\n            self.chunks.append(chunk)\n\n\nif __name__ == \"__main__\":\n    AsyncHTTPClient.configure(SimpleAsyncHTTPClient)\n    main()\n",
            "header": {
                "file": {
                    "path": "tornado/simple_httpclient.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "ac6bd26e",
                "new_commit_hash": "44e45c43",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/simple_httpclient.py"
            },
            "plus_file": {
                "path": "b/tornado/simple_httpclient.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 323,
                            "length": 7
                        },
                        "new_range": {
                            "start": 323,
                            "length": 7
                        },
                        "section": "class _HTTPConnection(httputil.HTTPMessageDelegate):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        if self.request.request_timeout:",
                                "type": "context"
                            },
                            {
                                "content": "            self._timeout = self.io_loop.add_timeout(",
                                "type": "context"
                            },
                            {
                                "content": "                self.start_time + self.request.request_timeout,",
                                "type": "context"
                            },
                            {
                                "content": "                stack_context.wrap(functools.partial(self._on_timeout, \"while interacting\")))",
                                "type": "deleted"
                            },
                            {
                                "content": "                stack_context.wrap(functools.partial(self._on_timeout, \"during request\")))",
                                "type": "added"
                            },
                            {
                                "content": "        if (self.request.method not in self._SUPPORTED_METHODS and",
                                "type": "context"
                            },
                            {
                                "content": "                not self.request.allow_nonstandard_methods):",
                                "type": "context"
                            },
                            {
                                "content": "            raise KeyError(\"unknown method %s\" % self.request.method)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/simple_httpclient.py",
                            "type": "method",
                            "name": "_HTTPConnection._on_connect",
                            "content": "class _HTTPConnection(httputil.HTTPMessageDelegate):\n    _SUPPORTED_METHODS = set([\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"])\n\n    def __init__(self, io_loop, client, request, release_callback,\n                 final_callback, max_buffer_size, tcp_client,\n                 max_header_size, max_body_size):\n        self.start_time = io_loop.time()\n        self.io_loop = io_loop\n        self.client = client\n        self.request = request\n        self.release_callback = release_callback\n        self.final_callback = final_callback\n        self.max_buffer_size = max_buffer_size\n        self.tcp_client = tcp_client\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        self.code = None\n        self.headers = None\n        self.chunks = []\n        self._decompressor = None\n        # Timeout handle returned by IOLoop.add_timeout\n        self._timeout = None\n        self._sockaddr = None\n        with stack_context.ExceptionStackContext(self._handle_exception):\n            self.parsed = urlparse.urlsplit(_unicode(self.request.url))\n            if self.parsed.scheme not in (\"http\", \"https\"):\n                raise ValueError(\"Unsupported url scheme: %s\" %\n                                 self.request.url)\n            # urlsplit results have hostname and port results, but they\n            # didn't support ipv6 literals until python 2.7.\n            netloc = self.parsed.netloc\n            if \"@\" in netloc:\n                userpass, _, netloc = netloc.rpartition(\"@\")\n            host, port = httputil.split_host_and_port(netloc)\n            if port is None:\n                port = 443 if self.parsed.scheme == \"https\" else 80\n            if re.match(r'^\\[.*\\]$', host):\n                # raw ipv6 addresses in urls are enclosed in brackets\n                host = host[1:-1]\n            self.parsed_hostname = host  # save final host for _on_connect\n\n            if request.allow_ipv6 is False:\n                af = socket.AF_INET\n            else:\n                af = socket.AF_UNSPEC\n\n            ssl_options = self._get_ssl_options(self.parsed.scheme)\n\n            timeout = min(self.request.connect_timeout, self.request.request_timeout)\n            if timeout:\n                self._timeout = self.io_loop.add_timeout(\n                    self.start_time + timeout,\n                    stack_context.wrap(functools.partial(self._on_timeout, \"while connecting\")))\n            self.tcp_client.connect(host, port, af=af,\n                                    ssl_options=ssl_options,\n                                    max_buffer_size=self.max_buffer_size,\n                                    callback=self._on_connect)\n\n    def _get_ssl_options(self, scheme):\n        if scheme == \"https\":\n            if self.request.ssl_options is not None:\n                return self.request.ssl_options\n            # If we are using the defaults, don't construct a\n            # new SSLContext.\n            if (self.request.validate_cert and\n                    self.request.ca_certs is None and\n                    self.request.client_cert is None and\n                    self.request.client_key is None):\n                return _client_ssl_defaults\n            ssl_options = {}\n            if self.request.validate_cert:\n                ssl_options[\"cert_reqs\"] = ssl.CERT_REQUIRED\n            if self.request.ca_certs is not None:\n                ssl_options[\"ca_certs\"] = self.request.ca_certs\n            elif not hasattr(ssl, 'create_default_context'):\n                # When create_default_context is present,\n                # we can omit the \"ca_certs\" parameter entirely,\n                # which avoids the dependency on \"certifi\" for py34.\n                ssl_options[\"ca_certs\"] = _default_ca_certs()\n            if self.request.client_key is not None:\n                ssl_options[\"keyfile\"] = self.request.client_key\n            if self.request.client_cert is not None:\n                ssl_options[\"certfile\"] = self.request.client_cert\n\n            # SSL interoperability is tricky.  We want to disable\n            # SSLv2 for security reasons; it wasn't disabled by default\n            # until openssl 1.0.  The best way to do this is to use\n            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python\n            # until 3.2.  Python 2.7 adds the ciphers argument, which\n            # can also be used to disable SSLv2.  As a last resort\n            # on python 2.6, we set ssl_version to TLSv1.  This is\n            # more narrow than we'd like since it also breaks\n            # compatibility with servers configured for SSLv3 only,\n            # but nearly all servers support both SSLv3 and TLSv1:\n            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html\n            if sys.version_info >= (2, 7):\n                # In addition to disabling SSLv2, we also exclude certain\n                # classes of insecure ciphers.\n                ssl_options[\"ciphers\"] = \"DEFAULT:!SSLv2:!EXPORT:!DES\"\n            else:\n                # This is really only necessary for pre-1.0 versions\n                # of openssl, but python 2.6 doesn't expose version\n                # information.\n                ssl_options[\"ssl_version\"] = ssl.PROTOCOL_TLSv1\n            return ssl_options\n        return None\n\n    def _on_timeout(self, info=None):\n        \"\"\"Timeout callback of _HTTPConnection instance.\n\n        Raise a timeout HTTPError when a timeout occurs.\n\n        :info string key: More detailed timeout information.\n        \"\"\"\n        self._timeout = None\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        if self.final_callback is not None:\n            raise HTTPError(599, error_message)\n\n    def _remove_timeout(self):\n        if self._timeout is not None:\n            self.io_loop.remove_timeout(self._timeout)\n            self._timeout = None\n\n    def _on_connect(self, stream):\n        if self.final_callback is None:\n            # final_callback is cleared if we've hit our timeout.\n            stream.close()\n            return\n        self.stream = stream\n        self.stream.set_close_callback(self.on_connection_close)\n        self._remove_timeout()\n        if self.final_callback is None:\n            return\n        if self.request.request_timeout:\n            self._timeout = self.io_loop.add_timeout(\n                self.start_time + self.request.request_timeout,\n                stack_context.wrap(functools.partial(self._on_timeout, \"while interacting\")))\n        if (self.request.method not in self._SUPPORTED_METHODS and\n                not self.request.allow_nonstandard_methods):\n            raise KeyError(\"unknown method %s\" % self.request.method)\n        for key in ('network_interface',\n                    'proxy_host', 'proxy_port',\n                    'proxy_username', 'proxy_password'):\n            if getattr(self.request, key, None):\n                raise NotImplementedError('%s not supported' % key)\n        if \"Connection\" not in self.request.headers:\n            self.request.headers[\"Connection\"] = \"close\"\n        if \"Host\" not in self.request.headers:\n            if '@' in self.parsed.netloc:\n                self.request.headers[\"Host\"] = self.parsed.netloc.rpartition('@')[-1]\n            else:\n                self.request.headers[\"Host\"] = self.parsed.netloc\n        username, password = None, None\n        if self.parsed.username is not None:\n            username, password = self.parsed.username, self.parsed.password\n        elif self.request.auth_username is not None:\n            username = self.request.auth_username\n            password = self.request.auth_password or ''\n        if username is not None:\n            if self.request.auth_mode not in (None, \"basic\"):\n                raise ValueError(\"unsupported auth_mode %s\",\n                                 self.request.auth_mode)\n            auth = utf8(username) + b\":\" + utf8(password)\n            self.request.headers[\"Authorization\"] = (b\"Basic \" +\n                                                     base64.b64encode(auth))\n        if self.request.user_agent:\n            self.request.headers[\"User-Agent\"] = self.request.user_agent\n        if not self.request.allow_nonstandard_methods:\n            # Some HTTP methods nearly always have bodies while others\n            # almost never do. Fail in this case unless the user has\n            # opted out of sanity checks with allow_nonstandard_methods.\n            body_expected = self.request.method in (\"POST\", \"PATCH\", \"PUT\")\n            body_present = (self.request.body is not None or\n                            self.request.body_producer is not None)\n            if ((body_expected and not body_present) or\n                    (body_present and not body_expected)):\n                raise ValueError(\n                    'Body must %sbe None for method %s (unless '\n                    'allow_nonstandard_methods is true)' %\n                    ('not ' if body_expected else '', self.request.method))\n        if self.request.expect_100_continue:\n            self.request.headers[\"Expect\"] = \"100-continue\"\n        if self.request.body is not None:\n            # When body_producer is used the caller is responsible for\n            # setting Content-Length (or else chunked encoding will be used).\n            self.request.headers[\"Content-Length\"] = str(len(\n                self.request.body))\n        if (self.request.method == \"POST\" and\n                \"Content-Type\" not in self.request.headers):\n            self.request.headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n        if self.request.decompress_response:\n            self.request.headers[\"Accept-Encoding\"] = \"gzip\"\n        req_path = ((self.parsed.path or '/') +\n                    (('?' + self.parsed.query) if self.parsed.query else ''))\n        self.connection = self._create_connection(stream)\n        start_line = httputil.RequestStartLine(self.request.method,\n                                               req_path, '')\n        self.connection.write_headers(start_line, self.request.headers)\n        if self.request.expect_100_continue:\n            self._read_response()\n        else:\n            self._write_body(True)\n\n    def _create_connection(self, stream):\n        stream.set_nodelay(True)\n        connection = HTTP1Connection(\n            stream, True,\n            HTTP1ConnectionParameters(\n                no_keep_alive=True,\n                max_header_size=self.max_header_size,\n                max_body_size=self.max_body_size,\n                decompress=self.request.decompress_response),\n            self._sockaddr)\n        return connection\n\n    def _write_body(self, start_read):\n        if self.request.body is not None:\n            self.connection.write(self.request.body)\n        elif self.request.body_producer is not None:\n            fut = self.request.body_producer(self.connection.write)\n            if fut is not None:\n                fut = gen.convert_yielded(fut)\n\n                def on_body_written(fut):\n                    fut.result()\n                    self.connection.finish()\n                    if start_read:\n                        self._read_response()\n                self.io_loop.add_future(fut, on_body_written)\n                return\n        self.connection.finish()\n        if start_read:\n            self._read_response()\n\n    def _read_response(self):\n        # Ensure that any exception raised in read_response ends up in our\n        # stack context.\n        self.io_loop.add_future(\n            self.connection.read_response(self),\n            lambda f: f.result())\n\n    def _release(self):\n        if self.release_callback is not None:\n            release_callback = self.release_callback\n            self.release_callback = None\n            release_callback()\n\n    def _run_callback(self, response):\n        self._release()\n        if self.final_callback is not None:\n            final_callback = self.final_callback\n            self.final_callback = None\n            self.io_loop.add_callback(final_callback, response)\n\n    def _handle_exception(self, typ, value, tb):\n        if self.final_callback:\n            self._remove_timeout()\n            if isinstance(value, StreamClosedError):\n                if value.real_error is None:\n                    value = HTTPError(599, \"Stream closed\")\n                else:\n                    value = value.real_error\n            self._run_callback(HTTPResponse(self.request, 599, error=value,\n                                            request_time=self.io_loop.time() - self.start_time,\n                                            ))\n\n            if hasattr(self, \"stream\"):\n                # TODO: this may cause a StreamClosedError to be raised\n                # by the connection's Future.  Should we cancel the\n                # connection more gracefully?\n                self.stream.close()\n            return True\n        else:\n            # If our callback has already been called, we are probably\n            # catching an exception that is not caused by us but rather\n            # some child of our callback. Rather than drop it on the floor,\n            # pass it along, unless it's just the stream being closed.\n            return isinstance(value, StreamClosedError)\n\n    def on_connection_close(self):\n        if self.final_callback is not None:\n            message = \"Connection closed\"\n            if self.stream.error:\n                raise self.stream.error\n            try:\n                raise HTTPError(599, message)\n            except HTTPError:\n                self._handle_exception(*sys.exc_info())\n\n    def headers_received(self, first_line, headers):\n        if self.request.expect_100_continue and first_line.code == 100:\n            self._write_body(False)\n            return\n        self.code = first_line.code\n        self.reason = first_line.reason\n        self.headers = headers\n\n        if self._should_follow_redirect():\n            return\n\n        if self.request.header_callback is not None:\n            # Reassemble the start line.\n            self.request.header_callback('%s %s %s\\r\\n' % first_line)\n            for k, v in self.headers.get_all():\n                self.request.header_callback(\"%s: %s\\r\\n\" % (k, v))\n            self.request.header_callback('\\r\\n')\n\n    def _should_follow_redirect(self):\n        return (self.request.follow_redirects and\n                self.request.max_redirects > 0 and\n                self.code in (301, 302, 303, 307))\n\n    def finish(self):\n        data = b''.join(self.chunks)\n        self._remove_timeout()\n        original_request = getattr(self.request, \"original_request\",\n                                   self.request)\n        if self._should_follow_redirect():\n            assert isinstance(self.request, _RequestProxy)\n            new_request = copy.copy(self.request.request)\n            new_request.url = urlparse.urljoin(self.request.url,\n                                               self.headers[\"Location\"])\n            new_request.max_redirects = self.request.max_redirects - 1\n            del new_request.headers[\"Host\"]\n            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4\n            # Client SHOULD make a GET request after a 303.\n            # According to the spec, 302 should be followed by the same\n            # method as the original request, but in practice browsers\n            # treat 302 the same as 303, and many servers use 302 for\n            # compatibility with pre-HTTP/1.1 user agents which don't\n            # understand the 303 status.\n            if self.code in (302, 303):\n                new_request.method = \"GET\"\n                new_request.body = None\n                for h in [\"Content-Length\", \"Content-Type\",\n                          \"Content-Encoding\", \"Transfer-Encoding\"]:\n                    try:\n                        del self.request.headers[h]\n                    except KeyError:\n                        pass\n            new_request.original_request = original_request\n            final_callback = self.final_callback\n            self.final_callback = None\n            self._release()\n            self.client.fetch(new_request, final_callback)\n            self._on_end_request()\n            return\n        if self.request.streaming_callback:\n            buffer = BytesIO()\n        else:\n            buffer = BytesIO(data)  # TODO: don't require one big string?\n        response = HTTPResponse(original_request,\n                                self.code, reason=getattr(self, 'reason', None),\n                                headers=self.headers,\n                                request_time=self.io_loop.time() - self.start_time,\n                                buffer=buffer,\n                                effective_url=self.request.url)\n        self._run_callback(response)\n        self._on_end_request()\n\n    def _on_end_request(self):\n        self.stream.close()\n\n    def data_received(self, chunk):\n        if self._should_follow_redirect():\n            # We're going to follow a redirect so just discard the body.\n            return\n        if self.request.streaming_callback is not None:\n            self.request.streaming_callback(chunk)\n        else:\n            self.chunks.append(chunk)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 313,
                            "end_lineno": 391,
                            "parent": {
                                "file_name": "tornado/simple_httpclient.py",
                                "type": "class",
                                "name": "_HTTPConnection",
                                "content": "class _HTTPConnection(httputil.HTTPMessageDelegate):\n    _SUPPORTED_METHODS = set([\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"])\n\n    def __init__(self, io_loop, client, request, release_callback,\n                 final_callback, max_buffer_size, tcp_client,\n                 max_header_size, max_body_size):\n        self.start_time = io_loop.time()\n        self.io_loop = io_loop\n        self.client = client\n        self.request = request\n        self.release_callback = release_callback\n        self.final_callback = final_callback\n        self.max_buffer_size = max_buffer_size\n        self.tcp_client = tcp_client\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        self.code = None\n        self.headers = None\n        self.chunks = []\n        self._decompressor = None\n        # Timeout handle returned by IOLoop.add_timeout\n        self._timeout = None\n        self._sockaddr = None\n        with stack_context.ExceptionStackContext(self._handle_exception):\n            self.parsed = urlparse.urlsplit(_unicode(self.request.url))\n            if self.parsed.scheme not in (\"http\", \"https\"):\n                raise ValueError(\"Unsupported url scheme: %s\" %\n                                 self.request.url)\n            # urlsplit results have hostname and port results, but they\n            # didn't support ipv6 literals until python 2.7.\n            netloc = self.parsed.netloc\n            if \"@\" in netloc:\n                userpass, _, netloc = netloc.rpartition(\"@\")\n            host, port = httputil.split_host_and_port(netloc)\n            if port is None:\n                port = 443 if self.parsed.scheme == \"https\" else 80\n            if re.match(r'^\\[.*\\]$', host):\n                # raw ipv6 addresses in urls are enclosed in brackets\n                host = host[1:-1]\n            self.parsed_hostname = host  # save final host for _on_connect\n\n            if request.allow_ipv6 is False:\n                af = socket.AF_INET\n            else:\n                af = socket.AF_UNSPEC\n\n            ssl_options = self._get_ssl_options(self.parsed.scheme)\n\n            timeout = min(self.request.connect_timeout, self.request.request_timeout)\n            if timeout:\n                self._timeout = self.io_loop.add_timeout(\n                    self.start_time + timeout,\n                    stack_context.wrap(functools.partial(self._on_timeout, \"while connecting\")))\n            self.tcp_client.connect(host, port, af=af,\n                                    ssl_options=ssl_options,\n                                    max_buffer_size=self.max_buffer_size,\n                                    callback=self._on_connect)\n\n    def _get_ssl_options(self, scheme):\n        if scheme == \"https\":\n            if self.request.ssl_options is not None:\n                return self.request.ssl_options\n            # If we are using the defaults, don't construct a\n            # new SSLContext.\n            if (self.request.validate_cert and\n                    self.request.ca_certs is None and\n                    self.request.client_cert is None and\n                    self.request.client_key is None):\n                return _client_ssl_defaults\n            ssl_options = {}\n            if self.request.validate_cert:\n                ssl_options[\"cert_reqs\"] = ssl.CERT_REQUIRED\n            if self.request.ca_certs is not None:\n                ssl_options[\"ca_certs\"] = self.request.ca_certs\n            elif not hasattr(ssl, 'create_default_context'):\n                # When create_default_context is present,\n                # we can omit the \"ca_certs\" parameter entirely,\n                # which avoids the dependency on \"certifi\" for py34.\n                ssl_options[\"ca_certs\"] = _default_ca_certs()\n            if self.request.client_key is not None:\n                ssl_options[\"keyfile\"] = self.request.client_key\n            if self.request.client_cert is not None:\n                ssl_options[\"certfile\"] = self.request.client_cert\n\n            # SSL interoperability is tricky.  We want to disable\n            # SSLv2 for security reasons; it wasn't disabled by default\n            # until openssl 1.0.  The best way to do this is to use\n            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python\n            # until 3.2.  Python 2.7 adds the ciphers argument, which\n            # can also be used to disable SSLv2.  As a last resort\n            # on python 2.6, we set ssl_version to TLSv1.  This is\n            # more narrow than we'd like since it also breaks\n            # compatibility with servers configured for SSLv3 only,\n            # but nearly all servers support both SSLv3 and TLSv1:\n            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html\n            if sys.version_info >= (2, 7):\n                # In addition to disabling SSLv2, we also exclude certain\n                # classes of insecure ciphers.\n                ssl_options[\"ciphers\"] = \"DEFAULT:!SSLv2:!EXPORT:!DES\"\n            else:\n                # This is really only necessary for pre-1.0 versions\n                # of openssl, but python 2.6 doesn't expose version\n                # information.\n                ssl_options[\"ssl_version\"] = ssl.PROTOCOL_TLSv1\n            return ssl_options\n        return None\n\n    def _on_timeout(self, info=None):\n        \"\"\"Timeout callback of _HTTPConnection instance.\n\n        Raise a timeout HTTPError when a timeout occurs.\n\n        :info string key: More detailed timeout information.\n        \"\"\"\n        self._timeout = None\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        if self.final_callback is not None:\n            raise HTTPError(599, error_message)\n\n    def _remove_timeout(self):\n        if self._timeout is not None:\n            self.io_loop.remove_timeout(self._timeout)\n            self._timeout = None\n\n    def _on_connect(self, stream):\n        if self.final_callback is None:\n            # final_callback is cleared if we've hit our timeout.\n            stream.close()\n            return\n        self.stream = stream\n        self.stream.set_close_callback(self.on_connection_close)\n        self._remove_timeout()\n        if self.final_callback is None:\n            return\n        if self.request.request_timeout:\n            self._timeout = self.io_loop.add_timeout(\n                self.start_time + self.request.request_timeout,\n                stack_context.wrap(functools.partial(self._on_timeout, \"while interacting\")))\n        if (self.request.method not in self._SUPPORTED_METHODS and\n                not self.request.allow_nonstandard_methods):\n            raise KeyError(\"unknown method %s\" % self.request.method)\n        for key in ('network_interface',\n                    'proxy_host', 'proxy_port',\n                    'proxy_username', 'proxy_password'):\n            if getattr(self.request, key, None):\n                raise NotImplementedError('%s not supported' % key)\n        if \"Connection\" not in self.request.headers:\n            self.request.headers[\"Connection\"] = \"close\"\n        if \"Host\" not in self.request.headers:\n            if '@' in self.parsed.netloc:\n                self.request.headers[\"Host\"] = self.parsed.netloc.rpartition('@')[-1]\n            else:\n                self.request.headers[\"Host\"] = self.parsed.netloc\n        username, password = None, None\n        if self.parsed.username is not None:\n            username, password = self.parsed.username, self.parsed.password\n        elif self.request.auth_username is not None:\n            username = self.request.auth_username\n            password = self.request.auth_password or ''\n        if username is not None:\n            if self.request.auth_mode not in (None, \"basic\"):\n                raise ValueError(\"unsupported auth_mode %s\",\n                                 self.request.auth_mode)\n            auth = utf8(username) + b\":\" + utf8(password)\n            self.request.headers[\"Authorization\"] = (b\"Basic \" +\n                                                     base64.b64encode(auth))\n        if self.request.user_agent:\n            self.request.headers[\"User-Agent\"] = self.request.user_agent\n        if not self.request.allow_nonstandard_methods:\n            # Some HTTP methods nearly always have bodies while others\n            # almost never do. Fail in this case unless the user has\n            # opted out of sanity checks with allow_nonstandard_methods.\n            body_expected = self.request.method in (\"POST\", \"PATCH\", \"PUT\")\n            body_present = (self.request.body is not None or\n                            self.request.body_producer is not None)\n            if ((body_expected and not body_present) or\n                    (body_present and not body_expected)):\n                raise ValueError(\n                    'Body must %sbe None for method %s (unless '\n                    'allow_nonstandard_methods is true)' %\n                    ('not ' if body_expected else '', self.request.method))\n        if self.request.expect_100_continue:\n            self.request.headers[\"Expect\"] = \"100-continue\"\n        if self.request.body is not None:\n            # When body_producer is used the caller is responsible for\n            # setting Content-Length (or else chunked encoding will be used).\n            self.request.headers[\"Content-Length\"] = str(len(\n                self.request.body))\n        if (self.request.method == \"POST\" and\n                \"Content-Type\" not in self.request.headers):\n            self.request.headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n        if self.request.decompress_response:\n            self.request.headers[\"Accept-Encoding\"] = \"gzip\"\n        req_path = ((self.parsed.path or '/') +\n                    (('?' + self.parsed.query) if self.parsed.query else ''))\n        self.connection = self._create_connection(stream)\n        start_line = httputil.RequestStartLine(self.request.method,\n                                               req_path, '')\n        self.connection.write_headers(start_line, self.request.headers)\n        if self.request.expect_100_continue:\n            self._read_response()\n        else:\n            self._write_body(True)\n\n    def _create_connection(self, stream):\n        stream.set_nodelay(True)\n        connection = HTTP1Connection(\n            stream, True,\n            HTTP1ConnectionParameters(\n                no_keep_alive=True,\n                max_header_size=self.max_header_size,\n                max_body_size=self.max_body_size,\n                decompress=self.request.decompress_response),\n            self._sockaddr)\n        return connection\n\n    def _write_body(self, start_read):\n        if self.request.body is not None:\n            self.connection.write(self.request.body)\n        elif self.request.body_producer is not None:\n            fut = self.request.body_producer(self.connection.write)\n            if fut is not None:\n                fut = gen.convert_yielded(fut)\n\n                def on_body_written(fut):\n                    fut.result()\n                    self.connection.finish()\n                    if start_read:\n                        self._read_response()\n                self.io_loop.add_future(fut, on_body_written)\n                return\n        self.connection.finish()\n        if start_read:\n            self._read_response()\n\n    def _read_response(self):\n        # Ensure that any exception raised in read_response ends up in our\n        # stack context.\n        self.io_loop.add_future(\n            self.connection.read_response(self),\n            lambda f: f.result())\n\n    def _release(self):\n        if self.release_callback is not None:\n            release_callback = self.release_callback\n            self.release_callback = None\n            release_callback()\n\n    def _run_callback(self, response):\n        self._release()\n        if self.final_callback is not None:\n            final_callback = self.final_callback\n            self.final_callback = None\n            self.io_loop.add_callback(final_callback, response)\n\n    def _handle_exception(self, typ, value, tb):\n        if self.final_callback:\n            self._remove_timeout()\n            if isinstance(value, StreamClosedError):\n                if value.real_error is None:\n                    value = HTTPError(599, \"Stream closed\")\n                else:\n                    value = value.real_error\n            self._run_callback(HTTPResponse(self.request, 599, error=value,\n                                            request_time=self.io_loop.time() - self.start_time,\n                                            ))\n\n            if hasattr(self, \"stream\"):\n                # TODO: this may cause a StreamClosedError to be raised\n                # by the connection's Future.  Should we cancel the\n                # connection more gracefully?\n                self.stream.close()\n            return True\n        else:\n            # If our callback has already been called, we are probably\n            # catching an exception that is not caused by us but rather\n            # some child of our callback. Rather than drop it on the floor,\n            # pass it along, unless it's just the stream being closed.\n            return isinstance(value, StreamClosedError)\n\n    def on_connection_close(self):\n        if self.final_callback is not None:\n            message = \"Connection closed\"\n            if self.stream.error:\n                raise self.stream.error\n            try:\n                raise HTTPError(599, message)\n            except HTTPError:\n                self._handle_exception(*sys.exc_info())\n\n    def headers_received(self, first_line, headers):\n        if self.request.expect_100_continue and first_line.code == 100:\n            self._write_body(False)\n            return\n        self.code = first_line.code\n        self.reason = first_line.reason\n        self.headers = headers\n\n        if self._should_follow_redirect():\n            return\n\n        if self.request.header_callback is not None:\n            # Reassemble the start line.\n            self.request.header_callback('%s %s %s\\r\\n' % first_line)\n            for k, v in self.headers.get_all():\n                self.request.header_callback(\"%s: %s\\r\\n\" % (k, v))\n            self.request.header_callback('\\r\\n')\n\n    def _should_follow_redirect(self):\n        return (self.request.follow_redirects and\n                self.request.max_redirects > 0 and\n                self.code in (301, 302, 303, 307))\n\n    def finish(self):\n        data = b''.join(self.chunks)\n        self._remove_timeout()\n        original_request = getattr(self.request, \"original_request\",\n                                   self.request)\n        if self._should_follow_redirect():\n            assert isinstance(self.request, _RequestProxy)\n            new_request = copy.copy(self.request.request)\n            new_request.url = urlparse.urljoin(self.request.url,\n                                               self.headers[\"Location\"])\n            new_request.max_redirects = self.request.max_redirects - 1\n            del new_request.headers[\"Host\"]\n            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4\n            # Client SHOULD make a GET request after a 303.\n            # According to the spec, 302 should be followed by the same\n            # method as the original request, but in practice browsers\n            # treat 302 the same as 303, and many servers use 302 for\n            # compatibility with pre-HTTP/1.1 user agents which don't\n            # understand the 303 status.\n            if self.code in (302, 303):\n                new_request.method = \"GET\"\n                new_request.body = None\n                for h in [\"Content-Length\", \"Content-Type\",\n                          \"Content-Encoding\", \"Transfer-Encoding\"]:\n                    try:\n                        del self.request.headers[h]\n                    except KeyError:\n                        pass\n            new_request.original_request = original_request\n            final_callback = self.final_callback\n            self.final_callback = None\n            self._release()\n            self.client.fetch(new_request, final_callback)\n            self._on_end_request()\n            return\n        if self.request.streaming_callback:\n            buffer = BytesIO()\n        else:\n            buffer = BytesIO(data)  # TODO: don't require one big string?\n        response = HTTPResponse(original_request,\n                                self.code, reason=getattr(self, 'reason', None),\n                                headers=self.headers,\n                                request_time=self.io_loop.time() - self.start_time,\n                                buffer=buffer,\n                                effective_url=self.request.url)\n        self._run_callback(response)\n        self._on_end_request()\n\n    def _on_end_request(self):\n        self.stream.close()\n\n    def data_received(self, chunk):\n        if self._should_follow_redirect():\n            # We're going to follow a redirect so just discard the body.\n            return\n        if self.request.streaming_callback is not None:\n            self.request.streaming_callback(chunk)\n        else:\n            self.chunks.append(chunk)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 189,
                                "end_lineno": 560,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/simple_httpclient.py",
                            "type": "class",
                            "name": "_HTTPConnection",
                            "content": "class _HTTPConnection(httputil.HTTPMessageDelegate):\n    _SUPPORTED_METHODS = set([\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"])\n\n    def __init__(self, io_loop, client, request, release_callback,\n                 final_callback, max_buffer_size, tcp_client,\n                 max_header_size, max_body_size):\n        self.start_time = io_loop.time()\n        self.io_loop = io_loop\n        self.client = client\n        self.request = request\n        self.release_callback = release_callback\n        self.final_callback = final_callback\n        self.max_buffer_size = max_buffer_size\n        self.tcp_client = tcp_client\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        self.code = None\n        self.headers = None\n        self.chunks = []\n        self._decompressor = None\n        # Timeout handle returned by IOLoop.add_timeout\n        self._timeout = None\n        self._sockaddr = None\n        with stack_context.ExceptionStackContext(self._handle_exception):\n            self.parsed = urlparse.urlsplit(_unicode(self.request.url))\n            if self.parsed.scheme not in (\"http\", \"https\"):\n                raise ValueError(\"Unsupported url scheme: %s\" %\n                                 self.request.url)\n            # urlsplit results have hostname and port results, but they\n            # didn't support ipv6 literals until python 2.7.\n            netloc = self.parsed.netloc\n            if \"@\" in netloc:\n                userpass, _, netloc = netloc.rpartition(\"@\")\n            host, port = httputil.split_host_and_port(netloc)\n            if port is None:\n                port = 443 if self.parsed.scheme == \"https\" else 80\n            if re.match(r'^\\[.*\\]$', host):\n                # raw ipv6 addresses in urls are enclosed in brackets\n                host = host[1:-1]\n            self.parsed_hostname = host  # save final host for _on_connect\n\n            if request.allow_ipv6 is False:\n                af = socket.AF_INET\n            else:\n                af = socket.AF_UNSPEC\n\n            ssl_options = self._get_ssl_options(self.parsed.scheme)\n\n            timeout = min(self.request.connect_timeout, self.request.request_timeout)\n            if timeout:\n                self._timeout = self.io_loop.add_timeout(\n                    self.start_time + timeout,\n                    stack_context.wrap(functools.partial(self._on_timeout, \"while connecting\")))\n            self.tcp_client.connect(host, port, af=af,\n                                    ssl_options=ssl_options,\n                                    max_buffer_size=self.max_buffer_size,\n                                    callback=self._on_connect)\n\n    def _get_ssl_options(self, scheme):\n        if scheme == \"https\":\n            if self.request.ssl_options is not None:\n                return self.request.ssl_options\n            # If we are using the defaults, don't construct a\n            # new SSLContext.\n            if (self.request.validate_cert and\n                    self.request.ca_certs is None and\n                    self.request.client_cert is None and\n                    self.request.client_key is None):\n                return _client_ssl_defaults\n            ssl_options = {}\n            if self.request.validate_cert:\n                ssl_options[\"cert_reqs\"] = ssl.CERT_REQUIRED\n            if self.request.ca_certs is not None:\n                ssl_options[\"ca_certs\"] = self.request.ca_certs\n            elif not hasattr(ssl, 'create_default_context'):\n                # When create_default_context is present,\n                # we can omit the \"ca_certs\" parameter entirely,\n                # which avoids the dependency on \"certifi\" for py34.\n                ssl_options[\"ca_certs\"] = _default_ca_certs()\n            if self.request.client_key is not None:\n                ssl_options[\"keyfile\"] = self.request.client_key\n            if self.request.client_cert is not None:\n                ssl_options[\"certfile\"] = self.request.client_cert\n\n            # SSL interoperability is tricky.  We want to disable\n            # SSLv2 for security reasons; it wasn't disabled by default\n            # until openssl 1.0.  The best way to do this is to use\n            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python\n            # until 3.2.  Python 2.7 adds the ciphers argument, which\n            # can also be used to disable SSLv2.  As a last resort\n            # on python 2.6, we set ssl_version to TLSv1.  This is\n            # more narrow than we'd like since it also breaks\n            # compatibility with servers configured for SSLv3 only,\n            # but nearly all servers support both SSLv3 and TLSv1:\n            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html\n            if sys.version_info >= (2, 7):\n                # In addition to disabling SSLv2, we also exclude certain\n                # classes of insecure ciphers.\n                ssl_options[\"ciphers\"] = \"DEFAULT:!SSLv2:!EXPORT:!DES\"\n            else:\n                # This is really only necessary for pre-1.0 versions\n                # of openssl, but python 2.6 doesn't expose version\n                # information.\n                ssl_options[\"ssl_version\"] = ssl.PROTOCOL_TLSv1\n            return ssl_options\n        return None\n\n    def _on_timeout(self, info=None):\n        \"\"\"Timeout callback of _HTTPConnection instance.\n\n        Raise a timeout HTTPError when a timeout occurs.\n\n        :info string key: More detailed timeout information.\n        \"\"\"\n        self._timeout = None\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        if self.final_callback is not None:\n            raise HTTPError(599, error_message)\n\n    def _remove_timeout(self):\n        if self._timeout is not None:\n            self.io_loop.remove_timeout(self._timeout)\n            self._timeout = None\n\n    def _on_connect(self, stream):\n        if self.final_callback is None:\n            # final_callback is cleared if we've hit our timeout.\n            stream.close()\n            return\n        self.stream = stream\n        self.stream.set_close_callback(self.on_connection_close)\n        self._remove_timeout()\n        if self.final_callback is None:\n            return\n        if self.request.request_timeout:\n            self._timeout = self.io_loop.add_timeout(\n                self.start_time + self.request.request_timeout,\n                stack_context.wrap(functools.partial(self._on_timeout, \"while interacting\")))\n        if (self.request.method not in self._SUPPORTED_METHODS and\n                not self.request.allow_nonstandard_methods):\n            raise KeyError(\"unknown method %s\" % self.request.method)\n        for key in ('network_interface',\n                    'proxy_host', 'proxy_port',\n                    'proxy_username', 'proxy_password'):\n            if getattr(self.request, key, None):\n                raise NotImplementedError('%s not supported' % key)\n        if \"Connection\" not in self.request.headers:\n            self.request.headers[\"Connection\"] = \"close\"\n        if \"Host\" not in self.request.headers:\n            if '@' in self.parsed.netloc:\n                self.request.headers[\"Host\"] = self.parsed.netloc.rpartition('@')[-1]\n            else:\n                self.request.headers[\"Host\"] = self.parsed.netloc\n        username, password = None, None\n        if self.parsed.username is not None:\n            username, password = self.parsed.username, self.parsed.password\n        elif self.request.auth_username is not None:\n            username = self.request.auth_username\n            password = self.request.auth_password or ''\n        if username is not None:\n            if self.request.auth_mode not in (None, \"basic\"):\n                raise ValueError(\"unsupported auth_mode %s\",\n                                 self.request.auth_mode)\n            auth = utf8(username) + b\":\" + utf8(password)\n            self.request.headers[\"Authorization\"] = (b\"Basic \" +\n                                                     base64.b64encode(auth))\n        if self.request.user_agent:\n            self.request.headers[\"User-Agent\"] = self.request.user_agent\n        if not self.request.allow_nonstandard_methods:\n            # Some HTTP methods nearly always have bodies while others\n            # almost never do. Fail in this case unless the user has\n            # opted out of sanity checks with allow_nonstandard_methods.\n            body_expected = self.request.method in (\"POST\", \"PATCH\", \"PUT\")\n            body_present = (self.request.body is not None or\n                            self.request.body_producer is not None)\n            if ((body_expected and not body_present) or\n                    (body_present and not body_expected)):\n                raise ValueError(\n                    'Body must %sbe None for method %s (unless '\n                    'allow_nonstandard_methods is true)' %\n                    ('not ' if body_expected else '', self.request.method))\n        if self.request.expect_100_continue:\n            self.request.headers[\"Expect\"] = \"100-continue\"\n        if self.request.body is not None:\n            # When body_producer is used the caller is responsible for\n            # setting Content-Length (or else chunked encoding will be used).\n            self.request.headers[\"Content-Length\"] = str(len(\n                self.request.body))\n        if (self.request.method == \"POST\" and\n                \"Content-Type\" not in self.request.headers):\n            self.request.headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n        if self.request.decompress_response:\n            self.request.headers[\"Accept-Encoding\"] = \"gzip\"\n        req_path = ((self.parsed.path or '/') +\n                    (('?' + self.parsed.query) if self.parsed.query else ''))\n        self.connection = self._create_connection(stream)\n        start_line = httputil.RequestStartLine(self.request.method,\n                                               req_path, '')\n        self.connection.write_headers(start_line, self.request.headers)\n        if self.request.expect_100_continue:\n            self._read_response()\n        else:\n            self._write_body(True)\n\n    def _create_connection(self, stream):\n        stream.set_nodelay(True)\n        connection = HTTP1Connection(\n            stream, True,\n            HTTP1ConnectionParameters(\n                no_keep_alive=True,\n                max_header_size=self.max_header_size,\n                max_body_size=self.max_body_size,\n                decompress=self.request.decompress_response),\n            self._sockaddr)\n        return connection\n\n    def _write_body(self, start_read):\n        if self.request.body is not None:\n            self.connection.write(self.request.body)\n        elif self.request.body_producer is not None:\n            fut = self.request.body_producer(self.connection.write)\n            if fut is not None:\n                fut = gen.convert_yielded(fut)\n\n                def on_body_written(fut):\n                    fut.result()\n                    self.connection.finish()\n                    if start_read:\n                        self._read_response()\n                self.io_loop.add_future(fut, on_body_written)\n                return\n        self.connection.finish()\n        if start_read:\n            self._read_response()\n\n    def _read_response(self):\n        # Ensure that any exception raised in read_response ends up in our\n        # stack context.\n        self.io_loop.add_future(\n            self.connection.read_response(self),\n            lambda f: f.result())\n\n    def _release(self):\n        if self.release_callback is not None:\n            release_callback = self.release_callback\n            self.release_callback = None\n            release_callback()\n\n    def _run_callback(self, response):\n        self._release()\n        if self.final_callback is not None:\n            final_callback = self.final_callback\n            self.final_callback = None\n            self.io_loop.add_callback(final_callback, response)\n\n    def _handle_exception(self, typ, value, tb):\n        if self.final_callback:\n            self._remove_timeout()\n            if isinstance(value, StreamClosedError):\n                if value.real_error is None:\n                    value = HTTPError(599, \"Stream closed\")\n                else:\n                    value = value.real_error\n            self._run_callback(HTTPResponse(self.request, 599, error=value,\n                                            request_time=self.io_loop.time() - self.start_time,\n                                            ))\n\n            if hasattr(self, \"stream\"):\n                # TODO: this may cause a StreamClosedError to be raised\n                # by the connection's Future.  Should we cancel the\n                # connection more gracefully?\n                self.stream.close()\n            return True\n        else:\n            # If our callback has already been called, we are probably\n            # catching an exception that is not caused by us but rather\n            # some child of our callback. Rather than drop it on the floor,\n            # pass it along, unless it's just the stream being closed.\n            return isinstance(value, StreamClosedError)\n\n    def on_connection_close(self):\n        if self.final_callback is not None:\n            message = \"Connection closed\"\n            if self.stream.error:\n                raise self.stream.error\n            try:\n                raise HTTPError(599, message)\n            except HTTPError:\n                self._handle_exception(*sys.exc_info())\n\n    def headers_received(self, first_line, headers):\n        if self.request.expect_100_continue and first_line.code == 100:\n            self._write_body(False)\n            return\n        self.code = first_line.code\n        self.reason = first_line.reason\n        self.headers = headers\n\n        if self._should_follow_redirect():\n            return\n\n        if self.request.header_callback is not None:\n            # Reassemble the start line.\n            self.request.header_callback('%s %s %s\\r\\n' % first_line)\n            for k, v in self.headers.get_all():\n                self.request.header_callback(\"%s: %s\\r\\n\" % (k, v))\n            self.request.header_callback('\\r\\n')\n\n    def _should_follow_redirect(self):\n        return (self.request.follow_redirects and\n                self.request.max_redirects > 0 and\n                self.code in (301, 302, 303, 307))\n\n    def finish(self):\n        data = b''.join(self.chunks)\n        self._remove_timeout()\n        original_request = getattr(self.request, \"original_request\",\n                                   self.request)\n        if self._should_follow_redirect():\n            assert isinstance(self.request, _RequestProxy)\n            new_request = copy.copy(self.request.request)\n            new_request.url = urlparse.urljoin(self.request.url,\n                                               self.headers[\"Location\"])\n            new_request.max_redirects = self.request.max_redirects - 1\n            del new_request.headers[\"Host\"]\n            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4\n            # Client SHOULD make a GET request after a 303.\n            # According to the spec, 302 should be followed by the same\n            # method as the original request, but in practice browsers\n            # treat 302 the same as 303, and many servers use 302 for\n            # compatibility with pre-HTTP/1.1 user agents which don't\n            # understand the 303 status.\n            if self.code in (302, 303):\n                new_request.method = \"GET\"\n                new_request.body = None\n                for h in [\"Content-Length\", \"Content-Type\",\n                          \"Content-Encoding\", \"Transfer-Encoding\"]:\n                    try:\n                        del self.request.headers[h]\n                    except KeyError:\n                        pass\n            new_request.original_request = original_request\n            final_callback = self.final_callback\n            self.final_callback = None\n            self._release()\n            self.client.fetch(new_request, final_callback)\n            self._on_end_request()\n            return\n        if self.request.streaming_callback:\n            buffer = BytesIO()\n        else:\n            buffer = BytesIO(data)  # TODO: don't require one big string?\n        response = HTTPResponse(original_request,\n                                self.code, reason=getattr(self, 'reason', None),\n                                headers=self.headers,\n                                request_time=self.io_loop.time() - self.start_time,\n                                buffer=buffer,\n                                effective_url=self.request.url)\n        self._run_callback(response)\n        self._on_end_request()\n\n    def _on_end_request(self):\n        self.stream.close()\n\n    def data_received(self, chunk):\n        if self._should_follow_redirect():\n            # We're going to follow a redirect so just discard the body.\n            return\n        if self.request.streaming_callback is not None:\n            self.request.streaming_callback(chunk)\n        else:\n            self.chunks.append(chunk)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 189,
                            "end_lineno": 560,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nfrom contextlib import closing\nimport errno\nimport gzip\nimport logging\nimport os\nimport re\nimport socket\nimport ssl\nimport sys\nimport time\n\nfrom tornado.escape import to_unicode\nfrom tornado import gen\nfrom tornado.httpclient import AsyncHTTPClient\nfrom tornado.httputil import HTTPHeaders, ResponseStartLine\nfrom tornado.ioloop import IOLoop\nfrom tornado.log import gen_log\nfrom tornado.netutil import Resolver, bind_sockets, BlockingResolver\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient, _HTTPConnection\nfrom tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler, RedirectHandler\nfrom tornado.test import httpclient_test\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog\nfrom tornado.test.util import skipOnTravis, skipIfNoIPv6, refusing_port, unittest, skipBefore35, exec_test\nfrom tornado.web import RequestHandler, Application, asynchronous, url, stream_request_body\n\n\nclass SimpleHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase):\n    def get_http_client(self):\n        client = SimpleAsyncHTTPClient(io_loop=self.io_loop,\n                                       force_instance=True)\n        self.assertTrue(isinstance(client, SimpleAsyncHTTPClient))\n        return client\n\n\nclass TriggerHandler(RequestHandler):\n    def initialize(self, queue, wake_callback):\n        self.queue = queue\n        self.wake_callback = wake_callback\n\n    @asynchronous\n    def get(self):\n        logging.debug(\"queuing trigger\")\n        self.queue.append(self.finish)\n        if self.get_argument(\"wake\", \"true\") == \"true\":\n            self.wake_callback()\n\n\nclass HangHandler(RequestHandler):\n    @asynchronous\n    def get(self):\n        pass\n\n\nclass ContentLengthHandler(RequestHandler):\n    def get(self):\n        self.set_header(\"Content-Length\", self.get_argument(\"value\"))\n        self.write(\"ok\")\n\n\nclass HeadHandler(RequestHandler):\n    def head(self):\n        self.set_header(\"Content-Length\", \"7\")\n\n\nclass OptionsHandler(RequestHandler):\n    def options(self):\n        self.set_header(\"Access-Control-Allow-Origin\", \"*\")\n        self.write(\"ok\")\n\n\nclass NoContentHandler(RequestHandler):\n    def get(self):\n        if self.get_argument(\"error\", None):\n            self.set_header(\"Content-Length\", \"5\")\n            self.write(\"hello\")\n        self.set_status(204)\n\n\nclass SeeOtherPostHandler(RequestHandler):\n    def post(self):\n        redirect_code = int(self.request.body)\n        assert redirect_code in (302, 303), \"unexpected body %r\" % self.request.body\n        self.set_header(\"Location\", \"/see_other_get\")\n        self.set_status(redirect_code)\n\n\nclass SeeOtherGetHandler(RequestHandler):\n    def get(self):\n        if self.request.body:\n            raise Exception(\"unexpected body %r\" % self.request.body)\n        self.write(\"ok\")\n\n\nclass HostEchoHandler(RequestHandler):\n    def get(self):\n        self.write(self.request.headers[\"Host\"])\n\n\nclass NoContentLengthHandler(RequestHandler):\n    @asynchronous\n    def get(self):\n        if self.request.version.startswith('HTTP/1'):\n            # Emulate the old HTTP/1.0 behavior of returning a body with no\n            # content-length.  Tornado handles content-length at the framework\n            # level so we have to go around it.\n            stream = self.request.connection.detach()\n            stream.write(b\"HTTP/1.0 200 OK\\r\\n\\r\\n\"\n                         b\"hello\")\n            stream.close()\n        else:\n            self.finish('HTTP/1 required')\n\n\nclass EchoPostHandler(RequestHandler):\n    def post(self):\n        self.write(self.request.body)\n\n\n@stream_request_body\nclass RespondInPrepareHandler(RequestHandler):\n    def prepare(self):\n        self.set_status(403)\n        self.finish(\"forbidden\")\n\n\nclass SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)\n\n\nclass SimpleHTTPClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPTestCase):\n    def setUp(self):\n        super(SimpleHTTPClientTestCase, self).setUp()\n        self.http_client = self.create_client()\n\n    def create_client(self, **kwargs):\n        return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,\n                                     **kwargs)\n\n\nclass SimpleHTTPSClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPSTestCase):\n    def setUp(self):\n        super(SimpleHTTPSClientTestCase, self).setUp()\n        self.http_client = self.create_client()\n\n    def create_client(self, **kwargs):\n        return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,\n                                     defaults=dict(validate_cert=False),\n                                     **kwargs)\n\n    def test_ssl_options(self):\n        resp = self.fetch(\"/hello\", ssl_options={})\n        self.assertEqual(resp.body, b\"Hello world!\")\n\n    @unittest.skipIf(not hasattr(ssl, 'SSLContext'),\n                     'ssl.SSLContext not present')\n    def test_ssl_context(self):\n        resp = self.fetch(\"/hello\",\n                          ssl_options=ssl.SSLContext(ssl.PROTOCOL_SSLv23))\n        self.assertEqual(resp.body, b\"Hello world!\")\n\n    def test_ssl_options_handshake_fail(self):\n        with ExpectLog(gen_log, \"SSL Error|Uncaught exception\",\n                       required=False):\n            resp = self.fetch(\n                \"/hello\", ssl_options=dict(cert_reqs=ssl.CERT_REQUIRED))\n        self.assertRaises(ssl.SSLError, resp.rethrow)\n\n    @unittest.skipIf(not hasattr(ssl, 'SSLContext'),\n                     'ssl.SSLContext not present')\n    def test_ssl_context_handshake_fail(self):\n        with ExpectLog(gen_log, \"SSL Error|Uncaught exception\"):\n            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n            ctx.verify_mode = ssl.CERT_REQUIRED\n            resp = self.fetch(\"/hello\", ssl_options=ctx)\n        self.assertRaises(ssl.SSLError, resp.rethrow)\n\n    def test_error_logging(self):\n        # No stack traces are logged for SSL errors (in this case,\n        # failure to validate the testing self-signed cert).\n        # The SSLError is exposed through ssl.SSLError.\n        with ExpectLog(gen_log, '.*') as expect_log:\n            response = self.fetch(\"/\", validate_cert=True)\n            self.assertEqual(response.code, 599)\n            self.assertIsInstance(response.error, ssl.SSLError)\n        self.assertFalse(expect_log.logged_stack)\n\n\nclass CreateAsyncHTTPClientTestCase(AsyncTestCase):\n    def setUp(self):\n        super(CreateAsyncHTTPClientTestCase, self).setUp()\n        self.saved = AsyncHTTPClient._save_configuration()\n\n    def tearDown(self):\n        AsyncHTTPClient._restore_configuration(self.saved)\n        super(CreateAsyncHTTPClientTestCase, self).tearDown()\n\n    def test_max_clients(self):\n        AsyncHTTPClient.configure(SimpleAsyncHTTPClient)\n        with closing(AsyncHTTPClient(\n                self.io_loop, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 10)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=11, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 11)\n\n        # Now configure max_clients statically and try overriding it\n        # with each way max_clients can be passed\n        AsyncHTTPClient.configure(SimpleAsyncHTTPClient, max_clients=12)\n        with closing(AsyncHTTPClient(\n                self.io_loop, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 12)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=13, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 13)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=14, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 14)\n\n\nclass HTTP100ContinueTestCase(AsyncHTTPTestCase):\n    def respond_100(self, request):\n        self.http1 = request.version.startswith('HTTP/1.')\n        if not self.http1:\n            request.connection.write_headers(ResponseStartLine('', 200, 'OK'),\n                                             HTTPHeaders())\n            request.connection.finish()\n            return\n        self.request = request\n        self.request.connection.stream.write(\n            b\"HTTP/1.1 100 CONTINUE\\r\\n\\r\\n\",\n            self.respond_200)\n\n    def respond_200(self):\n        self.request.connection.stream.write(\n            b\"HTTP/1.1 200 OK\\r\\nContent-Length: 1\\r\\n\\r\\nA\",\n            self.request.connection.stream.close)\n\n    def get_app(self):\n        # Not a full Application, but works as an HTTPServer callback\n        return self.respond_100\n\n    def test_100_continue(self):\n        res = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(res.body, b'A')\n\n\nclass HTTP204NoContentTestCase(AsyncHTTPTestCase):\n    def respond_204(self, request):\n        self.http1 = request.version.startswith('HTTP/1.')\n        if not self.http1:\n            # Close the request cleanly in HTTP/2; it will be skipped anyway.\n            request.connection.write_headers(ResponseStartLine('', 200, 'OK'),\n                                             HTTPHeaders())\n            request.connection.finish()\n            return\n        # A 204 response never has a body, even if doesn't have a content-length\n        # (which would otherwise mean read-until-close).  Tornado always\n        # sends a content-length, so we simulate here a server that sends\n        # no content length and does not close the connection.\n        #\n        # Tests of a 204 response with a Content-Length header are included\n        # in SimpleHTTPClientTestMixin.\n        stream = request.connection.detach()\n        stream.write(\n            b\"HTTP/1.1 204 No content\\r\\n\\r\\n\")\n        stream.close()\n\n    def get_app(self):\n        return self.respond_204\n\n    def test_204_no_content(self):\n        resp = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(resp.code, 204)\n        self.assertEqual(resp.body, b'')\n\n\nclass HostnameMappingTestCase(AsyncHTTPTestCase):\n    def setUp(self):\n        super(HostnameMappingTestCase, self).setUp()\n        self.http_client = SimpleAsyncHTTPClient(\n            self.io_loop,\n            hostname_mapping={\n                'www.example.com': '127.0.0.1',\n                ('foo.example.com', 8000): ('127.0.0.1', self.get_http_port()),\n            })\n\n    def get_app(self):\n        return Application([url(\"/hello\", HelloWorldHandler), ])\n\n    def test_hostname_mapping(self):\n        self.http_client.fetch(\n            'http://www.example.com:%d/hello' % self.get_http_port(), self.stop)\n        response = self.wait()\n        response.rethrow()\n        self.assertEqual(response.body, b'Hello world!')\n\n    def test_port_mapping(self):\n        self.http_client.fetch('http://foo.example.com:8000/hello', self.stop)\n        response = self.wait()\n        response.rethrow()\n        self.assertEqual(response.body, b'Hello world!')\n\n\nclass ResolveTimeoutTestCase(AsyncHTTPTestCase):\n    def setUp(self):\n        # Dummy Resolver subclass that never invokes its callback.\n        class BadResolver(Resolver):\n            def resolve(self, *args, **kwargs):\n                pass\n\n        super(ResolveTimeoutTestCase, self).setUp()\n        self.http_client = SimpleAsyncHTTPClient(\n            self.io_loop,\n            resolver=BadResolver())\n\n    def get_app(self):\n        return Application([url(\"/hello\", HelloWorldHandler), ])\n\n    def test_resolve_timeout(self):\n        response = self.fetch('/hello', connect_timeout=0.1)\n        self.assertEqual(response.code, 599)\n\n\nclass MaxHeaderSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class SmallHeaders(RequestHandler):\n            def get(self):\n                self.set_header(\"X-Filler\", \"a\" * 100)\n                self.write(\"ok\")\n\n        class LargeHeaders(RequestHandler):\n            def get(self):\n                self.set_header(\"X-Filler\", \"a\" * 1000)\n                self.write(\"ok\")\n\n        return Application([('/small', SmallHeaders),\n                            ('/large', LargeHeaders)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_header_size=1024)\n\n    def test_small_headers(self):\n        response = self.fetch('/small')\n        response.rethrow()\n        self.assertEqual(response.body, b'ok')\n\n    def test_large_headers(self):\n        with ExpectLog(gen_log, \"Unsatisfiable read\"):\n            response = self.fetch('/large')\n        self.assertEqual(response.code, 599)\n\n\nclass MaxBodySizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class SmallBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 64)\n\n        class LargeBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 100)\n\n        return Application([('/small', SmallBody),\n                            ('/large', LargeBody)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 64)\n\n    def test_small_body(self):\n        response = self.fetch('/small')\n        response.rethrow()\n        self.assertEqual(response.body, b'a' * 1024 * 64)\n\n    def test_large_body(self):\n        with ExpectLog(gen_log, \"Malformed HTTP message from None: Content-Length too long\"):\n            response = self.fetch('/large')\n        self.assertEqual(response.code, 599)\n\n\nclass MaxBufferSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n\n        class LargeBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 100)\n\n        return Application([('/large', LargeBody)])\n\n    def get_http_client(self):\n        # 100KB body with 64KB buffer\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 100, max_buffer_size=1024 * 64)\n\n    def test_large_body(self):\n        response = self.fetch('/large')\n        response.rethrow()\n        self.assertEqual(response.body, b'a' * 1024 * 100)\n\n\nclass ChunkedWithContentLengthTest(AsyncHTTPTestCase):\n    def get_app(self):\n\n        class ChunkedWithContentLength(RequestHandler):\n            def get(self):\n                # Add an invalid Transfer-Encoding to the response\n                self.set_header('Transfer-Encoding', 'chunked')\n                self.write(\"Hello world\")\n\n        return Application([('/chunkwithcl', ChunkedWithContentLength)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient()\n\n    def test_chunked_with_content_length(self):\n        # Make sure the invalid headers are detected\n        with ExpectLog(gen_log, (\"Malformed HTTP message from None: Response \"\n                       \"with both Transfer-Encoding and Content-Length\")):\n            response = self.fetch('/chunkwithcl')\n        self.assertEqual(response.code, 599)\n",
            "new_file_content": "from __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nfrom contextlib import closing\nimport errno\nimport gzip\nimport logging\nimport os\nimport re\nimport socket\nimport ssl\nimport sys\n\nfrom tornado.escape import to_unicode\nfrom tornado import gen\nfrom tornado.httpclient import AsyncHTTPClient\nfrom tornado.httputil import HTTPHeaders, ResponseStartLine\nfrom tornado.ioloop import IOLoop\nfrom tornado.log import gen_log\nfrom tornado.concurrent import Future\nfrom tornado.netutil import Resolver, bind_sockets, BlockingResolver\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler, RedirectHandler\nfrom tornado.test import httpclient_test\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog\nfrom tornado.test.util import skipOnTravis, skipIfNoIPv6, refusing_port, unittest, skipBefore35, exec_test\nfrom tornado.web import RequestHandler, Application, asynchronous, url, stream_request_body\n\n\nclass SimpleHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase):\n    def get_http_client(self):\n        client = SimpleAsyncHTTPClient(io_loop=self.io_loop,\n                                       force_instance=True)\n        self.assertTrue(isinstance(client, SimpleAsyncHTTPClient))\n        return client\n\n\nclass TriggerHandler(RequestHandler):\n    def initialize(self, queue, wake_callback):\n        self.queue = queue\n        self.wake_callback = wake_callback\n\n    @asynchronous\n    def get(self):\n        logging.debug(\"queuing trigger\")\n        self.queue.append(self.finish)\n        if self.get_argument(\"wake\", \"true\") == \"true\":\n            self.wake_callback()\n\n\nclass HangHandler(RequestHandler):\n    @asynchronous\n    def get(self):\n        pass\n\n\nclass ContentLengthHandler(RequestHandler):\n    def get(self):\n        self.set_header(\"Content-Length\", self.get_argument(\"value\"))\n        self.write(\"ok\")\n\n\nclass HeadHandler(RequestHandler):\n    def head(self):\n        self.set_header(\"Content-Length\", \"7\")\n\n\nclass OptionsHandler(RequestHandler):\n    def options(self):\n        self.set_header(\"Access-Control-Allow-Origin\", \"*\")\n        self.write(\"ok\")\n\n\nclass NoContentHandler(RequestHandler):\n    def get(self):\n        if self.get_argument(\"error\", None):\n            self.set_header(\"Content-Length\", \"5\")\n            self.write(\"hello\")\n        self.set_status(204)\n\n\nclass SeeOtherPostHandler(RequestHandler):\n    def post(self):\n        redirect_code = int(self.request.body)\n        assert redirect_code in (302, 303), \"unexpected body %r\" % self.request.body\n        self.set_header(\"Location\", \"/see_other_get\")\n        self.set_status(redirect_code)\n\n\nclass SeeOtherGetHandler(RequestHandler):\n    def get(self):\n        if self.request.body:\n            raise Exception(\"unexpected body %r\" % self.request.body)\n        self.write(\"ok\")\n\n\nclass HostEchoHandler(RequestHandler):\n    def get(self):\n        self.write(self.request.headers[\"Host\"])\n\n\nclass NoContentLengthHandler(RequestHandler):\n    @asynchronous\n    def get(self):\n        if self.request.version.startswith('HTTP/1'):\n            # Emulate the old HTTP/1.0 behavior of returning a body with no\n            # content-length.  Tornado handles content-length at the framework\n            # level so we have to go around it.\n            stream = self.request.connection.detach()\n            stream.write(b\"HTTP/1.0 200 OK\\r\\n\\r\\n\"\n                         b\"hello\")\n            stream.close()\n        else:\n            self.finish('HTTP/1 required')\n\n\nclass EchoPostHandler(RequestHandler):\n    def post(self):\n        self.write(self.request.body)\n\n\n@stream_request_body\nclass RespondInPrepareHandler(RequestHandler):\n    def prepare(self):\n        self.set_status(403)\n        self.finish(\"forbidden\")\n\n\nclass SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                return Future()\n\n        with closing(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout during request\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)\n\n\nclass SimpleHTTPClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPTestCase):\n    def setUp(self):\n        super(SimpleHTTPClientTestCase, self).setUp()\n        self.http_client = self.create_client()\n\n    def create_client(self, **kwargs):\n        return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,\n                                     **kwargs)\n\n\nclass SimpleHTTPSClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPSTestCase):\n    def setUp(self):\n        super(SimpleHTTPSClientTestCase, self).setUp()\n        self.http_client = self.create_client()\n\n    def create_client(self, **kwargs):\n        return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,\n                                     defaults=dict(validate_cert=False),\n                                     **kwargs)\n\n    def test_ssl_options(self):\n        resp = self.fetch(\"/hello\", ssl_options={})\n        self.assertEqual(resp.body, b\"Hello world!\")\n\n    @unittest.skipIf(not hasattr(ssl, 'SSLContext'),\n                     'ssl.SSLContext not present')\n    def test_ssl_context(self):\n        resp = self.fetch(\"/hello\",\n                          ssl_options=ssl.SSLContext(ssl.PROTOCOL_SSLv23))\n        self.assertEqual(resp.body, b\"Hello world!\")\n\n    def test_ssl_options_handshake_fail(self):\n        with ExpectLog(gen_log, \"SSL Error|Uncaught exception\",\n                       required=False):\n            resp = self.fetch(\n                \"/hello\", ssl_options=dict(cert_reqs=ssl.CERT_REQUIRED))\n        self.assertRaises(ssl.SSLError, resp.rethrow)\n\n    @unittest.skipIf(not hasattr(ssl, 'SSLContext'),\n                     'ssl.SSLContext not present')\n    def test_ssl_context_handshake_fail(self):\n        with ExpectLog(gen_log, \"SSL Error|Uncaught exception\"):\n            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n            ctx.verify_mode = ssl.CERT_REQUIRED\n            resp = self.fetch(\"/hello\", ssl_options=ctx)\n        self.assertRaises(ssl.SSLError, resp.rethrow)\n\n    def test_error_logging(self):\n        # No stack traces are logged for SSL errors (in this case,\n        # failure to validate the testing self-signed cert).\n        # The SSLError is exposed through ssl.SSLError.\n        with ExpectLog(gen_log, '.*') as expect_log:\n            response = self.fetch(\"/\", validate_cert=True)\n            self.assertEqual(response.code, 599)\n            self.assertIsInstance(response.error, ssl.SSLError)\n        self.assertFalse(expect_log.logged_stack)\n\n\nclass CreateAsyncHTTPClientTestCase(AsyncTestCase):\n    def setUp(self):\n        super(CreateAsyncHTTPClientTestCase, self).setUp()\n        self.saved = AsyncHTTPClient._save_configuration()\n\n    def tearDown(self):\n        AsyncHTTPClient._restore_configuration(self.saved)\n        super(CreateAsyncHTTPClientTestCase, self).tearDown()\n\n    def test_max_clients(self):\n        AsyncHTTPClient.configure(SimpleAsyncHTTPClient)\n        with closing(AsyncHTTPClient(\n                self.io_loop, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 10)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=11, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 11)\n\n        # Now configure max_clients statically and try overriding it\n        # with each way max_clients can be passed\n        AsyncHTTPClient.configure(SimpleAsyncHTTPClient, max_clients=12)\n        with closing(AsyncHTTPClient(\n                self.io_loop, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 12)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=13, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 13)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=14, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 14)\n\n\nclass HTTP100ContinueTestCase(AsyncHTTPTestCase):\n    def respond_100(self, request):\n        self.http1 = request.version.startswith('HTTP/1.')\n        if not self.http1:\n            request.connection.write_headers(ResponseStartLine('', 200, 'OK'),\n                                             HTTPHeaders())\n            request.connection.finish()\n            return\n        self.request = request\n        self.request.connection.stream.write(\n            b\"HTTP/1.1 100 CONTINUE\\r\\n\\r\\n\",\n            self.respond_200)\n\n    def respond_200(self):\n        self.request.connection.stream.write(\n            b\"HTTP/1.1 200 OK\\r\\nContent-Length: 1\\r\\n\\r\\nA\",\n            self.request.connection.stream.close)\n\n    def get_app(self):\n        # Not a full Application, but works as an HTTPServer callback\n        return self.respond_100\n\n    def test_100_continue(self):\n        res = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(res.body, b'A')\n\n\nclass HTTP204NoContentTestCase(AsyncHTTPTestCase):\n    def respond_204(self, request):\n        self.http1 = request.version.startswith('HTTP/1.')\n        if not self.http1:\n            # Close the request cleanly in HTTP/2; it will be skipped anyway.\n            request.connection.write_headers(ResponseStartLine('', 200, 'OK'),\n                                             HTTPHeaders())\n            request.connection.finish()\n            return\n        # A 204 response never has a body, even if doesn't have a content-length\n        # (which would otherwise mean read-until-close).  Tornado always\n        # sends a content-length, so we simulate here a server that sends\n        # no content length and does not close the connection.\n        #\n        # Tests of a 204 response with a Content-Length header are included\n        # in SimpleHTTPClientTestMixin.\n        stream = request.connection.detach()\n        stream.write(\n            b\"HTTP/1.1 204 No content\\r\\n\\r\\n\")\n        stream.close()\n\n    def get_app(self):\n        return self.respond_204\n\n    def test_204_no_content(self):\n        resp = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(resp.code, 204)\n        self.assertEqual(resp.body, b'')\n\n\nclass HostnameMappingTestCase(AsyncHTTPTestCase):\n    def setUp(self):\n        super(HostnameMappingTestCase, self).setUp()\n        self.http_client = SimpleAsyncHTTPClient(\n            self.io_loop,\n            hostname_mapping={\n                'www.example.com': '127.0.0.1',\n                ('foo.example.com', 8000): ('127.0.0.1', self.get_http_port()),\n            })\n\n    def get_app(self):\n        return Application([url(\"/hello\", HelloWorldHandler), ])\n\n    def test_hostname_mapping(self):\n        self.http_client.fetch(\n            'http://www.example.com:%d/hello' % self.get_http_port(), self.stop)\n        response = self.wait()\n        response.rethrow()\n        self.assertEqual(response.body, b'Hello world!')\n\n    def test_port_mapping(self):\n        self.http_client.fetch('http://foo.example.com:8000/hello', self.stop)\n        response = self.wait()\n        response.rethrow()\n        self.assertEqual(response.body, b'Hello world!')\n\n\nclass ResolveTimeoutTestCase(AsyncHTTPTestCase):\n    def setUp(self):\n        # Dummy Resolver subclass that never invokes its callback.\n        class BadResolver(Resolver):\n            def resolve(self, *args, **kwargs):\n                pass\n\n        super(ResolveTimeoutTestCase, self).setUp()\n        self.http_client = SimpleAsyncHTTPClient(\n            self.io_loop,\n            resolver=BadResolver())\n\n    def get_app(self):\n        return Application([url(\"/hello\", HelloWorldHandler), ])\n\n    def test_resolve_timeout(self):\n        response = self.fetch('/hello', connect_timeout=0.1)\n        self.assertEqual(response.code, 599)\n\n\nclass MaxHeaderSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class SmallHeaders(RequestHandler):\n            def get(self):\n                self.set_header(\"X-Filler\", \"a\" * 100)\n                self.write(\"ok\")\n\n        class LargeHeaders(RequestHandler):\n            def get(self):\n                self.set_header(\"X-Filler\", \"a\" * 1000)\n                self.write(\"ok\")\n\n        return Application([('/small', SmallHeaders),\n                            ('/large', LargeHeaders)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_header_size=1024)\n\n    def test_small_headers(self):\n        response = self.fetch('/small')\n        response.rethrow()\n        self.assertEqual(response.body, b'ok')\n\n    def test_large_headers(self):\n        with ExpectLog(gen_log, \"Unsatisfiable read\"):\n            response = self.fetch('/large')\n        self.assertEqual(response.code, 599)\n\n\nclass MaxBodySizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class SmallBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 64)\n\n        class LargeBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 100)\n\n        return Application([('/small', SmallBody),\n                            ('/large', LargeBody)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 64)\n\n    def test_small_body(self):\n        response = self.fetch('/small')\n        response.rethrow()\n        self.assertEqual(response.body, b'a' * 1024 * 64)\n\n    def test_large_body(self):\n        with ExpectLog(gen_log, \"Malformed HTTP message from None: Content-Length too long\"):\n            response = self.fetch('/large')\n        self.assertEqual(response.code, 599)\n\n\nclass MaxBufferSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n\n        class LargeBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 100)\n\n        return Application([('/large', LargeBody)])\n\n    def get_http_client(self):\n        # 100KB body with 64KB buffer\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 100, max_buffer_size=1024 * 64)\n\n    def test_large_body(self):\n        response = self.fetch('/large')\n        response.rethrow()\n        self.assertEqual(response.body, b'a' * 1024 * 100)\n\n\nclass ChunkedWithContentLengthTest(AsyncHTTPTestCase):\n    def get_app(self):\n\n        class ChunkedWithContentLength(RequestHandler):\n            def get(self):\n                # Add an invalid Transfer-Encoding to the response\n                self.set_header('Transfer-Encoding', 'chunked')\n                self.write(\"Hello world\")\n\n        return Application([('/chunkwithcl', ChunkedWithContentLength)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient()\n\n    def test_chunked_with_content_length(self):\n        # Make sure the invalid headers are detected\n        with ExpectLog(gen_log, (\"Malformed HTTP message from None: Response \"\n                       \"with both Transfer-Encoding and Content-Length\")):\n            response = self.fetch('/chunkwithcl')\n        self.assertEqual(response.code, 599)\n",
            "header": {
                "file": {
                    "path": "tornado/test/simple_httpclient_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "ca1e2869",
                "new_commit_hash": "52bae50d",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/simple_httpclient_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/simple_httpclient_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 10,
                            "length": 7
                        },
                        "new_range": {
                            "start": 10,
                            "length": 6
                        },
                        "section": "import re"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "import socket",
                                "type": "context"
                            },
                            {
                                "content": "import ssl",
                                "type": "context"
                            },
                            {
                                "content": "import sys",
                                "type": "context"
                            },
                            {
                                "content": "import time",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.escape import to_unicode",
                                "type": "context"
                            },
                            {
                                "content": "from tornado import gen",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [],
                    "deleted_entities": [
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "import",
                            "name": "time",
                            "content": "import time",
                            "ast_type_str": "Import",
                            "start_lineno": 13,
                            "end_lineno": 13,
                            "parent": null
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 18,
                            "length": 8
                        },
                        "new_range": {
                            "start": 17,
                            "length": 9
                        },
                        "section": "from tornado.httpclient import AsyncHTTPClient"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "from tornado.httputil import HTTPHeaders, ResponseStartLine",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.ioloop import IOLoop",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.log import gen_log",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.concurrent import Future",
                                "type": "added"
                            },
                            {
                                "content": "from tornado.netutil import Resolver, bind_sockets, BlockingResolver",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.simple_httpclient import SimpleAsyncHTTPClient, _HTTPConnection",
                                "type": "deleted"
                            },
                            {
                                "content": "from tornado.simple_httpclient import SimpleAsyncHTTPClient",
                                "type": "added"
                            },
                            {
                                "content": "from tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler, RedirectHandler",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.test import httpclient_test",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "statement",
                            "name": "",
                            "content": "from tornado.simple_httpclient import SimpleAsyncHTTPClient",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 22,
                            "end_lineno": 22,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "statement",
                            "name": "",
                            "content": "from tornado.concurrent import Future",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 20,
                            "end_lineno": 20,
                            "parent": null
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "statement",
                            "name": "",
                            "content": "from tornado.simple_httpclient import SimpleAsyncHTTPClient, _HTTPConnection",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 22,
                            "end_lineno": 22,
                            "parent": null
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 241,
                            "length": 90
                        },
                        "new_range": {
                            "start": 241,
                            "length": 19
                        },
                        "section": "class SimpleHTTPClientTestMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    @skipOnTravis",
                                "type": "context"
                            },
                            {
                                "content": "    def test_connect_timeout(self):",
                                "type": "context"
                            },
                            {
                                "content": "        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`",
                                "type": "context"
                            },
                            {
                                "content": "        # `timeout_max` is raised up compare to `self.test_request_timeout`.",
                                "type": "deleted"
                            },
                            {
                                "content": "        #",
                                "type": "deleted"
                            },
                            {
                                "content": "        # Because at windows system, in `TimeoutResolver.resolve` call, if",
                                "type": "deleted"
                            },
                            {
                                "content": "        # `time.sleep's parameter` is the same as the `connect_timeout` value,",
                                "type": "deleted"
                            },
                            {
                                "content": "        # maybe no error occurs and everything works well(and we get response",
                                "type": "deleted"
                            },
                            {
                                "content": "        # 200 instead of 599). So `time.sleep's parameter` should be bigger",
                                "type": "deleted"
                            },
                            {
                                "content": "        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is",
                                "type": "deleted"
                            },
                            {
                                "content": "        # raised up(add 0.4).",
                                "type": "deleted"
                            },
                            {
                                "content": "        connect_timeout = 0.1",
                                "type": "deleted"
                            },
                            {
                                "content": "        timeout_min, timeout_max = 0.099, 0.5",
                                "type": "deleted"
                            },
                            {
                                "content": "        timeout = 0.1",
                                "type": "added"
                            },
                            {
                                "content": "        timeout_min, timeout_max = 0.099, 0.15",
                                "type": "added"
                            },
                            {
                                "content": "        if os.name == 'nt':",
                                "type": "context"
                            },
                            {
                                "content": "            connect_timeout = 0.5",
                                "type": "deleted"
                            },
                            {
                                "content": "            timeout_min, timeout_max = 0.4, 0.9",
                                "type": "deleted"
                            },
                            {
                                "content": "        sleep_seconds = connect_timeout + 0.2",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "        class patching(object):",
                                "type": "deleted"
                            },
                            {
                                "content": "            # In `simple_httpclient._HTTPConnection.__init__`:",
                                "type": "deleted"
                            },
                            {
                                "content": "            # We add a connect timeout to io_loop and then begin our",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `self.tcp_connect.connect` step.",
                                "type": "deleted"
                            },
                            {
                                "content": "            #",
                                "type": "deleted"
                            },
                            {
                                "content": "            # If connect timeout is triggered, but `self.tcp_client.connect`",
                                "type": "deleted"
                            },
                            {
                                "content": "            # call is still in progress, at this moment: an error may occur",
                                "type": "deleted"
                            },
                            {
                                "content": "            # while connecting(yield from `self.tcp_client.connect` at",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `stream.start_tls`, which is mostly caused by",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `SSLIOStream._do_ssl_handshake` call), since connection is not",
                                "type": "deleted"
                            },
                            {
                                "content": "            # finished because of the exception, the self._on_connect will not",
                                "type": "deleted"
                            },
                            {
                                "content": "            # be called. The exception(`ssl.SSL_ERROR_EOF`,",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by",
                                "type": "deleted"
                            },
                            {
                                "content": "            # the stack_context's exception handler.",
                                "type": "deleted"
                            },
                            {
                                "content": "            #",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `_HTTPConnection` has add exception handler",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `_HTTPConnection._handle_exception` to stack_context.",
                                "type": "deleted"
                            },
                            {
                                "content": "            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all",
                                "type": "deleted"
                            },
                            {
                                "content": "            # context in",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before",
                                "type": "deleted"
                            },
                            {
                                "content": "            # handling any request. So, if we want to handle the exception",
                                "type": "deleted"
                            },
                            {
                                "content": "            # raised by `self.tcp_client.connect`(connection is not finished),",
                                "type": "deleted"
                            },
                            {
                                "content": "            # we have to add a context(or patch a context) after",
                                "type": "deleted"
                            },
                            {
                                "content": "            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call",
                                "type": "deleted"
                            },
                            {
                                "content": "            # and before `self.tcp_client.connect` call.",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "            def __init__(self, client):",
                                "type": "deleted"
                            },
                            {
                                "content": "                self.client = client",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "            def __enter__(self):",
                                "type": "deleted"
                            },
                            {
                                "content": "                def _patched_handle_exception(instance, typ, value, tb):",
                                "type": "deleted"
                            },
                            {
                                "content": "                    \"\"\"Handle extra exception while connection failed.",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and",
                                "type": "deleted"
                            },
                            {
                                "content": "                    `errno.WSAECONNABORTED`(windows) may occur if connection",
                                "type": "deleted"
                            },
                            {
                                "content": "                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just",
                                "type": "deleted"
                            },
                            {
                                "content": "                    ignore them. Other logic is the same as",
                                "type": "deleted"
                            },
                            {
                                "content": "                    `_HTTPConnection._handle_exception`",
                                "type": "deleted"
                            },
                            {
                                "content": "                    \"\"\"",
                                "type": "deleted"
                            },
                            {
                                "content": "                    result = self._origin_handle_exception(instance, typ, value, tb)",
                                "type": "deleted"
                            },
                            {
                                "content": "                    if result is False:",
                                "type": "deleted"
                            },
                            {
                                "content": "                        if isinstance(value, ssl.SSLError) \\",
                                "type": "deleted"
                            },
                            {
                                "content": "                                and value.args[0] == ssl.SSL_ERROR_EOF:",
                                "type": "deleted"
                            },
                            {
                                "content": "                            return True",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "                        ignored_io_error = [errno.ECONNRESET]",
                                "type": "deleted"
                            },
                            {
                                "content": "                        if hasattr(errno, \"WSAECONNRESET\"):",
                                "type": "deleted"
                            },
                            {
                                "content": "                            ignored_io_error.append(errno.WSAECONNABORTED)",
                                "type": "deleted"
                            },
                            {
                                "content": "                        if isinstance(value, IOError) \\",
                                "type": "deleted"
                            },
                            {
                                "content": "                                and value.args[0] in ignored_io_error:",
                                "type": "deleted"
                            },
                            {
                                "content": "                            return True",
                                "type": "deleted"
                            },
                            {
                                "content": "                    return result",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "                self._origin_handle_exception = _HTTPConnection._handle_exception",
                                "type": "deleted"
                            },
                            {
                                "content": "                _HTTPConnection._handle_exception = _patched_handle_exception",
                                "type": "deleted"
                            },
                            {
                                "content": "                return self.client",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "            def __exit__(self, *exc_info):",
                                "type": "deleted"
                            },
                            {
                                "content": "                _HTTPConnection._handle_exception = self._origin_handle_exception",
                                "type": "deleted"
                            },
                            {
                                "content": "                self.client.close()",
                                "type": "deleted"
                            },
                            {
                                "content": "            timeout = 0.5",
                                "type": "added"
                            },
                            {
                                "content": "            timeout_min, timeout_max = 0.4, 0.6",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        class TimeoutResolver(BlockingResolver):",
                                "type": "context"
                            },
                            {
                                "content": "            def resolve(self, *args, **kwargs):",
                                "type": "context"
                            },
                            {
                                "content": "                time.sleep(sleep_seconds)",
                                "type": "deleted"
                            },
                            {
                                "content": "                return super(TimeoutResolver, self).resolve(*args, **kwargs)",
                                "type": "deleted"
                            },
                            {
                                "content": "                return Future()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        with patching(self.create_client(resolver=TimeoutResolver())) as client:",
                                "type": "deleted"
                            },
                            {
                                "content": "        with closing(self.create_client(resolver=TimeoutResolver())) as client:",
                                "type": "added"
                            },
                            {
                                "content": "            client.fetch(self.get_url('/hello'), self.stop,",
                                "type": "context"
                            },
                            {
                                "content": "                         connect_timeout=connect_timeout)",
                                "type": "deleted"
                            },
                            {
                                "content": "                         connect_timeout=timeout)",
                                "type": "added"
                            },
                            {
                                "content": "            response = self.wait()",
                                "type": "context"
                            },
                            {
                                "content": "            self.assertEqual(response.code, 599)",
                                "type": "context"
                            },
                            {
                                "content": "            self.assertTrue(timeout_min < response.request_time < timeout_max,",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "class",
                            "name": "SimpleHTTPClientTestMixin",
                            "content": "class SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 129,
                            "end_lineno": 558,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "method",
                            "name": "SimpleHTTPClientTestMixin.test_connect_timeout",
                            "content": "class SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 242,
                            "end_lineno": 332,
                            "parent": {
                                "file_name": "tornado/test/simple_httpclient_test.py",
                                "type": "class",
                                "name": "SimpleHTTPClientTestMixin",
                                "content": "class SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 129,
                                "end_lineno": 558,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 343,
                            "length": 7
                        },
                        "new_range": {
                            "start": 272,
                            "length": 7
                        },
                        "section": "class SimpleHTTPClientTestMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.assertEqual(response.code, 599)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertTrue(timeout_min < response.request_time < timeout_max,",
                                "type": "context"
                            },
                            {
                                "content": "                        response.request_time)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.assertEqual(str(response.error), \"HTTP 599: Timeout during request\")",
                                "type": "added"
                            },
                            {
                                "content": "        # trigger the hanging request to let it clean up after itself",
                                "type": "context"
                            },
                            {
                                "content": "        self.triggers.popleft()()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "class",
                            "name": "SimpleHTTPClientTestMixin",
                            "content": "class SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 129,
                            "end_lineno": 558,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/simple_httpclient_test.py",
                            "type": "method",
                            "name": "SimpleHTTPClientTestMixin.test_request_timeout",
                            "content": "class SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 335,
                            "end_lineno": 348,
                            "parent": {
                                "file_name": "tornado/test/simple_httpclient_test.py",
                                "type": "class",
                                "name": "SimpleHTTPClientTestMixin",
                                "content": "class SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        # `timeout_max` is raised up compare to `self.test_request_timeout`.\n        #\n        # Because at windows system, in `TimeoutResolver.resolve` call, if\n        # `time.sleep's parameter` is the same as the `connect_timeout` value,\n        # maybe no error occurs and everything works well(and we get response\n        # 200 instead of 599). So `time.sleep's parameter` should be bigger\n        # than the `connect_timeout`(add 0.2), that's why the `timeout_max` is\n        # raised up(add 0.4).\n        connect_timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.5\n        if os.name == 'nt':\n            connect_timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.9\n        sleep_seconds = connect_timeout + 0.2\n\n        class patching(object):\n            # In `simple_httpclient._HTTPConnection.__init__`:\n            # We add a connect timeout to io_loop and then begin our\n            # `self.tcp_connect.connect` step.\n            #\n            # If connect timeout is triggered, but `self.tcp_client.connect`\n            # call is still in progress, at this moment: an error may occur\n            # while connecting(yield from `self.tcp_client.connect` at\n            # `stream.start_tls`, which is mostly caused by\n            # `SSLIOStream._do_ssl_handshake` call), since connection is not\n            # finished because of the exception, the self._on_connect will not\n            # be called. The exception(`ssl.SSL_ERROR_EOF`,\n            # `errno.ECONNRESET`, `errno.WSAECONNABORTED`) will be handled by\n            # the stack_context's exception handler.\n            #\n            # `_HTTPConnection` has add exception handler\n            # `_HTTPConnection._handle_exception` to stack_context.\n            # And in `simple_httpclient.SimpleAsyncHTTPClient`, we cleaned all\n            # context in\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` before\n            # handling any request. So, if we want to handle the exception\n            # raised by `self.tcp_client.connect`(connection is not finished),\n            # we have to add a context(or patch a context) after\n            # `simple_httpclient.SimpleAsyncHTTPClient._process_queue` call\n            # and before `self.tcp_client.connect` call.\n\n            def __init__(self, client):\n                self.client = client\n\n            def __enter__(self):\n                def _patched_handle_exception(instance, typ, value, tb):\n                    \"\"\"Handle extra exception while connection failed.\n\n                    `ssl.SSL_ERROR_EOF`, `errno.ECONNRESET` and\n                    `errno.WSAECONNABORTED`(windows) may occur if connection\n                    failed(mostly in `SSLIOStream._do_ssl_handshake`), just\n                    ignore them. Other logic is the same as\n                    `_HTTPConnection._handle_exception`\n                    \"\"\"\n                    result = self._origin_handle_exception(instance, typ, value, tb)\n                    if result is False:\n                        if isinstance(value, ssl.SSLError) \\\n                                and value.args[0] == ssl.SSL_ERROR_EOF:\n                            return True\n\n                        ignored_io_error = [errno.ECONNRESET]\n                        if hasattr(errno, \"WSAECONNRESET\"):\n                            ignored_io_error.append(errno.WSAECONNABORTED)\n                        if isinstance(value, IOError) \\\n                                and value.args[0] in ignored_io_error:\n                            return True\n                    return result\n\n                self._origin_handle_exception = _HTTPConnection._handle_exception\n                _HTTPConnection._handle_exception = _patched_handle_exception\n                return self.client\n\n            def __exit__(self, *exc_info):\n                _HTTPConnection._handle_exception = self._origin_handle_exception\n                self.client.close()\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                time.sleep(sleep_seconds)\n                return super(TimeoutResolver, self).resolve(*args, **kwargs)\n\n        with patching(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=connect_timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout while interacting\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 129,
                                "end_lineno": 558,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "fa38173fe2c4c4959cda7d80299595b5b71181a1^",
    "new_commit_hash": "fa38173fe2c4c4959cda7d80299595b5b71181a1",
    "commit_message": "refractor test_connect_timeout with a never finished future",
    "commit_date": "2015-12-22T09:44:47+08:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "fa38173fe2c4c4959cda7d80299595b5b71181a1",
    "test_file_codes": [
        "from __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nfrom contextlib import closing\nimport errno\nimport gzip\nimport logging\nimport os\nimport re\nimport socket\nimport ssl\nimport sys\n\nfrom tornado.escape import to_unicode\nfrom tornado import gen\nfrom tornado.httpclient import AsyncHTTPClient\nfrom tornado.httputil import HTTPHeaders, ResponseStartLine\nfrom tornado.ioloop import IOLoop\nfrom tornado.log import gen_log\nfrom tornado.concurrent import Future\nfrom tornado.netutil import Resolver, bind_sockets, BlockingResolver\nfrom tornado.simple_httpclient import SimpleAsyncHTTPClient\nfrom tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler, RedirectHandler\nfrom tornado.test import httpclient_test\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog\nfrom tornado.test.util import skipOnTravis, skipIfNoIPv6, refusing_port, unittest, skipBefore35, exec_test\nfrom tornado.web import RequestHandler, Application, asynchronous, url, stream_request_body\n\n\nclass SimpleHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase):\n    def get_http_client(self):\n        client = SimpleAsyncHTTPClient(io_loop=self.io_loop,\n                                       force_instance=True)\n        self.assertTrue(isinstance(client, SimpleAsyncHTTPClient))\n        return client\n\n\nclass TriggerHandler(RequestHandler):\n    def initialize(self, queue, wake_callback):\n        self.queue = queue\n        self.wake_callback = wake_callback\n\n    @asynchronous\n    def get(self):\n        logging.debug(\"queuing trigger\")\n        self.queue.append(self.finish)\n        if self.get_argument(\"wake\", \"true\") == \"true\":\n            self.wake_callback()\n\n\nclass HangHandler(RequestHandler):\n    @asynchronous\n    def get(self):\n        pass\n\n\nclass ContentLengthHandler(RequestHandler):\n    def get(self):\n        self.set_header(\"Content-Length\", self.get_argument(\"value\"))\n        self.write(\"ok\")\n\n\nclass HeadHandler(RequestHandler):\n    def head(self):\n        self.set_header(\"Content-Length\", \"7\")\n\n\nclass OptionsHandler(RequestHandler):\n    def options(self):\n        self.set_header(\"Access-Control-Allow-Origin\", \"*\")\n        self.write(\"ok\")\n\n\nclass NoContentHandler(RequestHandler):\n    def get(self):\n        if self.get_argument(\"error\", None):\n            self.set_header(\"Content-Length\", \"5\")\n            self.write(\"hello\")\n        self.set_status(204)\n\n\nclass SeeOtherPostHandler(RequestHandler):\n    def post(self):\n        redirect_code = int(self.request.body)\n        assert redirect_code in (302, 303), \"unexpected body %r\" % self.request.body\n        self.set_header(\"Location\", \"/see_other_get\")\n        self.set_status(redirect_code)\n\n\nclass SeeOtherGetHandler(RequestHandler):\n    def get(self):\n        if self.request.body:\n            raise Exception(\"unexpected body %r\" % self.request.body)\n        self.write(\"ok\")\n\n\nclass HostEchoHandler(RequestHandler):\n    def get(self):\n        self.write(self.request.headers[\"Host\"])\n\n\nclass NoContentLengthHandler(RequestHandler):\n    @asynchronous\n    def get(self):\n        if self.request.version.startswith('HTTP/1'):\n            # Emulate the old HTTP/1.0 behavior of returning a body with no\n            # content-length.  Tornado handles content-length at the framework\n            # level so we have to go around it.\n            stream = self.request.connection.detach()\n            stream.write(b\"HTTP/1.0 200 OK\\r\\n\\r\\n\"\n                         b\"hello\")\n            stream.close()\n        else:\n            self.finish('HTTP/1 required')\n\n\nclass EchoPostHandler(RequestHandler):\n    def post(self):\n        self.write(self.request.body)\n\n\n@stream_request_body\nclass RespondInPrepareHandler(RequestHandler):\n    def prepare(self):\n        self.set_status(403)\n        self.finish(\"forbidden\")\n\n\nclass SimpleHTTPClientTestMixin(object):\n    def get_app(self):\n        # callable objects to finish pending /trigger requests\n        self.triggers = collections.deque()\n        return Application([\n            url(\"/trigger\", TriggerHandler, dict(queue=self.triggers,\n                                                 wake_callback=self.stop)),\n            url(\"/chunk\", ChunkHandler),\n            url(\"/countdown/([0-9]+)\", CountdownHandler, name=\"countdown\"),\n            url(\"/hang\", HangHandler),\n            url(\"/hello\", HelloWorldHandler),\n            url(\"/content_length\", ContentLengthHandler),\n            url(\"/head\", HeadHandler),\n            url(\"/options\", OptionsHandler),\n            url(\"/no_content\", NoContentHandler),\n            url(\"/see_other_post\", SeeOtherPostHandler),\n            url(\"/see_other_get\", SeeOtherGetHandler),\n            url(\"/host_echo\", HostEchoHandler),\n            url(\"/no_content_length\", NoContentLengthHandler),\n            url(\"/echo_post\", EchoPostHandler),\n            url(\"/respond_in_prepare\", RespondInPrepareHandler),\n            url(\"/redirect\", RedirectHandler),\n        ], gzip=True)\n\n    def test_singleton(self):\n        # Class \"constructor\" reuses objects on the same IOLoop\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is\n                        SimpleAsyncHTTPClient(self.io_loop))\n        # unless force_instance is used\n        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                        SimpleAsyncHTTPClient(self.io_loop,\n                                              force_instance=True))\n        # different IOLoops use different objects\n        with closing(IOLoop()) as io_loop2:\n            self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not\n                            SimpleAsyncHTTPClient(io_loop2))\n\n    def test_connection_limit(self):\n        with closing(self.create_client(max_clients=2)) as client:\n            self.assertEqual(client.max_clients, 2)\n            seen = []\n            # Send 4 requests.  Two can be sent immediately, while the others\n            # will be queued\n            for i in range(4):\n                client.fetch(self.get_url(\"/trigger\"),\n                             lambda response, i=i: (seen.append(i), self.stop()))\n            self.wait(condition=lambda: len(self.triggers) == 2)\n            self.assertEqual(len(client.queue), 2)\n\n            # Finish the first two requests and let the next two through\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: (len(self.triggers) == 2 and\n                                         len(seen) == 2))\n            self.assertEqual(set(seen), set([0, 1]))\n            self.assertEqual(len(client.queue), 0)\n\n            # Finish all the pending requests\n            self.triggers.popleft()()\n            self.triggers.popleft()()\n            self.wait(condition=lambda: len(seen) == 4)\n            self.assertEqual(set(seen), set([0, 1, 2, 3]))\n            self.assertEqual(len(self.triggers), 0)\n\n    def test_redirect_connection_limit(self):\n        # following redirects should not consume additional connections\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/countdown/3'), self.stop,\n                         max_redirects=3)\n            response = self.wait()\n            response.rethrow()\n\n    def test_gzip(self):\n        # All the tests in this file should be using gzip, but this test\n        # ensures that it is in fact getting compressed.\n        # Setting Accept-Encoding manually bypasses the client's\n        # decompression so we can see the raw data.\n        response = self.fetch(\"/chunk\", use_gzip=False,\n                              headers={\"Accept-Encoding\": \"gzip\"})\n        self.assertEqual(response.headers[\"Content-Encoding\"], \"gzip\")\n        self.assertNotEqual(response.body, b\"asdfqwer\")\n        # Our test data gets bigger when gzipped.  Oops.  :)\n        # Chunked encoding bypasses the MIN_LENGTH check.\n        self.assertEqual(len(response.body), 34)\n        f = gzip.GzipFile(mode=\"r\", fileobj=response.buffer)\n        self.assertEqual(f.read(), b\"asdfqwer\")\n\n    def test_max_redirects(self):\n        response = self.fetch(\"/countdown/5\", max_redirects=3)\n        self.assertEqual(302, response.code)\n        # We requested 5, followed three redirects for 4, 3, 2, then the last\n        # unfollowed redirect is to 1.\n        self.assertTrue(response.request.url.endswith(\"/countdown/5\"))\n        self.assertTrue(response.effective_url.endswith(\"/countdown/2\"))\n        self.assertTrue(response.headers[\"Location\"].endswith(\"/countdown/1\"))\n\n    def test_header_reuse(self):\n        # Apps may reuse a headers object if they are only passing in constant\n        # headers like user-agent.  The header object should not be modified.\n        headers = HTTPHeaders({'User-Agent': 'Foo'})\n        self.fetch(\"/hello\", headers=headers)\n        self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])\n\n    def test_see_other_redirect(self):\n        for code in (302, 303):\n            response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n            self.assertEqual(200, response.code)\n            self.assertTrue(response.request.url.endswith(\"/see_other_post\"))\n            self.assertTrue(response.effective_url.endswith(\"/see_other_get\"))\n            # request is the original request, is a POST still\n            self.assertEqual(\"POST\", response.request.method)\n\n    @skipOnTravis\n    def test_connect_timeout(self):\n        # 0.1 and 0.5(nt) is copied from `self.test_request_timeout`\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        class TimeoutResolver(BlockingResolver):\n            def resolve(self, *args, **kwargs):\n                return Future()\n\n        with closing(self.create_client(resolver=TimeoutResolver())) as client:\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=timeout)\n            response = self.wait()\n            self.assertEqual(response.code, 599)\n            self.assertTrue(timeout_min < response.request_time < timeout_max,\n                            response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout while connecting\")\n\n    @skipOnTravis\n    def test_request_timeout(self):\n        timeout = 0.1\n        timeout_min, timeout_max = 0.099, 0.15\n        if os.name == 'nt':\n            timeout = 0.5\n            timeout_min, timeout_max = 0.4, 0.6\n\n        response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n        self.assertEqual(response.code, 599)\n        self.assertTrue(timeout_min < response.request_time < timeout_max,\n                        response.request_time)\n        self.assertEqual(str(response.error), \"HTTP 599: Timeout during request\")\n        # trigger the hanging request to let it clean up after itself\n        self.triggers.popleft()()\n\n    @skipIfNoIPv6\n    def test_ipv6(self):\n        try:\n            [sock] = bind_sockets(None, '::1', family=socket.AF_INET6)\n            port = sock.getsockname()[1]\n            self.http_server.add_socket(sock)\n        except socket.gaierror as e:\n            if e.args[0] == socket.EAI_ADDRFAMILY:\n                # python supports ipv6, but it's not configured on the network\n                # interface, so skip this test.\n                return\n            raise\n        url = '%s://[::1]:%d/hello' % (self.get_protocol(), port)\n\n        # ipv6 is currently enabled by default but can be disabled\n        self.http_client.fetch(url, self.stop, allow_ipv6=False)\n        response = self.wait()\n        self.assertEqual(response.code, 599)\n\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def xtest_multiple_content_length_accepted(self):\n        response = self.fetch(\"/content_length?value=2,2\")\n        self.assertEqual(response.body, b\"ok\")\n        response = self.fetch(\"/content_length?value=2,%202,2\")\n        self.assertEqual(response.body, b\"ok\")\n\n        response = self.fetch(\"/content_length?value=2,4\")\n        self.assertEqual(response.code, 599)\n        response = self.fetch(\"/content_length?value=2,%202,3\")\n        self.assertEqual(response.code, 599)\n\n    def test_head_request(self):\n        response = self.fetch(\"/head\", method=\"HEAD\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"7\")\n        self.assertFalse(response.body)\n\n    def test_options_request(self):\n        response = self.fetch(\"/options\", method=\"OPTIONS\")\n        self.assertEqual(response.code, 200)\n        self.assertEqual(response.headers[\"content-length\"], \"2\")\n        self.assertEqual(response.headers[\"access-control-allow-origin\"], \"*\")\n        self.assertEqual(response.body, b\"ok\")\n\n    def test_no_content(self):\n        response = self.fetch(\"/no_content\")\n        self.assertEqual(response.code, 204)\n        # 204 status doesn't need a content-length, but tornado will\n        # add a zero content-length anyway.\n        #\n        # A test without a content-length header is included below\n        # in HTTP204NoContentTestCase.\n        self.assertEqual(response.headers[\"Content-length\"], \"0\")\n\n        # 204 status with non-zero content length is malformed\n        with ExpectLog(gen_log, \"Malformed HTTP message\"):\n            response = self.fetch(\"/no_content?error=1\")\n        self.assertEqual(response.code, 599)\n\n    def test_host_header(self):\n        host_re = re.compile(b\"^localhost:[0-9]+$\")\n        response = self.fetch(\"/host_echo\")\n        self.assertTrue(host_re.match(response.body))\n\n        url = self.get_url(\"/host_echo\").replace(\"http://\", \"http://me:secret@\")\n        self.http_client.fetch(url, self.stop)\n        response = self.wait()\n        self.assertTrue(host_re.match(response.body), response.body)\n\n    def test_connection_refused(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with ExpectLog(gen_log, \".*\", required=False):\n            self.http_client.fetch(\"http://127.0.0.1:%d/\" % port, self.stop)\n            response = self.wait()\n        self.assertEqual(599, response.code)\n\n        if sys.platform != 'cygwin':\n            # cygwin returns EPERM instead of ECONNREFUSED here\n            contains_errno = str(errno.ECONNREFUSED) in str(response.error)\n            if not contains_errno and hasattr(errno, \"WSAECONNREFUSED\"):\n                contains_errno = str(errno.WSAECONNREFUSED) in str(response.error)\n            self.assertTrue(contains_errno, response.error)\n            # This is usually \"Connection refused\".\n            # On windows, strerror is broken and returns \"Unknown error\".\n            expected_message = os.strerror(errno.ECONNREFUSED)\n            self.assertTrue(expected_message in str(response.error),\n                            response.error)\n\n    def test_queue_timeout(self):\n        with closing(self.create_client(max_clients=1)) as client:\n            client.fetch(self.get_url('/trigger'), self.stop,\n                         request_timeout=10)\n            # Wait for the trigger request to block, not complete.\n            self.wait()\n            client.fetch(self.get_url('/hello'), self.stop,\n                         connect_timeout=0.1)\n            response = self.wait()\n\n            self.assertEqual(response.code, 599)\n            self.assertTrue(response.request_time < 1, response.request_time)\n            self.assertEqual(str(response.error), \"HTTP 599: Timeout in request queue\")\n            self.triggers.popleft()()\n            self.wait()\n\n    def test_no_content_length(self):\n        response = self.fetch(\"/no_content_length\")\n        if response.body == b\"HTTP/1 required\":\n            self.skipTest(\"requires HTTP/1.x\")\n        else:\n            self.assertEquals(b\"hello\", response.body)\n\n    def sync_body_producer(self, write):\n        write(b'1234')\n        write(b'5678')\n\n    @gen.coroutine\n    def async_body_producer(self, write):\n        yield write(b'1234')\n        yield gen.Task(IOLoop.current().add_callback)\n        yield write(b'5678')\n\n    def test_sync_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_sync_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.sync_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_chunked(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer)\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_async_body_producer_content_length(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=self.async_body_producer,\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_chunked(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"])\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    @skipBefore35\n    def test_native_body_producer_content_length(self):\n        namespace = exec_test(globals(), locals(), \"\"\"\n        async def body_producer(write):\n            await write(b'1234')\n            await gen.Task(IOLoop.current().add_callback)\n            await write(b'5678')\n        \"\"\")\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body_producer=namespace[\"body_producer\"],\n                              headers={'Content-Length': '8'})\n        response.rethrow()\n        self.assertEqual(response.body, b\"12345678\")\n\n    def test_100_continue(self):\n        response = self.fetch(\"/echo_post\", method=\"POST\",\n                              body=b\"1234\",\n                              expect_100_continue=True)\n        self.assertEqual(response.body, b\"1234\")\n\n    def test_100_continue_early_response(self):\n        def body_producer(write):\n            raise Exception(\"should not be called\")\n        response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n                              body_producer=body_producer,\n                              expect_100_continue=True)\n        self.assertEqual(response.code, 403)\n\n    def test_streaming_follow_redirects(self):\n        # When following redirects, header and streaming callbacks\n        # should only be called for the final result.\n        # TODO(bdarnell): this test belongs in httpclient_test instead of\n        # simple_httpclient_test, but it fails with the version of libcurl\n        # available on travis-ci. Move it when that has been upgraded\n        # or we have a better framework to skip tests based on curl version.\n        headers = []\n        chunks = []\n        self.fetch(\"/redirect?url=/hello\",\n                   header_callback=headers.append,\n                   streaming_callback=chunks.append)\n        chunks = list(map(to_unicode, chunks))\n        self.assertEqual(chunks, ['Hello world!'])\n        # Make sure we only got one set of headers.\n        num_start_lines = len([h for h in headers if h.startswith(\"HTTP/\")])\n        self.assertEqual(num_start_lines, 1)\n\n\nclass SimpleHTTPClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPTestCase):\n    def setUp(self):\n        super(SimpleHTTPClientTestCase, self).setUp()\n        self.http_client = self.create_client()\n\n    def create_client(self, **kwargs):\n        return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,\n                                     **kwargs)\n\n\nclass SimpleHTTPSClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPSTestCase):\n    def setUp(self):\n        super(SimpleHTTPSClientTestCase, self).setUp()\n        self.http_client = self.create_client()\n\n    def create_client(self, **kwargs):\n        return SimpleAsyncHTTPClient(self.io_loop, force_instance=True,\n                                     defaults=dict(validate_cert=False),\n                                     **kwargs)\n\n    def test_ssl_options(self):\n        resp = self.fetch(\"/hello\", ssl_options={})\n        self.assertEqual(resp.body, b\"Hello world!\")\n\n    @unittest.skipIf(not hasattr(ssl, 'SSLContext'),\n                     'ssl.SSLContext not present')\n    def test_ssl_context(self):\n        resp = self.fetch(\"/hello\",\n                          ssl_options=ssl.SSLContext(ssl.PROTOCOL_SSLv23))\n        self.assertEqual(resp.body, b\"Hello world!\")\n\n    def test_ssl_options_handshake_fail(self):\n        with ExpectLog(gen_log, \"SSL Error|Uncaught exception\",\n                       required=False):\n            resp = self.fetch(\n                \"/hello\", ssl_options=dict(cert_reqs=ssl.CERT_REQUIRED))\n        self.assertRaises(ssl.SSLError, resp.rethrow)\n\n    @unittest.skipIf(not hasattr(ssl, 'SSLContext'),\n                     'ssl.SSLContext not present')\n    def test_ssl_context_handshake_fail(self):\n        with ExpectLog(gen_log, \"SSL Error|Uncaught exception\"):\n            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n            ctx.verify_mode = ssl.CERT_REQUIRED\n            resp = self.fetch(\"/hello\", ssl_options=ctx)\n        self.assertRaises(ssl.SSLError, resp.rethrow)\n\n    def test_error_logging(self):\n        # No stack traces are logged for SSL errors (in this case,\n        # failure to validate the testing self-signed cert).\n        # The SSLError is exposed through ssl.SSLError.\n        with ExpectLog(gen_log, '.*') as expect_log:\n            response = self.fetch(\"/\", validate_cert=True)\n            self.assertEqual(response.code, 599)\n            self.assertIsInstance(response.error, ssl.SSLError)\n        self.assertFalse(expect_log.logged_stack)\n\n\nclass CreateAsyncHTTPClientTestCase(AsyncTestCase):\n    def setUp(self):\n        super(CreateAsyncHTTPClientTestCase, self).setUp()\n        self.saved = AsyncHTTPClient._save_configuration()\n\n    def tearDown(self):\n        AsyncHTTPClient._restore_configuration(self.saved)\n        super(CreateAsyncHTTPClientTestCase, self).tearDown()\n\n    def test_max_clients(self):\n        AsyncHTTPClient.configure(SimpleAsyncHTTPClient)\n        with closing(AsyncHTTPClient(\n                self.io_loop, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 10)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=11, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 11)\n\n        # Now configure max_clients statically and try overriding it\n        # with each way max_clients can be passed\n        AsyncHTTPClient.configure(SimpleAsyncHTTPClient, max_clients=12)\n        with closing(AsyncHTTPClient(\n                self.io_loop, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 12)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=13, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 13)\n        with closing(AsyncHTTPClient(\n                self.io_loop, max_clients=14, force_instance=True)) as client:\n            self.assertEqual(client.max_clients, 14)\n\n\nclass HTTP100ContinueTestCase(AsyncHTTPTestCase):\n    def respond_100(self, request):\n        self.http1 = request.version.startswith('HTTP/1.')\n        if not self.http1:\n            request.connection.write_headers(ResponseStartLine('', 200, 'OK'),\n                                             HTTPHeaders())\n            request.connection.finish()\n            return\n        self.request = request\n        self.request.connection.stream.write(\n            b\"HTTP/1.1 100 CONTINUE\\r\\n\\r\\n\",\n            self.respond_200)\n\n    def respond_200(self):\n        self.request.connection.stream.write(\n            b\"HTTP/1.1 200 OK\\r\\nContent-Length: 1\\r\\n\\r\\nA\",\n            self.request.connection.stream.close)\n\n    def get_app(self):\n        # Not a full Application, but works as an HTTPServer callback\n        return self.respond_100\n\n    def test_100_continue(self):\n        res = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(res.body, b'A')\n\n\nclass HTTP204NoContentTestCase(AsyncHTTPTestCase):\n    def respond_204(self, request):\n        self.http1 = request.version.startswith('HTTP/1.')\n        if not self.http1:\n            # Close the request cleanly in HTTP/2; it will be skipped anyway.\n            request.connection.write_headers(ResponseStartLine('', 200, 'OK'),\n                                             HTTPHeaders())\n            request.connection.finish()\n            return\n        # A 204 response never has a body, even if doesn't have a content-length\n        # (which would otherwise mean read-until-close).  Tornado always\n        # sends a content-length, so we simulate here a server that sends\n        # no content length and does not close the connection.\n        #\n        # Tests of a 204 response with a Content-Length header are included\n        # in SimpleHTTPClientTestMixin.\n        stream = request.connection.detach()\n        stream.write(\n            b\"HTTP/1.1 204 No content\\r\\n\\r\\n\")\n        stream.close()\n\n    def get_app(self):\n        return self.respond_204\n\n    def test_204_no_content(self):\n        resp = self.fetch('/')\n        if not self.http1:\n            self.skipTest(\"requires HTTP/1.x\")\n        self.assertEqual(resp.code, 204)\n        self.assertEqual(resp.body, b'')\n\n\nclass HostnameMappingTestCase(AsyncHTTPTestCase):\n    def setUp(self):\n        super(HostnameMappingTestCase, self).setUp()\n        self.http_client = SimpleAsyncHTTPClient(\n            self.io_loop,\n            hostname_mapping={\n                'www.example.com': '127.0.0.1',\n                ('foo.example.com', 8000): ('127.0.0.1', self.get_http_port()),\n            })\n\n    def get_app(self):\n        return Application([url(\"/hello\", HelloWorldHandler), ])\n\n    def test_hostname_mapping(self):\n        self.http_client.fetch(\n            'http://www.example.com:%d/hello' % self.get_http_port(), self.stop)\n        response = self.wait()\n        response.rethrow()\n        self.assertEqual(response.body, b'Hello world!')\n\n    def test_port_mapping(self):\n        self.http_client.fetch('http://foo.example.com:8000/hello', self.stop)\n        response = self.wait()\n        response.rethrow()\n        self.assertEqual(response.body, b'Hello world!')\n\n\nclass ResolveTimeoutTestCase(AsyncHTTPTestCase):\n    def setUp(self):\n        # Dummy Resolver subclass that never invokes its callback.\n        class BadResolver(Resolver):\n            def resolve(self, *args, **kwargs):\n                pass\n\n        super(ResolveTimeoutTestCase, self).setUp()\n        self.http_client = SimpleAsyncHTTPClient(\n            self.io_loop,\n            resolver=BadResolver())\n\n    def get_app(self):\n        return Application([url(\"/hello\", HelloWorldHandler), ])\n\n    def test_resolve_timeout(self):\n        response = self.fetch('/hello', connect_timeout=0.1)\n        self.assertEqual(response.code, 599)\n\n\nclass MaxHeaderSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class SmallHeaders(RequestHandler):\n            def get(self):\n                self.set_header(\"X-Filler\", \"a\" * 100)\n                self.write(\"ok\")\n\n        class LargeHeaders(RequestHandler):\n            def get(self):\n                self.set_header(\"X-Filler\", \"a\" * 1000)\n                self.write(\"ok\")\n\n        return Application([('/small', SmallHeaders),\n                            ('/large', LargeHeaders)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_header_size=1024)\n\n    def test_small_headers(self):\n        response = self.fetch('/small')\n        response.rethrow()\n        self.assertEqual(response.body, b'ok')\n\n    def test_large_headers(self):\n        with ExpectLog(gen_log, \"Unsatisfiable read\"):\n            response = self.fetch('/large')\n        self.assertEqual(response.code, 599)\n\n\nclass MaxBodySizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n        class SmallBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 64)\n\n        class LargeBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 100)\n\n        return Application([('/small', SmallBody),\n                            ('/large', LargeBody)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 64)\n\n    def test_small_body(self):\n        response = self.fetch('/small')\n        response.rethrow()\n        self.assertEqual(response.body, b'a' * 1024 * 64)\n\n    def test_large_body(self):\n        with ExpectLog(gen_log, \"Malformed HTTP message from None: Content-Length too long\"):\n            response = self.fetch('/large')\n        self.assertEqual(response.code, 599)\n\n\nclass MaxBufferSizeTest(AsyncHTTPTestCase):\n    def get_app(self):\n\n        class LargeBody(RequestHandler):\n            def get(self):\n                self.write(\"a\" * 1024 * 100)\n\n        return Application([('/large', LargeBody)])\n\n    def get_http_client(self):\n        # 100KB body with 64KB buffer\n        return SimpleAsyncHTTPClient(io_loop=self.io_loop, max_body_size=1024 * 100, max_buffer_size=1024 * 64)\n\n    def test_large_body(self):\n        response = self.fetch('/large')\n        response.rethrow()\n        self.assertEqual(response.body, b'a' * 1024 * 100)\n\n\nclass ChunkedWithContentLengthTest(AsyncHTTPTestCase):\n    def get_app(self):\n\n        class ChunkedWithContentLength(RequestHandler):\n            def get(self):\n                # Add an invalid Transfer-Encoding to the response\n                self.set_header('Transfer-Encoding', 'chunked')\n                self.write(\"Hello world\")\n\n        return Application([('/chunkwithcl', ChunkedWithContentLength)])\n\n    def get_http_client(self):\n        return SimpleAsyncHTTPClient()\n\n    def test_chunked_with_content_length(self):\n        # Make sure the invalid headers are detected\n        with ExpectLog(gen_log, (\"Malformed HTTP message from None: Response \"\n                       \"with both Transfer-Encoding and Content-Length\")):\n            response = self.fetch('/chunkwithcl')\n        self.assertEqual(response.code, 599)\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 585ms\nPrepared 1 package in 757ms\nInstalled 1 package in 1ms\n + tornado==4.4.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1)\nResolved 29 packages in 11ms\nInstalled 29 packages in 71ms\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_fa38173fe2c4c4959cda7d80299595b5b71181a1\n.................................................................................................\ncollected 97 items\n\n=================================== ERRORS =====================================\n__________ ChunkedWithContentLengthTest.test_chunked_with_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 781, in test_chunked_with_content_length\n    response = self.fetch('/chunkwithcl')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ MaxBodySizeTest.test_large_body __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 740, in test_large_body\n    response = self.fetch('/large')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ MaxHeaderSizeTest.test_large_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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 713, in test_large_headers\n    response = self.fetch('/large')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ SimpleHTTPClientTestCase.test_no_content __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 338, in test_no_content\n    response = self.fetch(\"/no_content?error=1\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ SimpleHTTPSClientTestCase.test_100_continue __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 458, in test_100_continue\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_100_continue_early_response __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 466, in test_100_continue_early_response\n    response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_async_body_producer_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 418, in test_async_body_producer_chunked\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_async_body_producer_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 424, in test_async_body_producer_content_length\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_connection_limit __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 175, in test_connection_limit\n    self.wait(condition=lambda: len(self.triggers) == 2)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 542, in test_error_logging\n    response = self.fetch(\"/\", validate_cert=True)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_gzip __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 206, in test_gzip\n    response = self.fetch(\"/chunk\", use_gzip=False,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_head_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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 314, in test_head_request\n    response = self.fetch(\"/head\", method=\"HEAD\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_header_reuse __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 229, in test_header_reuse\n    self.fetch(\"/hello\", headers=headers)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_host_header __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 343, in test_host_header\n    response = self.fetch(\"/host_echo\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ipv6 __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 299, in test_ipv6\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_max_redirects __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 217, in test_max_redirects\n    response = self.fetch(\"/countdown/5\", max_redirects=3)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_native_body_producer_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 438, in test_native_body_producer_chunked\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_native_body_producer_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 451, in test_native_body_producer_content_length\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_no_content __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 327, in test_no_content\n    response = self.fetch(\"/no_content\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_no_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 388, in test_no_content_length\n    response = self.fetch(\"/no_content_length\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_options_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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 320, in test_options_request\n    response = self.fetch(\"/options\", method=\"OPTIONS\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_queue_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 376, in test_queue_timeout\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_redirect_connection_limit __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 198, in test_redirect_connection_limit\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_request_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 271, in test_request_timeout\n    response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_see_other_redirect __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 234, in test_see_other_redirect\n    response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_context __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 517, in test_ssl_context\n    resp = self.fetch(\"/hello\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_context_handshake_fail __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 534, in test_ssl_context_handshake_fail\n    resp = self.fetch(\"/hello\", ssl_options=ctx)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_options __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 511, in test_ssl_options\n    resp = self.fetch(\"/hello\", ssl_options={})\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_options_handshake_fail __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 524, in test_ssl_options_handshake_fail\n    resp = self.fetch(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_streaming_follow_redirects __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 480, in test_streaming_follow_redirects\n    self.fetch(\"/redirect?url=/hello\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_sync_body_producer_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 405, in test_sync_body_producer_chunked\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_sync_body_producer_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 411, in test_sync_body_producer_content_length\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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 ====================\nERROR r2e_tests.test_1::ChunkedWithContentLengthTest::test_chunked_with_content_length\nPASSED r2e_tests.test_1::CreateAsyncHTTPClientTestCase::test_max_clients\nPASSED r2e_tests.test_1::HTTP100ContinueTestCase::test_100_continue\nPASSED r2e_tests.test_1::HTTP204NoContentTestCase::test_204_no_content\nPASSED r2e_tests.test_1::HostnameMappingTestCase::test_hostname_mapping\nPASSED r2e_tests.test_1::HostnameMappingTestCase::test_port_mapping\nERROR r2e_tests.test_1::MaxBodySizeTest::test_large_body\nPASSED r2e_tests.test_1::MaxBodySizeTest::test_small_body\nPASSED r2e_tests.test_1::MaxBufferSizeTest::test_large_body\nERROR r2e_tests.test_1::MaxHeaderSizeTest::test_large_headers\nPASSED r2e_tests.test_1::MaxHeaderSizeTest::test_small_headers\nPASSED r2e_tests.test_1::ResolveTimeoutTestCase::test_resolve_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_304_with_content_length\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_all_methods\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_basic_auth\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_basic_auth_explicit_mode\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_body_encoding\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_body_sanity_checks\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_chunked_close\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_configure_defaults\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_credentials_in_url\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_final_callback_stack_context\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_follow_redirect\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_future_http_error\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_future_http_error_no_raise\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_future_interface\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_header_callback\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_header_callback_stack_context\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_header_types\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_hello_world\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_multi_line_headers\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_patch_receives_payload\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_post\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_put_307\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_reuse_request_from_response\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_streaming_callback\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_streaming_stack_context\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_types\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_unsupported_auth_mode\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_100_continue\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_100_continue_early_response\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_async_body_producer_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_async_body_producer_content_length\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_connect_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_connection_limit\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_connection_refused\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_gzip\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_head_request\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_header_reuse\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_host_header\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_ipv6\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_max_redirects\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_native_body_producer_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_native_body_producer_content_length\nERROR r2e_tests.test_1::SimpleHTTPClientTestCase::test_no_content\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_no_content_length\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_options_request\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_queue_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_redirect_connection_limit\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_request_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_see_other_redirect\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_singleton\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_streaming_follow_redirects\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_sync_body_producer_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_sync_body_producer_content_length\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_100_continue\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_100_continue_early_response\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_async_body_producer_chunked\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_async_body_producer_content_length\nPASSED r2e_tests.test_1::SimpleHTTPSClientTestCase::test_connect_timeout\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_connection_limit\nPASSED r2e_tests.test_1::SimpleHTTPSClientTestCase::test_connection_refused\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_error_logging\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_gzip\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_head_request\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_header_reuse\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_host_header\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ipv6\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_max_redirects\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_native_body_producer_chunked\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_native_body_producer_content_length\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_no_content\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_no_content_length\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_options_request\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_queue_timeout\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_redirect_connection_limit\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_request_timeout\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_see_other_redirect\nPASSED r2e_tests.test_1::SimpleHTTPSClientTestCase::test_singleton\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_context\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_context_handshake_fail\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_options\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_options_handshake_fail\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_streaming_follow_redirects\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_sync_body_producer_chunked\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_sync_body_producer_content_length\n=================== 32 errors, 65 passed in 0.68s ===================\n",
    "new_commit_res_stderr": "WARNING:tornado.access:405 HEAD /all_methods (127.0.0.1) 0.21ms\nWARNING:tornado.access:404 GET /notfound (127.0.0.1) 0.26ms\nWARNING:tornado.access:404 GET /notfound (127.0.0.1) 0.26ms\nWARNING:tornado.access:403 POST /respond_in_prepare (127.0.0.1) 0.19ms\nERROR:tornado.application:Future <tornado.concurrent.Future object at 0x7812bc7ecbb0> exception was never retrieved: Traceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/iostream.py\", line 1259, in _do_ssl_handshake\n    self.socket.do_handshake()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1343, in do_handshake\n    self._sslobj.do_handshake()\nConnectionResetError: [Errno 104] Connection reset by peer\n",
    "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_fa38173fe2c4c4959cda7d80299595b5b71181a1\n.................................................................................................\ncollected 97 items\n\n=================================== FAILURES ===================================\n__________ SimpleHTTPClientTestCase.test_request_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 275, in test_request_timeout\n    self.assertEqual(str(response.error), \"HTTP 599: Timeout during request\")\nAssertionError: 'HTTP 599: Timeout while interacting' != 'HTTP 599: Timeout during request'\n- HTTP 599: Timeout while interacting\n+ HTTP 599: Timeout during request\n\n\n=================================== ERRORS =====================================\n__________ ChunkedWithContentLengthTest.test_chunked_with_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 781, in test_chunked_with_content_length\n    response = self.fetch('/chunkwithcl')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ MaxBodySizeTest.test_large_body __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 740, in test_large_body\n    response = self.fetch('/large')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ MaxHeaderSizeTest.test_large_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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 713, in test_large_headers\n    response = self.fetch('/large')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ SimpleHTTPClientTestCase.test_no_content __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 338, in test_no_content\n    response = self.fetch(\"/no_content?error=1\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 647, in __exit__\n    raise Exception(\"did not get expected log message\")\nException: did not get expected log message\n__________ SimpleHTTPSClientTestCase.test_100_continue __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 458, in test_100_continue\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_100_continue_early_response __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 466, in test_100_continue_early_response\n    response = self.fetch(\"/respond_in_prepare\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_async_body_producer_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 418, in test_async_body_producer_chunked\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_async_body_producer_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 424, in test_async_body_producer_content_length\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_connection_limit __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 175, in test_connection_limit\n    self.wait(condition=lambda: len(self.triggers) == 2)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 542, in test_error_logging\n    response = self.fetch(\"/\", validate_cert=True)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_gzip __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 206, in test_gzip\n    response = self.fetch(\"/chunk\", use_gzip=False,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_head_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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 314, in test_head_request\n    response = self.fetch(\"/head\", method=\"HEAD\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_header_reuse __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 229, in test_header_reuse\n    self.fetch(\"/hello\", headers=headers)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_host_header __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 343, in test_host_header\n    response = self.fetch(\"/host_echo\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ipv6 __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 299, in test_ipv6\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_max_redirects __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 217, in test_max_redirects\n    response = self.fetch(\"/countdown/5\", max_redirects=3)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_native_body_producer_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 438, in test_native_body_producer_chunked\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_native_body_producer_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 451, in test_native_body_producer_content_length\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_no_content __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 327, in test_no_content\n    response = self.fetch(\"/no_content\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_no_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 388, in test_no_content_length\n    response = self.fetch(\"/no_content_length\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_options_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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 320, in test_options_request\n    response = self.fetch(\"/options\", method=\"OPTIONS\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_queue_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 376, in test_queue_timeout\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_redirect_connection_limit __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 198, in test_redirect_connection_limit\n    response = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_request_timeout __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 271, in test_request_timeout\n    response = self.fetch('/trigger?wake=false', request_timeout=timeout)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_see_other_redirect __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 234, in test_see_other_redirect\n    response = self.fetch(\"/see_other_post\", method=\"POST\", body=\"%d\" % code)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_context __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 517, in test_ssl_context\n    resp = self.fetch(\"/hello\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_context_handshake_fail __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 534, in test_ssl_context_handshake_fail\n    resp = self.fetch(\"/hello\", ssl_options=ctx)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_options __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 511, in test_ssl_options\n    resp = self.fetch(\"/hello\", ssl_options={})\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_ssl_options_handshake_fail __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 524, in test_ssl_options_handshake_fail\n    resp = self.fetch(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_streaming_follow_redirects __________\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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 480, in test_streaming_follow_redirects\n    self.fetch(\"/redirect?url=/hello\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_sync_body_producer_chunked __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 405, in test_sync_body_producer_chunked\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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__________ SimpleHTTPSClientTestCase.test_sync_body_producer_content_length __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 132, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/r2e_tests/test_1.py\", line 411, in test_sync_body_producer_content_length\n    response = self.fetch(\"/echo_post\", method=\"POST\",\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 402, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 332, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/testing.py\", line 268, 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_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 274, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/tcpserver.py\", line 236, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 510, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/netutil.py\", line 487, 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 ====================\nERROR r2e_tests.test_1::ChunkedWithContentLengthTest::test_chunked_with_content_length\nPASSED r2e_tests.test_1::CreateAsyncHTTPClientTestCase::test_max_clients\nPASSED r2e_tests.test_1::HTTP100ContinueTestCase::test_100_continue\nPASSED r2e_tests.test_1::HTTP204NoContentTestCase::test_204_no_content\nPASSED r2e_tests.test_1::HostnameMappingTestCase::test_hostname_mapping\nPASSED r2e_tests.test_1::HostnameMappingTestCase::test_port_mapping\nERROR r2e_tests.test_1::MaxBodySizeTest::test_large_body\nPASSED r2e_tests.test_1::MaxBodySizeTest::test_small_body\nPASSED r2e_tests.test_1::MaxBufferSizeTest::test_large_body\nERROR r2e_tests.test_1::MaxHeaderSizeTest::test_large_headers\nPASSED r2e_tests.test_1::MaxHeaderSizeTest::test_small_headers\nPASSED r2e_tests.test_1::ResolveTimeoutTestCase::test_resolve_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_304_with_content_length\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_all_methods\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_basic_auth\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_basic_auth_explicit_mode\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_body_encoding\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_body_sanity_checks\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_chunked_close\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_configure_defaults\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_credentials_in_url\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_final_callback_stack_context\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_follow_redirect\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_future_http_error\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_future_http_error_no_raise\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_future_interface\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_header_callback\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_header_callback_stack_context\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_header_types\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_hello_world\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_multi_line_headers\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_patch_receives_payload\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_post\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_put_307\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_reuse_request_from_response\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_streaming_callback\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_streaming_stack_context\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_types\nPASSED r2e_tests.test_1::SimpleHTTPClientCommonTestCase::test_unsupported_auth_mode\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_100_continue\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_100_continue_early_response\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_async_body_producer_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_async_body_producer_content_length\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_connect_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_connection_limit\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_connection_refused\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_gzip\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_head_request\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_header_reuse\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_host_header\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_ipv6\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_max_redirects\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_native_body_producer_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_native_body_producer_content_length\nERROR r2e_tests.test_1::SimpleHTTPClientTestCase::test_no_content\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_no_content_length\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_options_request\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_queue_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_redirect_connection_limit\nFAILED r2e_tests.test_1::SimpleHTTPClientTestCase::test_request_timeout\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_see_other_redirect\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_singleton\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_streaming_follow_redirects\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_sync_body_producer_chunked\nPASSED r2e_tests.test_1::SimpleHTTPClientTestCase::test_sync_body_producer_content_length\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_100_continue\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_100_continue_early_response\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_async_body_producer_chunked\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_async_body_producer_content_length\nPASSED r2e_tests.test_1::SimpleHTTPSClientTestCase::test_connect_timeout\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_connection_limit\nPASSED r2e_tests.test_1::SimpleHTTPSClientTestCase::test_connection_refused\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_error_logging\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_gzip\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_head_request\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_header_reuse\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_host_header\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ipv6\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_max_redirects\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_native_body_producer_chunked\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_native_body_producer_content_length\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_no_content\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_no_content_length\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_options_request\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_queue_timeout\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_redirect_connection_limit\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_request_timeout\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_see_other_redirect\nPASSED r2e_tests.test_1::SimpleHTTPSClientTestCase::test_singleton\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_context\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_context_handshake_fail\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_options\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_ssl_options_handshake_fail\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_streaming_follow_redirects\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_sync_body_producer_chunked\nERROR r2e_tests.test_1::SimpleHTTPSClientTestCase::test_sync_body_producer_content_length\n=================== 1 failed, 32 errors, 64 passed in 0.68s ===================\n",
    "old_commit_res_stderr": "WARNING:tornado.access:405 HEAD /all_methods (127.0.0.1) 0.17ms\nWARNING:tornado.access:404 GET /notfound (127.0.0.1) 0.19ms\nWARNING:tornado.access:404 GET /notfound (127.0.0.1) 0.18ms\nWARNING:tornado.access:403 POST /respond_in_prepare (127.0.0.1) 0.15ms\nERROR:tornado.application:Future <tornado.concurrent.Future object at 0x724f36fbd730> exception was never retrieved: Traceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_fa38173fe2c4c4959cda7d80299595b5b71181a1/tornado/iostream.py\", line 1259, in _do_ssl_handshake\n    self.socket.do_handshake()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1343, in do_handshake\n    self._sslobj.do_handshake()\nConnectionResetError: [Errno 104] Connection reset by peer\n"
}
tornado/simple_httpclient.py tornado/test/simple_httpclient_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Incorrect Error Message on Request Timeout in HTTP Client

**Description:**
When an HTTP request exceeds the specified timeout, the error message returned does not accurately describe where the timeout occurred. Instead of indicating that the timeout happened during the request, it states that the timeout occurred while interacting. This ambiguity can make debugging and handling timeout issues more challenging.

**Example:**
```python
client.fetch('http://example.com/slow', connect_timeout=0.1)
response = client.wait()
print(str(response.error))  # Outputs: "HTTP 599: Timeout while interacting"
```

**Expected Behavior:**
The error message should clearly indicate that the timeout occurred during the request process. For example:
```
"HTTP 599: Timeout during request"
```

**Actual Behavior:**
The error message incorrectly states:
```
"HTTP 599: Timeout while interacting"
```
This misleading message does not clearly convey that the timeout was specifically related to the request itself.

[/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/simple_httpclient.py
#!/usr/bin/env python
from __future__ import absolute_import, division, print_function, with_statement

from tornado.escape import utf8, _unicode
from tornado import gen
from tornado.httpclient import HTTPResponse, HTTPError, AsyncHTTPClient, main, _RequestProxy
from tornado import httputil
from tornado.http1connection import HTTP1Connection, HTTP1ConnectionParameters
from tornado.iostream import StreamClosedError
from tornado.netutil import Resolver, OverrideResolver, _client_ssl_defaults
from tornado.log import gen_log
from tornado import stack_context
from tornado.tcpclient import TCPClient

import base64
import collections
import copy
import functools
import re
import socket
import sys
from io import BytesIO


try:
    import urlparse  # py2
except ImportError:
    import urllib.parse as urlparse  # py3

try:
    import ssl
except ImportError:
    # ssl is not available on Google App Engine.
    ssl = None

try:
    import certifi
except ImportError:
    certifi = None


def _default_ca_certs():
    if certifi is None:
        raise Exception("The 'certifi' package is required to use https "
                        "in simple_httpclient")
    return certifi.where()


class SimpleAsyncHTTPClient(AsyncHTTPClient):
    """Non-blocking HTTP client with no external dependencies.

    This class implements an HTTP 1.1 client on top of Tornado's IOStreams.
    Some features found in the curl-based AsyncHTTPClient are not yet
    supported.  In particular, proxies are not supported, connections
    are not reused, and callers cannot select the network interface to be
    used.
    """
    def initialize(self, io_loop, max_clients=10,
                   hostname_mapping=None, max_buffer_size=104857600,
                   resolver=None, defaults=None, max_header_size=None,
                   max_body_size=None):
        """Creates a AsyncHTTPClient.

        Only a single AsyncHTTPClient instance exists per IOLoop
        in order to provide limitations on the number of pending connections.
        ``force_instance=True`` may be used to suppress this behavior.

        Note that because of this implicit reuse, unless ``force_instance``
        is used, only the first call to the constructor actually uses
        its arguments. It is recommended to use the ``configure`` method
        instead of the constructor to ensure that arguments take effect.

        ``max_clients`` is the number of concurrent requests that can be
        in progress; when this limit is reached additional requests will be
        queued. Note that time spent waiting in this queue still counts
        against the ``request_timeout``.

        ``hostname_mapping`` is a dictionary mapping hostnames to IP addresses.
        It can be used to make local DNS changes when modifying system-wide
        settings like ``/etc/hosts`` is not possible or desirable (e.g. in
        unittests).

        ``max_buffer_size`` (default 100MB) is the number of bytes
        that can be read into memory at once. ``max_body_size``
        (defaults to ``max_buffer_size``) is the largest response body
        that the client will accept.  Without a
        ``streaming_callback``, the smaller of these two limits
        applies; with a ``streaming_callback`` only ``max_body_size``
        does.

        .. versionchanged:: 4.2
           Added the ``max_body_size`` argument.
        """
        super(SimpleAsyncHTTPClient, self).initialize(io_loop,
                                                      defaults=defaults)
        self.max_clients = max_clients
        self.queue = collections.deque()
        self.active = {}
        self.waiting = {}
        self.max_buffer_size = max_buffer_size
        self.max_header_size = max_header_size
        self.max_body_size = max_body_size
        # TCPClient could create a Resolver for us, but we have to do it
        # ourselves to support hostname_mapping.
        if resolver:
            self.resolver = resolver
            self.own_resolver = False
        else:
            self.resolver = Resolver(io_loop=io_loop)
            self.own_resolver = True
        if hostname_mapping is not None:
            self.resolver = OverrideResolver(resolver=self.resolver,
                                             mapping=hostname_mapping)
        self.tcp_client = TCPClient(resolver=self.resolver, io_loop=io_loop)

    def close(self):
        super(SimpleAsyncHTTPClient, self).close()
        if self.own_resolver:
            self.resolver.close()
        self.tcp_client.close()

    def fetch_impl(self, request, callback):
        key = object()
        self.queue.append((key, request, callback))
        if not len(self.active) < self.max_clients:
            timeout_handle = self.io_loop.add_timeout(
                self.io_loop.time() + min(request.connect_timeout,
                                          request.request_timeout),
                functools.partial(self._on_timeout, key, "in request queue"))
        else:
            timeout_handle = None
        self.waiting[key] = (request, callback, timeout_handle)
        self._process_queue()
        if self.queue:
            gen_log.debug("max_clients limit reached, request queued. "
                          "%d active, %d queued requests." % (
                              len(self.active), len(self.queue)))

    def _process_queue(self):
        with stack_context.NullContext():
            while self.queue and len(self.active) < self.max_clients:
                key, request, callback = self.queue.popleft()
                if key not in self.waiting:
                    continue
                self._remove_timeout(key)
                self.active[key] = (request, callback)
                release_callback = functools.partial(self._release_fetch, key)
                self._handle_request(request, release_callback, callback)

    def _connection_class(self):
        return _HTTPConnection

    def _handle_request(self, request, release_callback, final_callback):
        self._connection_class()(
            self.io_loop, self, request, release_callback,
            final_callback, self.max_buffer_size, self.tcp_client,
            self.max_header_size, self.max_body_size)

    def _release_fetch(self, key):
        del self.active[key]
        self._process_queue()

    def _remove_timeout(self, key):
        if key in self.waiting:
            request, callback, timeout_handle = self.waiting[key]
            if timeout_handle is not None:
                self.io_loop.remove_timeout(timeout_handle)
            del self.waiting[key]

    def _on_timeout(self, key, info=None):
        """Timeout callback of request.

        Construct a timeout HTTPResponse when a timeout occurs.

        :arg object key: A simple object to mark the request.
        :info string key: More detailed timeout information.
        """
        request, callback, timeout_handle = self.waiting[key]
        self.queue.remove((key, request, callback))

        error_message = "Timeout {0}".format(info) if info else "Timeout"
        timeout_response = HTTPResponse(
            request, 599, error=HTTPError(599, error_message),
            request_time=self.io_loop.time() - request.start_time)
        self.io_loop.add_callback(callback, timeout_response)
        del self.waiting[key]


class _HTTPConnection(httputil.HTTPMessageDelegate):
    _SUPPORTED_METHODS = set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])

    def __init__(self, io_loop, client, request, release_callback,
                 final_callback, max_buffer_size, tcp_client,
                 max_header_size, max_body_size):
        self.start_time = io_loop.time()
        self.io_loop = io_loop
        self.client = client
        self.request = request
        self.release_callback = release_callback
        self.final_callback = final_callback
        self.max_buffer_size = max_buffer_size
        self.tcp_client = tcp_client
        self.max_header_size = max_header_size
        self.max_body_size = max_body_size
        self.code = None
        self.headers = None
        self.chunks = []
        self._decompressor = None
        # Timeout handle returned by IOLoop.add_timeout
        self._timeout = None
        self._sockaddr = None
        with stack_context.ExceptionStackContext(self._handle_exception):
            self.parsed = urlparse.urlsplit(_unicode(self.request.url))
            if self.parsed.scheme not in ("http", "https"):
                raise ValueError("Unsupported url scheme: %s" %
                                 self.request.url)
            # urlsplit results have hostname and port results, but they
            # didn't support ipv6 literals until python 2.7.
            netloc = self.parsed.netloc
            if "@" in netloc:
                userpass, _, netloc = netloc.rpartition("@")
            host, port = httputil.split_host_and_port(netloc)
            if port is None:
                port = 443 if self.parsed.scheme == "https" else 80
            if re.match(r'^\[.*\]$', host):
                # raw ipv6 addresses in urls are enclosed in brackets
                host = host[1:-1]
            self.parsed_hostname = host  # save final host for _on_connect

            if request.allow_ipv6 is False:
                af = socket.AF_INET
            else:
                af = socket.AF_UNSPEC

            ssl_options = self._get_ssl_options(self.parsed.scheme)

            timeout = min(self.request.connect_timeout, self.request.request_timeout)
            if timeout:
                self._timeout = self.io_loop.add_timeout(
                    self.start_time + timeout,
                    stack_context.wrap(functools.partial(self._on_timeout, "while connecting")))
            self.tcp_client.connect(host, port, af=af,
                                    ssl_options=ssl_options,
                                    max_buffer_size=self.max_buffer_size,
                                    callback=self._on_connect)

    def _get_ssl_options(self, scheme):
        if scheme == "https":
            if self.request.ssl_options is not None:
                return self.request.ssl_options
            # If we are using the defaults, don't construct a
            # new SSLContext.
            if (self.request.validate_cert and
                    self.request.ca_certs is None and
                    self.request.client_cert is None and
                    self.request.client_key is None):
                return _client_ssl_defaults
            ssl_options = {}
            if self.request.validate_cert:
                ssl_options["cert_reqs"] = ssl.CERT_REQUIRED
            if self.request.ca_certs is not None:
                ssl_options["ca_certs"] = self.request.ca_certs
            elif not hasattr(ssl, 'create_default_context'):
                # When create_default_context is present,
                # we can omit the "ca_certs" parameter entirely,
                # which avoids the dependency on "certifi" for py34.
                ssl_options["ca_certs"] = _default_ca_certs()
            if self.request.client_key is not None:
                ssl_options["keyfile"] = self.request.client_key
            if self.request.client_cert is not None:
                ssl_options["certfile"] = self.request.client_cert

            # SSL interoperability is tricky.  We want to disable
            # SSLv2 for security reasons; it wasn't disabled by default
            # until openssl 1.0.  The best way to do this is to use
            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python
            # until 3.2.  Python 2.7 adds the ciphers argument, which
            # can also be used to disable SSLv2.  As a last resort
            # on python 2.6, we set ssl_version to TLSv1.  This is
            # more narrow than we'd like since it also breaks
            # compatibility with servers configured for SSLv3 only,
            # but nearly all servers support both SSLv3 and TLSv1:
            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html
            if sys.version_info >= (2, 7):
                # In addition to disabling SSLv2, we also exclude certain
                # classes of insecure ciphers.
                ssl_options["ciphers"] = "DEFAULT:!SSLv2:!EXPORT:!DES"
            else:
                # This is really only necessary for pre-1.0 versions
                # of openssl, but python 2.6 doesn't expose version
                # information.
                ssl_options["ssl_version"] = ssl.PROTOCOL_TLSv1
            return ssl_options
        return None

    def _on_timeout(self, info=None):
        """Timeout callback of _HTTPConnection instance.

        Raise a timeout HTTPError when a timeout occurs.

        :info string key: More detailed timeout information.
        """
        self._timeout = None
        error_message = "Timeout {0}".format(info) if info else "Timeout"
        if self.final_callback is not None:
            raise HTTPError(599, error_message)

    def _remove_timeout(self):
        if self._timeout is not None:
            self.io_loop.remove_timeout(self._timeout)
            self._timeout = None

    def _on_connect(self, stream):
        if self.final_callback is None:
            # final_callback is cleared if we've hit our timeout.
            stream.close()
            return
        self.stream = stream
        self.stream.set_close_callback(self.on_connection_close)
        self._remove_timeout()
        if self.final_callback is None:
            return
        if self.request.request_timeout:
            self._timeout = self.io_loop.add_timeout(
                self.start_time + self.request.request_timeout,
                stack_context.wrap(functools.partial(self._on_timeout, "while interacting")))
        if (self.request.method not in self._SUPPORTED_METHODS and
                not self.request.allow_nonstandard_methods):
            raise KeyError("unknown method %s" % self.request.method)
        for key in ('network_interface',
                    'proxy_host', 'proxy_port',
                    'proxy_username', 'proxy_password'):
            if getattr(self.request, key, None):
                raise NotImplementedError('%s not supported' % key)
        if "Connection" not in self.request.headers:
            self.request.headers["Connection"] = "close"
        if "Host" not in self.request.headers:
            if '@' in self.parsed.netloc:
                self.request.headers["Host"] = self.parsed.netloc.rpartition('@')[-1]
            else:
                self.request.headers["Host"] = self.parsed.netloc
        username, password = None, None
        if self.parsed.username is not None:
            username, password = self.parsed.username, self.parsed.password
        elif self.request.auth_username is not None:
            username = self.request.auth_username
            password = self.request.auth_password or ''
        if username is not None:
            if self.request.auth_mode not in (None, "basic"):
                raise ValueError("unsupported auth_mode %s",
                                 self.request.auth_mode)
            auth = utf8(username) + b":" + utf8(password)
            self.request.headers["Authorization"] = (b"Basic " +
                                                     base64.b64encode(auth))
        if self.request.user_agent:
            self.request.headers["User-Agent"] = self.request.user_agent
        if not self.request.allow_nonstandard_methods:
            # Some HTTP methods nearly always have bodies while others
            # almost never do. Fail in this case unless the user has
            # opted out of sanity checks with allow_nonstandard_methods.
            body_expected = self.request.method in ("POST", "PATCH", "PUT")
            body_present = (self.request.body is not None or
                            self.request.body_producer is not None)
            if ((body_expected and not body_present) or
                    (body_present and not body_expected)):
                raise ValueError(
                    'Body must %sbe None for method %s (unless '
                    'allow_nonstandard_methods is true)' %
                    ('not ' if body_expected else '', self.request.method))
        if self.request.expect_100_continue:
            self.request.headers["Expect"] = "100-continue"
        if self.request.body is not None:
            # When body_producer is used the caller is responsible for
            # setting Content-Length (or else chunked encoding will be used).
            self.request.headers["Content-Length"] = str(len(
                self.request.body))
        if (self.request.method == "POST" and
                "Content-Type" not in self.request.headers):
            self.request.headers["Content-Type"] = "application/x-www-form-urlencoded"
        if self.request.decompress_response:
            self.request.headers["Accept-Encoding"] = "gzip"
        req_path = ((self.parsed.path or '/') +
                    (('?' + self.parsed.query) if self.parsed.query else ''))
        self.connection = self._create_connection(stream)
        start_line = httputil.RequestStartLine(self.request.method,
                                               req_path, '')
        self.connection.write_headers(start_line, self.request.headers)
        if self.request.expect_100_continue:
            self._read_response()
        else:
            self._write_body(True)

    def _create_connection(self, stream):
        stream.set_nodelay(True)
        connection = HTTP1Connection(
            stream, True,
            HTTP1ConnectionParameters(
                no_keep_alive=True,
                max_header_size=self.max_header_size,
                max_body_size=self.max_body_size,
                decompress=self.request.decompress_response),
            self._sockaddr)
        return connection

    def _write_body(self, start_read):
        if self.request.body is not None:
            self.connection.write(self.request.body)
        elif self.request.body_producer is not None:
            fut = self.request.body_producer(self.connection.write)
            if fut is not None:
                fut = gen.convert_yielded(fut)

                def on_body_written(fut):
                    fut.result()
                    self.connection.finish()
                    if start_read:
                        self._read_response()
                self.io_loop.add_future(fut, on_body_written)
                return
        self.connection.finish()
        if start_read:
            self._read_response()

    def _read_response(self):
        # Ensure that any exception raised in read_response ends up in our
        # stack context.
        self.io_loop.add_future(
            self.connection.read_response(self),
            lambda f: f.result())

    def _release(self):
        if self.release_callback is not None:
            release_callback = self.release_callback
            self.release_callback = None
            release_callback()

    def _run_callback(self, response):
        self._release()
        if self.final_callback is not None:
            final_callback = self.final_callback
            self.final_callback = None
            self.io_loop.add_callback(final_callback, response)

    def _handle_exception(self, typ, value, tb):
        if self.final_callback:
            self._remove_timeout()
            if isinstance(value, StreamClosedError):
                if value.real_error is None:
                    value = HTTPError(599, "Stream closed")
                else:
                    value = value.real_error
            self._run_callback(HTTPResponse(self.request, 599, error=value,
                                            request_time=self.io_loop.time() - self.start_time,
                                            ))

            if hasattr(self, "stream"):
                # TODO: this may cause a StreamClosedError to be raised
                # by the connection's Future.  Should we cancel the
                # connection more gracefully?
                self.stream.close()
            return True
        else:
            # If our callback has already been called, we are probably
            # catching an exception that is not caused by us but rather
            # some child of our callback. Rather than drop it on the floor,
            # pass it along, unless it's just the stream being closed.
            return isinstance(value, StreamClosedError)

    def on_connection_close(self):
        if self.final_callback is not None:
            message = "Connection closed"
            if self.stream.error:
                raise self.stream.error
            try:
                raise HTTPError(599, message)
            except HTTPError:
                self._handle_exception(*sys.exc_info())

    def headers_received(self, first_line, headers):
        if self.request.expect_100_continue and first_line.code == 100:
            self._write_body(False)
            return
        self.code = first_line.code
        self.reason = first_line.reason
        self.headers = headers

        if self._should_follow_redirect():
            return

        if self.request.header_callback is not None:
            # Reassemble the start line.
            self.request.header_callback('%s %s %s\r\n' % first_line)
            for k, v in self.headers.get_all():
                self.request.header_callback("%s: %s\r\n" % (k, v))
            self.request.header_callback('\r\n')

    def _should_follow_redirect(self):
        return (self.request.follow_redirects and
                self.request.max_redirects > 0 and
                self.code in (301, 302, 303, 307))

    def finish(self):
        data = b''.join(self.chunks)
        self._remove_timeout()
        original_request = getattr(self.request, "original_request",
                                   self.request)
        if self._should_follow_redirect():
            assert isinstance(self.request, _RequestProxy)
            new_request = copy.copy(self.request.request)
            new_request.url = urlparse.urljoin(self.request.url,
                                               self.headers["Location"])
            new_request.max_redirects = self.request.max_redirects - 1
            del new_request.headers["Host"]
            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
            # Client SHOULD make a GET request after a 303.
            # According to the spec, 302 should be followed by the same
            # method as the original request, but in practice browsers
            # treat 302 the same as 303, and many servers use 302 for
            # compatibility with pre-HTTP/1.1 user agents which don't
            # understand the 303 status.
            if self.code in (302, 303):
                new_request.method = "GET"
                new_request.body = None
                for h in ["Content-Length", "Content-Type",
                          "Content-Encoding", "Transfer-Encoding"]:
                    try:
                        del self.request.headers[h]
                    except KeyError:
                        pass
            new_request.original_request = original_request
            final_callback = self.final_callback
            self.final_callback = None
            self._release()
            self.client.fetch(new_request, final_callback)
            self._on_end_request()
            return
        if self.request.streaming_callback:
            buffer = BytesIO()
        else:
            buffer = BytesIO(data)  # TODO: don't require one big string?
        response = HTTPResponse(original_request,
                                self.code, reason=getattr(self, 'reason', None),
                                headers=self.headers,
                                request_time=self.io_loop.time() - self.start_time,
                                buffer=buffer,
                                effective_url=self.request.url)
        self._run_callback(response)
        self._on_end_request()

    def _on_end_request(self):
        self.stream.close()

    def data_received(self, chunk):
        if self._should_follow_redirect():
            # We're going to follow a redirect so just discard the body.
            return
        if self.request.streaming_callback is not None:
            self.request.streaming_callback(chunk)
        else:
            self.chunks.append(chunk)


if __name__ == "__main__":
    AsyncHTTPClient.configure(SimpleAsyncHTTPClient)
    main()

```
--- 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 Error Message on Request Timeout in HTTP Client

**Description:**
When an HTTP request exceeds the specified timeout, the error message returned does not accurately describe where the timeout occurred. Instead of indicating that the timeout happened during the request, it states that the timeout occurred while interacting. This ambiguity can make debugging and handling timeout issues more challenging.

**Example:**
```python
client.fetch('http://example.com/slow', connect_timeout=0.1)
response = client.wait()
print(str(response.error))  # Outputs: "HTTP 599: Timeout while interacting"
```

**Expected Behavior:**
The error message should clearly indicate that the timeout occurred during the request process. For example:
```
"HTTP 599: Timeout during request"
```

**Actual Behavior:**
The error message incorrectly states:
```
"HTTP 599: Timeout while interacting"
```
This misleading message does not clearly convey that the timeout was specifically related to the request itself.

[/ISSUE]
{
    "ChunkedWithContentLengthTest.test_chunked_with_content_length": "ERROR",
    "CreateAsyncHTTPClientTestCase.test_max_clients": "PASSED",
    "HTTP100ContinueTestCase.test_100_continue": "PASSED",
    "HTTP204NoContentTestCase.test_204_no_content": "PASSED",
    "HostnameMappingTestCase.test_hostname_mapping": "PASSED",
    "HostnameMappingTestCase.test_port_mapping": "PASSED",
    "MaxBodySizeTest.test_large_body": "ERROR",
    "MaxBodySizeTest.test_small_body": "PASSED",
    "MaxBufferSizeTest.test_large_body": "PASSED",
    "MaxHeaderSizeTest.test_large_headers": "ERROR",
    "MaxHeaderSizeTest.test_small_headers": "PASSED",
    "ResolveTimeoutTestCase.test_resolve_timeout": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_304_with_content_length": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_all_methods": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_basic_auth": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_basic_auth_explicit_mode": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_body_encoding": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_body_sanity_checks": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_chunked": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_chunked_close": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_configure_defaults": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_credentials_in_url": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_final_callback_stack_context": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_follow_redirect": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_future_http_error": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_future_http_error_no_raise": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_future_interface": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_header_callback": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_header_callback_stack_context": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_header_types": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_hello_world": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_multi_line_headers": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_patch_receives_payload": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_post": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_put_307": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_reuse_request_from_response": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_streaming_callback": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_streaming_stack_context": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_types": "PASSED",
    "SimpleHTTPClientCommonTestCase.test_unsupported_auth_mode": "PASSED",
    "SimpleHTTPClientTestCase.test_100_continue": "PASSED",
    "SimpleHTTPClientTestCase.test_100_continue_early_response": "PASSED",
    "SimpleHTTPClientTestCase.test_async_body_producer_chunked": "PASSED",
    "SimpleHTTPClientTestCase.test_async_body_producer_content_length": "PASSED",
    "SimpleHTTPClientTestCase.test_connect_timeout": "PASSED",
    "SimpleHTTPClientTestCase.test_connection_limit": "PASSED",
    "SimpleHTTPClientTestCase.test_connection_refused": "PASSED",
    "SimpleHTTPClientTestCase.test_gzip": "PASSED",
    "SimpleHTTPClientTestCase.test_head_request": "PASSED",
    "SimpleHTTPClientTestCase.test_header_reuse": "PASSED",
    "SimpleHTTPClientTestCase.test_host_header": "PASSED",
    "SimpleHTTPClientTestCase.test_ipv6": "PASSED",
    "SimpleHTTPClientTestCase.test_max_redirects": "PASSED",
    "SimpleHTTPClientTestCase.test_native_body_producer_chunked": "PASSED",
    "SimpleHTTPClientTestCase.test_native_body_producer_content_length": "PASSED",
    "SimpleHTTPClientTestCase.test_no_content": "ERROR",
    "SimpleHTTPClientTestCase.test_no_content_length": "PASSED",
    "SimpleHTTPClientTestCase.test_options_request": "PASSED",
    "SimpleHTTPClientTestCase.test_queue_timeout": "PASSED",
    "SimpleHTTPClientTestCase.test_redirect_connection_limit": "PASSED",
    "SimpleHTTPClientTestCase.test_request_timeout": "PASSED",
    "SimpleHTTPClientTestCase.test_see_other_redirect": "PASSED",
    "SimpleHTTPClientTestCase.test_singleton": "PASSED",
    "SimpleHTTPClientTestCase.test_streaming_follow_redirects": "PASSED",
    "SimpleHTTPClientTestCase.test_sync_body_producer_chunked": "PASSED",
    "SimpleHTTPClientTestCase.test_sync_body_producer_content_length": "PASSED",
    "SimpleHTTPSClientTestCase.test_100_continue": "ERROR",
    "SimpleHTTPSClientTestCase.test_100_continue_early_response": "ERROR",
    "SimpleHTTPSClientTestCase.test_async_body_producer_chunked": "ERROR",
    "SimpleHTTPSClientTestCase.test_async_body_producer_content_length": "ERROR",
    "SimpleHTTPSClientTestCase.test_connect_timeout": "PASSED",
    "SimpleHTTPSClientTestCase.test_connection_limit": "ERROR",
    "SimpleHTTPSClientTestCase.test_connection_refused": "PASSED",
    "SimpleHTTPSClientTestCase.test_error_logging": "ERROR",
    "SimpleHTTPSClientTestCase.test_gzip": "ERROR",
    "SimpleHTTPSClientTestCase.test_head_request": "ERROR",
    "SimpleHTTPSClientTestCase.test_header_reuse": "ERROR",
    "SimpleHTTPSClientTestCase.test_host_header": "ERROR",
    "SimpleHTTPSClientTestCase.test_ipv6": "ERROR",
    "SimpleHTTPSClientTestCase.test_max_redirects": "ERROR",
    "SimpleHTTPSClientTestCase.test_native_body_producer_chunked": "ERROR",
    "SimpleHTTPSClientTestCase.test_native_body_producer_content_length": "ERROR",
    "SimpleHTTPSClientTestCase.test_no_content": "ERROR",
    "SimpleHTTPSClientTestCase.test_no_content_length": "ERROR",
    "SimpleHTTPSClientTestCase.test_options_request": "ERROR",
    "SimpleHTTPSClientTestCase.test_queue_timeout": "ERROR",
    "SimpleHTTPSClientTestCase.test_redirect_connection_limit": "ERROR",
    "SimpleHTTPSClientTestCase.test_request_timeout": "ERROR",
    "SimpleHTTPSClientTestCase.test_see_other_redirect": "ERROR",
    "SimpleHTTPSClientTestCase.test_singleton": "PASSED",
    "SimpleHTTPSClientTestCase.test_ssl_context": "ERROR",
    "SimpleHTTPSClientTestCase.test_ssl_context_handshake_fail": "ERROR",
    "SimpleHTTPSClientTestCase.test_ssl_options": "ERROR",
    "SimpleHTTPSClientTestCase.test_ssl_options_handshake_fail": "ERROR",
    "SimpleHTTPSClientTestCase.test_streaming_follow_redirects": "ERROR",
    "SimpleHTTPSClientTestCase.test_sync_body_producer_chunked": "ERROR",
    "SimpleHTTPSClientTestCase.test_sync_body_producer_content_length": "ERROR"
}
diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py
index ac6bd26e..44e45c43 100644
--- a/tornado/simple_httpclient.py
+++ b/tornado/simple_httpclient.py
@@ -323,7 +323,7 @@ class _HTTPConnection(httputil.HTTPMessageDelegate):
         if self.request.request_timeout:
             self._timeout = self.io_loop.add_timeout(
                 self.start_time + self.request.request_timeout,
-                stack_context.wrap(functools.partial(self._on_timeout, "while interacting")))
+                stack_context.wrap(functools.partial(self._on_timeout, "during request")))
         if (self.request.method not in self._SUPPORTED_METHODS and
                 not self.request.allow_nonstandard_methods):
             raise KeyError("unknown method %s" % self.request.method)

{"tornado/simple_httpclient.py": "#!/usr/bin/env python\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom tornado.escape import utf8, _unicode\nfrom tornado import gen\nfrom tornado.httpclient import HTTPResponse, HTTPError, AsyncHTTPClient, main, _RequestProxy\nfrom tornado import httputil\nfrom tornado.http1connection import HTTP1Connection, HTTP1ConnectionParameters\nfrom tornado.iostream import StreamClosedError\nfrom tornado.netutil import Resolver, OverrideResolver, _client_ssl_defaults\nfrom tornado.log import gen_log\nfrom tornado import stack_context\nfrom tornado.tcpclient import TCPClient\n\nimport base64\nimport collections\nimport copy\nimport functools\nimport re\nimport socket\nimport sys\nfrom io import BytesIO\n\n\ntry:\n    import urlparse  # py2\nexcept ImportError:\n    import urllib.parse as urlparse  # py3\n\ntry:\n    import ssl\nexcept ImportError:\n    # ssl is not available on Google App Engine.\n    ssl = None\n\ntry:\n    import certifi\nexcept ImportError:\n    certifi = None\n\n\ndef _default_ca_certs():\n    if certifi is None:\n        raise Exception(\"The 'certifi' package is required to use https \"\n                        \"in simple_httpclient\")\n    return certifi.where()\n\n\nclass SimpleAsyncHTTPClient(AsyncHTTPClient):\n    \"\"\"Non-blocking HTTP client with no external dependencies.\n\n    This class implements an HTTP 1.1 client on top of Tornado's IOStreams.\n    Some features found in the curl-based AsyncHTTPClient are not yet\n    supported.  In particular, proxies are not supported, connections\n    are not reused, and callers cannot select the network interface to be\n    used.\n    \"\"\"\n    def initialize(self, io_loop, max_clients=10,\n                   hostname_mapping=None, max_buffer_size=104857600,\n                   resolver=None, defaults=None, max_header_size=None,\n                   max_body_size=None):\n        \"\"\"Creates a AsyncHTTPClient.\n\n        Only a single AsyncHTTPClient instance exists per IOLoop\n        in order to provide limitations on the number of pending connections.\n        ``force_instance=True`` may be used to suppress this behavior.\n\n        Note that because of this implicit reuse, unless ``force_instance``\n        is used, only the first call to the constructor actually uses\n        its arguments. It is recommended to use the ``configure`` method\n        instead of the constructor to ensure that arguments take effect.\n\n        ``max_clients`` is the number of concurrent requests that can be\n        in progress; when this limit is reached additional requests will be\n        queued. Note that time spent waiting in this queue still counts\n        against the ``request_timeout``.\n\n        ``hostname_mapping`` is a dictionary mapping hostnames to IP addresses.\n        It can be used to make local DNS changes when modifying system-wide\n        settings like ``/etc/hosts`` is not possible or desirable (e.g. in\n        unittests).\n\n        ``max_buffer_size`` (default 100MB) is the number of bytes\n        that can be read into memory at once. ``max_body_size``\n        (defaults to ``max_buffer_size``) is the largest response body\n        that the client will accept.  Without a\n        ``streaming_callback``, the smaller of these two limits\n        applies; with a ``streaming_callback`` only ``max_body_size``\n        does.\n\n        .. versionchanged:: 4.2\n           Added the ``max_body_size`` argument.\n        \"\"\"\n        super(SimpleAsyncHTTPClient, self).initialize(io_loop,\n                                                      defaults=defaults)\n        self.max_clients = max_clients\n        self.queue = collections.deque()\n        self.active = {}\n        self.waiting = {}\n        self.max_buffer_size = max_buffer_size\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        # TCPClient could create a Resolver for us, but we have to do it\n        # ourselves to support hostname_mapping.\n        if resolver:\n            self.resolver = resolver\n            self.own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self.own_resolver = True\n        if hostname_mapping is not None:\n            self.resolver = OverrideResolver(resolver=self.resolver,\n                                             mapping=hostname_mapping)\n        self.tcp_client = TCPClient(resolver=self.resolver, io_loop=io_loop)\n\n    def close(self):\n        super(SimpleAsyncHTTPClient, self).close()\n        if self.own_resolver:\n            self.resolver.close()\n        self.tcp_client.close()\n\n    def fetch_impl(self, request, callback):\n        key = object()\n        self.queue.append((key, request, callback))\n        if not len(self.active) < self.max_clients:\n            timeout_handle = self.io_loop.add_timeout(\n                self.io_loop.time() + min(request.connect_timeout,\n                                          request.request_timeout),\n                functools.partial(self._on_timeout, key, \"in request queue\"))\n        else:\n            timeout_handle = None\n        self.waiting[key] = (request, callback, timeout_handle)\n        self._process_queue()\n        if self.queue:\n            gen_log.debug(\"max_clients limit reached, request queued. \"\n                          \"%d active, %d queued requests.\" % (\n                              len(self.active), len(self.queue)))\n\n    def _process_queue(self):\n        with stack_context.NullContext():\n            while self.queue and len(self.active) < self.max_clients:\n                key, request, callback = self.queue.popleft()\n                if key not in self.waiting:\n                    continue\n                self._remove_timeout(key)\n                self.active[key] = (request, callback)\n                release_callback = functools.partial(self._release_fetch, key)\n                self._handle_request(request, release_callback, callback)\n\n    def _connection_class(self):\n        return _HTTPConnection\n\n    def _handle_request(self, request, release_callback, final_callback):\n        self._connection_class()(\n            self.io_loop, self, request, release_callback,\n            final_callback, self.max_buffer_size, self.tcp_client,\n            self.max_header_size, self.max_body_size)\n\n    def _release_fetch(self, key):\n        del self.active[key]\n        self._process_queue()\n\n    def _remove_timeout(self, key):\n        if key in self.waiting:\n            request, callback, timeout_handle = self.waiting[key]\n            if timeout_handle is not None:\n                self.io_loop.remove_timeout(timeout_handle)\n            del self.waiting[key]\n\n    def _on_timeout(self, key, info=None):\n        \"\"\"Timeout callback of request.\n\n        Construct a timeout HTTPResponse when a timeout occurs.\n\n        :arg object key: A simple object to mark the request.\n        :info string key: More detailed timeout information.\n        \"\"\"\n        request, callback, timeout_handle = self.waiting[key]\n        self.queue.remove((key, request, callback))\n\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        timeout_response = HTTPResponse(\n            request, 599, error=HTTPError(599, error_message),\n            request_time=self.io_loop.time() - request.start_time)\n        self.io_loop.add_callback(callback, timeout_response)\n        del self.waiting[key]\n\n\nclass _HTTPConnection(httputil.HTTPMessageDelegate):\n    _SUPPORTED_METHODS = set([\"GET\", \"HEAD\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"])\n\n    def __init__(self, io_loop, client, request, release_callback,\n                 final_callback, max_buffer_size, tcp_client,\n                 max_header_size, max_body_size):\n        self.start_time = io_loop.time()\n        self.io_loop = io_loop\n        self.client = client\n        self.request = request\n        self.release_callback = release_callback\n        self.final_callback = final_callback\n        self.max_buffer_size = max_buffer_size\n        self.tcp_client = tcp_client\n        self.max_header_size = max_header_size\n        self.max_body_size = max_body_size\n        self.code = None\n        self.headers = None\n        self.chunks = []\n        self._decompressor = None\n        # Timeout handle returned by IOLoop.add_timeout\n        self._timeout = None\n        self._sockaddr = None\n        with stack_context.ExceptionStackContext(self._handle_exception):\n            self.parsed = urlparse.urlsplit(_unicode(self.request.url))\n            if self.parsed.scheme not in (\"http\", \"https\"):\n                raise ValueError(\"Unsupported url scheme: %s\" %\n                                 self.request.url)\n            # urlsplit results have hostname and port results, but they\n            # didn't support ipv6 literals until python 2.7.\n            netloc = self.parsed.netloc\n            if \"@\" in netloc:\n                userpass, _, netloc = netloc.rpartition(\"@\")\n            host, port = httputil.split_host_and_port(netloc)\n            if port is None:\n                port = 443 if self.parsed.scheme == \"https\" else 80\n            if re.match(r'^\\[.*\\]$', host):\n                # raw ipv6 addresses in urls are enclosed in brackets\n                host = host[1:-1]\n            self.parsed_hostname = host  # save final host for _on_connect\n\n            if request.allow_ipv6 is False:\n                af = socket.AF_INET\n            else:\n                af = socket.AF_UNSPEC\n\n            ssl_options = self._get_ssl_options(self.parsed.scheme)\n\n            timeout = min(self.request.connect_timeout, self.request.request_timeout)\n            if timeout:\n                self._timeout = self.io_loop.add_timeout(\n                    self.start_time + timeout,\n                    stack_context.wrap(functools.partial(self._on_timeout, \"while connecting\")))\n            self.tcp_client.connect(host, port, af=af,\n                                    ssl_options=ssl_options,\n                                    max_buffer_size=self.max_buffer_size,\n                                    callback=self._on_connect)\n\n    def _get_ssl_options(self, scheme):\n        if scheme == \"https\":\n            if self.request.ssl_options is not None:\n                return self.request.ssl_options\n            # If we are using the defaults, don't construct a\n            # new SSLContext.\n            if (self.request.validate_cert and\n                    self.request.ca_certs is None and\n                    self.request.client_cert is None and\n                    self.request.client_key is None):\n                return _client_ssl_defaults\n            ssl_options = {}\n            if self.request.validate_cert:\n                ssl_options[\"cert_reqs\"] = ssl.CERT_REQUIRED\n            if self.request.ca_certs is not None:\n                ssl_options[\"ca_certs\"] = self.request.ca_certs\n            elif not hasattr(ssl, 'create_default_context'):\n                # When create_default_context is present,\n                # we can omit the \"ca_certs\" parameter entirely,\n                # which avoids the dependency on \"certifi\" for py34.\n                ssl_options[\"ca_certs\"] = _default_ca_certs()\n            if self.request.client_key is not None:\n                ssl_options[\"keyfile\"] = self.request.client_key\n            if self.request.client_cert is not None:\n                ssl_options[\"certfile\"] = self.request.client_cert\n\n            # SSL interoperability is tricky.  We want to disable\n            # SSLv2 for security reasons; it wasn't disabled by default\n            # until openssl 1.0.  The best way to do this is to use\n            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python\n            # until 3.2.  Python 2.7 adds the ciphers argument, which\n            # can also be used to disable SSLv2.  As a last resort\n            # on python 2.6, we set ssl_version to TLSv1.  This is\n            # more narrow than we'd like since it also breaks\n            # compatibility with servers configured for SSLv3 only,\n            # but nearly all servers support both SSLv3 and TLSv1:\n            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html\n            if sys.version_info >= (2, 7):\n                # In addition to disabling SSLv2, we also exclude certain\n                # classes of insecure ciphers.\n                ssl_options[\"ciphers\"] = \"DEFAULT:!SSLv2:!EXPORT:!DES\"\n            else:\n                # This is really only necessary for pre-1.0 versions\n                # of openssl, but python 2.6 doesn't expose version\n                # information.\n                ssl_options[\"ssl_version\"] = ssl.PROTOCOL_TLSv1\n            return ssl_options\n        return None\n\n    def _on_timeout(self, info=None):\n        \"\"\"Timeout callback of _HTTPConnection instance.\n\n        Raise a timeout HTTPError when a timeout occurs.\n\n        :info string key: More detailed timeout information.\n        \"\"\"\n        self._timeout = None\n        error_message = \"Timeout {0}\".format(info) if info else \"Timeout\"\n        if self.final_callback is not None:\n            raise HTTPError(599, error_message)\n\n    def _remove_timeout(self):\n        if self._timeout is not None:\n            self.io_loop.remove_timeout(self._timeout)\n            self._timeout = None\n\n    def _on_connect(self, stream):\n        if self.final_callback is None:\n            # final_callback is cleared if we've hit our timeout.\n            stream.close()\n            return\n        self.stream = stream\n        self.stream.set_close_callback(self.on_connection_close)\n        self._remove_timeout()\n        if self.final_callback is None:\n            return\n        if self.request.request_timeout:\n            self._timeout = self.io_loop.add_timeout(\n                self.start_time + self.request.request_timeout,\n                stack_context.wrap(functools.partial(self._on_timeout, \"while interacting\")))\n        if (self.request.method not in self._SUPPORTED_METHODS and\n                not self.request.allow_nonstandard_methods):\n            raise KeyError(\"unknown method %s\" % self.request.method)\n        for key in ('network_interface',\n                    'proxy_host', 'proxy_port',\n                    'proxy_username', 'proxy_password'):\n            if getattr(self.request, key, None):\n                raise NotImplementedError('%s not supported' % key)\n        if \"Connection\" not in self.request.headers:\n            self.request.headers[\"Connection\"] = \"close\"\n        if \"Host\" not in self.request.headers:\n            if '@' in self.parsed.netloc:\n                self.request.headers[\"Host\"] = self.parsed.netloc.rpartition('@')[-1]\n            else:\n                self.request.headers[\"Host\"] = self.parsed.netloc\n        username, password = None, None\n        if self.parsed.username is not None:\n            username, password = self.parsed.username, self.parsed.password\n        elif self.request.auth_username is not None:\n            username = self.request.auth_username\n            password = self.request.auth_password or ''\n        if username is not None:\n            if self.request.auth_mode not in (None, \"basic\"):\n                raise ValueError(\"unsupported auth_mode %s\",\n                                 self.request.auth_mode)\n            auth = utf8(username) + b\":\" + utf8(password)\n            self.request.headers[\"Authorization\"] = (b\"Basic \" +\n                                                     base64.b64encode(auth))\n        if self.request.user_agent:\n            self.request.headers[\"User-Agent\"] = self.request.user_agent\n        if not self.request.allow_nonstandard_methods:\n            # Some HTTP methods nearly always have bodies while others\n            # almost never do. Fail in this case unless the user has\n            # opted out of sanity checks with allow_nonstandard_methods.\n            body_expected = self.request.method in (\"POST\", \"PATCH\", \"PUT\")\n            body_present = (self.request.body is not None or\n                            self.request.body_producer is not None)\n            if ((body_expected and not body_present) or\n                    (body_present and not body_expected)):\n                raise ValueError(\n                    'Body must %sbe None for method %s (unless '\n                    'allow_nonstandard_methods is true)' %\n                    ('not ' if body_expected else '', self.request.method))\n        if self.request.expect_100_continue:\n            self.request.headers[\"Expect\"] = \"100-continue\"\n        if self.request.body is not None:\n            # When body_producer is used the caller is responsible for\n            # setting Content-Length (or else chunked encoding will be used).\n            self.request.headers[\"Content-Length\"] = str(len(\n                self.request.body))\n        if (self.request.method == \"POST\" and\n                \"Content-Type\" not in self.request.headers):\n            self.request.headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n        if self.request.decompress_response:\n            self.request.headers[\"Accept-Encoding\"] = \"gzip\"\n        req_path = ((self.parsed.path or '/') +\n                    (('?' + self.parsed.query) if self.parsed.query else ''))\n        self.connection = self._create_connection(stream)\n        start_line = httputil.RequestStartLine(self.request.method,\n                                               req_path, '')\n        self.connection.write_headers(start_line, self.request.headers)\n        if self.request.expect_100_continue:\n            self._read_response()\n        else:\n            self._write_body(True)\n\n    def _create_connection(self, stream):\n        stream.set_nodelay(True)\n        connection = HTTP1Connection(\n            stream, True,\n            HTTP1ConnectionParameters(\n                no_keep_alive=True,\n                max_header_size=self.max_header_size,\n                max_body_size=self.max_body_size,\n                decompress=self.request.decompress_response),\n            self._sockaddr)\n        return connection\n\n    def _write_body(self, start_read):\n        if self.request.body is not None:\n            self.connection.write(self.request.body)\n        elif self.request.body_producer is not None:\n            fut = self.request.body_producer(self.connection.write)\n            if fut is not None:\n                fut = gen.convert_yielded(fut)\n\n                def on_body_written(fut):\n                    fut.result()\n                    self.connection.finish()\n                    if start_read:\n                        self._read_response()\n                self.io_loop.add_future(fut, on_body_written)\n                return\n        self.connection.finish()\n        if start_read:\n            self._read_response()\n\n    def _read_response(self):\n        # Ensure that any exception raised in read_response ends up in our\n        # stack context.\n        self.io_loop.add_future(\n            self.connection.read_response(self),\n            lambda f: f.result())\n\n    def _release(self):\n        if self.release_callback is not None:\n            release_callback = self.release_callback\n            self.release_callback = None\n            release_callback()\n\n    def _run_callback(self, response):\n        self._release()\n        if self.final_callback is not None:\n            final_callback = self.final_callback\n            self.final_callback = None\n            self.io_loop.add_callback(final_callback, response)\n\n    def _handle_exception(self, typ, value, tb):\n        if self.final_callback:\n            self._remove_timeout()\n            if isinstance(value, StreamClosedError):\n                if value.real_error is None:\n                    value = HTTPError(599, \"Stream closed\")\n                else:\n                    value = value.real_error\n            self._run_callback(HTTPResponse(self.request, 599, error=value,\n                                            request_time=self.io_loop.time() - self.start_time,\n                                            ))\n\n            if hasattr(self, \"stream\"):\n                # TODO: this may cause a StreamClosedError to be raised\n                # by the connection's Future.  Should we cancel the\n                # connection more gracefully?\n                self.stream.close()\n            return True\n        else:\n            # If our callback has already been called, we are probably\n            # catching an exception that is not caused by us but rather\n            # some child of our callback. Rather than drop it on the floor,\n            # pass it along, unless it's just the stream being closed.\n            return isinstance(value, StreamClosedError)\n\n    def on_connection_close(self):\n        if self.final_callback is not None:\n            message = \"Connection closed\"\n            if self.stream.error:\n                raise self.stream.error\n            try:\n                raise HTTPError(599, message)\n            except HTTPError:\n                self._handle_exception(*sys.exc_info())\n\n    def headers_received(self, first_line, headers):\n        if self.request.expect_100_continue and first_line.code == 100:\n            self._write_body(False)\n            return\n        self.code = first_line.code\n        self.reason = first_line.reason\n        self.headers = headers\n\n        if self._should_follow_redirect():\n            return\n\n        if self.request.header_callback is not None:\n            # Reassemble the start line.\n            self.request.header_callback('%s %s %s\\r\\n' % first_line)\n            for k, v in self.headers.get_all():\n                self.request.header_callback(\"%s: %s\\r\\n\" % (k, v))\n            self.request.header_callback('\\r\\n')\n\n    def _should_follow_redirect(self):\n        return (self.request.follow_redirects and\n                self.request.max_redirects > 0 and\n                self.code in (301, 302, 303, 307))\n\n    def finish(self):\n        data = b''.join(self.chunks)\n        self._remove_timeout()\n        original_request = getattr(self.request, \"original_request\",\n                                   self.request)\n        if self._should_follow_redirect():\n            assert isinstance(self.request, _RequestProxy)\n            new_request = copy.copy(self.request.request)\n            new_request.url = urlparse.urljoin(self.request.url,\n                                               self.headers[\"Location\"])\n            new_request.max_redirects = self.request.max_redirects - 1\n            del new_request.headers[\"Host\"]\n            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4\n            # Client SHOULD make a GET request after a 303.\n            # According to the spec, 302 should be followed by the same\n            # method as the original request, but in practice browsers\n            # treat 302 the same as 303, and many servers use 302 for\n            # compatibility with pre-HTTP/1.1 user agents which don't\n            # understand the 303 status.\n            if self.code in (302, 303):\n                new_request.method = \"GET\"\n                new_request.body = None\n                for h in [\"Content-Length\", \"Content-Type\",\n                          \"Content-Encoding\", \"Transfer-Encoding\"]:\n                    try:\n                        del self.request.headers[h]\n                    except KeyError:\n                        pass\n            new_request.original_request = original_request\n            final_callback = self.final_callback\n            self.final_callback = None\n            self._release()\n            self.client.fetch(new_request, final_callback)\n            self._on_end_request()\n            return\n        if self.request.streaming_callback:\n            buffer = BytesIO()\n        else:\n            buffer = BytesIO(data)  # TODO: don't require one big string?\n        response = HTTPResponse(original_request,\n                                self.code, reason=getattr(self, 'reason', None),\n                                headers=self.headers,\n                                request_time=self.io_loop.time() - self.start_time,\n                                buffer=buffer,\n                                effective_url=self.request.url)\n        self._run_callback(response)\n        self._on_end_request()\n\n    def _on_end_request(self):\n        self.stream.close()\n\n    def data_received(self, chunk):\n        if self._should_follow_redirect():\n            # We're going to follow a redirect so just discard the body.\n            return\n        if self.request.streaming_callback is not None:\n            self.request.streaming_callback(chunk)\n        else:\n            self.chunks.append(chunk)\n\n\nif __name__ == \"__main__\":\n    AsyncHTTPClient.configure(SimpleAsyncHTTPClient)\n    main()\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 Error Message on Request Timeout in HTTP Client

**Description:**
When an HTTP request exceeds the specified timeout, the error message returned does not accurately describe where the timeout occurred. Instead of indicating that the timeout happened during the request, it states that the timeout occurred while interacting. This ambiguity can make debugging and handling timeout issues more challenging.

**Example:**
```python
client.fetch('http://example.com/slow', connect_timeout=0.1)
response = client.wait()
print(str(response.error))  # Outputs: "HTTP 599: Timeout while interacting"
```

**Expected Behavior:**
The error message should clearly indicate that the timeout occurred during the request process. For example:
```
"HTTP 599: Timeout during request"
```

**Actual Behavior:**
The error message incorrectly states:
```
"HTTP 599: Timeout while interacting"
```
This misleading message does not clearly convey that the timeout was specifically related to the request itself.

[/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/simple_httpclient.py
#!/usr/bin/env python
from __future__ import absolute_import, division, print_function, with_statement

from tornado.escape import utf8, _unicode
from tornado import gen
from tornado.httpclient import HTTPResponse, HTTPError, AsyncHTTPClient, main, _RequestProxy
from tornado import httputil
from tornado.http1connection import HTTP1Connection, HTTP1ConnectionParameters
from tornado.iostream import StreamClosedError
from tornado.netutil import Resolver, OverrideResolver, _client_ssl_defaults
from tornado.log import gen_log
from tornado import stack_context
from tornado.tcpclient import TCPClient

import base64
import collections
import copy
import functools
import re
import socket
import sys
from io import BytesIO


try:
    import urlparse  # py2
except ImportError:
    import urllib.parse as urlparse  # py3

try:
    import ssl
except ImportError:
    # ssl is not available on Google App Engine.
    ssl = None

try:
    import certifi
except ImportError:
    certifi = None


def _default_ca_certs():
    if certifi is None:
        raise Exception("The 'certifi' package is required to use https "
                        "in simple_httpclient")
    return certifi.where()


class SimpleAsyncHTTPClient(AsyncHTTPClient):
    """Non-blocking HTTP client with no external dependencies.

    This class implements an HTTP 1.1 client on top of Tornado's IOStreams.
    Some features found in the curl-based AsyncHTTPClient are not yet
    supported.  In particular, proxies are not supported, connections
    are not reused, and callers cannot select the network interface to be
    used.
    """
    def initialize(self, io_loop, max_clients=10,
                   hostname_mapping=None, max_buffer_size=104857600,
                   resolver=None, defaults=None, max_header_size=None,
                   max_body_size=None):
        """Creates a AsyncHTTPClient.

        Only a single AsyncHTTPClient instance exists per IOLoop
        in order to provide limitations on the number of pending connections.
        ``force_instance=True`` may be used to suppress this behavior.

        Note that because of this implicit reuse, unless ``force_instance``
        is used, only the first call to the constructor actually uses
        its arguments. It is recommended to use the ``configure`` method
        instead of the constructor to ensure that arguments take effect.

        ``max_clients`` is the number of concurrent requests that can be
        in progress; when this limit is reached additional requests will be
        queued. Note that time spent waiting in this queue still counts
        against the ``request_timeout``.

        ``hostname_mapping`` is a dictionary mapping hostnames to IP addresses.
        It can be used to make local DNS changes when modifying system-wide
        settings like ``/etc/hosts`` is not possible or desirable (e.g. in
        unittests).

        ``max_buffer_size`` (default 100MB) is the number of bytes
        that can be read into memory at once. ``max_body_size``
        (defaults to ``max_buffer_size``) is the largest response body
        that the client will accept.  Without a
        ``streaming_callback``, the smaller of these two limits
        applies; with a ``streaming_callback`` only ``max_body_size``
        does.

        .. versionchanged:: 4.2
           Added the ``max_body_size`` argument.
        """
        super(SimpleAsyncHTTPClient, self).initialize(io_loop,
                                                      defaults=defaults)
        self.max_clients = max_clients
        self.queue = collections.deque()
        self.active = {}
        self.waiting = {}
        self.max_buffer_size = max_buffer_size
        self.max_header_size = max_header_size
        self.max_body_size = max_body_size
        # TCPClient could create a Resolver for us, but we have to do it
        # ourselves to support hostname_mapping.
        if resolver:
            self.resolver = resolver
            self.own_resolver = False
        else:
            self.resolver = Resolver(io_loop=io_loop)
            self.own_resolver = True
        if hostname_mapping is not None:
            self.resolver = OverrideResolver(resolver=self.resolver,
                                             mapping=hostname_mapping)
        self.tcp_client = TCPClient(resolver=self.resolver, io_loop=io_loop)

    def close(self):
        super(SimpleAsyncHTTPClient, self).close()
        if self.own_resolver:
            self.resolver.close()
        self.tcp_client.close()

    def fetch_impl(self, request, callback):
        key = object()
        self.queue.append((key, request, callback))
        if not len(self.active) < self.max_clients:
            timeout_handle = self.io_loop.add_timeout(
                self.io_loop.time() + min(request.connect_timeout,
                                          request.request_timeout),
                functools.partial(self._on_timeout, key, "in request queue"))
        else:
            timeout_handle = None
        self.waiting[key] = (request, callback, timeout_handle)
        self._process_queue()
        if self.queue:
            gen_log.debug("max_clients limit reached, request queued. "
                          "%d active, %d queued requests." % (
                              len(self.active), len(self.queue)))

    def _process_queue(self):
        with stack_context.NullContext():
            while self.queue and len(self.active) < self.max_clients:
                key, request, callback = self.queue.popleft()
                if key not in self.waiting:
                    continue
                self._remove_timeout(key)
                self.active[key] = (request, callback)
                release_callback = functools.partial(self._release_fetch, key)
                self._handle_request(request, release_callback, callback)

    def _connection_class(self):
        return _HTTPConnection

    def _handle_request(self, request, release_callback, final_callback):
        self._connection_class()(
            self.io_loop, self, request, release_callback,
            final_callback, self.max_buffer_size, self.tcp_client,
            self.max_header_size, self.max_body_size)

    def _release_fetch(self, key):
        del self.active[key]
        self._process_queue()

    def _remove_timeout(self, key):
        if key in self.waiting:
            request, callback, timeout_handle = self.waiting[key]
            if timeout_handle is not None:
                self.io_loop.remove_timeout(timeout_handle)
            del self.waiting[key]

    def _on_timeout(self, key, info=None):
        """Timeout callback of request.

        Construct a timeout HTTPResponse when a timeout occurs.

        :arg object key: A simple object to mark the request.
        :info string key: More detailed timeout information.
        """
        request, callback, timeout_handle = self.waiting[key]
        self.queue.remove((key, request, callback))

        error_message = "Timeout {0}".format(info) if info else "Timeout"
        timeout_response = HTTPResponse(
            request, 599, error=HTTPError(599, error_message),
            request_time=self.io_loop.time() - request.start_time)
        self.io_loop.add_callback(callback, timeout_response)
        del self.waiting[key]


class _HTTPConnection(httputil.HTTPMessageDelegate):
    _SUPPORTED_METHODS = set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])

    def __init__(self, io_loop, client, request, release_callback,
                 final_callback, max_buffer_size, tcp_client,
                 max_header_size, max_body_size):
        self.start_time = io_loop.time()
        self.io_loop = io_loop
        self.client = client
        self.request = request
        self.release_callback = release_callback
        self.final_callback = final_callback
        self.max_buffer_size = max_buffer_size
        self.tcp_client = tcp_client
        self.max_header_size = max_header_size
        self.max_body_size = max_body_size
        self.code = None
        self.headers = None
        self.chunks = []
        self._decompressor = None
        # Timeout handle returned by IOLoop.add_timeout
        self._timeout = None
        self._sockaddr = None
        with stack_context.ExceptionStackContext(self._handle_exception):
            self.parsed = urlparse.urlsplit(_unicode(self.request.url))
            if self.parsed.scheme not in ("http", "https"):
                raise ValueError("Unsupported url scheme: %s" %
                                 self.request.url)
            # urlsplit results have hostname and port results, but they
            # didn't support ipv6 literals until python 2.7.
            netloc = self.parsed.netloc
            if "@" in netloc:
                userpass, _, netloc = netloc.rpartition("@")
            host, port = httputil.split_host_and_port(netloc)
            if port is None:
                port = 443 if self.parsed.scheme == "https" else 80
            if re.match(r'^\[.*\]$', host):
                # raw ipv6 addresses in urls are enclosed in brackets
                host = host[1:-1]
            self.parsed_hostname = host  # save final host for _on_connect

            if request.allow_ipv6 is False:
                af = socket.AF_INET
            else:
                af = socket.AF_UNSPEC

            ssl_options = self._get_ssl_options(self.parsed.scheme)

            timeout = min(self.request.connect_timeout, self.request.request_timeout)
            if timeout:
                self._timeout = self.io_loop.add_timeout(
                    self.start_time + timeout,
                    stack_context.wrap(functools.partial(self._on_timeout, "while connecting")))
            self.tcp_client.connect(host, port, af=af,
                                    ssl_options=ssl_options,
                                    max_buffer_size=self.max_buffer_size,
                                    callback=self._on_connect)

    def _get_ssl_options(self, scheme):
        if scheme == "https":
            if self.request.ssl_options is not None:
                return self.request.ssl_options
            # If we are using the defaults, don't construct a
            # new SSLContext.
            if (self.request.validate_cert and
                    self.request.ca_certs is None and
                    self.request.client_cert is None and
                    self.request.client_key is None):
                return _client_ssl_defaults
            ssl_options = {}
            if self.request.validate_cert:
                ssl_options["cert_reqs"] = ssl.CERT_REQUIRED
            if self.request.ca_certs is not None:
                ssl_options["ca_certs"] = self.request.ca_certs
            elif not hasattr(ssl, 'create_default_context'):
                # When create_default_context is present,
                # we can omit the "ca_certs" parameter entirely,
                # which avoids the dependency on "certifi" for py34.
                ssl_options["ca_certs"] = _default_ca_certs()
            if self.request.client_key is not None:
                ssl_options["keyfile"] = self.request.client_key
            if self.request.client_cert is not None:
                ssl_options["certfile"] = self.request.client_cert

            # SSL interoperability is tricky.  We want to disable
            # SSLv2 for security reasons; it wasn't disabled by default
            # until openssl 1.0.  The best way to do this is to use
            # the SSL_OP_NO_SSLv2, but that wasn't exposed to python
            # until 3.2.  Python 2.7 adds the ciphers argument, which
            # can also be used to disable SSLv2.  As a last resort
            # on python 2.6, we set ssl_version to TLSv1.  This is
            # more narrow than we'd like since it also breaks
            # compatibility with servers configured for SSLv3 only,
            # but nearly all servers support both SSLv3 and TLSv1:
            # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html
            if sys.version_info >= (2, 7):
                # In addition to disabling SSLv2, we also exclude certain
                # classes of insecure ciphers.
                ssl_options["ciphers"] = "DEFAULT:!SSLv2:!EXPORT:!DES"
            else:
                # This is really only necessary for pre-1.0 versions
                # of openssl, but python 2.6 doesn't expose version
                # information.
                ssl_options["ssl_version"] = ssl.PROTOCOL_TLSv1
            return ssl_options
        return None

    def _on_timeout(self, info=None):
        """Timeout callback of _HTTPConnection instance.

        Raise a timeout HTTPError when a timeout occurs.

        :info string key: More detailed timeout information.
        """
        self._timeout = None
        error_message = "Timeout {0}".format(info) if info else "Timeout"
        if self.final_callback is not None:
            raise HTTPError(599, error_message)

    def _remove_timeout(self):
        if self._timeout is not None:
            self.io_loop.remove_timeout(self._timeout)
            self._timeout = None

    def _on_connect(self, stream):
        if self.final_callback is None:
            # final_callback is cleared if we've hit our timeout.
            stream.close()
            return
        self.stream = stream
        self.stream.set_close_callback(self.on_connection_close)
        self._remove_timeout()
        if self.final_callback is None:
            return
        if self.request.request_timeout:
            self._timeout = self.io_loop.add_timeout(
                self.start_time + self.request.request_timeout,
                stack_context.wrap(functools.partial(self._on_timeout, "while interacting")))
        if (self.request.method not in self._SUPPORTED_METHODS and
                not self.request.allow_nonstandard_methods):
            raise KeyError("unknown method %s" % self.request.method)
        for key in ('network_interface',
                    'proxy_host', 'proxy_port',
                    'proxy_username', 'proxy_password'):
            if getattr(self.request, key, None):
                raise NotImplementedError('%s not supported' % key)
        if "Connection" not in self.request.headers:
            self.request.headers["Connection"] = "close"
        if "Host" not in self.request.headers:
            if '@' in self.parsed.netloc:
                self.request.headers["Host"] = self.parsed.netloc.rpartition('@')[-1]
            else:
                self.request.headers["Host"] = self.parsed.netloc
        username, password = None, None
        if self.parsed.username is not None:
            username, password = self.parsed.username, self.parsed.password
        elif self.request.auth_username is not None:
            username = self.request.auth_username
            password = self.request.auth_password or ''
        if username is not None:
            if self.request.auth_mode not in (None, "basic"):
                raise ValueError("unsupported auth_mode %s",
                                 self.request.auth_mode)
            auth = utf8(username) + b":" + utf8(password)
            self.request.headers["Authorization"] = (b"Basic " +
                                                     base64.b64encode(auth))
        if self.request.user_agent:
            self.request.headers["User-Agent"] = self.request.user_agent
        if not self.request.allow_nonstandard_methods:
            # Some HTTP methods nearly always have bodies while others
            # almost never do. Fail in this case unless the user has
            # opted out of sanity checks with allow_nonstandard_methods.
            body_expected = self.request.method in ("POST", "PATCH", "PUT")
            body_present = (self.request.body is not None or
                            self.request.body_producer is not None)
            if ((body_expected and not body_present) or
                    (body_present and not body_expected)):
                raise ValueError(
                    'Body must %sbe None for method %s (unless '
                    'allow_nonstandard_methods is true)' %
                    ('not ' if body_expected else '', self.request.method))
        if self.request.expect_100_continue:
            self.request.headers["Expect"] = "100-continue"
        if self.request.body is not None:
            # When body_producer is used the caller is responsible for
            # setting Content-Length (or else chunked encoding will be used).
            self.request.headers["Content-Length"] = str(len(
                self.request.body))
        if (self.request.method == "POST" and
                "Content-Type" not in self.request.headers):
            self.request.headers["Content-Type"] = "application/x-www-form-urlencoded"
        if self.request.decompress_response:
            self.request.headers["Accept-Encoding"] = "gzip"
        req_path = ((self.parsed.path or '/') +
                    (('?' + self.parsed.query) if self.parsed.query else ''))
        self.connection = self._create_connection(stream)
        start_line = httputil.RequestStartLine(self.request.method,
                                               req_path, '')
        self.connection.write_headers(start_line, self.request.headers)
        if self.request.expect_100_continue:
            self._read_response()
        else:
            self._write_body(True)

    def _create_connection(self, stream):
        stream.set_nodelay(True)
        connection = HTTP1Connection(
            stream, True,
            HTTP1ConnectionParameters(
                no_keep_alive=True,
                max_header_size=self.max_header_size,
                max_body_size=self.max_body_size,
                decompress=self.request.decompress_response),
            self._sockaddr)
        return connection

    def _write_body(self, start_read):
        if self.request.body is not None:
            self.connection.write(self.request.body)
        elif self.request.body_producer is not None:
            fut = self.request.body_producer(self.connection.write)
            if fut is not None:
                fut = gen.convert_yielded(fut)

                def on_body_written(fut):
                    fut.result()
                    self.connection.finish()
                    if start_read:
                        self._read_response()
                self.io_loop.add_future(fut, on_body_written)
                return
        self.connection.finish()
        if start_read:
            self._read_response()

    def _read_response(self):
        # Ensure that any exception raised in read_response ends up in our
        # stack context.
        self.io_loop.add_future(
            self.connection.read_response(self),
            lambda f: f.result())

    def _release(self):
        if self.release_callback is not None:
            release_callback = self.release_callback
            self.release_callback = None
            release_callback()

    def _run_callback(self, response):
        self._release()
        if self.final_callback is not None:
            final_callback = self.final_callback
            self.final_callback = None
            self.io_loop.add_callback(final_callback, response)

    def _handle_exception(self, typ, value, tb):
        if self.final_callback:
            self._remove_timeout()
            if isinstance(value, StreamClosedError):
                if value.real_error is None:
                    value = HTTPError(599, "Stream closed")
                else:
                    value = value.real_error
            self._run_callback(HTTPResponse(self.request, 599, error=value,
                                            request_time=self.io_loop.time() - self.start_time,
                                            ))

            if hasattr(self, "stream"):
                # TODO: this may cause a StreamClosedError to be raised
                # by the connection's Future.  Should we cancel the
                # connection more gracefully?
                self.stream.close()
            return True
        else:
            # If our callback has already been called, we are probably
            # catching an exception that is not caused by us but rather
            # some child of our callback. Rather than drop it on the floor,
            # pass it along, unless it's just the stream being closed.
            return isinstance(value, StreamClosedError)

    def on_connection_close(self):
        if self.final_callback is not None:
            message = "Connection closed"
            if self.stream.error:
                raise self.stream.error
            try:
                raise HTTPError(599, message)
            except HTTPError:
                self._handle_exception(*sys.exc_info())

    def headers_received(self, first_line, headers):
        if self.request.expect_100_continue and first_line.code == 100:
            self._write_body(False)
            return
        self.code = first_line.code
        self.reason = first_line.reason
        self.headers = headers

        if self._should_follow_redirect():
            return

        if self.request.header_callback is not None:
            # Reassemble the start line.
            self.request.header_callback('%s %s %s\r\n' % first_line)
            for k, v in self.headers.get_all():
                self.request.header_callback("%s: %s\r\n" % (k, v))
            self.request.header_callback('\r\n')

    def _should_follow_redirect(self):
        return (self.request.follow_redirects and
                self.request.max_redirects > 0 and
                self.code in (301, 302, 303, 307))

    def finish(self):
        data = b''.join(self.chunks)
        self._remove_timeout()
        original_request = getattr(self.request, "original_request",
                                   self.request)
        if self._should_follow_redirect():
            assert isinstance(self.request, _RequestProxy)
            new_request = copy.copy(self.request.request)
            new_request.url = urlparse.urljoin(self.request.url,
                                               self.headers["Location"])
            new_request.max_redirects = self.request.max_redirects - 1
            del new_request.headers["Host"]
            # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
            # Client SHOULD make a GET request after a 303.
            # According to the spec, 302 should be followed by the same
            # method as the original request, but in practice browsers
            # treat 302 the same as 303, and many servers use 302 for
            # compatibility with pre-HTTP/1.1 user agents which don't
            # understand the 303 status.
            if self.code in (302, 303):
                new_request.method = "GET"
                new_request.body = None
                for h in ["Content-Length", "Content-Type",
                          "Content-Encoding", "Transfer-Encoding"]:
                    try:
                        del self.request.headers[h]
                    except KeyError:
                        pass
            new_request.original_request = original_request
            final_callback = self.final_callback
            self.final_callback = None
            self._release()
            self.client.fetch(new_request, final_callback)
            self._on_end_request()
            return
        if self.request.streaming_callback:
            buffer = BytesIO()
        else:
            buffer = BytesIO(data)  # TODO: don't require one big string?
        response = HTTPResponse(original_request,
                                self.code, reason=getattr(self, 'reason', None),
                                headers=self.headers,
                                request_time=self.io_loop.time() - self.start_time,
                                buffer=buffer,
                                effective_url=self.request.url)
        self._run_callback(response)
        self._on_end_request()

    def _on_end_request(self):
        self.stream.close()

    def data_received(self, chunk):
        if self._should_follow_redirect():
            # We're going to follow a redirect so just discard the body.
            return
        if self.request.streaming_callback is not None:
            self.request.streaming_callback(chunk)
        else:
            self.chunks.append(chunk)


if __name__ == "__main__":
    AsyncHTTPClient.configure(SimpleAsyncHTTPClient)
    main()

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