1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
import http.client
import requests
from werkzeug.datastructures import Headers
from werkzeug.http import parse_dict_header
from pytest_httpserver import HTTPServer
from pytest_httpserver.httpserver import HeaderValueMatcher
def test_custom_headers(httpserver: HTTPServer):
headers_with_values_in_direct_order = {"Custom": 'Scheme key0="value0", key1="value1"'}
httpserver.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"
# By default different order of items in header value dicts means different header values
headers_with_values_in_modified_order = {"Custom": 'Scheme key1="value1", key0="value0"'}
response = requests.get(httpserver.url_for("/"), headers=headers_with_values_in_modified_order)
assert response.status_code == 500
# Define header_value_matcher that ignores the order of items in header value dict
def custom_header_value_matcher(actual: str, expected: str) -> bool:
actual_scheme, _, actual_dict_str = actual.partition(" ")
expected_scheme, _, expected_dict_str = expected.partition(" ")
actual_dict = parse_dict_header(actual_dict_str)
expected_dict = parse_dict_header(expected_dict_str)
return actual_scheme == expected_scheme and actual_dict == expected_dict
matchers = HeaderValueMatcher.DEFAULT_MATCHERS.copy() # type: ignore
matchers["Custom"] = custom_header_value_matcher
header_value_matcher = HeaderValueMatcher(matchers)
httpserver.handlers.clear()
httpserver.expect_request(
uri="/", headers=headers_with_values_in_direct_order, header_value_matcher=header_value_matcher
).respond_with_data("OK")
response = requests.get(httpserver.url_for("/"), headers=headers_with_values_in_modified_order)
assert response.status_code == 200
assert response.text == "OK"
# See https://en.wikipedia.org/wiki/Digest_access_authentication
def test_authorization_headers(httpserver: HTTPServer):
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"'
)
}
httpserver.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"
headers_with_values_in_modified_order = {
"Authorization": (
"Digest qop=auth,"
'username="Mufasa",'
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",'
'uri="/dir/index.html",'
"nc=00000001,"
'realm="testrealm@host.com",'
'response="6629fae49393a05397450978507c4ef1",'
'cnonce="0a4f113b",'
'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
)
}
response = requests.get(httpserver.url_for("/"), headers=headers_with_values_in_modified_order)
assert response.status_code == 200
assert response.text == "OK"
def test_header_one_key_multiple_values(httpserver: HTTPServer):
httpserver.expect_request(uri="/t1").respond_with_data(headers=[("X-Foo", "123"), ("X-Foo", "456")])
httpserver.expect_request(uri="/t2").respond_with_data(headers={"X-Foo": ["123", "456"]})
headers = Headers()
headers.add("X-Foo", "123")
headers.add("X-Foo", "456")
httpserver.expect_request(uri="/t3").respond_with_data(headers=headers)
for uri in ("/t1", "/t2", "/t3"):
conn = http.client.HTTPConnection("localhost:{}".format(httpserver.port))
conn.request("GET", uri)
response = conn.getresponse()
conn.close()
assert response.status == 200
assert response.headers.get_all("X-Foo") == ["123", "456"]
|