Skip to content

Commit

Permalink
Requests chunk encoded request handling
Browse files Browse the repository at this point in the history
  • Loading branch information
p1c2u committed Apr 13, 2023
1 parent 4658b25 commit d6be0ce
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
13 changes: 13 additions & 0 deletions openapi_core/contrib/requests/requests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""OpenAPI core contrib requests requests module"""
from typing import Mapping
from typing import Optional
from typing import Union
from urllib.parse import parse_qs
Expand All @@ -7,6 +8,7 @@
from requests import PreparedRequest
from requests import Request
from requests.cookies import RequestsCookieJar
from requests.utils import rewind_body
from werkzeug.datastructures import Headers
from werkzeug.datastructures import ImmutableMultiDict

Expand Down Expand Up @@ -67,6 +69,17 @@ def method(self) -> str:
def body(self) -> Optional[str]:
if self.request.body is None:
return None
is_stream = all(
[
hasattr(self.request.body, "__iter__"),
not isinstance(self.request.body, (str, list, tuple, Mapping)),
]
)
if is_stream:
chunks = list(self.request.body)
body = "".join(chunks)
self.request.body = (x for x in chunks)
return body
if isinstance(self.request.body, bytes):
return self.request.body.decode("utf-8")
assert isinstance(self.request.body, str)
Expand Down
18 changes: 18 additions & 0 deletions tests/integration/contrib/requests/test_requests_validation.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from types import GeneratorType

import pytest
import requests
import responses
Expand Down Expand Up @@ -72,6 +74,22 @@ def test_request_validator_path_pattern(self, request_unmarshaller):
result = request_unmarshaller.unmarshal(openapi_request)
assert not result.errors

def test_request_validator_encoded_chunks(self, request_unmarshaller):
def gen():
yield '{"param1": 1}'

request = requests.Request(
"POST",
"http://localhost/browse/12/",
params={"q": "string"},
headers={"content-type": "application/json"},
data=gen(),
)
openapi_request = RequestsOpenAPIRequest(request)
result = request_unmarshaller.unmarshal(openapi_request)
assert not result.errors
assert request.data is GeneratorType

def test_request_validator_prepared_request(self, request_unmarshaller):
request = requests.Request(
"POST",
Expand Down

0 comments on commit d6be0ce

Please sign in to comment.