1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-09 17:15:35 +00:00

Ensure body is consumed only once

Fixes: #846
Signed-off-by: Mathieu Parent <math.parent@gmail.com>
This commit is contained in:
Mathieu Parent
2024-06-27 23:28:25 +02:00
parent 042e16c3e4
commit 241b0bbd91
4 changed files with 114 additions and 3 deletions

View File

@@ -3,7 +3,7 @@ import warnings
from io import BytesIO
from urllib.parse import parse_qsl, urlparse
from .util import CaseInsensitiveDict
from .util import CaseInsensitiveDict, _is_nonsequence_iterator
log = logging.getLogger(__name__)
@@ -17,8 +17,11 @@ class Request:
self.method = method
self.uri = uri
self._was_file = hasattr(body, "read")
self._was_iter = _is_nonsequence_iterator(body)
if self._was_file:
self.body = body.read()
elif self._was_iter:
self.body = list(body)
else:
self.body = body
self.headers = headers
@@ -36,7 +39,11 @@ class Request:
@property
def body(self):
return BytesIO(self._body) if self._was_file else self._body
if self._was_file:
return BytesIO(self._body)
if self._was_iter:
return iter(self._body)
return self._body
@body.setter
def body(self, value):

View File

@@ -89,9 +89,28 @@ def compose(*functions):
return composed
def _is_nonsequence_iterator(obj):
return hasattr(obj, "__iter__") and not isinstance(
obj,
(bytearray, bytes, dict, list, str),
)
def read_body(request):
if hasattr(request.body, "read"):
return request.body.read()
if _is_nonsequence_iterator(request.body):
body = list(request.body)
if body:
if isinstance(body[0], str):
return "".join(body).encode("utf-8")
elif isinstance(body[0], (bytes, bytearray)):
return b"".join(body)
elif isinstance(body[0], int):
return bytes(body)
else:
raise ValueError(f"Body type {type(body[0])} not supported")
return b""
return request.body