response.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from ..utils import cached_property
  2. from .auth import WWWAuthenticateMixin
  3. from .base_response import BaseResponse
  4. from .common_descriptors import CommonResponseDescriptorsMixin
  5. from .cors import CORSResponseMixin
  6. from .etag import ETagResponseMixin
  7. class ResponseStream(object):
  8. """A file descriptor like object used by the :class:`ResponseStreamMixin` to
  9. represent the body of the stream. It directly pushes into the response
  10. iterable of the response object.
  11. """
  12. mode = "wb+"
  13. def __init__(self, response):
  14. self.response = response
  15. self.closed = False
  16. def write(self, value):
  17. if self.closed:
  18. raise ValueError("I/O operation on closed file")
  19. self.response._ensure_sequence(mutable=True)
  20. self.response.response.append(value)
  21. self.response.headers.pop("Content-Length", None)
  22. return len(value)
  23. def writelines(self, seq):
  24. for item in seq:
  25. self.write(item)
  26. def close(self):
  27. self.closed = True
  28. def flush(self):
  29. if self.closed:
  30. raise ValueError("I/O operation on closed file")
  31. def isatty(self):
  32. if self.closed:
  33. raise ValueError("I/O operation on closed file")
  34. return False
  35. def tell(self):
  36. self.response._ensure_sequence()
  37. return sum(map(len, self.response.response))
  38. @property
  39. def encoding(self):
  40. return self.response.charset
  41. class ResponseStreamMixin(object):
  42. """Mixin for :class:`BaseResponse` subclasses. Classes that inherit from
  43. this mixin will automatically get a :attr:`stream` property that provides
  44. a write-only interface to the response iterable.
  45. """
  46. @cached_property
  47. def stream(self):
  48. """The response iterable as write-only stream."""
  49. return ResponseStream(self)
  50. class Response(
  51. BaseResponse,
  52. ETagResponseMixin,
  53. WWWAuthenticateMixin,
  54. CORSResponseMixin,
  55. ResponseStreamMixin,
  56. CommonResponseDescriptorsMixin,
  57. ):
  58. """Full featured response object implementing the following mixins:
  59. - :class:`ETagResponseMixin` for etag and cache control handling
  60. - :class:`WWWAuthenticateMixin` for HTTP authentication support
  61. - :class:`~werkzeug.wrappers.cors.CORSResponseMixin` for Cross
  62. Origin Resource Sharing headers
  63. - :class:`ResponseStreamMixin` to add support for the ``stream``
  64. property
  65. - :class:`CommonResponseDescriptorsMixin` for various HTTP
  66. descriptors
  67. """