+def make_line_iter(stream, limit=None, buffer_size=10 * 1024):
+ """Savely iterates line-based over an input stream. If the input stream
+ is not a :class:`LimitedStream` the `limit` parameter is mandatory.
+ This uses the stream's :meth:`~file.read` method internally as opposite
+ to the :meth:`~file.readline` method that is unsafe and can only be used
+ in violation of the WSGI specification. The same problem applies to the
+ `__iter__` function of the input stream which calls :meth:`~file.readline`
+ If you need line-by-line processing it's strongly recommended to iterate
+ over the input stream using this helper function.
+ :param stream: the stream to iterate over.
+ :param limit: the limit in bytes for the stream. (Usually
+ content length. Not necessary if the `stream`
+ is a :class:`LimitedStream`.
+ :param buffer_size: The optional buffer size.
+ if not isinstance(stream, LimitedStream):
+ raise TypeError('stream not limited and no limit provided.')
+ stream = LimitedStream(stream, limit)
+ chunks = stream.read(buffer_size).splitlines(True)
+ first_chunk = buffer and buffer or ''
+ first_chunk += chunks.pop(0)
"""Wraps a stream so that it doesn't read more than n bytes. If the
stream is exhausted and the caller tries to get more bytes from it
- :func:`on_exhausted` is called which by default raises a
- :exc:`~werkzeug.exceptions.BadRequest`. The return value of that
- function is forwarded to the reader function. So if it returns an
- empty string :meth:`read` will return an empty string as well.
+ :func:`on_exhausted` is called which by default returns an empty
+ string or raises :exc:`~werkzeug.exceptions.BadRequest` if silent
+ is set to `False`. The return value of that function is forwarded
+ to the reader function. So if it returns an empty string
+ :meth:`read` will return an empty string as well.
The limit however must never be higher than what the stream can
output. Otherwise :meth:`readlines` will try to read past the
The `silent` parameter has no effect if :meth:`is_exhausted` is
+ .. admonition:: Note on WSGI compliance
+ calls to :meth:`readline` and :meth:`readlines` are not
+ WSGI compliant because it passes a size argument to the
+ readline methods. Unfortunately the WSGI PEP is not safely
+ implementable without a size argument to :meth:`readline`
+ because there is no EOF marker in the stream. As a result
+ of that the use of :meth:`readline` is discouraged.
+ For the same reason iterating over the :class:`LimitedStream`
+ is not portable. It internally calls :meth:`readline`.
+ We strongly suggest using :meth:`read` only or using the
+ :func:`make_line_iter` which savely iterates line-based
+ over a WSGI input stream.
:param stream: the stream to wrap.
:param limit: the limit for the stream, must not be longer than
what the string can provide if the stream does not
past the limit and will return an empty string.
- def __init__(self, stream, limit, silent=
+ def __init__(self, stream, limit, silent=e):
def readline(self, size=None):
- """Read a line from the stream. Arguments are forwarded to the
- `readline` function of the underlaying stream if it supports
+ """Reads one line from the stream."""
if self._pos >= self.limit:
charset, errors=errors, dict_class=dict_class)
- stream = LimitedStream(environ['wsgi.input'], content_length,
+ stream = LimitedStream(environ['wsgi.input'], content_length)
return stream, form, dict_class(files)