Repository navigation
Conversation
|
hi @00200200, First of all, thanks for your PR! In its current state, I see two solution for your issue (I agree that header matching should be case-insensitive, no question in this). One solution is to implement a totally new HeaderValueMatcher class for case-insensitive case (no pun intended :)), this would live separately and initially users like you would need to specify it explicitly. Once it is working fine then we could possibly flip the default to this new class. pytest-httpserver is designed to be fully customizable so hence I'd suggest creating a new class. The other solution is just simply add a few lines to your tests. from pytest_httpserver import HeaderValueMatcher
def header_matcher(header_name: str, actual: str | None, expected: str) -> bool:
if header_name.lower() == "authorization":
return HeaderValueMatcher.authorization_header_value_matcher(actual, expected)
return actual == expectedThen you can use it like this, we even provide the @pytest.mark.parametrize(
"header_name",
[
"foo",
"Foo",
"FOO",
"FoO",
],
)
def test_case_insensitive_header_matcher(httpserver: HTTPServer, header_name: str):
server = httpserver.bake(header_value_matcher=header_matcher)
server.expect_request("/foo", headers={"Foo": "bar"}).respond_with_data("OK")
assert requests.get(server.url_for("/foo"), headers={header_name: "bar"}).text == "OK"And it will also work with the authorization header in a case insensitive way: def test_authorization_headers(httpserver: HTTPServer):
server = httpserver.bake(header_value_matcher=header_matcher)
headers_with_values_in_direct_order = {
"AuTHoRIZation": (
'Digest username="Mufasa",'
'realm="testrealm@host.com",'
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",'
'uri="/dir/index.html",'
"qop=auth,"
"nc=00000001,"
'cnonce="0a4f113b",'
'response="6629fae49393a05397450978507c4ef1",'
'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
)
}
server.expect_request(uri="/", headers=headers_with_values_in_direct_order).respond_with_data("OK")
response = requests.get(httpserver.url_for("/"), headers=headers_with_values_in_direct_order)
assert response.status_code == 200
assert response.text == "OK"note that I added 1 line to the original authorization test I think this itself is much cleaner solution than your PR. In addition to that: you have full authority how you do the comparison in that function. What do you think? Zsolt |
542a6bc to
6fc4ef9
Compare
|
Thanks for your PR, I've just merge it. |
Reworked following the review to provide a separate, opt-in matcher rather than change the existing class.
Approach
HeaderValueMatcher's exact-name lookup and existing defaults.CaseInsensitiveHeaderValueMatcher, selected explicitly throughheader_value_matcherorbake().HeaderValueMatcher.DEFAULT_MATCHERS.BlockingHTTPServer, and document opt-in usage.Tests cover Digest header-name casing, custom comparator names, fallback behavior, duplicate keys, instance isolation, legacy behavior, and both regular and blocking HTTP servers.
Validation
On macOS with Python 3.12.11:
git diff --checkpassed.Other operating systems and Python versions, and the full pinned pre-commit environment, were not run locally. Prepared and tested with Codex.