"""
return None
- def read_until_regex(self, regex, callback=None):
+ def read_until_regex(self, regex, callback=None, max_bytes=None):
- """Run ``callback`` when we read the given regex pattern.
+ """Asynchronously read until we have matched the given regex.
- The callback will get the data read (including the data that
- matched the regex and anything that came before it) as an argument.
+ The result includes the data that matches the regex and anything
+ that came before it. If a callback is given, it will be run
+ with the data as an argument; if not, this method returns a
+ `.Future`.
- The callback argument is now optional and a `.Future` will
- be returned if it is omitted.
+ If ``max_bytes`` is not None, the connection will be closed
+ if more than ``max_bytes`` bytes have been read and the regex is
+ not satisfied.
++
+ .. versionchanged:: 3.3
++ Added the ``max_bytes`` argument. The ``callback`` argument is
++ now optional and a `.Future` will be returned if it is omitted.
"""
future = self._set_read_callback(callback)
self._read_regex = re.compile(regex)
- self._try_inline_read()
+ self._read_max_bytes = max_bytes
+ try:
+ self._try_inline_read()
+ except UnsatisfiableReadError as e:
+ # Handle this the same way as in _handle_events.
+ gen_log.info("Unsatisfiable read, closing connection: %s" % e)
+ self.close(exc_info=True)
+ return future
return future
- def read_until(self, delimiter, callback=None):
+ def read_until(self, delimiter, callback=None, max_bytes=None):
- """Run ``callback`` when we read the given delimiter.
+ """Asynchronously read until we have found the given delimiter.
- The callback will get the data read (including the delimiter)
- as an argument.
+ The result includes all the data read including the delimiter.
+ If a callback is given, it will be run with the data as an argument;
+ if not, this method returns a `.Future`.
- The callback argument is now optional and a `.Future` will
- be returned if it is omitted.
+ If ``max_bytes`` is not None, the connection will be closed
+ if more than ``max_bytes`` bytes have been read and the delimiter
+ is not found.
++
+ .. versionchanged:: 3.3
++ Added the ``max_bytes`` argument. The ``callback`` argument is
++ now optional and a `.Future` will be returned if it is omitted.
"""
future = self._set_read_callback(callback)
self._read_delimiter = delimiter
- self._try_inline_read()
+ self._read_max_bytes = max_bytes
+ try:
+ self._try_inline_read()
+ except UnsatisfiableReadError as e:
+ # Handle this the same way as in _handle_events.
+ gen_log.info("Unsatisfiable read, closing connection: %s" % e)
+ self.close(exc_info=True)
+ return future
return future
- def read_bytes(self, num_bytes, callback=None, streaming_callback=None):
+ def read_bytes(self, num_bytes, callback=None, streaming_callback=None,
+ partial=False):
- """Run callback when we read the given number of bytes.
+ """Asynchronously read a 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. Otherwise, the ``callback`` gets
- the data as an argument.
+ of data as they become available, and the final result will be empty.
+ Otherwise, the result is all the data that was read.
+ If a callback is given, it will be run with the data as an argument;
+ if not, this method returns a `.Future`.
- The callback argument is now optional and a `.Future` will
- be returned if it is omitted.
+ If ``partial`` is true, the callback is run as soon as we have
+ any bytes to return (but never more than ``num_bytes``)
++
+ .. versionchanged:: 3.3
++ Added the ``partial`` argument. The callback argument is now
++ optional and a `.Future` will be returned if it is omitted.
"""
future = self._set_read_callback(callback)
assert isinstance(num_bytes, numbers.Integral)
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_read_callback(self._consume(self._read_buffer_size))
+ self._run_read_callback(self._read_buffer_size, True)
+ self._run_read_callback(self._read_buffer_size, False)
return future
self._read_until_close = True
- self._streaming_callback = stack_context.wrap(streaming_callback)
self._try_inline_read()
return future