{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"Utility classes to write to and read from non-blocking files and sockets.\n\nContents:\n\n* `BaseIOStream`: Generic interface for reading and writing.\n* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.\n* `SSLIOStream`: SSL-aware version of IOStream.\n* `PipeIOStream`: Pipe-based IOStream implementation.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nimport errno\nimport numbers\nimport os\nimport socket\nimport ssl\nimport sys\nimport re\n\nfrom tornado import ioloop\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    from tornado.platform.posix import _set_nonblocking\nexcept ImportError:\n    _set_nonblocking = None\n\n\nclass StreamClosedError(IOError):\n    pass\n\n\nclass BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's `error`\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=104857600,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.instance()\n        self.max_buffer_size = max_buffer_size\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket returned\n        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,\n        should return no more than ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the IOLoop has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback):\n        \"\"\"Call callback when we read the given regex pattern.\"\"\"\n        self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n\n    def read_until(self, delimiter, callback):\n        \"\"\"Call callback when we read the given delimiter.\"\"\"\n        self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n\n    def read_bytes(self, num_bytes, callback, streaming_callback=None):\n        \"\"\"Call callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n        \"\"\"\n        self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n\n    def read_until_close(self, callback, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_callback(self._read_callback,\n                               self._consume(self._read_buffer_size))\n            self._streaming_callback = None\n            self._read_callback = None\n            return\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._add_io_state(self.io_loop.READ)\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If callback is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            if len(data) > WRITE_BUFFER_CHUNK_SIZE:\n                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n            else:\n                self._write_buffer.append(data)\n        self._write_callback = stack_context.wrap(callback)\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                callback = self._read_callback\n                self._read_callback = None\n                self._read_until_close = False\n                self._run_callback(callback,\n                                   self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        if (self.closed() and self._close_callback and\n                self._pending_callbacks == 0):\n            # if there are pending callbacks, don't run the close callback\n            # until they're done (see _maybe_add_error_handler)\n            cb = self._close_callback\n            self._close_callback = None\n            self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %d\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert not self._read_callback, \"Already reading\"\n        self._read_callback = stack_context.wrap(callback)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            # See comments in _handle_read about incrementing _pending_callbacks\n            self._pending_callbacks += 1\n            while not self.closed():\n                if self._read_to_buffer() == 0:\n                    break\n        finally:\n            self._pending_callbacks -= 1\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] == errno.ECONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            callback = self._read_callback\n            self._read_callback = None\n            self._streaming_callback = None\n            self._read_bytes = None\n            self._run_callback(callback, self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        callback = self._read_callback\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_delimiter = None\n                        self._run_callback(callback,\n                                           self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        callback = self._read_callback\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_regex = None\n                        self._run_callback(callback, self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except socket.error as e:\n                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    gen_log.warning(\"Write error on %d: %s\",\n                                    self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer and self._write_callback:\n            callback = self._write_callback\n            self._write_callback = None\n            self._run_callback(callback)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)\n\n\nclass IOStream(BaseIOStream):\n    r\"\"\"Socket-based IOStream implementation.\n\n    This class supports the read and write methods from `BaseIOStream`\n    plus a `connect` method.\n\n    The socket parameter may either be connected or unconnected.  For\n    server operations the socket is the result of calling socket.accept().\n    For client operations the socket is created with socket.socket(),\n    and may either be connected before passing it to the IOStream or\n    connected with IOStream.connect.\n\n    A very simple (and broken) HTTP client using this class::\n\n        from tornado import ioloop\n        from tornado import iostream\n        import socket\n\n        def send_request():\n            stream.write(\"GET / HTTP/1.0\\r\\nHost: friendfeed.com\\r\\n\\r\\n\")\n            stream.read_until(\"\\r\\n\\r\\n\", on_headers)\n\n        def on_headers(data):\n            headers = {}\n            for line in data.split(\"\\r\\n\"):\n               parts = line.split(\":\")\n               if len(parts) == 2:\n                   headers[parts[0].strip()] = parts[1].strip()\n            stream.read_bytes(int(headers[\"Content-Length\"]), on_body)\n\n        def on_body(data):\n            print data\n            stream.close()\n            ioloop.IOLoop.instance().stop()\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = iostream.IOStream(s)\n        stream.connect((\"friendfeed.com\", 80), send_request)\n        ioloop.IOLoop.instance().start()\n    \"\"\"\n    def __init__(self, socket, *args, **kwargs):\n        self.socket = socket\n        self.socket.setblocking(False)\n        super(IOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    def close_fd(self):\n        self.socket.close()\n        self.socket = None\n\n    def get_fd_error(self):\n        errno = self.socket.getsockopt(socket.SOL_SOCKET,\n                                       socket.SO_ERROR)\n        return socket.error(errno, os.strerror(errno))\n\n    def read_from_fd(self):\n        try:\n            chunk = self.socket.recv(self.read_chunk_size)\n        except socket.error as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n    def write_to_fd(self, data):\n        return self.socket.send(data)\n\n    def connect(self, address, callback=None, server_hostname=None):\n        \"\"\"Connects the socket to a remote address without blocking.\n\n        May only be called if the socket passed to the constructor was\n        not previously connected.  The address parameter is in the\n        same format as for socket.connect, i.e. a (host, port) tuple.\n        If callback is specified, it will be called when the\n        connection is completed.\n\n        If specified, the ``server_hostname`` parameter will be used\n        in SSL connections for certificate validation (if requested in\n        the ``ssl_options``) and SNI (if supported; requires\n        Python 3.2+).\n\n        Note that it is safe to call IOStream.write while the\n        connection is pending, in which case the data will be written\n        as soon as the connection is ready.  Calling IOStream read\n        methods before the socket is connected works on some platforms\n        but is non-portable.\n        \"\"\"\n        self._connecting = True\n        try:\n            self.socket.connect(address)\n        except socket.error as e:\n            # In non-blocking mode we expect connect() to raise an\n            # exception with EINPROGRESS or EWOULDBLOCK.\n            #\n            # On freebsd, other errors such as ECONNREFUSED may be\n            # returned immediately when attempting to connect to\n            # localhost, so handle them the same way as an error\n            # reported later in _handle_connect.\n            if e.args[0] not in (errno.EINPROGRESS, errno.EWOULDBLOCK):\n                gen_log.warning(\"Connect error on fd %d: %s\",\n                                self.socket.fileno(), e)\n                self.close(exc_info=True)\n                return\n        self._connect_callback = stack_context.wrap(callback)\n        self._add_io_state(self.io_loop.WRITE)\n\n    def _handle_connect(self):\n        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)\n        if err != 0:\n            self.error = socket.error(err, os.strerror(err))\n            # IOLoop implementations may vary: some of them return\n            # an error state before the socket becomes writable, so\n            # in that case a connection failure would be handled by the\n            # error path in _handle_events instead of here.\n            gen_log.warning(\"Connect error on fd %d: %s\",\n                            self.socket.fileno(), errno.errorcode[err])\n            self.close()\n            return\n        if self._connect_callback is not None:\n            callback = self._connect_callback\n            self._connect_callback = None\n            self._run_callback(callback)\n        self._connecting = False\n\n\nclass SSLIOStream(IOStream):\n    \"\"\"A utility class to write to and read from a non-blocking SSL socket.\n\n    If the socket passed to the constructor is already connected,\n    it should be wrapped with::\n\n        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)\n\n    before constructing the SSLIOStream.  Unconnected sockets will be\n    wrapped when IOStream.connect is finished.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        \"\"\"Creates an SSLIOStream.\n\n        The ``ssl_options`` keyword argument may either be a dictionary\n        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`\n        object.\n        \"\"\"\n        self._ssl_options = kwargs.pop('ssl_options', {})\n        super(SSLIOStream, self).__init__(*args, **kwargs)\n        self._ssl_accepting = True\n        self._handshake_reading = False\n        self._handshake_writing = False\n        self._ssl_connect_callback = None\n        self._server_hostname = None\n\n    def reading(self):\n        return self._handshake_reading or super(SSLIOStream, self).reading()\n\n    def writing(self):\n        return self._handshake_writing or super(SSLIOStream, self).writing()\n\n    def _do_ssl_handshake(self):\n        # Based on code from test_ssl.py in the python stdlib\n        try:\n            self._handshake_reading = False\n            self._handshake_writing = False\n            self.socket.do_handshake()\n        except ssl.SSLError as err:\n            if err.args[0] == ssl.SSL_ERROR_WANT_READ:\n                self._handshake_reading = True\n                return\n            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:\n                self._handshake_writing = True\n                return\n            elif err.args[0] in (ssl.SSL_ERROR_EOF,\n                                 ssl.SSL_ERROR_ZERO_RETURN):\n                return self.close(exc_info=True)\n            elif err.args[0] == ssl.SSL_ERROR_SSL:\n                try:\n                    peer = self.socket.getpeername()\n                except:\n                    peer = '(not connected)'\n                gen_log.warning(\"SSL Error on %d %s: %s\",\n                                self.socket.fileno(), peer, err)\n                return self.close(exc_info=True)\n            raise\n        except socket.error as err:\n            if err.args[0] in (errno.ECONNABORTED, errno.ECONNRESET):\n                return self.close(exc_info=True)\n        else:\n            self._ssl_accepting = False\n            if not self._verify_cert(self.socket.getpeercert()):\n                self.close()\n                return\n            if self._ssl_connect_callback is not None:\n                callback = self._ssl_connect_callback\n                self._ssl_connect_callback = None\n                self._run_callback(callback)\n\n    def _verify_cert(self, peercert):\n        \"\"\"Returns True if peercert is valid according to the configured\n        validation mode and hostname.\n\n        The ssl handshake already tested the certificate for a valid\n        CA signature; the only thing that remains is to check\n        the hostname.\n        \"\"\"\n        if isinstance(self._ssl_options, dict):\n            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)\n        elif isinstance(self._ssl_options, ssl.SSLContext):\n            verify_mode = self._ssl_options.verify_mode\n        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)\n        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:\n            return True\n        cert = self.socket.getpeercert()\n        if cert is None and verify_mode == ssl.CERT_REQUIRED:\n            gen_log.warning(\"No SSL certificate given\")\n            return False\n        try:\n            ssl_match_hostname(peercert, self._server_hostname)\n        except SSLCertificateError:\n            gen_log.warning(\"Invalid SSL certificate\", exc_info=True)\n            return False\n        else:\n            return True\n\n    def _handle_read(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_read()\n\n    def _handle_write(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_write()\n\n    def connect(self, address, callback=None, server_hostname=None):\n        # Save the user's callback and run it after the ssl handshake\n        # has completed.\n        self._ssl_connect_callback = callback\n        self._server_hostname = server_hostname\n        super(SSLIOStream, self).connect(address, callback=None)\n\n    def _handle_connect(self):\n        # When the connection is complete, wrap the socket for SSL\n        # traffic.  Note that we do this by overriding _handle_connect\n        # instead of by passing a callback to super().connect because\n        # user callbacks are enqueued asynchronously on the IOLoop,\n        # but since _handle_events calls _handle_connect immediately\n        # followed by _handle_write we need this to be synchronous.\n        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,\n                                      server_hostname=self._server_hostname,\n                                      do_handshake_on_connect=False)\n        super(SSLIOStream, self)._handle_connect()\n\n    def read_from_fd(self):\n        if self._ssl_accepting:\n            # If the handshake hasn't finished yet, there can't be anything\n            # to read (attempting to read may or may not raise an exception\n            # depending on the SSL version)\n            return None\n        try:\n            # SSLSocket objects have both a read() and recv() method,\n            # while regular sockets only have recv().\n            # The recv() method blocks (at least in python 2.6) if it is\n            # called when there is nothing to read, so we have to use\n            # read() instead.\n            chunk = self.socket.read(self.read_chunk_size)\n        except ssl.SSLError as e:\n            # SSLError is a subclass of socket.error, so this except\n            # block must come first.\n            if e.args[0] == ssl.SSL_ERROR_WANT_READ:\n                return None\n            else:\n                raise\n        except socket.error as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\nclass PipeIOStream(BaseIOStream):\n    \"\"\"Pipe-based IOStream implementation.\n\n    The constructor takes an integer file descriptor (such as one returned\n    by `os.pipe`) rather than an open file object.\n    \"\"\"\n    def __init__(self, fd, *args, **kwargs):\n        self.fd = fd\n        _set_nonblocking(fd)\n        super(PipeIOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.fd\n\n    def close_fd(self):\n        os.close(self.fd)\n\n    def write_to_fd(self, data):\n        return os.write(self.fd, data)\n\n    def read_from_fd(self):\n        try:\n            chunk = os.read(self.fd, self.read_chunk_size)\n        except (IOError, OSError) as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            elif e.args[0] == errno.EBADF:\n                # If the writing half of a pipe is closed, select will\n                # report it as readable but reads will fail with EBADF.\n                self.close(exc_info=True)\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\ndef _double_prefix(deque):\n    \"\"\"Grow by doubling, but don't split the second chunk just because the\n    first one is small.\n    \"\"\"\n    new_len = max(len(deque[0]) * 2,\n                  (len(deque[0]) + len(deque[1])))\n    _merge_prefix(deque, new_len)\n\n\ndef _merge_prefix(deque, size):\n    \"\"\"Replace the first entries in a deque of strings with a single\n    string of up to size bytes.\n\n    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])\n    >>> _merge_prefix(d, 5); print(d)\n    deque(['abcde', 'fghi', 'j'])\n\n    Strings will be split as necessary to reach the desired size.\n    >>> _merge_prefix(d, 7); print(d)\n    deque(['abcdefg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 3); print(d)\n    deque(['abc', 'defg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 100); print(d)\n    deque(['abcdefghij'])\n    \"\"\"\n    if len(deque) == 1 and len(deque[0]) <= size:\n        return\n    prefix = []\n    remaining = size\n    while deque and remaining > 0:\n        chunk = deque.popleft()\n        if len(chunk) > remaining:\n            deque.appendleft(chunk[remaining:])\n            chunk = chunk[:remaining]\n        prefix.append(chunk)\n        remaining -= len(chunk)\n    # This data structure normally just contains byte strings, but\n    # the unittest gets messy if it doesn't use the default str() type,\n    # so do the merge based on the type of data that's actually present.\n    if prefix:\n        deque.appendleft(type(prefix[0])().join(prefix))\n    if not deque:\n        deque.appendleft(b\"\")\n\n\ndef doctests():\n    import doctest\n    return doctest.DocTestSuite()\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"Utility classes to write to and read from non-blocking files and sockets.\n\nContents:\n\n* `BaseIOStream`: Generic interface for reading and writing.\n* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.\n* `SSLIOStream`: SSL-aware version of IOStream.\n* `PipeIOStream`: Pipe-based IOStream implementation.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nimport errno\nimport numbers\nimport os\nimport socket\nimport ssl\nimport sys\nimport re\n\nfrom tornado import ioloop\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    from tornado.platform.posix import _set_nonblocking\nexcept ImportError:\n    _set_nonblocking = None\n\n\nclass StreamClosedError(IOError):\n    pass\n\n\nclass BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's `error`\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=104857600,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.instance()\n        self.max_buffer_size = max_buffer_size\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket returned\n        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,\n        should return no more than ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the IOLoop has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback):\n        \"\"\"Call callback when we read the given regex pattern.\"\"\"\n        self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n\n    def read_until(self, delimiter, callback):\n        \"\"\"Call callback when we read the given delimiter.\"\"\"\n        self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n\n    def read_bytes(self, num_bytes, callback, streaming_callback=None):\n        \"\"\"Call callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n        \"\"\"\n        self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n\n    def read_until_close(self, callback, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_callback(self._read_callback,\n                               self._consume(self._read_buffer_size))\n            self._streaming_callback = None\n            self._read_callback = None\n            return\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._read_from_buffer()\n        self._add_io_state(self.io_loop.READ)\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If callback is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            if len(data) > WRITE_BUFFER_CHUNK_SIZE:\n                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n            else:\n                self._write_buffer.append(data)\n        self._write_callback = stack_context.wrap(callback)\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                callback = self._read_callback\n                self._read_callback = None\n                self._read_until_close = False\n                self._run_callback(callback,\n                                   self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        if (self.closed() and self._close_callback and\n                self._pending_callbacks == 0):\n            # if there are pending callbacks, don't run the close callback\n            # until they're done (see _maybe_add_error_handler)\n            cb = self._close_callback\n            self._close_callback = None\n            self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %d\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert not self._read_callback, \"Already reading\"\n        self._read_callback = stack_context.wrap(callback)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            # See comments in _handle_read about incrementing _pending_callbacks\n            self._pending_callbacks += 1\n            while not self.closed():\n                if self._read_to_buffer() == 0:\n                    break\n        finally:\n            self._pending_callbacks -= 1\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] == errno.ECONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            callback = self._read_callback\n            self._read_callback = None\n            self._streaming_callback = None\n            self._read_bytes = None\n            self._run_callback(callback, self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        callback = self._read_callback\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_delimiter = None\n                        self._run_callback(callback,\n                                           self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        callback = self._read_callback\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_regex = None\n                        self._run_callback(callback, self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except socket.error as e:\n                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    gen_log.warning(\"Write error on %d: %s\",\n                                    self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer and self._write_callback:\n            callback = self._write_callback\n            self._write_callback = None\n            self._run_callback(callback)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)\n\n\nclass IOStream(BaseIOStream):\n    r\"\"\"Socket-based IOStream implementation.\n\n    This class supports the read and write methods from `BaseIOStream`\n    plus a `connect` method.\n\n    The socket parameter may either be connected or unconnected.  For\n    server operations the socket is the result of calling socket.accept().\n    For client operations the socket is created with socket.socket(),\n    and may either be connected before passing it to the IOStream or\n    connected with IOStream.connect.\n\n    A very simple (and broken) HTTP client using this class::\n\n        from tornado import ioloop\n        from tornado import iostream\n        import socket\n\n        def send_request():\n            stream.write(\"GET / HTTP/1.0\\r\\nHost: friendfeed.com\\r\\n\\r\\n\")\n            stream.read_until(\"\\r\\n\\r\\n\", on_headers)\n\n        def on_headers(data):\n            headers = {}\n            for line in data.split(\"\\r\\n\"):\n               parts = line.split(\":\")\n               if len(parts) == 2:\n                   headers[parts[0].strip()] = parts[1].strip()\n            stream.read_bytes(int(headers[\"Content-Length\"]), on_body)\n\n        def on_body(data):\n            print data\n            stream.close()\n            ioloop.IOLoop.instance().stop()\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = iostream.IOStream(s)\n        stream.connect((\"friendfeed.com\", 80), send_request)\n        ioloop.IOLoop.instance().start()\n    \"\"\"\n    def __init__(self, socket, *args, **kwargs):\n        self.socket = socket\n        self.socket.setblocking(False)\n        super(IOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    def close_fd(self):\n        self.socket.close()\n        self.socket = None\n\n    def get_fd_error(self):\n        errno = self.socket.getsockopt(socket.SOL_SOCKET,\n                                       socket.SO_ERROR)\n        return socket.error(errno, os.strerror(errno))\n\n    def read_from_fd(self):\n        try:\n            chunk = self.socket.recv(self.read_chunk_size)\n        except socket.error as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n    def write_to_fd(self, data):\n        return self.socket.send(data)\n\n    def connect(self, address, callback=None, server_hostname=None):\n        \"\"\"Connects the socket to a remote address without blocking.\n\n        May only be called if the socket passed to the constructor was\n        not previously connected.  The address parameter is in the\n        same format as for socket.connect, i.e. a (host, port) tuple.\n        If callback is specified, it will be called when the\n        connection is completed.\n\n        If specified, the ``server_hostname`` parameter will be used\n        in SSL connections for certificate validation (if requested in\n        the ``ssl_options``) and SNI (if supported; requires\n        Python 3.2+).\n\n        Note that it is safe to call IOStream.write while the\n        connection is pending, in which case the data will be written\n        as soon as the connection is ready.  Calling IOStream read\n        methods before the socket is connected works on some platforms\n        but is non-portable.\n        \"\"\"\n        self._connecting = True\n        try:\n            self.socket.connect(address)\n        except socket.error as e:\n            # In non-blocking mode we expect connect() to raise an\n            # exception with EINPROGRESS or EWOULDBLOCK.\n            #\n            # On freebsd, other errors such as ECONNREFUSED may be\n            # returned immediately when attempting to connect to\n            # localhost, so handle them the same way as an error\n            # reported later in _handle_connect.\n            if e.args[0] not in (errno.EINPROGRESS, errno.EWOULDBLOCK):\n                gen_log.warning(\"Connect error on fd %d: %s\",\n                                self.socket.fileno(), e)\n                self.close(exc_info=True)\n                return\n        self._connect_callback = stack_context.wrap(callback)\n        self._add_io_state(self.io_loop.WRITE)\n\n    def _handle_connect(self):\n        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)\n        if err != 0:\n            self.error = socket.error(err, os.strerror(err))\n            # IOLoop implementations may vary: some of them return\n            # an error state before the socket becomes writable, so\n            # in that case a connection failure would be handled by the\n            # error path in _handle_events instead of here.\n            gen_log.warning(\"Connect error on fd %d: %s\",\n                            self.socket.fileno(), errno.errorcode[err])\n            self.close()\n            return\n        if self._connect_callback is not None:\n            callback = self._connect_callback\n            self._connect_callback = None\n            self._run_callback(callback)\n        self._connecting = False\n\n\nclass SSLIOStream(IOStream):\n    \"\"\"A utility class to write to and read from a non-blocking SSL socket.\n\n    If the socket passed to the constructor is already connected,\n    it should be wrapped with::\n\n        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)\n\n    before constructing the SSLIOStream.  Unconnected sockets will be\n    wrapped when IOStream.connect is finished.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        \"\"\"Creates an SSLIOStream.\n\n        The ``ssl_options`` keyword argument may either be a dictionary\n        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`\n        object.\n        \"\"\"\n        self._ssl_options = kwargs.pop('ssl_options', {})\n        super(SSLIOStream, self).__init__(*args, **kwargs)\n        self._ssl_accepting = True\n        self._handshake_reading = False\n        self._handshake_writing = False\n        self._ssl_connect_callback = None\n        self._server_hostname = None\n\n    def reading(self):\n        return self._handshake_reading or super(SSLIOStream, self).reading()\n\n    def writing(self):\n        return self._handshake_writing or super(SSLIOStream, self).writing()\n\n    def _do_ssl_handshake(self):\n        # Based on code from test_ssl.py in the python stdlib\n        try:\n            self._handshake_reading = False\n            self._handshake_writing = False\n            self.socket.do_handshake()\n        except ssl.SSLError as err:\n            if err.args[0] == ssl.SSL_ERROR_WANT_READ:\n                self._handshake_reading = True\n                return\n            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:\n                self._handshake_writing = True\n                return\n            elif err.args[0] in (ssl.SSL_ERROR_EOF,\n                                 ssl.SSL_ERROR_ZERO_RETURN):\n                return self.close(exc_info=True)\n            elif err.args[0] == ssl.SSL_ERROR_SSL:\n                try:\n                    peer = self.socket.getpeername()\n                except:\n                    peer = '(not connected)'\n                gen_log.warning(\"SSL Error on %d %s: %s\",\n                                self.socket.fileno(), peer, err)\n                return self.close(exc_info=True)\n            raise\n        except socket.error as err:\n            if err.args[0] in (errno.ECONNABORTED, errno.ECONNRESET):\n                return self.close(exc_info=True)\n        else:\n            self._ssl_accepting = False\n            if not self._verify_cert(self.socket.getpeercert()):\n                self.close()\n                return\n            if self._ssl_connect_callback is not None:\n                callback = self._ssl_connect_callback\n                self._ssl_connect_callback = None\n                self._run_callback(callback)\n\n    def _verify_cert(self, peercert):\n        \"\"\"Returns True if peercert is valid according to the configured\n        validation mode and hostname.\n\n        The ssl handshake already tested the certificate for a valid\n        CA signature; the only thing that remains is to check\n        the hostname.\n        \"\"\"\n        if isinstance(self._ssl_options, dict):\n            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)\n        elif isinstance(self._ssl_options, ssl.SSLContext):\n            verify_mode = self._ssl_options.verify_mode\n        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)\n        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:\n            return True\n        cert = self.socket.getpeercert()\n        if cert is None and verify_mode == ssl.CERT_REQUIRED:\n            gen_log.warning(\"No SSL certificate given\")\n            return False\n        try:\n            ssl_match_hostname(peercert, self._server_hostname)\n        except SSLCertificateError:\n            gen_log.warning(\"Invalid SSL certificate\", exc_info=True)\n            return False\n        else:\n            return True\n\n    def _handle_read(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_read()\n\n    def _handle_write(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_write()\n\n    def connect(self, address, callback=None, server_hostname=None):\n        # Save the user's callback and run it after the ssl handshake\n        # has completed.\n        self._ssl_connect_callback = callback\n        self._server_hostname = server_hostname\n        super(SSLIOStream, self).connect(address, callback=None)\n\n    def _handle_connect(self):\n        # When the connection is complete, wrap the socket for SSL\n        # traffic.  Note that we do this by overriding _handle_connect\n        # instead of by passing a callback to super().connect because\n        # user callbacks are enqueued asynchronously on the IOLoop,\n        # but since _handle_events calls _handle_connect immediately\n        # followed by _handle_write we need this to be synchronous.\n        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,\n                                      server_hostname=self._server_hostname,\n                                      do_handshake_on_connect=False)\n        super(SSLIOStream, self)._handle_connect()\n\n    def read_from_fd(self):\n        if self._ssl_accepting:\n            # If the handshake hasn't finished yet, there can't be anything\n            # to read (attempting to read may or may not raise an exception\n            # depending on the SSL version)\n            return None\n        try:\n            # SSLSocket objects have both a read() and recv() method,\n            # while regular sockets only have recv().\n            # The recv() method blocks (at least in python 2.6) if it is\n            # called when there is nothing to read, so we have to use\n            # read() instead.\n            chunk = self.socket.read(self.read_chunk_size)\n        except ssl.SSLError as e:\n            # SSLError is a subclass of socket.error, so this except\n            # block must come first.\n            if e.args[0] == ssl.SSL_ERROR_WANT_READ:\n                return None\n            else:\n                raise\n        except socket.error as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\nclass PipeIOStream(BaseIOStream):\n    \"\"\"Pipe-based IOStream implementation.\n\n    The constructor takes an integer file descriptor (such as one returned\n    by `os.pipe`) rather than an open file object.\n    \"\"\"\n    def __init__(self, fd, *args, **kwargs):\n        self.fd = fd\n        _set_nonblocking(fd)\n        super(PipeIOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.fd\n\n    def close_fd(self):\n        os.close(self.fd)\n\n    def write_to_fd(self, data):\n        return os.write(self.fd, data)\n\n    def read_from_fd(self):\n        try:\n            chunk = os.read(self.fd, self.read_chunk_size)\n        except (IOError, OSError) as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            elif e.args[0] == errno.EBADF:\n                # If the writing half of a pipe is closed, select will\n                # report it as readable but reads will fail with EBADF.\n                self.close(exc_info=True)\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\ndef _double_prefix(deque):\n    \"\"\"Grow by doubling, but don't split the second chunk just because the\n    first one is small.\n    \"\"\"\n    new_len = max(len(deque[0]) * 2,\n                  (len(deque[0]) + len(deque[1])))\n    _merge_prefix(deque, new_len)\n\n\ndef _merge_prefix(deque, size):\n    \"\"\"Replace the first entries in a deque of strings with a single\n    string of up to size bytes.\n\n    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])\n    >>> _merge_prefix(d, 5); print(d)\n    deque(['abcde', 'fghi', 'j'])\n\n    Strings will be split as necessary to reach the desired size.\n    >>> _merge_prefix(d, 7); print(d)\n    deque(['abcdefg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 3); print(d)\n    deque(['abc', 'defg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 100); print(d)\n    deque(['abcdefghij'])\n    \"\"\"\n    if len(deque) == 1 and len(deque[0]) <= size:\n        return\n    prefix = []\n    remaining = size\n    while deque and remaining > 0:\n        chunk = deque.popleft()\n        if len(chunk) > remaining:\n            deque.appendleft(chunk[remaining:])\n            chunk = chunk[:remaining]\n        prefix.append(chunk)\n        remaining -= len(chunk)\n    # This data structure normally just contains byte strings, but\n    # the unittest gets messy if it doesn't use the default str() type,\n    # so do the merge based on the type of data that's actually present.\n    if prefix:\n        deque.appendleft(type(prefix[0])().join(prefix))\n    if not deque:\n        deque.appendleft(b\"\")\n\n\ndef doctests():\n    import doctest\n    return doctest.DocTestSuite()\n",
            "header": {
                "file": {
                    "path": "tornado/iostream.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "86cd68a8",
                "new_commit_hash": "9d9fb715",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/iostream.py"
            },
            "plus_file": {
                "path": "b/tornado/iostream.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 174,
                            "length": 6
                        },
                        "new_range": {
                            "start": 174,
                            "length": 7
                        },
                        "section": "class BaseIOStream(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            return",
                                "type": "context"
                            },
                            {
                                "content": "        self._read_until_close = True",
                                "type": "context"
                            },
                            {
                                "content": "        self._streaming_callback = stack_context.wrap(streaming_callback)",
                                "type": "context"
                            },
                            {
                                "content": "        self._read_from_buffer()",
                                "type": "added"
                            },
                            {
                                "content": "        self._add_io_state(self.io_loop.READ)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def write(self, data, callback=None):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/iostream.py",
                            "type": "class",
                            "name": "BaseIOStream",
                            "content": "class BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's `error`\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=104857600,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.instance()\n        self.max_buffer_size = max_buffer_size\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket returned\n        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,\n        should return no more than ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the IOLoop has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback):\n        \"\"\"Call callback when we read the given regex pattern.\"\"\"\n        self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n\n    def read_until(self, delimiter, callback):\n        \"\"\"Call callback when we read the given delimiter.\"\"\"\n        self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n\n    def read_bytes(self, num_bytes, callback, streaming_callback=None):\n        \"\"\"Call callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n        \"\"\"\n        self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n\n    def read_until_close(self, callback, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_callback(self._read_callback,\n                               self._consume(self._read_buffer_size))\n            self._streaming_callback = None\n            self._read_callback = None\n            return\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._read_from_buffer()\n        self._add_io_state(self.io_loop.READ)\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If callback is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            if len(data) > WRITE_BUFFER_CHUNK_SIZE:\n                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n            else:\n                self._write_buffer.append(data)\n        self._write_callback = stack_context.wrap(callback)\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                callback = self._read_callback\n                self._read_callback = None\n                self._read_until_close = False\n                self._run_callback(callback,\n                                   self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        if (self.closed() and self._close_callback and\n                self._pending_callbacks == 0):\n            # if there are pending callbacks, don't run the close callback\n            # until they're done (see _maybe_add_error_handler)\n            cb = self._close_callback\n            self._close_callback = None\n            self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %d\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert not self._read_callback, \"Already reading\"\n        self._read_callback = stack_context.wrap(callback)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            # See comments in _handle_read about incrementing _pending_callbacks\n            self._pending_callbacks += 1\n            while not self.closed():\n                if self._read_to_buffer() == 0:\n                    break\n        finally:\n            self._pending_callbacks -= 1\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] == errno.ECONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            callback = self._read_callback\n            self._read_callback = None\n            self._streaming_callback = None\n            self._read_bytes = None\n            self._run_callback(callback, self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        callback = self._read_callback\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_delimiter = None\n                        self._run_callback(callback,\n                                           self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        callback = self._read_callback\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_regex = None\n                        self._run_callback(callback, self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except socket.error as e:\n                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    gen_log.warning(\"Write error on %d: %s\",\n                                    self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer and self._write_callback:\n            callback = self._write_callback\n            self._write_callback = None\n            self._run_callback(callback)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 54,
                            "end_lineno": 573,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/iostream.py",
                            "type": "method",
                            "name": "BaseIOStream.read_until_close",
                            "content": "class BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's `error`\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=104857600,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.instance()\n        self.max_buffer_size = max_buffer_size\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket returned\n        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,\n        should return no more than ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the IOLoop has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback):\n        \"\"\"Call callback when we read the given regex pattern.\"\"\"\n        self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n\n    def read_until(self, delimiter, callback):\n        \"\"\"Call callback when we read the given delimiter.\"\"\"\n        self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n\n    def read_bytes(self, num_bytes, callback, streaming_callback=None):\n        \"\"\"Call callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n        \"\"\"\n        self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n\n    def read_until_close(self, callback, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_callback(self._read_callback,\n                               self._consume(self._read_buffer_size))\n            self._streaming_callback = None\n            self._read_callback = None\n            return\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._read_from_buffer()\n        self._add_io_state(self.io_loop.READ)\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If callback is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            if len(data) > WRITE_BUFFER_CHUNK_SIZE:\n                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n            else:\n                self._write_buffer.append(data)\n        self._write_callback = stack_context.wrap(callback)\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                callback = self._read_callback\n                self._read_callback = None\n                self._read_until_close = False\n                self._run_callback(callback,\n                                   self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        if (self.closed() and self._close_callback and\n                self._pending_callbacks == 0):\n            # if there are pending callbacks, don't run the close callback\n            # until they're done (see _maybe_add_error_handler)\n            cb = self._close_callback\n            self._close_callback = None\n            self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %d\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert not self._read_callback, \"Already reading\"\n        self._read_callback = stack_context.wrap(callback)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            # See comments in _handle_read about incrementing _pending_callbacks\n            self._pending_callbacks += 1\n            while not self.closed():\n                if self._read_to_buffer() == 0:\n                    break\n        finally:\n            self._pending_callbacks -= 1\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] == errno.ECONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            callback = self._read_callback\n            self._read_callback = None\n            self._streaming_callback = None\n            self._read_bytes = None\n            self._run_callback(callback, self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        callback = self._read_callback\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_delimiter = None\n                        self._run_callback(callback,\n                                           self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        callback = self._read_callback\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_regex = None\n                        self._run_callback(callback, self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except socket.error as e:\n                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    gen_log.warning(\"Write error on %d: %s\",\n                                    self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer and self._write_callback:\n            callback = self._write_callback\n            self._write_callback = None\n            self._run_callback(callback)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 154,
                            "end_lineno": 178,
                            "parent": {
                                "file_name": "tornado/iostream.py",
                                "type": "class",
                                "name": "BaseIOStream",
                                "content": "class BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's `error`\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=104857600,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.instance()\n        self.max_buffer_size = max_buffer_size\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket returned\n        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,\n        should return no more than ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the IOLoop has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback):\n        \"\"\"Call callback when we read the given regex pattern.\"\"\"\n        self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n\n    def read_until(self, delimiter, callback):\n        \"\"\"Call callback when we read the given delimiter.\"\"\"\n        self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n\n    def read_bytes(self, num_bytes, callback, streaming_callback=None):\n        \"\"\"Call callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n        \"\"\"\n        self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n\n    def read_until_close(self, callback, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_callback(self._read_callback,\n                               self._consume(self._read_buffer_size))\n            self._streaming_callback = None\n            self._read_callback = None\n            return\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._read_from_buffer()\n        self._add_io_state(self.io_loop.READ)\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If callback is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            if len(data) > WRITE_BUFFER_CHUNK_SIZE:\n                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n            else:\n                self._write_buffer.append(data)\n        self._write_callback = stack_context.wrap(callback)\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                callback = self._read_callback\n                self._read_callback = None\n                self._read_until_close = False\n                self._run_callback(callback,\n                                   self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        if (self.closed() and self._close_callback and\n                self._pending_callbacks == 0):\n            # if there are pending callbacks, don't run the close callback\n            # until they're done (see _maybe_add_error_handler)\n            cb = self._close_callback\n            self._close_callback = None\n            self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %d\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert not self._read_callback, \"Already reading\"\n        self._read_callback = stack_context.wrap(callback)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            # See comments in _handle_read about incrementing _pending_callbacks\n            self._pending_callbacks += 1\n            while not self.closed():\n                if self._read_to_buffer() == 0:\n                    break\n        finally:\n            self._pending_callbacks -= 1\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] == errno.ECONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            callback = self._read_callback\n            self._read_callback = None\n            self._streaming_callback = None\n            self._read_bytes = None\n            self._run_callback(callback, self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        callback = self._read_callback\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_delimiter = None\n                        self._run_callback(callback,\n                                           self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        callback = self._read_callback\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_regex = None\n                        self._run_callback(callback, self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except socket.error as e:\n                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    gen_log.warning(\"Write error on %d: %s\",\n                                    self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer and self._write_callback:\n            callback = self._write_callback\n            self._write_callback = None\n            self._run_callback(callback)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 54,
                                "end_lineno": 573,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import netutil\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream, SSLIOStream, PipeIOStream\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket\nfrom tornado.stack_context import NullContext\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog\nfrom tornado.test.util import unittest, skipIfNonUnix\nfrom tornado.web import RequestHandler, Application\nimport errno\nimport logging\nimport os\nimport platform\nimport socket\nimport ssl\nimport sys\n\n\nclass HelloHandler(RequestHandler):\n    def get(self):\n        self.write(\"Hello\")\n\n\nclass TestIOStreamWebMixin(object):\n    def _make_client_iostream(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        return Application([('/', HelloHandler)])\n\n    def test_connection_closed(self):\n        # When a server sends a response and then closes the connection,\n        # the client must be allowed to read the data before the IOStream\n        # closes itself.  Epoll reports closed connections with a separate\n        # EPOLLRDHUP event delivered at the same time as the read event,\n        # while kqueue reports them as a second read/write event with an EOF\n        # flag.\n        response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n        response.rethrow()\n\n    def test_read_until_close(self):\n        stream = self._make_client_iostream()\n        stream.connect(('localhost', self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.0 200\"))\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n    def test_read_zero_bytes(self):\n        self.stream = self._make_client_iostream()\n        self.stream.connect((\"localhost\", self.get_http_port()),\n                            callback=self.stop)\n        self.wait()\n        self.stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        # normal read\n        self.stream.read_bytes(9, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"HTTP/1.0 \")\n\n        # zero bytes\n        self.stream.read_bytes(0, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"\")\n\n        # another normal read\n        self.stream.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"200\")\n\n        self.stream.close()\n\n    def test_write_while_connecting(self):\n        stream = self._make_client_iostream()\n        connected = [False]\n\n        def connected_callback():\n            connected[0] = True\n            self.stop()\n        stream.connect((\"localhost\", self.get_http_port()),\n                       callback=connected_callback)\n        # unlike the previous tests, try to write before the connection\n        # is complete.\n        written = [False]\n\n        def write_callback():\n            written[0] = True\n            self.stop()\n        stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\",\n                     callback=write_callback)\n        self.assertTrue(not connected[0])\n        # by the time the write has flushed, the connection callback has\n        # also run\n        try:\n            self.wait(lambda: connected[0] and written[0])\n        finally:\n            logging.debug((connected, written))\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n        stream.close()\n\n\nclass TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            if isinstance(streams[0], SSLIOStream):\n                # HACK: The SSL handshake won't complete (and\n                # therefore the client connect callback won't be\n                # run)until the server side has tried to do something\n                # with the connection.  For these tests we want both\n                # sides to connect before we do anything else with the\n                # connection, so we must cause some dummy activity on the\n                # server.  If this turns out to be useful for real apps\n                # it should have a cleaner interface.\n                streams[0]._add_io_state(IOLoop.READ)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n\n            def callback(data):\n                chunks.append(data)\n                self.stop()\n            client.read_until_close(callback=callback,\n                                    streaming_callback=callback)\n            server.write(b\"1234\")\n            self.wait()\n            server.write(b\"5678\")\n            self.wait()\n            server.close()\n            self.wait()\n            self.assertEqual(chunks, [b\"1234\", b\"5678\", b\"\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n\nclass TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):\n    def _make_client_iostream(self):\n        return IOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):\n    def _make_client_iostream(self):\n        return SSLIOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStream(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        return IOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return IOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\nclass TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        ssl_options = dict(\n            certfile=os.path.join(os.path.dirname(__file__), 'test.crt'),\n            keyfile=os.path.join(os.path.dirname(__file__), 'test.key'),\n        )\n        connection = ssl.wrap_socket(connection,\n                                     server_side=True,\n                                     do_handshake_on_connect=False,\n                                     **ssl_options)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\n# This will run some tests that are basically redundant but it's the\n# simplest way to make sure that it works to pass an SSLContext\n# instead of an ssl_options dict to the SSLIOStream constructor.\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\nclass TestIOStreamSSLContext(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        context.load_cert_chain(\n            os.path.join(os.path.dirname(__file__), 'test.crt'),\n            os.path.join(os.path.dirname(__file__), 'test.key'))\n        connection = ssl_wrap_socket(connection, context,\n                                     server_side=True,\n                                     do_handshake_on_connect=False)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        return SSLIOStream(connection, io_loop=self.io_loop,\n                           ssl_options=context, **kwargs)\n\n\n@skipIfNonUnix\nclass TestPipeIOStream(AsyncTestCase):\n    def test_pipe_iostream(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        ws.write(b\"hel\")\n        ws.write(b\"lo world\")\n\n        rs.read_until(b' ', callback=self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"hello \")\n\n        rs.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"wor\")\n\n        ws.close()\n\n        rs.read_until_close(self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"ld\")\n\n        rs.close()\n",
            "new_file_content": "from __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import netutil\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream, SSLIOStream, PipeIOStream\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket\nfrom tornado.stack_context import NullContext\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog\nfrom tornado.test.util import unittest, skipIfNonUnix\nfrom tornado.web import RequestHandler, Application\nimport errno\nimport logging\nimport os\nimport platform\nimport socket\nimport ssl\nimport sys\n\n\nclass HelloHandler(RequestHandler):\n    def get(self):\n        self.write(\"Hello\")\n\n\nclass TestIOStreamWebMixin(object):\n    def _make_client_iostream(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        return Application([('/', HelloHandler)])\n\n    def test_connection_closed(self):\n        # When a server sends a response and then closes the connection,\n        # the client must be allowed to read the data before the IOStream\n        # closes itself.  Epoll reports closed connections with a separate\n        # EPOLLRDHUP event delivered at the same time as the read event,\n        # while kqueue reports them as a second read/write event with an EOF\n        # flag.\n        response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n        response.rethrow()\n\n    def test_read_until_close(self):\n        stream = self._make_client_iostream()\n        stream.connect(('localhost', self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.0 200\"))\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n    def test_read_zero_bytes(self):\n        self.stream = self._make_client_iostream()\n        self.stream.connect((\"localhost\", self.get_http_port()),\n                            callback=self.stop)\n        self.wait()\n        self.stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        # normal read\n        self.stream.read_bytes(9, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"HTTP/1.0 \")\n\n        # zero bytes\n        self.stream.read_bytes(0, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"\")\n\n        # another normal read\n        self.stream.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"200\")\n\n        self.stream.close()\n\n    def test_write_while_connecting(self):\n        stream = self._make_client_iostream()\n        connected = [False]\n\n        def connected_callback():\n            connected[0] = True\n            self.stop()\n        stream.connect((\"localhost\", self.get_http_port()),\n                       callback=connected_callback)\n        # unlike the previous tests, try to write before the connection\n        # is complete.\n        written = [False]\n\n        def write_callback():\n            written[0] = True\n            self.stop()\n        stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\",\n                     callback=write_callback)\n        self.assertTrue(not connected[0])\n        # by the time the write has flushed, the connection callback has\n        # also run\n        try:\n            self.wait(lambda: connected[0] and written[0])\n        finally:\n            logging.debug((connected, written))\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n        stream.close()\n\n\nclass TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            if isinstance(streams[0], SSLIOStream):\n                # HACK: The SSL handshake won't complete (and\n                # therefore the client connect callback won't be\n                # run)until the server side has tried to do something\n                # with the connection.  For these tests we want both\n                # sides to connect before we do anything else with the\n                # connection, so we must cause some dummy activity on the\n                # server.  If this turns out to be useful for real apps\n                # it should have a cleaner interface.\n                streams[0]._add_io_state(IOLoop.READ)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n\n            def callback(data):\n                chunks.append(data)\n                self.stop()\n            client.read_until_close(callback=callback,\n                                    streaming_callback=callback)\n            server.write(b\"1234\")\n            self.wait()\n            server.write(b\"5678\")\n            self.wait()\n            server.close()\n            self.wait()\n            self.assertEqual(chunks, [b\"1234\", b\"5678\", b\"\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n\nclass TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):\n    def _make_client_iostream(self):\n        return IOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):\n    def _make_client_iostream(self):\n        return SSLIOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStream(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        return IOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return IOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\nclass TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        ssl_options = dict(\n            certfile=os.path.join(os.path.dirname(__file__), 'test.crt'),\n            keyfile=os.path.join(os.path.dirname(__file__), 'test.key'),\n        )\n        connection = ssl.wrap_socket(connection,\n                                     server_side=True,\n                                     do_handshake_on_connect=False,\n                                     **ssl_options)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\n# This will run some tests that are basically redundant but it's the\n# simplest way to make sure that it works to pass an SSLContext\n# instead of an ssl_options dict to the SSLIOStream constructor.\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\nclass TestIOStreamSSLContext(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        context.load_cert_chain(\n            os.path.join(os.path.dirname(__file__), 'test.crt'),\n            os.path.join(os.path.dirname(__file__), 'test.key'))\n        connection = ssl_wrap_socket(connection, context,\n                                     server_side=True,\n                                     do_handshake_on_connect=False)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        return SSLIOStream(connection, io_loop=self.io_loop,\n                           ssl_options=context, **kwargs)\n\n\n@skipIfNonUnix\nclass TestPipeIOStream(AsyncTestCase):\n    def test_pipe_iostream(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        ws.write(b\"hel\")\n        ws.write(b\"lo world\")\n\n        rs.read_until(b' ', callback=self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"hello \")\n\n        rs.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"wor\")\n\n        ws.close()\n\n        rs.read_until_close(self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"ld\")\n\n        rs.close()\n",
            "header": {
                "file": {
                    "path": "tornado/test/iostream_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "79a2b730",
                "new_commit_hash": "c2e9cab9",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/iostream_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/iostream_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 145,
                            "length": 6
                        },
                        "new_range": {
                            "start": 145,
                            "length": 22
                        },
                        "section": "class TestIOStreamMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        listener.close()",
                                "type": "context"
                            },
                            {
                                "content": "        return streams",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_streaming_callback_with_data_in_buffer(self):",
                                "type": "added"
                            },
                            {
                                "content": "        server, client = self.make_iostream_pair()",
                                "type": "added"
                            },
                            {
                                "content": "        client.write(b\"abcd\\r\\nefgh\")",
                                "type": "added"
                            },
                            {
                                "content": "        server.read_until(b\"\\r\\n\", self.stop)",
                                "type": "added"
                            },
                            {
                                "content": "        data = self.wait()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(data, b\"abcd\\r\\n\")",
                                "type": "added"
                            },
                            {
                                "content": "        def closed_callback(chunk):",
                                "type": "added"
                            },
                            {
                                "content": "            self.fail()",
                                "type": "added"
                            },
                            {
                                "content": "        server.read_until_close(callback=closed_callback,",
                                "type": "added"
                            },
                            {
                                "content": "                                streaming_callback=self.stop)",
                                "type": "added"
                            },
                            {
                                "content": "        self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)",
                                "type": "added"
                            },
                            {
                                "content": "        data = self.wait()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(data, b\"efgh\")",
                                "type": "added"
                            },
                            {
                                "content": "        server.close()",
                                "type": "added"
                            },
                            {
                                "content": "        client.close()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_write_zero_bytes(self):",
                                "type": "context"
                            },
                            {
                                "content": "        # Attempting to write zero bytes should run the callback without",
                                "type": "context"
                            },
                            {
                                "content": "        # going into an infinite loop.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/iostream_test.py",
                            "type": "class",
                            "name": "TestIOStreamMixin",
                            "content": "class TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            if isinstance(streams[0], SSLIOStream):\n                # HACK: The SSL handshake won't complete (and\n                # therefore the client connect callback won't be\n                # run)until the server side has tried to do something\n                # with the connection.  For these tests we want both\n                # sides to connect before we do anything else with the\n                # connection, so we must cause some dummy activity on the\n                # server.  If this turns out to be useful for real apps\n                # it should have a cleaner interface.\n                streams[0]._add_io_state(IOLoop.READ)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n\n            def callback(data):\n                chunks.append(data)\n                self.stop()\n            client.read_until_close(callback=callback,\n                                    streaming_callback=callback)\n            server.write(b\"1234\")\n            self.wait()\n            server.write(b\"5678\")\n            self.wait()\n            server.close()\n            self.wait()\n            self.assertEqual(chunks, [b\"1234\", b\"5678\", b\"\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 110,
                            "end_lineno": 456,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/iostream_test.py",
                            "type": "method",
                            "name": "TestIOStreamMixin.test_streaming_callback_with_data_in_buffer",
                            "content": "class TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            if isinstance(streams[0], SSLIOStream):\n                # HACK: The SSL handshake won't complete (and\n                # therefore the client connect callback won't be\n                # run)until the server side has tried to do something\n                # with the connection.  For these tests we want both\n                # sides to connect before we do anything else with the\n                # connection, so we must cause some dummy activity on the\n                # server.  If this turns out to be useful for real apps\n                # it should have a cleaner interface.\n                streams[0]._add_io_state(IOLoop.READ)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n\n            def callback(data):\n                chunks.append(data)\n                self.stop()\n            client.read_until_close(callback=callback,\n                                    streaming_callback=callback)\n            server.write(b\"1234\")\n            self.wait()\n            server.write(b\"5678\")\n            self.wait()\n            server.close()\n            self.wait()\n            self.assertEqual(chunks, [b\"1234\", b\"5678\", b\"\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 148,
                            "end_lineno": 162,
                            "parent": {
                                "file_name": "tornado/test/iostream_test.py",
                                "type": "class",
                                "name": "TestIOStreamMixin",
                                "content": "class TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            if isinstance(streams[0], SSLIOStream):\n                # HACK: The SSL handshake won't complete (and\n                # therefore the client connect callback won't be\n                # run)until the server side has tried to do something\n                # with the connection.  For these tests we want both\n                # sides to connect before we do anything else with the\n                # connection, so we must cause some dummy activity on the\n                # server.  If this turns out to be useful for real apps\n                # it should have a cleaner interface.\n                streams[0]._add_io_state(IOLoop.READ)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n\n            def callback(data):\n                chunks.append(data)\n                self.stop()\n            client.read_until_close(callback=callback,\n                                    streaming_callback=callback)\n            server.write(b\"1234\")\n            self.wait()\n            server.write(b\"5678\")\n            self.wait()\n            server.close()\n            self.wait()\n            self.assertEqual(chunks, [b\"1234\", b\"5678\", b\"\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 110,
                                "end_lineno": 456,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "4d51ee80ef0b64e31a175f7e95c9df001dfff491^",
    "new_commit_hash": "4d51ee80ef0b64e31a175f7e95c9df001dfff491",
    "commit_message": "Merge pull request #686 from omribahumi/master\n\nFlushing the buffer when calling IOStream.read_until_close()",
    "commit_date": "2013-03-02T11:48:53-08:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "4d51ee80ef0b64e31a175f7e95c9df001dfff491",
    "test_file_codes": [
        "from __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import netutil\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream, SSLIOStream, PipeIOStream\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket\nfrom tornado.stack_context import NullContext\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog\nfrom tornado.test.util import unittest, skipIfNonUnix\nfrom tornado.web import RequestHandler, Application\nimport errno\nimport logging\nimport os\nimport platform\nimport socket\nimport ssl\nimport sys\n\n\nclass HelloHandler(RequestHandler):\n    def get(self):\n        self.write(\"Hello\")\n\n\nclass TestIOStreamWebMixin(object):\n    def _make_client_iostream(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        return Application([('/', HelloHandler)])\n\n    def test_connection_closed(self):\n        # When a server sends a response and then closes the connection,\n        # the client must be allowed to read the data before the IOStream\n        # closes itself.  Epoll reports closed connections with a separate\n        # EPOLLRDHUP event delivered at the same time as the read event,\n        # while kqueue reports them as a second read/write event with an EOF\n        # flag.\n        response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n        response.rethrow()\n\n    def test_read_until_close(self):\n        stream = self._make_client_iostream()\n        stream.connect(('localhost', self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.0 200\"))\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n    def test_read_zero_bytes(self):\n        self.stream = self._make_client_iostream()\n        self.stream.connect((\"localhost\", self.get_http_port()),\n                            callback=self.stop)\n        self.wait()\n        self.stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        # normal read\n        self.stream.read_bytes(9, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"HTTP/1.0 \")\n\n        # zero bytes\n        self.stream.read_bytes(0, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"\")\n\n        # another normal read\n        self.stream.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"200\")\n\n        self.stream.close()\n\n    def test_write_while_connecting(self):\n        stream = self._make_client_iostream()\n        connected = [False]\n\n        def connected_callback():\n            connected[0] = True\n            self.stop()\n        stream.connect((\"localhost\", self.get_http_port()),\n                       callback=connected_callback)\n        # unlike the previous tests, try to write before the connection\n        # is complete.\n        written = [False]\n\n        def write_callback():\n            written[0] = True\n            self.stop()\n        stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\",\n                     callback=write_callback)\n        self.assertTrue(not connected[0])\n        # by the time the write has flushed, the connection callback has\n        # also run\n        try:\n            self.wait(lambda: connected[0] and written[0])\n        finally:\n            logging.debug((connected, written))\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n        stream.close()\n\n\nclass TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            if isinstance(streams[0], SSLIOStream):\n                # HACK: The SSL handshake won't complete (and\n                # therefore the client connect callback won't be\n                # run)until the server side has tried to do something\n                # with the connection.  For these tests we want both\n                # sides to connect before we do anything else with the\n                # connection, so we must cause some dummy activity on the\n                # server.  If this turns out to be useful for real apps\n                # it should have a cleaner interface.\n                streams[0]._add_io_state(IOLoop.READ)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n\n            def callback(data):\n                chunks.append(data)\n                self.stop()\n            client.read_until_close(callback=callback,\n                                    streaming_callback=callback)\n            server.write(b\"1234\")\n            self.wait()\n            server.write(b\"5678\")\n            self.wait()\n            server.close()\n            self.wait()\n            self.assertEqual(chunks, [b\"1234\", b\"5678\", b\"\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n\nclass TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):\n    def _make_client_iostream(self):\n        return IOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):\n    def _make_client_iostream(self):\n        return SSLIOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStream(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        return IOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return IOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\nclass TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        ssl_options = dict(\n            certfile=os.path.join(os.path.dirname(__file__), 'test.crt'),\n            keyfile=os.path.join(os.path.dirname(__file__), 'test.key'),\n        )\n        connection = ssl.wrap_socket(connection,\n                                     server_side=True,\n                                     do_handshake_on_connect=False,\n                                     **ssl_options)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\n# This will run some tests that are basically redundant but it's the\n# simplest way to make sure that it works to pass an SSLContext\n# instead of an ssl_options dict to the SSLIOStream constructor.\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\nclass TestIOStreamSSLContext(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        context.load_cert_chain(\n            os.path.join(os.path.dirname(__file__), 'test.crt'),\n            os.path.join(os.path.dirname(__file__), 'test.key'))\n        connection = ssl_wrap_socket(connection, context,\n                                     server_side=True,\n                                     do_handshake_on_connect=False)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        return SSLIOStream(connection, io_loop=self.io_loop,\n                           ssl_options=context, **kwargs)\n\n\n@skipIfNonUnix\nclass TestPipeIOStream(AsyncTestCase):\n    def test_pipe_iostream(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        ws.write(b\"hel\")\n        ws.write(b\"lo world\")\n\n        rs.read_until(b' ', callback=self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"hello \")\n\n        rs.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"wor\")\n\n        ws.close()\n\n        rs.read_until_close(self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"ld\")\n\n        rs.close()\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 735ms\nPrepared 1 package in 785ms\nInstalled 1 package in 1ms\n + tornado==2.4.post3 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491)\nResolved 29 packages in 17ms\nInstalled 29 packages in 115ms\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491\n......................................................\ncollected 54 items\n\n=================================== ERRORS =====================================\n__________ TestIOStreamSSL.test_async_read_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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 439, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_buffered_data __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 314, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_callback_with_pending_read __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 398, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_delayed_close_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 285, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_inline_read_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 427, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_large_read_until __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 373, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_callback_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 213, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 336, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 230, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback_with_data_in_buffer __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 149, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 353, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_until_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 260, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_write_zero_bytes __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 167, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_async_read_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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 439, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_buffered_data __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 314, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_callback_with_pending_read __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 398, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_delayed_close_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 285, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_inline_read_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 427, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_large_read_until __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 373, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_callback_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 213, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 336, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 230, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback_with_data_in_buffer __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 149, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 353, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_until_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 260, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_write_zero_bytes __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 167, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamWebHTTPS.test_connection_closed __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 39, in test_connection_closed\n    response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 306, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, 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__________ TestIOStreamWebHTTPS.test_read_until_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 45, in test_read_until_close\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, 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__________ TestIOStreamWebHTTPS.test_read_zero_bytes __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 57, in test_read_zero_bytes\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, 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__________ TestIOStreamWebHTTPS.test_write_while_connecting __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 99, in test_write_while_connecting\n    self.wait(lambda: connected[0] and written[0])\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::TestIOStream::test_async_read_error_logging\nPASSED r2e_tests.test_1::TestIOStream::test_close_buffered_data\nPASSED r2e_tests.test_1::TestIOStream::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStream::test_connection_refused\nPASSED r2e_tests.test_1::TestIOStream::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_gaierror\nPASSED r2e_tests.test_1::TestIOStream::test_inline_read_error\nPASSED r2e_tests.test_1::TestIOStream::test_large_read_until\nPASSED r2e_tests.test_1::TestIOStream::test_read_callback_error\nPASSED r2e_tests.test_1::TestIOStream::test_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback_with_data_in_buffer\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_until_close\nPASSED r2e_tests.test_1::TestIOStream::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSL::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSL::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSL::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_write_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_connection_closed\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_until_close\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_write_while_connecting\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_connection_closed\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_write_while_connecting\nPASSED r2e_tests.test_1::TestPipeIOStream::test_pipe_iostream\n=================== 30 errors, 24 passed in 0.18s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491\n......................................................\ncollected 54 items\n\n=================================== FAILURES ===================================\n__________ TestIOStream.test_streaming_callback_with_data_in_buffer __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 160, in test_streaming_callback_with_data_in_buffer\n    self.assertEqual(data, b\"efgh\")\nAssertionError: None != b'efgh'\n\n=================================== ERRORS =====================================\n__________ TestIOStreamSSL.test_async_read_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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 439, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_buffered_data __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 314, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_callback_with_pending_read __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 398, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_delayed_close_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 285, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_inline_read_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 427, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_large_read_until __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 373, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_callback_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 213, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 336, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 230, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback_with_data_in_buffer __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 149, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 353, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_until_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 260, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_write_zero_bytes __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 167, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 483, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_async_read_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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 439, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_buffered_data __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 314, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_callback_with_pending_read __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 398, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_delayed_close_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 285, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_inline_read_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 427, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_large_read_until __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 373, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_callback_error __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 213, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 336, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 230, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback_with_data_in_buffer __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 149, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_read_until_close_after_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 353, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_until_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 260, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_write_zero_bytes __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 167, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 143, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 122, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 500, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamWebHTTPS.test_connection_closed __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 39, in test_connection_closed\n    response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 306, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, 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__________ TestIOStreamWebHTTPS.test_read_until_close __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 45, in test_read_until_close\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, 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__________ TestIOStreamWebHTTPS.test_read_zero_bytes __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 57, in test_read_zero_bytes\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, 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__________ TestIOStreamWebHTTPS.test_write_while_connecting __________\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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/r2e_tests/test_1.py\", line 99, in test_write_while_connecting\n    self.wait(lambda: connected[0] and written[0])\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 245, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/testing.py\", line 190, 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_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/stack_context.py\", line 235, in wrapped\n    callback(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 141, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/tcpserver.py\", line 209, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 274, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_4d51ee80ef0b64e31a175f7e95c9df001dfff491/tornado/netutil.py\", line 255, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::TestIOStream::test_async_read_error_logging\nPASSED r2e_tests.test_1::TestIOStream::test_close_buffered_data\nPASSED r2e_tests.test_1::TestIOStream::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStream::test_connection_refused\nPASSED r2e_tests.test_1::TestIOStream::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_gaierror\nPASSED r2e_tests.test_1::TestIOStream::test_inline_read_error\nPASSED r2e_tests.test_1::TestIOStream::test_large_read_until\nPASSED r2e_tests.test_1::TestIOStream::test_read_callback_error\nPASSED r2e_tests.test_1::TestIOStream::test_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback\nFAILED r2e_tests.test_1::TestIOStream::test_streaming_callback_with_data_in_buffer\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_until_close\nPASSED r2e_tests.test_1::TestIOStream::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSL::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSL::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSL::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_write_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_connection_closed\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_until_close\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_write_while_connecting\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_connection_closed\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_write_while_connecting\nPASSED r2e_tests.test_1::TestPipeIOStream::test_pipe_iostream\n=================== 1 failed, 30 errors, 23 passed in 0.13s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/iostream.py tornado/test/iostream_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Title:** `read_until_close` Fails to Flush Buffer, Missing Data in Streaming Callback

**Description:**
When using `read_until_close` with a streaming callback, any data remaining in the buffer after a partial read is not flushed correctly. This results in the streaming callback receiving `None` instead of the expected remaining data.

**Example Code:**
```python
server, client = self.make_iostream_pair()
client.write(b"abcd\r\nefgh")
server.read_until(b"\r\n", self.stop)
data = self.wait()
self.assertEqual(data, b"abcd\r\n")

def closed_callback(chunk):
    self.fail()
server.read_until_close(callback=closed_callback, streaming_callback=self.stop)
self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)
data = self.wait()
self.assertEqual(data, b"efgh")
server.close()
client.close()
```

In this example, after reading until `b"\r\n"`, the remaining data `b"efgh"` should be passed to the streaming callback. However, the callback receives `None` instead, causing the assertion to fail.

**Expected Behavior:**
After calling `read_until_close`, the streaming callback should receive all remaining data in the buffer (`b"efgh"` in this case) instead of `None`.

**Actual Behavior:**
The streaming callback receives `None`, indicating that the remaining buffer was not flushed properly.

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

"""Utility classes to write to and read from non-blocking files and sockets.

Contents:

* `BaseIOStream`: Generic interface for reading and writing.
* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.
* `SSLIOStream`: SSL-aware version of IOStream.
* `PipeIOStream`: Pipe-based IOStream implementation.
"""

from __future__ import absolute_import, division, print_function, with_statement

import collections
import errno
import numbers
import os
import socket
import ssl
import sys
import re

from tornado import ioloop
from tornado.log import gen_log, app_log
from tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError
from tornado import stack_context
from tornado.util import bytes_type

try:
    from tornado.platform.posix import _set_nonblocking
except ImportError:
    _set_nonblocking = None


class StreamClosedError(IOError):
    pass


class BaseIOStream(object):
    """A utility class to write to and read from a non-blocking file or socket.

    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.
    All of the methods take callbacks (since writing and reading are
    non-blocking and asynchronous).

    When a stream is closed due to an error, the IOStream's `error`
    attribute contains the exception object.

    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,
    `read_from_fd`, and optionally `get_fd_error`.
    """
    def __init__(self, io_loop=None, max_buffer_size=104857600,
                 read_chunk_size=4096):
        self.io_loop = io_loop or ioloop.IOLoop.instance()
        self.max_buffer_size = max_buffer_size
        self.read_chunk_size = read_chunk_size
        self.error = None
        self._read_buffer = collections.deque()
        self._write_buffer = collections.deque()
        self._read_buffer_size = 0
        self._write_buffer_frozen = False
        self._read_delimiter = None
        self._read_regex = None
        self._read_bytes = None
        self._read_until_close = False
        self._read_callback = None
        self._streaming_callback = None
        self._write_callback = None
        self._close_callback = None
        self._connect_callback = None
        self._connecting = False
        self._state = None
        self._pending_callbacks = 0
        self._closed = False

    def fileno(self):
        """Returns the file descriptor for this stream."""
        raise NotImplementedError()

    def close_fd(self):
        """Closes the file underlying this stream.

        ``close_fd`` is called by `BaseIOStream` and should not be called
        elsewhere; other users should call `close` instead.
        """
        raise NotImplementedError()

    def write_to_fd(self, data):
        """Attempts to write ``data`` to the underlying file.

        Returns the number of bytes written.
        """
        raise NotImplementedError()

    def read_from_fd(self):
        """Attempts to read from the underlying file.

        Returns ``None`` if there was nothing to read (the socket returned
        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,
        should return no more than ``self.read_chunk_size`` bytes at a time.
        """
        raise NotImplementedError()

    def get_fd_error(self):
        """Returns information about any error on the underlying file.

        This method is called after the IOLoop has signaled an error on the
        file descriptor, and should return an Exception (such as `socket.error`
        with additional information, or None if no such information is
        available.
        """
        return None

    def read_until_regex(self, regex, callback):
        """Call callback when we read the given regex pattern."""
        self._set_read_callback(callback)
        self._read_regex = re.compile(regex)
        self._try_inline_read()

    def read_until(self, delimiter, callback):
        """Call callback when we read the given delimiter."""
        self._set_read_callback(callback)
        self._read_delimiter = delimiter
        self._try_inline_read()

    def read_bytes(self, num_bytes, callback, streaming_callback=None):
        """Call callback when we read the given number of bytes.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.
        """
        self._set_read_callback(callback)
        assert isinstance(num_bytes, numbers.Integral)
        self._read_bytes = num_bytes
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._try_inline_read()

    def read_until_close(self, callback, streaming_callback=None):
        """Reads all data from the socket until it is closed.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.

        Subject to ``max_buffer_size`` limit from `IOStream` constructor if
        a ``streaming_callback`` is not used.
        """
        self._set_read_callback(callback)
        self._streaming_callback = stack_context.wrap(streaming_callback)
        if self.closed():
            if self._streaming_callback is not None:
                self._run_callback(self._streaming_callback,
                                   self._consume(self._read_buffer_size))
            self._run_callback(self._read_callback,
                               self._consume(self._read_buffer_size))
            self._streaming_callback = None
            self._read_callback = None
            return
        self._read_until_close = True
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._add_io_state(self.io_loop.READ)

    def write(self, data, callback=None):
        """Write the given data to this stream.

        If callback is given, we call it when all of the buffered write
        data has been successfully written to the stream. If there was
        previously buffered write data and an old write callback, that
        callback is simply overwritten with this new callback.
        """
        assert isinstance(data, bytes_type)
        self._check_closed()
        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,
        # so never put empty strings in the buffer.
        if data:
            # Break up large contiguous strings before inserting them in the
            # write buffer, so we don't have to recopy the entire thing
            # as we slice off pieces to send to the socket.
            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024
            if len(data) > WRITE_BUFFER_CHUNK_SIZE:
                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):
                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])
            else:
                self._write_buffer.append(data)
        self._write_callback = stack_context.wrap(callback)
        if not self._connecting:
            self._handle_write()
            if self._write_buffer:
                self._add_io_state(self.io_loop.WRITE)
            self._maybe_add_error_listener()

    def set_close_callback(self, callback):
        """Call the given callback when the stream is closed."""
        self._close_callback = stack_context.wrap(callback)

    def close(self, exc_info=False):
        """Close this stream.

        If ``exc_info`` is true, set the ``error`` attribute to the current
        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,
        use that instead of `sys.exc_info`).
        """
        if not self.closed():
            if exc_info:
                if not isinstance(exc_info, tuple):
                    exc_info = sys.exc_info()
                if any(exc_info):
                    self.error = exc_info[1]
            if self._read_until_close:
                callback = self._read_callback
                self._read_callback = None
                self._read_until_close = False
                self._run_callback(callback,
                                   self._consume(self._read_buffer_size))
            if self._state is not None:
                self.io_loop.remove_handler(self.fileno())
                self._state = None
            self.close_fd()
            self._closed = True
        self._maybe_run_close_callback()

    def _maybe_run_close_callback(self):
        if (self.closed() and self._close_callback and
                self._pending_callbacks == 0):
            # if there are pending callbacks, don't run the close callback
            # until they're done (see _maybe_add_error_handler)
            cb = self._close_callback
            self._close_callback = None
            self._run_callback(cb)
            # Delete any unfinished callbacks to break up reference cycles.
            self._read_callback = self._write_callback = None

    def reading(self):
        """Returns true if we are currently reading from the stream."""
        return self._read_callback is not None

    def writing(self):
        """Returns true if we are currently writing to the stream."""
        return bool(self._write_buffer)

    def closed(self):
        """Returns true if the stream has been closed."""
        return self._closed

    def _handle_events(self, fd, events):
        if self.closed():
            gen_log.warning("Got events for closed stream %d", fd)
            return
        try:
            if events & self.io_loop.READ:
                self._handle_read()
            if self.closed():
                return
            if events & self.io_loop.WRITE:
                if self._connecting:
                    self._handle_connect()
                self._handle_write()
            if self.closed():
                return
            if events & self.io_loop.ERROR:
                self.error = self.get_fd_error()
                # We may have queued up a user callback in _handle_read or
                # _handle_write, so don't close the IOStream until those
                # callbacks have had a chance to run.
                self.io_loop.add_callback(self.close)
                return
            state = self.io_loop.ERROR
            if self.reading():
                state |= self.io_loop.READ
            if self.writing():
                state |= self.io_loop.WRITE
            if state == self.io_loop.ERROR:
                state |= self.io_loop.READ
            if state != self._state:
                assert self._state is not None, \
                    "shouldn't happen: _handle_events without self._state"
                self._state = state
                self.io_loop.update_handler(self.fileno(), self._state)
        except Exception:
            gen_log.error("Uncaught exception, closing connection.",
                          exc_info=True)
            self.close(exc_info=True)
            raise

    def _run_callback(self, callback, *args):
        def wrapper():
            self._pending_callbacks -= 1
            try:
                callback(*args)
            except Exception:
                app_log.error("Uncaught exception, closing connection.",
                              exc_info=True)
                # Close the socket on an uncaught exception from a user callback
                # (It would eventually get closed when the socket object is
                # gc'd, but we don't want to rely on gc happening before we
                # run out of file descriptors)
                self.close(exc_info=True)
                # Re-raise the exception so that IOLoop.handle_callback_exception
                # can see it and log the error
                raise
            self._maybe_add_error_listener()
        # We schedule callbacks to be run on the next IOLoop iteration
        # rather than running them directly for several reasons:
        # * Prevents unbounded stack growth when a callback calls an
        #   IOLoop operation that immediately runs another callback
        # * Provides a predictable execution context for e.g.
        #   non-reentrant mutexes
        # * Ensures that the try/except in wrapper() is run outside
        #   of the application's StackContexts
        with stack_context.NullContext():
            # stack_context was already captured in callback, we don't need to
            # capture it again for IOStream's wrapper.  This is especially
            # important if the callback was pre-wrapped before entry to
            # IOStream (as in HTTPConnection._header_callback), as we could
            # capture and leak the wrong context here.
            self._pending_callbacks += 1
            self.io_loop.add_callback(wrapper)

    def _handle_read(self):
        try:
            try:
                # Pretend to have a pending callback so that an EOF in
                # _read_to_buffer doesn't trigger an immediate close
                # callback.  At the end of this method we'll either
                # estabilsh a real pending callback via
                # _read_from_buffer or run the close callback.
                #
                # We need two try statements here so that
                # pending_callbacks is decremented before the `except`
                # clause below (which calls `close` and does need to
                # trigger the callback)
                self._pending_callbacks += 1
                while not self.closed():
                    # Read from the socket until we get EWOULDBLOCK or equivalent.
                    # SSL sockets do some internal buffering, and if the data is
                    # sitting in the SSL object's buffer select() and friends
                    # can't see it; the only way to find out if it's there is to
                    # try to read it.
                    if self._read_to_buffer() == 0:
                        break
            finally:
                self._pending_callbacks -= 1
        except Exception:
            gen_log.warning("error on read", exc_info=True)
            self.close(exc_info=True)
            return
        if self._read_from_buffer():
            return
        else:
            self._maybe_run_close_callback()

    def _set_read_callback(self, callback):
        assert not self._read_callback, "Already reading"
        self._read_callback = stack_context.wrap(callback)

    def _try_inline_read(self):
        """Attempt to complete the current read operation from buffered data.

        If the read can be completed without blocking, schedules the
        read callback on the next IOLoop iteration; otherwise starts
        listening for reads on the socket.
        """
        # See if we've already got the data from a previous read
        if self._read_from_buffer():
            return
        self._check_closed()
        try:
            # See comments in _handle_read about incrementing _pending_callbacks
            self._pending_callbacks += 1
            while not self.closed():
                if self._read_to_buffer() == 0:
                    break
        finally:
            self._pending_callbacks -= 1
        if self._read_from_buffer():
            return
        self._maybe_add_error_listener()

    def _read_to_buffer(self):
        """Reads from the socket and appends the result to the read buffer.

        Returns the number of bytes read.  Returns 0 if there is nothing
        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On
        error closes the socket and raises an exception.
        """
        try:
            chunk = self.read_from_fd()
        except (socket.error, IOError, OSError) as e:
            # ssl.SSLError is a subclass of socket.error
            if e.args[0] == errno.ECONNRESET:
                # Treat ECONNRESET as a connection close rather than
                # an error to minimize log spam  (the exception will
                # be available on self.error for apps that care).
                self.close(exc_info=True)
                return
            self.close(exc_info=True)
            raise
        if chunk is None:
            return 0
        self._read_buffer.append(chunk)
        self._read_buffer_size += len(chunk)
        if self._read_buffer_size >= self.max_buffer_size:
            gen_log.error("Reached maximum read buffer size")
            self.close()
            raise IOError("Reached maximum read buffer size")
        return len(chunk)

    def _read_from_buffer(self):
        """Attempts to complete the currently-pending read from the buffer.

        Returns True if the read was completed.
        """
        if self._streaming_callback is not None and self._read_buffer_size:
            bytes_to_consume = self._read_buffer_size
            if self._read_bytes is not None:
                bytes_to_consume = min(self._read_bytes, bytes_to_consume)
                self._read_bytes -= bytes_to_consume
            self._run_callback(self._streaming_callback,
                               self._consume(bytes_to_consume))
        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:
            num_bytes = self._read_bytes
            callback = self._read_callback
            self._read_callback = None
            self._streaming_callback = None
            self._read_bytes = None
            self._run_callback(callback, self._consume(num_bytes))
            return True
        elif self._read_delimiter is not None:
            # Multi-byte delimiters (e.g. '\r\n') may straddle two
            # chunks in the read buffer, so we can't easily find them
            # without collapsing the buffer.  However, since protocols
            # using delimited reads (as opposed to reads of a known
            # length) tend to be "line" oriented, the delimiter is likely
            # to be in the first few chunks.  Merge the buffer gradually
            # since large merges are relatively expensive and get undone in
            # consume().
            if self._read_buffer:
                while True:
                    loc = self._read_buffer[0].find(self._read_delimiter)
                    if loc != -1:
                        callback = self._read_callback
                        delimiter_len = len(self._read_delimiter)
                        self._read_callback = None
                        self._streaming_callback = None
                        self._read_delimiter = None
                        self._run_callback(callback,
                                           self._consume(loc + delimiter_len))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        elif self._read_regex is not None:
            if self._read_buffer:
                while True:
                    m = self._read_regex.search(self._read_buffer[0])
                    if m is not None:
                        callback = self._read_callback
                        self._read_callback = None
                        self._streaming_callback = None
                        self._read_regex = None
                        self._run_callback(callback, self._consume(m.end()))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        return False

    def _handle_write(self):
        while self._write_buffer:
            try:
                if not self._write_buffer_frozen:
                    # On windows, socket.send blows up if given a
                    # write buffer that's too large, instead of just
                    # returning the number of bytes it was able to
                    # process.  Therefore we must not call socket.send
                    # with more than 128KB at a time.
                    _merge_prefix(self._write_buffer, 128 * 1024)
                num_bytes = self.write_to_fd(self._write_buffer[0])
                if num_bytes == 0:
                    # With OpenSSL, if we couldn't write the entire buffer,
                    # the very same string object must be used on the
                    # next call to send.  Therefore we suppress
                    # merging the write buffer after an incomplete send.
                    # A cleaner solution would be to set
                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is
                    # not yet accessible from python
                    # (http://bugs.python.org/issue8240)
                    self._write_buffer_frozen = True
                    break
                self._write_buffer_frozen = False
                _merge_prefix(self._write_buffer, num_bytes)
                self._write_buffer.popleft()
            except socket.error as e:
                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                    self._write_buffer_frozen = True
                    break
                else:
                    gen_log.warning("Write error on %d: %s",
                                    self.fileno(), e)
                    self.close(exc_info=True)
                    return
        if not self._write_buffer and self._write_callback:
            callback = self._write_callback
            self._write_callback = None
            self._run_callback(callback)

    def _consume(self, loc):
        if loc == 0:
            return b""
        _merge_prefix(self._read_buffer, loc)
        self._read_buffer_size -= loc
        return self._read_buffer.popleft()

    def _check_closed(self):
        if self.closed():
            raise StreamClosedError("Stream is closed")

    def _maybe_add_error_listener(self):
        if self._state is None and self._pending_callbacks == 0:
            if self.closed():
                self._maybe_run_close_callback()
            else:
                self._add_io_state(ioloop.IOLoop.READ)

    def _add_io_state(self, state):
        """Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.

        Implementation notes: Reads and writes have a fast path and a
        slow path.  The fast path reads synchronously from socket
        buffers, while the slow path uses `_add_io_state` to schedule
        an IOLoop callback.  Note that in both cases, the callback is
        run asynchronously with `_run_callback`.

        To detect closed connections, we must have called
        `_add_io_state` at some point, but we want to delay this as
        much as possible so we don't have to set an `IOLoop.ERROR`
        listener that will be overwritten by the next slow-path
        operation.  As long as there are callbacks scheduled for
        fast-path ops, those callbacks may do more reads.
        If a sequence of fast-path ops do not end in a slow-path op,
        (e.g. for an @asynchronous long-poll request), we must add
        the error handler.  This is done in `_run_callback` and `write`
        (since the write callback is optional so we can have a
        fast-path write with no `_run_callback`)
        """
        if self.closed():
            # connection has been closed, so there can be no future events
            return
        if self._state is None:
            self._state = ioloop.IOLoop.ERROR | state
            with stack_context.NullContext():
                self.io_loop.add_handler(
                    self.fileno(), self._handle_events, self._state)
        elif not self._state & state:
            self._state = self._state | state
            self.io_loop.update_handler(self.fileno(), self._state)


class IOStream(BaseIOStream):
    r"""Socket-based IOStream implementation.

    This class supports the read and write methods from `BaseIOStream`
    plus a `connect` method.

    The socket parameter may either be connected or unconnected.  For
    server operations the socket is the result of calling socket.accept().
    For client operations the socket is created with socket.socket(),
    and may either be connected before passing it to the IOStream or
    connected with IOStream.connect.

    A very simple (and broken) HTTP client using this class::

        from tornado import ioloop
        from tornado import iostream
        import socket

        def send_request():
            stream.write("GET / HTTP/1.0\r\nHost: friendfeed.com\r\n\r\n")
            stream.read_until("\r\n\r\n", on_headers)

        def on_headers(data):
            headers = {}
            for line in data.split("\r\n"):
               parts = line.split(":")
               if len(parts) == 2:
                   headers[parts[0].strip()] = parts[1].strip()
            stream.read_bytes(int(headers["Content-Length"]), on_body)

        def on_body(data):
            print data
            stream.close()
            ioloop.IOLoop.instance().stop()

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        stream = iostream.IOStream(s)
        stream.connect(("friendfeed.com", 80), send_request)
        ioloop.IOLoop.instance().start()
    """
    def __init__(self, socket, *args, **kwargs):
        self.socket = socket
        self.socket.setblocking(False)
        super(IOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.socket.fileno()

    def close_fd(self):
        self.socket.close()
        self.socket = None

    def get_fd_error(self):
        errno = self.socket.getsockopt(socket.SOL_SOCKET,
                                       socket.SO_ERROR)
        return socket.error(errno, os.strerror(errno))

    def read_from_fd(self):
        try:
            chunk = self.socket.recv(self.read_chunk_size)
        except socket.error as e:
            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk

    def write_to_fd(self, data):
        return self.socket.send(data)

    def connect(self, address, callback=None, server_hostname=None):
        """Connects the socket to a remote address without blocking.

        May only be called if the socket passed to the constructor was
        not previously connected.  The address parameter is in the
        same format as for socket.connect, i.e. a (host, port) tuple.
        If callback is specified, it will be called when the
        connection is completed.

        If specified, the ``server_hostname`` parameter will be used
        in SSL connections for certificate validation (if requested in
        the ``ssl_options``) and SNI (if supported; requires
        Python 3.2+).

        Note that it is safe to call IOStream.write while the
        connection is pending, in which case the data will be written
        as soon as the connection is ready.  Calling IOStream read
        methods before the socket is connected works on some platforms
        but is non-portable.
        """
        self._connecting = True
        try:
            self.socket.connect(address)
        except socket.error as e:
            # In non-blocking mode we expect connect() to raise an
            # exception with EINPROGRESS or EWOULDBLOCK.
            #
            # On freebsd, other errors such as ECONNREFUSED may be
            # returned immediately when attempting to connect to
            # localhost, so handle them the same way as an error
            # reported later in _handle_connect.
            if e.args[0] not in (errno.EINPROGRESS, errno.EWOULDBLOCK):
                gen_log.warning("Connect error on fd %d: %s",
                                self.socket.fileno(), e)
                self.close(exc_info=True)
                return
        self._connect_callback = stack_context.wrap(callback)
        self._add_io_state(self.io_loop.WRITE)

    def _handle_connect(self):
        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
        if err != 0:
            self.error = socket.error(err, os.strerror(err))
            # IOLoop implementations may vary: some of them return
            # an error state before the socket becomes writable, so
            # in that case a connection failure would be handled by the
            # error path in _handle_events instead of here.
            gen_log.warning("Connect error on fd %d: %s",
                            self.socket.fileno(), errno.errorcode[err])
            self.close()
            return
        if self._connect_callback is not None:
            callback = self._connect_callback
            self._connect_callback = None
            self._run_callback(callback)
        self._connecting = False


class SSLIOStream(IOStream):
    """A utility class to write to and read from a non-blocking SSL socket.

    If the socket passed to the constructor is already connected,
    it should be wrapped with::

        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)

    before constructing the SSLIOStream.  Unconnected sockets will be
    wrapped when IOStream.connect is finished.
    """
    def __init__(self, *args, **kwargs):
        """Creates an SSLIOStream.

        The ``ssl_options`` keyword argument may either be a dictionary
        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`
        object.
        """
        self._ssl_options = kwargs.pop('ssl_options', {})
        super(SSLIOStream, self).__init__(*args, **kwargs)
        self._ssl_accepting = True
        self._handshake_reading = False
        self._handshake_writing = False
        self._ssl_connect_callback = None
        self._server_hostname = None

    def reading(self):
        return self._handshake_reading or super(SSLIOStream, self).reading()

    def writing(self):
        return self._handshake_writing or super(SSLIOStream, self).writing()

    def _do_ssl_handshake(self):
        # Based on code from test_ssl.py in the python stdlib
        try:
            self._handshake_reading = False
            self._handshake_writing = False
            self.socket.do_handshake()
        except ssl.SSLError as err:
            if err.args[0] == ssl.SSL_ERROR_WANT_READ:
                self._handshake_reading = True
                return
            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                self._handshake_writing = True
                return
            elif err.args[0] in (ssl.SSL_ERROR_EOF,
                                 ssl.SSL_ERROR_ZERO_RETURN):
                return self.close(exc_info=True)
            elif err.args[0] == ssl.SSL_ERROR_SSL:
                try:
                    peer = self.socket.getpeername()
                except:
                    peer = '(not connected)'
                gen_log.warning("SSL Error on %d %s: %s",
                                self.socket.fileno(), peer, err)
                return self.close(exc_info=True)
            raise
        except socket.error as err:
            if err.args[0] in (errno.ECONNABORTED, errno.ECONNRESET):
                return self.close(exc_info=True)
        else:
            self._ssl_accepting = False
            if not self._verify_cert(self.socket.getpeercert()):
                self.close()
                return
            if self._ssl_connect_callback is not None:
                callback = self._ssl_connect_callback
                self._ssl_connect_callback = None
                self._run_callback(callback)

    def _verify_cert(self, peercert):
        """Returns True if peercert is valid according to the configured
        validation mode and hostname.

        The ssl handshake already tested the certificate for a valid
        CA signature; the only thing that remains is to check
        the hostname.
        """
        if isinstance(self._ssl_options, dict):
            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)
        elif isinstance(self._ssl_options, ssl.SSLContext):
            verify_mode = self._ssl_options.verify_mode
        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)
        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:
            return True
        cert = self.socket.getpeercert()
        if cert is None and verify_mode == ssl.CERT_REQUIRED:
            gen_log.warning("No SSL certificate given")
            return False
        try:
            ssl_match_hostname(peercert, self._server_hostname)
        except SSLCertificateError:
            gen_log.warning("Invalid SSL certificate", exc_info=True)
            return False
        else:
            return True

    def _handle_read(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_read()

    def _handle_write(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_write()

    def connect(self, address, callback=None, server_hostname=None):
        # Save the user's callback and run it after the ssl handshake
        # has completed.
        self._ssl_connect_callback = callback
        self._server_hostname = server_hostname
        super(SSLIOStream, self).connect(address, callback=None)

    def _handle_connect(self):
        # When the connection is complete, wrap the socket for SSL
        # traffic.  Note that we do this by overriding _handle_connect
        # instead of by passing a callback to super().connect because
        # user callbacks are enqueued asynchronously on the IOLoop,
        # but since _handle_events calls _handle_connect immediately
        # followed by _handle_write we need this to be synchronous.
        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                      server_hostname=self._server_hostname,
                                      do_handshake_on_connect=False)
        super(SSLIOStream, self)._handle_connect()

    def read_from_fd(self):
        if self._ssl_accepting:
            # If the handshake hasn't finished yet, there can't be anything
            # to read (attempting to read may or may not raise an exception
            # depending on the SSL version)
            return None
        try:
            # SSLSocket objects have both a read() and recv() method,
            # while regular sockets only have recv().
            # The recv() method blocks (at least in python 2.6) if it is
            # called when there is nothing to read, so we have to use
            # read() instead.
            chunk = self.socket.read(self.read_chunk_size)
        except ssl.SSLError as e:
            # SSLError is a subclass of socket.error, so this except
            # block must come first.
            if e.args[0] == ssl.SSL_ERROR_WANT_READ:
                return None
            else:
                raise
        except socket.error as e:
            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


class PipeIOStream(BaseIOStream):
    """Pipe-based IOStream implementation.

    The constructor takes an integer file descriptor (such as one returned
    by `os.pipe`) rather than an open file object.
    """
    def __init__(self, fd, *args, **kwargs):
        self.fd = fd
        _set_nonblocking(fd)
        super(PipeIOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.fd

    def close_fd(self):
        os.close(self.fd)

    def write_to_fd(self, data):
        return os.write(self.fd, data)

    def read_from_fd(self):
        try:
            chunk = os.read(self.fd, self.read_chunk_size)
        except (IOError, OSError) as e:
            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                return None
            elif e.args[0] == errno.EBADF:
                # If the writing half of a pipe is closed, select will
                # report it as readable but reads will fail with EBADF.
                self.close(exc_info=True)
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


def _double_prefix(deque):
    """Grow by doubling, but don't split the second chunk just because the
    first one is small.
    """
    new_len = max(len(deque[0]) * 2,
                  (len(deque[0]) + len(deque[1])))
    _merge_prefix(deque, new_len)


def _merge_prefix(deque, size):
    """Replace the first entries in a deque of strings with a single
    string of up to size bytes.

    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])
    >>> _merge_prefix(d, 5); print(d)
    deque(['abcde', 'fghi', 'j'])

    Strings will be split as necessary to reach the desired size.
    >>> _merge_prefix(d, 7); print(d)
    deque(['abcdefg', 'hi', 'j'])

    >>> _merge_prefix(d, 3); print(d)
    deque(['abc', 'defg', 'hi', 'j'])

    >>> _merge_prefix(d, 100); print(d)
    deque(['abcdefghij'])
    """
    if len(deque) == 1 and len(deque[0]) <= size:
        return
    prefix = []
    remaining = size
    while deque and remaining > 0:
        chunk = deque.popleft()
        if len(chunk) > remaining:
            deque.appendleft(chunk[remaining:])
            chunk = chunk[:remaining]
        prefix.append(chunk)
        remaining -= len(chunk)
    # This data structure normally just contains byte strings, but
    # the unittest gets messy if it doesn't use the default str() type,
    # so do the merge based on the type of data that's actually present.
    if prefix:
        deque.appendleft(type(prefix[0])().join(prefix))
    if not deque:
        deque.appendleft(b"")


def doctests():
    import doctest
    return doctest.DocTestSuite()

```
--- 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:** `read_until_close` Fails to Flush Buffer, Missing Data in Streaming Callback

**Description:**
When using `read_until_close` with a streaming callback, any data remaining in the buffer after a partial read is not flushed correctly. This results in the streaming callback receiving `None` instead of the expected remaining data.

**Example Code:**
```python
server, client = self.make_iostream_pair()
client.write(b"abcd\r\nefgh")
server.read_until(b"\r\n", self.stop)
data = self.wait()
self.assertEqual(data, b"abcd\r\n")

def closed_callback(chunk):
    self.fail()
server.read_until_close(callback=closed_callback, streaming_callback=self.stop)
self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)
data = self.wait()
self.assertEqual(data, b"efgh")
server.close()
client.close()
```

In this example, after reading until `b"\r\n"`, the remaining data `b"efgh"` should be passed to the streaming callback. However, the callback receives `None` instead, causing the assertion to fail.

**Expected Behavior:**
After calling `read_until_close`, the streaming callback should receive all remaining data in the buffer (`b"efgh"` in this case) instead of `None`.

**Actual Behavior:**
The streaming callback receives `None`, indicating that the remaining buffer was not flushed properly.

[/ISSUE]
{
    "TestIOStream.test_async_read_error_logging": "PASSED",
    "TestIOStream.test_close_buffered_data": "PASSED",
    "TestIOStream.test_close_callback_with_pending_read": "PASSED",
    "TestIOStream.test_connection_refused": "PASSED",
    "TestIOStream.test_delayed_close_callback": "PASSED",
    "TestIOStream.test_gaierror": "PASSED",
    "TestIOStream.test_inline_read_error": "PASSED",
    "TestIOStream.test_large_read_until": "PASSED",
    "TestIOStream.test_read_callback_error": "PASSED",
    "TestIOStream.test_read_until_close_after_close": "PASSED",
    "TestIOStream.test_streaming_callback": "PASSED",
    "TestIOStream.test_streaming_callback_with_data_in_buffer": "PASSED",
    "TestIOStream.test_streaming_read_until_close_after_close": "PASSED",
    "TestIOStream.test_streaming_until_close": "PASSED",
    "TestIOStream.test_write_zero_bytes": "PASSED",
    "TestIOStreamSSL.test_async_read_error_logging": "ERROR",
    "TestIOStreamSSL.test_close_buffered_data": "ERROR",
    "TestIOStreamSSL.test_close_callback_with_pending_read": "ERROR",
    "TestIOStreamSSL.test_connection_refused": "PASSED",
    "TestIOStreamSSL.test_delayed_close_callback": "ERROR",
    "TestIOStreamSSL.test_gaierror": "PASSED",
    "TestIOStreamSSL.test_inline_read_error": "ERROR",
    "TestIOStreamSSL.test_large_read_until": "ERROR",
    "TestIOStreamSSL.test_read_callback_error": "ERROR",
    "TestIOStreamSSL.test_read_until_close_after_close": "ERROR",
    "TestIOStreamSSL.test_streaming_callback": "ERROR",
    "TestIOStreamSSL.test_streaming_callback_with_data_in_buffer": "ERROR",
    "TestIOStreamSSL.test_streaming_read_until_close_after_close": "ERROR",
    "TestIOStreamSSL.test_streaming_until_close": "ERROR",
    "TestIOStreamSSL.test_write_zero_bytes": "ERROR",
    "TestIOStreamSSLContext.test_async_read_error_logging": "ERROR",
    "TestIOStreamSSLContext.test_close_buffered_data": "ERROR",
    "TestIOStreamSSLContext.test_close_callback_with_pending_read": "ERROR",
    "TestIOStreamSSLContext.test_connection_refused": "PASSED",
    "TestIOStreamSSLContext.test_delayed_close_callback": "ERROR",
    "TestIOStreamSSLContext.test_gaierror": "PASSED",
    "TestIOStreamSSLContext.test_inline_read_error": "ERROR",
    "TestIOStreamSSLContext.test_large_read_until": "ERROR",
    "TestIOStreamSSLContext.test_read_callback_error": "ERROR",
    "TestIOStreamSSLContext.test_read_until_close_after_close": "ERROR",
    "TestIOStreamSSLContext.test_streaming_callback": "ERROR",
    "TestIOStreamSSLContext.test_streaming_callback_with_data_in_buffer": "ERROR",
    "TestIOStreamSSLContext.test_streaming_read_until_close_after_close": "ERROR",
    "TestIOStreamSSLContext.test_streaming_until_close": "ERROR",
    "TestIOStreamSSLContext.test_write_zero_bytes": "ERROR",
    "TestIOStreamWebHTTP.test_connection_closed": "PASSED",
    "TestIOStreamWebHTTP.test_read_until_close": "PASSED",
    "TestIOStreamWebHTTP.test_read_zero_bytes": "PASSED",
    "TestIOStreamWebHTTP.test_write_while_connecting": "PASSED",
    "TestIOStreamWebHTTPS.test_connection_closed": "ERROR",
    "TestIOStreamWebHTTPS.test_read_until_close": "ERROR",
    "TestIOStreamWebHTTPS.test_read_zero_bytes": "ERROR",
    "TestIOStreamWebHTTPS.test_write_while_connecting": "ERROR",
    "TestPipeIOStream.test_pipe_iostream": "PASSED"
}
diff --git a/tornado/iostream.py b/tornado/iostream.py
index 86cd68a8..9d9fb715 100644
--- a/tornado/iostream.py
+++ b/tornado/iostream.py
@@ -174,6 +174,7 @@ class BaseIOStream(object):
             return
         self._read_until_close = True
         self._streaming_callback = stack_context.wrap(streaming_callback)
+        self._read_from_buffer()
         self._add_io_state(self.io_loop.READ)
 
     def write(self, data, callback=None):

{"tornado/iostream.py": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"Utility classes to write to and read from non-blocking files and sockets.\n\nContents:\n\n* `BaseIOStream`: Generic interface for reading and writing.\n* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.\n* `SSLIOStream`: SSL-aware version of IOStream.\n* `PipeIOStream`: Pipe-based IOStream implementation.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nimport errno\nimport numbers\nimport os\nimport socket\nimport ssl\nimport sys\nimport re\n\nfrom tornado import ioloop\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    from tornado.platform.posix import _set_nonblocking\nexcept ImportError:\n    _set_nonblocking = None\n\n\nclass StreamClosedError(IOError):\n    pass\n\n\nclass BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's `error`\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=104857600,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.instance()\n        self.max_buffer_size = max_buffer_size\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket returned\n        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,\n        should return no more than ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the IOLoop has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback):\n        \"\"\"Call callback when we read the given regex pattern.\"\"\"\n        self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n\n    def read_until(self, delimiter, callback):\n        \"\"\"Call callback when we read the given delimiter.\"\"\"\n        self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n\n    def read_bytes(self, num_bytes, callback, streaming_callback=None):\n        \"\"\"Call callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n        \"\"\"\n        self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n\n    def read_until_close(self, callback, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_callback(self._read_callback,\n                               self._consume(self._read_buffer_size))\n            self._streaming_callback = None\n            self._read_callback = None\n            return\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._add_io_state(self.io_loop.READ)\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If callback is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            if len(data) > WRITE_BUFFER_CHUNK_SIZE:\n                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n            else:\n                self._write_buffer.append(data)\n        self._write_callback = stack_context.wrap(callback)\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                callback = self._read_callback\n                self._read_callback = None\n                self._read_until_close = False\n                self._run_callback(callback,\n                                   self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        if (self.closed() and self._close_callback and\n                self._pending_callbacks == 0):\n            # if there are pending callbacks, don't run the close callback\n            # until they're done (see _maybe_add_error_handler)\n            cb = self._close_callback\n            self._close_callback = None\n            self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %d\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert not self._read_callback, \"Already reading\"\n        self._read_callback = stack_context.wrap(callback)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            # See comments in _handle_read about incrementing _pending_callbacks\n            self._pending_callbacks += 1\n            while not self.closed():\n                if self._read_to_buffer() == 0:\n                    break\n        finally:\n            self._pending_callbacks -= 1\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] == errno.ECONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            callback = self._read_callback\n            self._read_callback = None\n            self._streaming_callback = None\n            self._read_bytes = None\n            self._run_callback(callback, self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        callback = self._read_callback\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_delimiter = None\n                        self._run_callback(callback,\n                                           self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        callback = self._read_callback\n                        self._read_callback = None\n                        self._streaming_callback = None\n                        self._read_regex = None\n                        self._run_callback(callback, self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except socket.error as e:\n                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    gen_log.warning(\"Write error on %d: %s\",\n                                    self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer and self._write_callback:\n            callback = self._write_callback\n            self._write_callback = None\n            self._run_callback(callback)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)\n\n\nclass IOStream(BaseIOStream):\n    r\"\"\"Socket-based IOStream implementation.\n\n    This class supports the read and write methods from `BaseIOStream`\n    plus a `connect` method.\n\n    The socket parameter may either be connected or unconnected.  For\n    server operations the socket is the result of calling socket.accept().\n    For client operations the socket is created with socket.socket(),\n    and may either be connected before passing it to the IOStream or\n    connected with IOStream.connect.\n\n    A very simple (and broken) HTTP client using this class::\n\n        from tornado import ioloop\n        from tornado import iostream\n        import socket\n\n        def send_request():\n            stream.write(\"GET / HTTP/1.0\\r\\nHost: friendfeed.com\\r\\n\\r\\n\")\n            stream.read_until(\"\\r\\n\\r\\n\", on_headers)\n\n        def on_headers(data):\n            headers = {}\n            for line in data.split(\"\\r\\n\"):\n               parts = line.split(\":\")\n               if len(parts) == 2:\n                   headers[parts[0].strip()] = parts[1].strip()\n            stream.read_bytes(int(headers[\"Content-Length\"]), on_body)\n\n        def on_body(data):\n            print data\n            stream.close()\n            ioloop.IOLoop.instance().stop()\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = iostream.IOStream(s)\n        stream.connect((\"friendfeed.com\", 80), send_request)\n        ioloop.IOLoop.instance().start()\n    \"\"\"\n    def __init__(self, socket, *args, **kwargs):\n        self.socket = socket\n        self.socket.setblocking(False)\n        super(IOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    def close_fd(self):\n        self.socket.close()\n        self.socket = None\n\n    def get_fd_error(self):\n        errno = self.socket.getsockopt(socket.SOL_SOCKET,\n                                       socket.SO_ERROR)\n        return socket.error(errno, os.strerror(errno))\n\n    def read_from_fd(self):\n        try:\n            chunk = self.socket.recv(self.read_chunk_size)\n        except socket.error as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n    def write_to_fd(self, data):\n        return self.socket.send(data)\n\n    def connect(self, address, callback=None, server_hostname=None):\n        \"\"\"Connects the socket to a remote address without blocking.\n\n        May only be called if the socket passed to the constructor was\n        not previously connected.  The address parameter is in the\n        same format as for socket.connect, i.e. a (host, port) tuple.\n        If callback is specified, it will be called when the\n        connection is completed.\n\n        If specified, the ``server_hostname`` parameter will be used\n        in SSL connections for certificate validation (if requested in\n        the ``ssl_options``) and SNI (if supported; requires\n        Python 3.2+).\n\n        Note that it is safe to call IOStream.write while the\n        connection is pending, in which case the data will be written\n        as soon as the connection is ready.  Calling IOStream read\n        methods before the socket is connected works on some platforms\n        but is non-portable.\n        \"\"\"\n        self._connecting = True\n        try:\n            self.socket.connect(address)\n        except socket.error as e:\n            # In non-blocking mode we expect connect() to raise an\n            # exception with EINPROGRESS or EWOULDBLOCK.\n            #\n            # On freebsd, other errors such as ECONNREFUSED may be\n            # returned immediately when attempting to connect to\n            # localhost, so handle them the same way as an error\n            # reported later in _handle_connect.\n            if e.args[0] not in (errno.EINPROGRESS, errno.EWOULDBLOCK):\n                gen_log.warning(\"Connect error on fd %d: %s\",\n                                self.socket.fileno(), e)\n                self.close(exc_info=True)\n                return\n        self._connect_callback = stack_context.wrap(callback)\n        self._add_io_state(self.io_loop.WRITE)\n\n    def _handle_connect(self):\n        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)\n        if err != 0:\n            self.error = socket.error(err, os.strerror(err))\n            # IOLoop implementations may vary: some of them return\n            # an error state before the socket becomes writable, so\n            # in that case a connection failure would be handled by the\n            # error path in _handle_events instead of here.\n            gen_log.warning(\"Connect error on fd %d: %s\",\n                            self.socket.fileno(), errno.errorcode[err])\n            self.close()\n            return\n        if self._connect_callback is not None:\n            callback = self._connect_callback\n            self._connect_callback = None\n            self._run_callback(callback)\n        self._connecting = False\n\n\nclass SSLIOStream(IOStream):\n    \"\"\"A utility class to write to and read from a non-blocking SSL socket.\n\n    If the socket passed to the constructor is already connected,\n    it should be wrapped with::\n\n        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)\n\n    before constructing the SSLIOStream.  Unconnected sockets will be\n    wrapped when IOStream.connect is finished.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        \"\"\"Creates an SSLIOStream.\n\n        The ``ssl_options`` keyword argument may either be a dictionary\n        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`\n        object.\n        \"\"\"\n        self._ssl_options = kwargs.pop('ssl_options', {})\n        super(SSLIOStream, self).__init__(*args, **kwargs)\n        self._ssl_accepting = True\n        self._handshake_reading = False\n        self._handshake_writing = False\n        self._ssl_connect_callback = None\n        self._server_hostname = None\n\n    def reading(self):\n        return self._handshake_reading or super(SSLIOStream, self).reading()\n\n    def writing(self):\n        return self._handshake_writing or super(SSLIOStream, self).writing()\n\n    def _do_ssl_handshake(self):\n        # Based on code from test_ssl.py in the python stdlib\n        try:\n            self._handshake_reading = False\n            self._handshake_writing = False\n            self.socket.do_handshake()\n        except ssl.SSLError as err:\n            if err.args[0] == ssl.SSL_ERROR_WANT_READ:\n                self._handshake_reading = True\n                return\n            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:\n                self._handshake_writing = True\n                return\n            elif err.args[0] in (ssl.SSL_ERROR_EOF,\n                                 ssl.SSL_ERROR_ZERO_RETURN):\n                return self.close(exc_info=True)\n            elif err.args[0] == ssl.SSL_ERROR_SSL:\n                try:\n                    peer = self.socket.getpeername()\n                except:\n                    peer = '(not connected)'\n                gen_log.warning(\"SSL Error on %d %s: %s\",\n                                self.socket.fileno(), peer, err)\n                return self.close(exc_info=True)\n            raise\n        except socket.error as err:\n            if err.args[0] in (errno.ECONNABORTED, errno.ECONNRESET):\n                return self.close(exc_info=True)\n        else:\n            self._ssl_accepting = False\n            if not self._verify_cert(self.socket.getpeercert()):\n                self.close()\n                return\n            if self._ssl_connect_callback is not None:\n                callback = self._ssl_connect_callback\n                self._ssl_connect_callback = None\n                self._run_callback(callback)\n\n    def _verify_cert(self, peercert):\n        \"\"\"Returns True if peercert is valid according to the configured\n        validation mode and hostname.\n\n        The ssl handshake already tested the certificate for a valid\n        CA signature; the only thing that remains is to check\n        the hostname.\n        \"\"\"\n        if isinstance(self._ssl_options, dict):\n            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)\n        elif isinstance(self._ssl_options, ssl.SSLContext):\n            verify_mode = self._ssl_options.verify_mode\n        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)\n        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:\n            return True\n        cert = self.socket.getpeercert()\n        if cert is None and verify_mode == ssl.CERT_REQUIRED:\n            gen_log.warning(\"No SSL certificate given\")\n            return False\n        try:\n            ssl_match_hostname(peercert, self._server_hostname)\n        except SSLCertificateError:\n            gen_log.warning(\"Invalid SSL certificate\", exc_info=True)\n            return False\n        else:\n            return True\n\n    def _handle_read(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_read()\n\n    def _handle_write(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_write()\n\n    def connect(self, address, callback=None, server_hostname=None):\n        # Save the user's callback and run it after the ssl handshake\n        # has completed.\n        self._ssl_connect_callback = callback\n        self._server_hostname = server_hostname\n        super(SSLIOStream, self).connect(address, callback=None)\n\n    def _handle_connect(self):\n        # When the connection is complete, wrap the socket for SSL\n        # traffic.  Note that we do this by overriding _handle_connect\n        # instead of by passing a callback to super().connect because\n        # user callbacks are enqueued asynchronously on the IOLoop,\n        # but since _handle_events calls _handle_connect immediately\n        # followed by _handle_write we need this to be synchronous.\n        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,\n                                      server_hostname=self._server_hostname,\n                                      do_handshake_on_connect=False)\n        super(SSLIOStream, self)._handle_connect()\n\n    def read_from_fd(self):\n        if self._ssl_accepting:\n            # If the handshake hasn't finished yet, there can't be anything\n            # to read (attempting to read may or may not raise an exception\n            # depending on the SSL version)\n            return None\n        try:\n            # SSLSocket objects have both a read() and recv() method,\n            # while regular sockets only have recv().\n            # The recv() method blocks (at least in python 2.6) if it is\n            # called when there is nothing to read, so we have to use\n            # read() instead.\n            chunk = self.socket.read(self.read_chunk_size)\n        except ssl.SSLError as e:\n            # SSLError is a subclass of socket.error, so this except\n            # block must come first.\n            if e.args[0] == ssl.SSL_ERROR_WANT_READ:\n                return None\n            else:\n                raise\n        except socket.error as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\nclass PipeIOStream(BaseIOStream):\n    \"\"\"Pipe-based IOStream implementation.\n\n    The constructor takes an integer file descriptor (such as one returned\n    by `os.pipe`) rather than an open file object.\n    \"\"\"\n    def __init__(self, fd, *args, **kwargs):\n        self.fd = fd\n        _set_nonblocking(fd)\n        super(PipeIOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.fd\n\n    def close_fd(self):\n        os.close(self.fd)\n\n    def write_to_fd(self, data):\n        return os.write(self.fd, data)\n\n    def read_from_fd(self):\n        try:\n            chunk = os.read(self.fd, self.read_chunk_size)\n        except (IOError, OSError) as e:\n            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):\n                return None\n            elif e.args[0] == errno.EBADF:\n                # If the writing half of a pipe is closed, select will\n                # report it as readable but reads will fail with EBADF.\n                self.close(exc_info=True)\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\ndef _double_prefix(deque):\n    \"\"\"Grow by doubling, but don't split the second chunk just because the\n    first one is small.\n    \"\"\"\n    new_len = max(len(deque[0]) * 2,\n                  (len(deque[0]) + len(deque[1])))\n    _merge_prefix(deque, new_len)\n\n\ndef _merge_prefix(deque, size):\n    \"\"\"Replace the first entries in a deque of strings with a single\n    string of up to size bytes.\n\n    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])\n    >>> _merge_prefix(d, 5); print(d)\n    deque(['abcde', 'fghi', 'j'])\n\n    Strings will be split as necessary to reach the desired size.\n    >>> _merge_prefix(d, 7); print(d)\n    deque(['abcdefg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 3); print(d)\n    deque(['abc', 'defg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 100); print(d)\n    deque(['abcdefghij'])\n    \"\"\"\n    if len(deque) == 1 and len(deque[0]) <= size:\n        return\n    prefix = []\n    remaining = size\n    while deque and remaining > 0:\n        chunk = deque.popleft()\n        if len(chunk) > remaining:\n            deque.appendleft(chunk[remaining:])\n            chunk = chunk[:remaining]\n        prefix.append(chunk)\n        remaining -= len(chunk)\n    # This data structure normally just contains byte strings, but\n    # the unittest gets messy if it doesn't use the default str() type,\n    # so do the merge based on the type of data that's actually present.\n    if prefix:\n        deque.appendleft(type(prefix[0])().join(prefix))\n    if not deque:\n        deque.appendleft(b\"\")\n\n\ndef doctests():\n    import doctest\n    return doctest.DocTestSuite()\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:** `read_until_close` Fails to Flush Buffer, Missing Data in Streaming Callback

**Description:**
When using `read_until_close` with a streaming callback, any data remaining in the buffer after a partial read is not flushed correctly. This results in the streaming callback receiving `None` instead of the expected remaining data.

**Example Code:**
```python
server, client = self.make_iostream_pair()
client.write(b"abcd\r\nefgh")
server.read_until(b"\r\n", self.stop)
data = self.wait()
self.assertEqual(data, b"abcd\r\n")

def closed_callback(chunk):
    self.fail()
server.read_until_close(callback=closed_callback, streaming_callback=self.stop)
self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)
data = self.wait()
self.assertEqual(data, b"efgh")
server.close()
client.close()
```

In this example, after reading until `b"\r\n"`, the remaining data `b"efgh"` should be passed to the streaming callback. However, the callback receives `None` instead, causing the assertion to fail.

**Expected Behavior:**
After calling `read_until_close`, the streaming callback should receive all remaining data in the buffer (`b"efgh"` in this case) instead of `None`.

**Actual Behavior:**
The streaming callback receives `None`, indicating that the remaining buffer was not flushed properly.

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

"""Utility classes to write to and read from non-blocking files and sockets.

Contents:

* `BaseIOStream`: Generic interface for reading and writing.
* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.
* `SSLIOStream`: SSL-aware version of IOStream.
* `PipeIOStream`: Pipe-based IOStream implementation.
"""

from __future__ import absolute_import, division, print_function, with_statement

import collections
import errno
import numbers
import os
import socket
import ssl
import sys
import re

from tornado import ioloop
from tornado.log import gen_log, app_log
from tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError
from tornado import stack_context
from tornado.util import bytes_type

try:
    from tornado.platform.posix import _set_nonblocking
except ImportError:
    _set_nonblocking = None


class StreamClosedError(IOError):
    pass


class BaseIOStream(object):
    """A utility class to write to and read from a non-blocking file or socket.

    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.
    All of the methods take callbacks (since writing and reading are
    non-blocking and asynchronous).

    When a stream is closed due to an error, the IOStream's `error`
    attribute contains the exception object.

    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,
    `read_from_fd`, and optionally `get_fd_error`.
    """
    def __init__(self, io_loop=None, max_buffer_size=104857600,
                 read_chunk_size=4096):
        self.io_loop = io_loop or ioloop.IOLoop.instance()
        self.max_buffer_size = max_buffer_size
        self.read_chunk_size = read_chunk_size
        self.error = None
        self._read_buffer = collections.deque()
        self._write_buffer = collections.deque()
        self._read_buffer_size = 0
        self._write_buffer_frozen = False
        self._read_delimiter = None
        self._read_regex = None
        self._read_bytes = None
        self._read_until_close = False
        self._read_callback = None
        self._streaming_callback = None
        self._write_callback = None
        self._close_callback = None
        self._connect_callback = None
        self._connecting = False
        self._state = None
        self._pending_callbacks = 0
        self._closed = False

    def fileno(self):
        """Returns the file descriptor for this stream."""
        raise NotImplementedError()

    def close_fd(self):
        """Closes the file underlying this stream.

        ``close_fd`` is called by `BaseIOStream` and should not be called
        elsewhere; other users should call `close` instead.
        """
        raise NotImplementedError()

    def write_to_fd(self, data):
        """Attempts to write ``data`` to the underlying file.

        Returns the number of bytes written.
        """
        raise NotImplementedError()

    def read_from_fd(self):
        """Attempts to read from the underlying file.

        Returns ``None`` if there was nothing to read (the socket returned
        EWOULDBLOCK or equivalent), otherwise returns the data.  When possible,
        should return no more than ``self.read_chunk_size`` bytes at a time.
        """
        raise NotImplementedError()

    def get_fd_error(self):
        """Returns information about any error on the underlying file.

        This method is called after the IOLoop has signaled an error on the
        file descriptor, and should return an Exception (such as `socket.error`
        with additional information, or None if no such information is
        available.
        """
        return None

    def read_until_regex(self, regex, callback):
        """Call callback when we read the given regex pattern."""
        self._set_read_callback(callback)
        self._read_regex = re.compile(regex)
        self._try_inline_read()

    def read_until(self, delimiter, callback):
        """Call callback when we read the given delimiter."""
        self._set_read_callback(callback)
        self._read_delimiter = delimiter
        self._try_inline_read()

    def read_bytes(self, num_bytes, callback, streaming_callback=None):
        """Call callback when we read the given number of bytes.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.
        """
        self._set_read_callback(callback)
        assert isinstance(num_bytes, numbers.Integral)
        self._read_bytes = num_bytes
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._try_inline_read()

    def read_until_close(self, callback, streaming_callback=None):
        """Reads all data from the socket until it is closed.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.

        Subject to ``max_buffer_size`` limit from `IOStream` constructor if
        a ``streaming_callback`` is not used.
        """
        self._set_read_callback(callback)
        self._streaming_callback = stack_context.wrap(streaming_callback)
        if self.closed():
            if self._streaming_callback is not None:
                self._run_callback(self._streaming_callback,
                                   self._consume(self._read_buffer_size))
            self._run_callback(self._read_callback,
                               self._consume(self._read_buffer_size))
            self._streaming_callback = None
            self._read_callback = None
            return
        self._read_until_close = True
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._add_io_state(self.io_loop.READ)

    def write(self, data, callback=None):
        """Write the given data to this stream.

        If callback is given, we call it when all of the buffered write
        data has been successfully written to the stream. If there was
        previously buffered write data and an old write callback, that
        callback is simply overwritten with this new callback.
        """
        assert isinstance(data, bytes_type)
        self._check_closed()
        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,
        # so never put empty strings in the buffer.
        if data:
            # Break up large contiguous strings before inserting them in the
            # write buffer, so we don't have to recopy the entire thing
            # as we slice off pieces to send to the socket.
            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024
            if len(data) > WRITE_BUFFER_CHUNK_SIZE:
                for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):
                    self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])
            else:
                self._write_buffer.append(data)
        self._write_callback = stack_context.wrap(callback)
        if not self._connecting:
            self._handle_write()
            if self._write_buffer:
                self._add_io_state(self.io_loop.WRITE)
            self._maybe_add_error_listener()

    def set_close_callback(self, callback):
        """Call the given callback when the stream is closed."""
        self._close_callback = stack_context.wrap(callback)

    def close(self, exc_info=False):
        """Close this stream.

        If ``exc_info`` is true, set the ``error`` attribute to the current
        exception from `sys.exc_info()` (or if ``exc_info`` is a tuple,
        use that instead of `sys.exc_info`).
        """
        if not self.closed():
            if exc_info:
                if not isinstance(exc_info, tuple):
                    exc_info = sys.exc_info()
                if any(exc_info):
                    self.error = exc_info[1]
            if self._read_until_close:
                callback = self._read_callback
                self._read_callback = None
                self._read_until_close = False
                self._run_callback(callback,
                                   self._consume(self._read_buffer_size))
            if self._state is not None:
                self.io_loop.remove_handler(self.fileno())
                self._state = None
            self.close_fd()
            self._closed = True
        self._maybe_run_close_callback()

    def _maybe_run_close_callback(self):
        if (self.closed() and self._close_callback and
                self._pending_callbacks == 0):
            # if there are pending callbacks, don't run the close callback
            # until they're done (see _maybe_add_error_handler)
            cb = self._close_callback
            self._close_callback = None
            self._run_callback(cb)
            # Delete any unfinished callbacks to break up reference cycles.
            self._read_callback = self._write_callback = None

    def reading(self):
        """Returns true if we are currently reading from the stream."""
        return self._read_callback is not None

    def writing(self):
        """Returns true if we are currently writing to the stream."""
        return bool(self._write_buffer)

    def closed(self):
        """Returns true if the stream has been closed."""
        return self._closed

    def _handle_events(self, fd, events):
        if self.closed():
            gen_log.warning("Got events for closed stream %d", fd)
            return
        try:
            if events & self.io_loop.READ:
                self._handle_read()
            if self.closed():
                return
            if events & self.io_loop.WRITE:
                if self._connecting:
                    self._handle_connect()
                self._handle_write()
            if self.closed():
                return
            if events & self.io_loop.ERROR:
                self.error = self.get_fd_error()
                # We may have queued up a user callback in _handle_read or
                # _handle_write, so don't close the IOStream until those
                # callbacks have had a chance to run.
                self.io_loop.add_callback(self.close)
                return
            state = self.io_loop.ERROR
            if self.reading():
                state |= self.io_loop.READ
            if self.writing():
                state |= self.io_loop.WRITE
            if state == self.io_loop.ERROR:
                state |= self.io_loop.READ
            if state != self._state:
                assert self._state is not None, \
                    "shouldn't happen: _handle_events without self._state"
                self._state = state
                self.io_loop.update_handler(self.fileno(), self._state)
        except Exception:
            gen_log.error("Uncaught exception, closing connection.",
                          exc_info=True)
            self.close(exc_info=True)
            raise

    def _run_callback(self, callback, *args):
        def wrapper():
            self._pending_callbacks -= 1
            try:
                callback(*args)
            except Exception:
                app_log.error("Uncaught exception, closing connection.",
                              exc_info=True)
                # Close the socket on an uncaught exception from a user callback
                # (It would eventually get closed when the socket object is
                # gc'd, but we don't want to rely on gc happening before we
                # run out of file descriptors)
                self.close(exc_info=True)
                # Re-raise the exception so that IOLoop.handle_callback_exception
                # can see it and log the error
                raise
            self._maybe_add_error_listener()
        # We schedule callbacks to be run on the next IOLoop iteration
        # rather than running them directly for several reasons:
        # * Prevents unbounded stack growth when a callback calls an
        #   IOLoop operation that immediately runs another callback
        # * Provides a predictable execution context for e.g.
        #   non-reentrant mutexes
        # * Ensures that the try/except in wrapper() is run outside
        #   of the application's StackContexts
        with stack_context.NullContext():
            # stack_context was already captured in callback, we don't need to
            # capture it again for IOStream's wrapper.  This is especially
            # important if the callback was pre-wrapped before entry to
            # IOStream (as in HTTPConnection._header_callback), as we could
            # capture and leak the wrong context here.
            self._pending_callbacks += 1
            self.io_loop.add_callback(wrapper)

    def _handle_read(self):
        try:
            try:
                # Pretend to have a pending callback so that an EOF in
                # _read_to_buffer doesn't trigger an immediate close
                # callback.  At the end of this method we'll either
                # estabilsh a real pending callback via
                # _read_from_buffer or run the close callback.
                #
                # We need two try statements here so that
                # pending_callbacks is decremented before the `except`
                # clause below (which calls `close` and does need to
                # trigger the callback)
                self._pending_callbacks += 1
                while not self.closed():
                    # Read from the socket until we get EWOULDBLOCK or equivalent.
                    # SSL sockets do some internal buffering, and if the data is
                    # sitting in the SSL object's buffer select() and friends
                    # can't see it; the only way to find out if it's there is to
                    # try to read it.
                    if self._read_to_buffer() == 0:
                        break
            finally:
                self._pending_callbacks -= 1
        except Exception:
            gen_log.warning("error on read", exc_info=True)
            self.close(exc_info=True)
            return
        if self._read_from_buffer():
            return
        else:
            self._maybe_run_close_callback()

    def _set_read_callback(self, callback):
        assert not self._read_callback, "Already reading"
        self._read_callback = stack_context.wrap(callback)

    def _try_inline_read(self):
        """Attempt to complete the current read operation from buffered data.

        If the read can be completed without blocking, schedules the
        read callback on the next IOLoop iteration; otherwise starts
        listening for reads on the socket.
        """
        # See if we've already got the data from a previous read
        if self._read_from_buffer():
            return
        self._check_closed()
        try:
            # See comments in _handle_read about incrementing _pending_callbacks
            self._pending_callbacks += 1
            while not self.closed():
                if self._read_to_buffer() == 0:
                    break
        finally:
            self._pending_callbacks -= 1
        if self._read_from_buffer():
            return
        self._maybe_add_error_listener()

    def _read_to_buffer(self):
        """Reads from the socket and appends the result to the read buffer.

        Returns the number of bytes read.  Returns 0 if there is nothing
        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On
        error closes the socket and raises an exception.
        """
        try:
            chunk = self.read_from_fd()
        except (socket.error, IOError, OSError) as e:
            # ssl.SSLError is a subclass of socket.error
            if e.args[0] == errno.ECONNRESET:
                # Treat ECONNRESET as a connection close rather than
                # an error to minimize log spam  (the exception will
                # be available on self.error for apps that care).
                self.close(exc_info=True)
                return
            self.close(exc_info=True)
            raise
        if chunk is None:
            return 0
        self._read_buffer.append(chunk)
        self._read_buffer_size += len(chunk)
        if self._read_buffer_size >= self.max_buffer_size:
            gen_log.error("Reached maximum read buffer size")
            self.close()
            raise IOError("Reached maximum read buffer size")
        return len(chunk)

    def _read_from_buffer(self):
        """Attempts to complete the currently-pending read from the buffer.

        Returns True if the read was completed.
        """
        if self._streaming_callback is not None and self._read_buffer_size:
            bytes_to_consume = self._read_buffer_size
            if self._read_bytes is not None:
                bytes_to_consume = min(self._read_bytes, bytes_to_consume)
                self._read_bytes -= bytes_to_consume
            self._run_callback(self._streaming_callback,
                               self._consume(bytes_to_consume))
        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:
            num_bytes = self._read_bytes
            callback = self._read_callback
            self._read_callback = None
            self._streaming_callback = None
            self._read_bytes = None
            self._run_callback(callback, self._consume(num_bytes))
            return True
        elif self._read_delimiter is not None:
            # Multi-byte delimiters (e.g. '\r\n') may straddle two
            # chunks in the read buffer, so we can't easily find them
            # without collapsing the buffer.  However, since protocols
            # using delimited reads (as opposed to reads of a known
            # length) tend to be "line" oriented, the delimiter is likely
            # to be in the first few chunks.  Merge the buffer gradually
            # since large merges are relatively expensive and get undone in
            # consume().
            if self._read_buffer:
                while True:
                    loc = self._read_buffer[0].find(self._read_delimiter)
                    if loc != -1:
                        callback = self._read_callback
                        delimiter_len = len(self._read_delimiter)
                        self._read_callback = None
                        self._streaming_callback = None
                        self._read_delimiter = None
                        self._run_callback(callback,
                                           self._consume(loc + delimiter_len))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        elif self._read_regex is not None:
            if self._read_buffer:
                while True:
                    m = self._read_regex.search(self._read_buffer[0])
                    if m is not None:
                        callback = self._read_callback
                        self._read_callback = None
                        self._streaming_callback = None
                        self._read_regex = None
                        self._run_callback(callback, self._consume(m.end()))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        return False

    def _handle_write(self):
        while self._write_buffer:
            try:
                if not self._write_buffer_frozen:
                    # On windows, socket.send blows up if given a
                    # write buffer that's too large, instead of just
                    # returning the number of bytes it was able to
                    # process.  Therefore we must not call socket.send
                    # with more than 128KB at a time.
                    _merge_prefix(self._write_buffer, 128 * 1024)
                num_bytes = self.write_to_fd(self._write_buffer[0])
                if num_bytes == 0:
                    # With OpenSSL, if we couldn't write the entire buffer,
                    # the very same string object must be used on the
                    # next call to send.  Therefore we suppress
                    # merging the write buffer after an incomplete send.
                    # A cleaner solution would be to set
                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is
                    # not yet accessible from python
                    # (http://bugs.python.org/issue8240)
                    self._write_buffer_frozen = True
                    break
                self._write_buffer_frozen = False
                _merge_prefix(self._write_buffer, num_bytes)
                self._write_buffer.popleft()
            except socket.error as e:
                if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                    self._write_buffer_frozen = True
                    break
                else:
                    gen_log.warning("Write error on %d: %s",
                                    self.fileno(), e)
                    self.close(exc_info=True)
                    return
        if not self._write_buffer and self._write_callback:
            callback = self._write_callback
            self._write_callback = None
            self._run_callback(callback)

    def _consume(self, loc):
        if loc == 0:
            return b""
        _merge_prefix(self._read_buffer, loc)
        self._read_buffer_size -= loc
        return self._read_buffer.popleft()

    def _check_closed(self):
        if self.closed():
            raise StreamClosedError("Stream is closed")

    def _maybe_add_error_listener(self):
        if self._state is None and self._pending_callbacks == 0:
            if self.closed():
                self._maybe_run_close_callback()
            else:
                self._add_io_state(ioloop.IOLoop.READ)

    def _add_io_state(self, state):
        """Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.

        Implementation notes: Reads and writes have a fast path and a
        slow path.  The fast path reads synchronously from socket
        buffers, while the slow path uses `_add_io_state` to schedule
        an IOLoop callback.  Note that in both cases, the callback is
        run asynchronously with `_run_callback`.

        To detect closed connections, we must have called
        `_add_io_state` at some point, but we want to delay this as
        much as possible so we don't have to set an `IOLoop.ERROR`
        listener that will be overwritten by the next slow-path
        operation.  As long as there are callbacks scheduled for
        fast-path ops, those callbacks may do more reads.
        If a sequence of fast-path ops do not end in a slow-path op,
        (e.g. for an @asynchronous long-poll request), we must add
        the error handler.  This is done in `_run_callback` and `write`
        (since the write callback is optional so we can have a
        fast-path write with no `_run_callback`)
        """
        if self.closed():
            # connection has been closed, so there can be no future events
            return
        if self._state is None:
            self._state = ioloop.IOLoop.ERROR | state
            with stack_context.NullContext():
                self.io_loop.add_handler(
                    self.fileno(), self._handle_events, self._state)
        elif not self._state & state:
            self._state = self._state | state
            self.io_loop.update_handler(self.fileno(), self._state)


class IOStream(BaseIOStream):
    r"""Socket-based IOStream implementation.

    This class supports the read and write methods from `BaseIOStream`
    plus a `connect` method.

    The socket parameter may either be connected or unconnected.  For
    server operations the socket is the result of calling socket.accept().
    For client operations the socket is created with socket.socket(),
    and may either be connected before passing it to the IOStream or
    connected with IOStream.connect.

    A very simple (and broken) HTTP client using this class::

        from tornado import ioloop
        from tornado import iostream
        import socket

        def send_request():
            stream.write("GET / HTTP/1.0\r\nHost: friendfeed.com\r\n\r\n")
            stream.read_until("\r\n\r\n", on_headers)

        def on_headers(data):
            headers = {}
            for line in data.split("\r\n"):
               parts = line.split(":")
               if len(parts) == 2:
                   headers[parts[0].strip()] = parts[1].strip()
            stream.read_bytes(int(headers["Content-Length"]), on_body)

        def on_body(data):
            print data
            stream.close()
            ioloop.IOLoop.instance().stop()

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        stream = iostream.IOStream(s)
        stream.connect(("friendfeed.com", 80), send_request)
        ioloop.IOLoop.instance().start()
    """
    def __init__(self, socket, *args, **kwargs):
        self.socket = socket
        self.socket.setblocking(False)
        super(IOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.socket.fileno()

    def close_fd(self):
        self.socket.close()
        self.socket = None

    def get_fd_error(self):
        errno = self.socket.getsockopt(socket.SOL_SOCKET,
                                       socket.SO_ERROR)
        return socket.error(errno, os.strerror(errno))

    def read_from_fd(self):
        try:
            chunk = self.socket.recv(self.read_chunk_size)
        except socket.error as e:
            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk

    def write_to_fd(self, data):
        return self.socket.send(data)

    def connect(self, address, callback=None, server_hostname=None):
        """Connects the socket to a remote address without blocking.

        May only be called if the socket passed to the constructor was
        not previously connected.  The address parameter is in the
        same format as for socket.connect, i.e. a (host, port) tuple.
        If callback is specified, it will be called when the
        connection is completed.

        If specified, the ``server_hostname`` parameter will be used
        in SSL connections for certificate validation (if requested in
        the ``ssl_options``) and SNI (if supported; requires
        Python 3.2+).

        Note that it is safe to call IOStream.write while the
        connection is pending, in which case the data will be written
        as soon as the connection is ready.  Calling IOStream read
        methods before the socket is connected works on some platforms
        but is non-portable.
        """
        self._connecting = True
        try:
            self.socket.connect(address)
        except socket.error as e:
            # In non-blocking mode we expect connect() to raise an
            # exception with EINPROGRESS or EWOULDBLOCK.
            #
            # On freebsd, other errors such as ECONNREFUSED may be
            # returned immediately when attempting to connect to
            # localhost, so handle them the same way as an error
            # reported later in _handle_connect.
            if e.args[0] not in (errno.EINPROGRESS, errno.EWOULDBLOCK):
                gen_log.warning("Connect error on fd %d: %s",
                                self.socket.fileno(), e)
                self.close(exc_info=True)
                return
        self._connect_callback = stack_context.wrap(callback)
        self._add_io_state(self.io_loop.WRITE)

    def _handle_connect(self):
        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
        if err != 0:
            self.error = socket.error(err, os.strerror(err))
            # IOLoop implementations may vary: some of them return
            # an error state before the socket becomes writable, so
            # in that case a connection failure would be handled by the
            # error path in _handle_events instead of here.
            gen_log.warning("Connect error on fd %d: %s",
                            self.socket.fileno(), errno.errorcode[err])
            self.close()
            return
        if self._connect_callback is not None:
            callback = self._connect_callback
            self._connect_callback = None
            self._run_callback(callback)
        self._connecting = False


class SSLIOStream(IOStream):
    """A utility class to write to and read from a non-blocking SSL socket.

    If the socket passed to the constructor is already connected,
    it should be wrapped with::

        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)

    before constructing the SSLIOStream.  Unconnected sockets will be
    wrapped when IOStream.connect is finished.
    """
    def __init__(self, *args, **kwargs):
        """Creates an SSLIOStream.

        The ``ssl_options`` keyword argument may either be a dictionary
        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`
        object.
        """
        self._ssl_options = kwargs.pop('ssl_options', {})
        super(SSLIOStream, self).__init__(*args, **kwargs)
        self._ssl_accepting = True
        self._handshake_reading = False
        self._handshake_writing = False
        self._ssl_connect_callback = None
        self._server_hostname = None

    def reading(self):
        return self._handshake_reading or super(SSLIOStream, self).reading()

    def writing(self):
        return self._handshake_writing or super(SSLIOStream, self).writing()

    def _do_ssl_handshake(self):
        # Based on code from test_ssl.py in the python stdlib
        try:
            self._handshake_reading = False
            self._handshake_writing = False
            self.socket.do_handshake()
        except ssl.SSLError as err:
            if err.args[0] == ssl.SSL_ERROR_WANT_READ:
                self._handshake_reading = True
                return
            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                self._handshake_writing = True
                return
            elif err.args[0] in (ssl.SSL_ERROR_EOF,
                                 ssl.SSL_ERROR_ZERO_RETURN):
                return self.close(exc_info=True)
            elif err.args[0] == ssl.SSL_ERROR_SSL:
                try:
                    peer = self.socket.getpeername()
                except:
                    peer = '(not connected)'
                gen_log.warning("SSL Error on %d %s: %s",
                                self.socket.fileno(), peer, err)
                return self.close(exc_info=True)
            raise
        except socket.error as err:
            if err.args[0] in (errno.ECONNABORTED, errno.ECONNRESET):
                return self.close(exc_info=True)
        else:
            self._ssl_accepting = False
            if not self._verify_cert(self.socket.getpeercert()):
                self.close()
                return
            if self._ssl_connect_callback is not None:
                callback = self._ssl_connect_callback
                self._ssl_connect_callback = None
                self._run_callback(callback)

    def _verify_cert(self, peercert):
        """Returns True if peercert is valid according to the configured
        validation mode and hostname.

        The ssl handshake already tested the certificate for a valid
        CA signature; the only thing that remains is to check
        the hostname.
        """
        if isinstance(self._ssl_options, dict):
            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)
        elif isinstance(self._ssl_options, ssl.SSLContext):
            verify_mode = self._ssl_options.verify_mode
        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)
        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:
            return True
        cert = self.socket.getpeercert()
        if cert is None and verify_mode == ssl.CERT_REQUIRED:
            gen_log.warning("No SSL certificate given")
            return False
        try:
            ssl_match_hostname(peercert, self._server_hostname)
        except SSLCertificateError:
            gen_log.warning("Invalid SSL certificate", exc_info=True)
            return False
        else:
            return True

    def _handle_read(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_read()

    def _handle_write(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_write()

    def connect(self, address, callback=None, server_hostname=None):
        # Save the user's callback and run it after the ssl handshake
        # has completed.
        self._ssl_connect_callback = callback
        self._server_hostname = server_hostname
        super(SSLIOStream, self).connect(address, callback=None)

    def _handle_connect(self):
        # When the connection is complete, wrap the socket for SSL
        # traffic.  Note that we do this by overriding _handle_connect
        # instead of by passing a callback to super().connect because
        # user callbacks are enqueued asynchronously on the IOLoop,
        # but since _handle_events calls _handle_connect immediately
        # followed by _handle_write we need this to be synchronous.
        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                      server_hostname=self._server_hostname,
                                      do_handshake_on_connect=False)
        super(SSLIOStream, self)._handle_connect()

    def read_from_fd(self):
        if self._ssl_accepting:
            # If the handshake hasn't finished yet, there can't be anything
            # to read (attempting to read may or may not raise an exception
            # depending on the SSL version)
            return None
        try:
            # SSLSocket objects have both a read() and recv() method,
            # while regular sockets only have recv().
            # The recv() method blocks (at least in python 2.6) if it is
            # called when there is nothing to read, so we have to use
            # read() instead.
            chunk = self.socket.read(self.read_chunk_size)
        except ssl.SSLError as e:
            # SSLError is a subclass of socket.error, so this except
            # block must come first.
            if e.args[0] == ssl.SSL_ERROR_WANT_READ:
                return None
            else:
                raise
        except socket.error as e:
            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


class PipeIOStream(BaseIOStream):
    """Pipe-based IOStream implementation.

    The constructor takes an integer file descriptor (such as one returned
    by `os.pipe`) rather than an open file object.
    """
    def __init__(self, fd, *args, **kwargs):
        self.fd = fd
        _set_nonblocking(fd)
        super(PipeIOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.fd

    def close_fd(self):
        os.close(self.fd)

    def write_to_fd(self, data):
        return os.write(self.fd, data)

    def read_from_fd(self):
        try:
            chunk = os.read(self.fd, self.read_chunk_size)
        except (IOError, OSError) as e:
            if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
                return None
            elif e.args[0] == errno.EBADF:
                # If the writing half of a pipe is closed, select will
                # report it as readable but reads will fail with EBADF.
                self.close(exc_info=True)
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


def _double_prefix(deque):
    """Grow by doubling, but don't split the second chunk just because the
    first one is small.
    """
    new_len = max(len(deque[0]) * 2,
                  (len(deque[0]) + len(deque[1])))
    _merge_prefix(deque, new_len)


def _merge_prefix(deque, size):
    """Replace the first entries in a deque of strings with a single
    string of up to size bytes.

    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])
    >>> _merge_prefix(d, 5); print(d)
    deque(['abcde', 'fghi', 'j'])

    Strings will be split as necessary to reach the desired size.
    >>> _merge_prefix(d, 7); print(d)
    deque(['abcdefg', 'hi', 'j'])

    >>> _merge_prefix(d, 3); print(d)
    deque(['abc', 'defg', 'hi', 'j'])

    >>> _merge_prefix(d, 100); print(d)
    deque(['abcdefghij'])
    """
    if len(deque) == 1 and len(deque[0]) <= size:
        return
    prefix = []
    remaining = size
    while deque and remaining > 0:
        chunk = deque.popleft()
        if len(chunk) > remaining:
            deque.appendleft(chunk[remaining:])
            chunk = chunk[:remaining]
        prefix.append(chunk)
        remaining -= len(chunk)
    # This data structure normally just contains byte strings, but
    # the unittest gets messy if it doesn't use the default str() type,
    # so do the merge based on the type of data that's actually present.
    if prefix:
        deque.appendleft(type(prefix[0])().join(prefix))
    if not deque:
        deque.appendleft(b"")


def doctests():
    import doctest
    return doctest.DocTestSuite()

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