diff --git a/.codegen.json b/.codegen.json index 20a478fc..09da4c40 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "0072e8b", "specHash": "88cd5aa", "version": "10.15.0" } +{ "engineHash": "daeb1ea", "specHash": "88cd5aa", "version": "10.15.0" } diff --git a/box_sdk_gen/networking/box_network_client.py b/box_sdk_gen/networking/box_network_client.py index 5bd7d595..ee97c9b4 100644 --- a/box_sdk_gen/networking/box_network_client.py +++ b/box_sdk_gen/networking/box_network_client.py @@ -8,6 +8,7 @@ import requests from requests import RequestException, Session, Response +from requests.structures import CaseInsensitiveDict from requests_toolbelt import MultipartEncoder from ..internal.logging import DataSanitizer @@ -92,12 +93,13 @@ def fetch(self, options: 'FetchOptions') -> FetchResponse: if response.network_response is not None: attempt_for_retry = attempt_nr network_response = response.network_response + response_headers = CaseInsensitiveDict(network_response.headers) if options.response_format == 'binary': fetch_response = FetchResponse( url=network_response.url, status=network_response.status_code, - headers=dict(response.network_response.headers), + headers=response_headers, content=ResponseByteStream( response.network_response.iter_content(chunk_size=1024) ), @@ -106,7 +108,7 @@ def fetch(self, options: 'FetchOptions') -> FetchResponse: fetch_response = FetchResponse( url=network_response.url, status=network_response.status_code, - headers=dict(response.network_response.headers), + headers=response_headers, data=(self._read_json_body(network_response.text)), content=io.BytesIO(network_response.content), ) diff --git a/test/box_network_client.py b/test/box_network_client.py index 5b295566..f6bc2828 100644 --- a/test/box_network_client.py +++ b/test/box_network_client.py @@ -30,6 +30,13 @@ ) from box_sdk_gen.networking.proxy_config import ProxyConfig +RETRY_AFTER_HEADER_CASES = [ + "retry-after", + "Retry-After", + "rEtRy-AfTeR", + "RETRY-AFTER", +] + @pytest.fixture def mock_requests_session(): @@ -609,13 +616,16 @@ def test_status_code_202_with_no_retry_after_header( assert fetch_response.data == {} -def test_retryable_status_code_202( +@pytest.mark.parametrize("retry_after_header", RETRY_AFTER_HEADER_CASES) +def test_retryable_status_code_202_with_case_insensitive_retry_after_header( network_client, mock_requests_session, network_session_mock, response_202_with_retry_after, response_200, + retry_after_header, ): + response_202_with_retry_after.headers = {retry_after_header: "0"} response_200.text = '{"id": "123456"}' response_200.headers = {"Retry-After": "0"} mock_requests_session.request.side_effect = [ @@ -847,14 +857,16 @@ def test_get_retry_after_time_use_exponential_backoff(network_session_mock): assert sleep_time > 0 -def test_pass_retry_after_header_to_get_retry_after_time_method( +@pytest.mark.parametrize("retry_after_header", RETRY_AFTER_HEADER_CASES) +def test_pass_case_insensitive_retry_after_header_to_get_retry_after_time_method( network_client, mock_requests_session, network_session_mock, response_429, response_200, + retry_after_header, ): - response_429.headers = {"Retry-After": "123"} + response_429.headers = {retry_after_header: "123"} mock_requests_session.request.side_effect = [response_429, response_200] with patch("time.sleep") as sleep_mock: