import pytest from .._headers import * def test_normalize_and_validate(): assert normalize_and_validate([("foo", "bar")]) == [(b"foo", b"bar")] assert normalize_and_validate([(b"foo", b"bar")]) == [(b"foo", b"bar")] # no leading/trailing whitespace in names with pytest.raises(LocalProtocolError): normalize_and_validate([(b"foo ", "bar")]) with pytest.raises(LocalProtocolError): normalize_and_validate([(b" foo", "bar")]) # no weird characters in names with pytest.raises(LocalProtocolError) as excinfo: normalize_and_validate([(b"foo bar", b"baz")]) assert "foo bar" in str(excinfo.value) with pytest.raises(LocalProtocolError): normalize_and_validate([(b"foo\x00bar", b"baz")]) # no return or NUL characters in values with pytest.raises(LocalProtocolError) as excinfo: normalize_and_validate([("foo", "bar\rbaz")]) assert "bar\\rbaz" in str(excinfo.value) with pytest.raises(LocalProtocolError): normalize_and_validate([("foo", "bar\nbaz")]) with pytest.raises(LocalProtocolError): normalize_and_validate([("foo", "bar\x00baz")]) # no leading/trailing whitespace with pytest.raises(LocalProtocolError): normalize_and_validate([("foo", " barbaz ")]) # content-length assert (normalize_and_validate([("Content-Length", "1")]) == [(b"content-length", b"1")]) with pytest.raises(LocalProtocolError): normalize_and_validate([("Content-Length", "asdf")]) with pytest.raises(LocalProtocolError): normalize_and_validate([("Content-Length", "1x")]) with pytest.raises(LocalProtocolError): normalize_and_validate([ ("Content-Length", "1"), ("Content-Length", "2"), ]) # transfer-encoding assert (normalize_and_validate([("Transfer-Encoding", "chunked")]) == [(b"transfer-encoding", b"chunked")]) assert (normalize_and_validate([("Transfer-Encoding", "cHuNkEd")]) == [(b"transfer-encoding", b"chunked")]) with pytest.raises(LocalProtocolError) as excinfo: normalize_and_validate([("Transfer-Encoding", "gzip")]) assert excinfo.value.error_status_hint == 501 # Not Implemented with pytest.raises(LocalProtocolError) as excinfo: normalize_and_validate([ ("Transfer-Encoding", "chunked"), ("Transfer-Encoding", "gzip"), ]) assert excinfo.value.error_status_hint == 501 # Not Implemented def test_get_set_comma_header(): headers = normalize_and_validate([ ("Connection", "close"), ("whatever", "something"), ("connectiON", "fOo,, , BAR"), ]) assert get_comma_header(headers, b"connection") == [ b"close", b"foo", b"bar"] set_comma_header(headers, b"newthing", ["a", "b"]) with pytest.raises(LocalProtocolError): set_comma_header(headers, b"newthing", [" a", "b"]) assert headers == [ (b"connection", b"close"), (b"whatever", b"something"), (b"connection", b"fOo,, , BAR"), (b"newthing", b"a"), (b"newthing", b"b"), ] set_comma_header(headers, b"whatever", ["different thing"]) assert headers == [ (b"connection", b"close"), (b"connection", b"fOo,, , BAR"), (b"newthing", b"a"), (b"newthing", b"b"), (b"whatever", b"different thing"), ] def test_has_100_continue(): from .._events import Request assert has_expect_100_continue(Request( method="GET", target="/", headers=[("Host", "example.com"), ("Expect", "100-continue")])) assert not has_expect_100_continue(Request( method="GET", target="/", headers=[("Host", "example.com")])) # Case insensitive assert has_expect_100_continue(Request( method="GET", target="/", headers=[("Host", "example.com"), ("Expect", "100-Continue")])) # Doesn't work in HTTP/1.0 assert not has_expect_100_continue(Request( method="GET", target="/", headers=[("Host", "example.com"), ("Expect", "100-continue")], http_version="1.0"))