MCPcopy
hub / github.com/pallets/werkzeug / LimitedStream

Class LimitedStream

src/werkzeug/wsgi.py:439–609  ·  view source on GitHub ↗

Wrap a stream so that it doesn't read more than a given limit. This is used to limit ``wsgi.input`` to the ``Content-Length`` header value or :attr:`.Request.max_content_length`. When attempting to read after the limit has been reached, :meth:`on_exhausted` is called. When the limit

Source from the content-addressed store, hash-verified

437
438
439class LimitedStream(io.RawIOBase):
440 """Wrap a stream so that it doesn't read more than a given limit. This is used to
441 limit ``wsgi.input`` to the ``Content-Length`` header value or
442 :attr:`.Request.max_content_length`.
443
444 When attempting to read after the limit has been reached, :meth:`on_exhausted` is
445 called. When the limit is a maximum, this raises :exc:`.RequestEntityTooLarge`.
446
447 If reading from the stream returns zero bytes or raises an error,
448 :meth:`on_disconnect` is called, which raises :exc:`.ClientDisconnected`. When the
449 limit is a maximum and zero bytes were read, no error is raised, since it may be the
450 end of the stream.
451
452 If the limit is reached before the underlying stream is exhausted (such as a file
453 that is too large, or an infinite stream), the remaining contents of the stream
454 cannot be read safely. Depending on how the server handles this, clients may show a
455 "connection reset" failure instead of seeing the 413 response.
456
457 :param stream: The stream to read from. Must be a readable binary IO object.
458 :param limit: The limit in bytes to not read past. Should be either the
459 ``Content-Length`` header value or ``request.max_content_length``.
460 :param is_max: Whether the given ``limit`` is ``request.max_content_length`` instead
461 of the ``Content-Length`` header value. This changes how exhausted and
462 disconnect events are handled.
463
464 .. versionchanged:: 2.3
465 Handle ``max_content_length`` differently than ``Content-Length``.
466
467 .. versionchanged:: 2.3
468 Implements ``io.RawIOBase`` rather than ``io.IOBase``.
469 """
470
471 def __init__(self, stream: t.IO[bytes], limit: int, is_max: bool = False) -> None:
472 self._stream = stream
473 self._pos = 0
474 self.limit = limit
475 self._limit_is_max = is_max
476
477 @property
478 def is_exhausted(self) -> bool:
479 """Whether the current stream position has reached the limit."""
480 return self._pos >= self.limit
481
482 def on_exhausted(self) -> None:
483 """Called when attempting to read after the limit has been reached.
484
485 The default behavior is to do nothing, unless the limit is a maximum, in which
486 case it raises :exc:`.RequestEntityTooLarge`.
487
488 .. versionchanged:: 2.3
489 Raises ``RequestEntityTooLarge`` if the limit is a maximum.
490
491 .. versionchanged:: 2.3
492 Any return value is ignored.
493 """
494 if self._limit_is_max:
495 raise RequestEntityTooLarge()
496

Callers 1

get_input_streamFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected