Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
registered URL's own query string) discarding blank-valued query params
(``b=``), which caused requests with an extra or missing blank param to
match incorrectly. See #804
* Fixed the default `header_matcher` (``strict_match=False``) matching header
field names case-sensitively, so a request whose header casing differed from
the matcher spec (for example lowercase names over HTTP/2) failed to match.
See #805

0.26.2
------
Expand Down
8 changes: 6 additions & 2 deletions responses/matchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,12 @@ def match(request: PreparedRequest) -> Tuple[bool, str]:
request_headers: Union[Mapping[Any, Any], Any] = request.headers or {}

if not strict_match:
# filter down to just the headers specified in the matcher
request_headers = {k: v for k, v in request_headers.items() if k in headers}
# Filter to the matcher's headers, keyed by the matcher's names, so
# the case-insensitive lookup on request.headers (a
# CaseInsensitiveDict) is not lost in the plain-dict rebuild.
request_headers = {
k: request_headers[k] for k in headers if k in request_headers
}

valid = _compare_with_regex(request_headers)

Expand Down
20 changes: 20 additions & 0 deletions responses/tests/test_matchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,26 @@ def run():
assert_reset()


def test_request_matches_headers_case_insensitive_field_names():
# HTTP header names are case-insensitive (and HTTP/2 lower-cases them), so
# the default matcher must match regardless of the field-name casing.
@responses.activate
def run():
url = "http://example.com/"
responses.add(
method=responses.GET,
url=url,
json={"success": True},
match=[matchers.header_matcher({"X-Custom": "token"})],
)

resp = requests.get(url, headers={"x-custom": "token"})
assert_response(resp, body='{"success": true}', content_type="application/json")
Comment on lines +873 to +874

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could there also be a test that covers case-mismatch on strict_match=True? There isn't a test for that scenario right now.


run()
assert_reset()


def test_request_header_value_mismatch_raises():
@responses.activate
def run():
Expand Down
Loading