def test_expected_http_body_size(): # Expect: 100-continue assert expected_http_body_size( treq(headers=Headers(expect="100-continue", content_length="42"))) == 0 # http://tools.ietf.org/html/rfc7230#section-3.3 assert expected_http_body_size( treq(method=b"HEAD"), tresp(headers=Headers(content_length="42"))) == 0 assert expected_http_body_size(treq(method=b"CONNECT"), tresp()) == 0 for code in (100, 204, 304): assert expected_http_body_size(treq(), tresp(status_code=code)) == 0 # chunked assert expected_http_body_size( treq(headers=Headers(transfer_encoding="chunked")), ) is None # explicit length for val in (b"foo", b"-7"): with pytest.raises(exceptions.HttpSyntaxException): expected_http_body_size(treq(headers=Headers(content_length=val))) assert expected_http_body_size( treq(headers=Headers(content_length="42"))) == 42 # no length assert expected_http_body_size(treq(headers=Headers())) == 0 assert expected_http_body_size(treq(headers=Headers()), tresp(headers=Headers())) == -1
def test_expected_http_body_size(): # Expect: 100-continue assert expected_http_body_size( treq(headers=Headers(expect="100-continue", content_length="42")) ) == 0 # http://tools.ietf.org/html/rfc7230#section-3.3 assert expected_http_body_size( treq(method=b"HEAD"), tresp(headers=Headers(content_length="42")) ) == 0 assert expected_http_body_size( treq(method=b"CONNECT"), tresp() ) == 0 for code in (100, 204, 304): assert expected_http_body_size( treq(), tresp(status_code=code) ) == 0 # chunked assert expected_http_body_size( treq(headers=Headers(transfer_encoding="chunked")), ) is None # explicit length for val in (b"foo", b"-7"): with pytest.raises(exceptions.HttpSyntaxException): expected_http_body_size( treq(headers=Headers(content_length=val)) ) assert expected_http_body_size( treq(headers=Headers(content_length="42")) ) == 42 # no length assert expected_http_body_size( treq(headers=Headers()) ) == 0 assert expected_http_body_size( treq(headers=Headers()), tresp(headers=Headers()) ) == -1
def expected_http_body_size( request: request.Request, response: Optional[response.Response] = None, expect_continue_as_0: bool = True, ): """ Like the non-sans-io version, but also treating CONNECT as content-length: 0 """ if request.data.method.upper() == b"CONNECT": return 0 return read.expected_http_body_size(request, response, expect_continue_as_0)
def test_expected_http_body_size(): # Expect: 100-continue assert expected_http_body_size( treq(headers=Headers(expect="100-continue", content_length="42")), expect_continue_as_0=True) == 0 # Expect: 100-continue assert expected_http_body_size( treq(headers=Headers(expect="100-continue", content_length="42")), expect_continue_as_0=False) == 42 # http://tools.ietf.org/html/rfc7230#section-3.3 assert expected_http_body_size( treq(method=b"HEAD"), tresp(headers=Headers(content_length="42"))) == 0 assert expected_http_body_size( treq(method=b"CONNECT"), None, ) == 0 assert expected_http_body_size(treq(method=b"CONNECT"), tresp()) == 0 for code in (100, 204, 304): assert expected_http_body_size(treq(), tresp(status_code=code)) == 0 # chunked assert expected_http_body_size( treq(headers=Headers(transfer_encoding="chunked")), ) is None # explicit length for val in (b"foo", b"-7"): with pytest.raises(ValueError): expected_http_body_size(treq(headers=Headers(content_length=val))) assert expected_http_body_size( treq(headers=Headers(content_length="42"))) == 42 # more than 1 content-length headers with same value assert expected_http_body_size( treq(headers=Headers([(b'content-length', b'42'), (b'content-length', b'42')]))) == 42 # more than 1 content-length headers with conflicting value with pytest.raises(ValueError): expected_http_body_size( treq(headers=Headers([(b'content-length', b'42'), (b'content-length', b'45')]))) # no length assert expected_http_body_size(treq(headers=Headers())) == 0 assert expected_http_body_size(treq(headers=Headers()), tresp(headers=Headers())) == -1
def test_expected_http_body_size(): # Expect: 100-continue assert expected_http_body_size( treq(headers=Headers(expect="100-continue", content_length="42")), ) == 42 # http://tools.ietf.org/html/rfc7230#section-3.3 assert expected_http_body_size( treq(method=b"HEAD"), tresp(headers=Headers(content_length="42"))) == 0 assert expected_http_body_size( treq(method=b"CONNECT", headers=Headers()), None, ) == 0 assert expected_http_body_size(treq(method=b"CONNECT"), tresp()) == 0 for code in (100, 204, 304): assert expected_http_body_size(treq(), tresp(status_code=code)) == 0 # chunked assert expected_http_body_size( treq(headers=Headers(transfer_encoding="chunked")), ) is None assert expected_http_body_size( treq(headers=Headers(transfer_encoding="gzip,\tchunked")), ) is None # both content-length and chunked (possible request smuggling) with pytest.raises( ValueError, match= "Received both a Transfer-Encoding and a Content-Length header"): expected_http_body_size( treq(headers=Headers(transfer_encoding="chunked", content_length="42")), ) with pytest.raises(ValueError, match="Invalid transfer encoding"): expected_http_body_size( treq(headers=Headers(transfer_encoding="chun\u212Aed") ), # "chunKed".lower() == "chunked" ) with pytest.raises(ValueError, match="Unknown transfer encoding"): expected_http_body_size( treq(headers=Headers(transfer_encoding="chun ked") ), # "chunKed".lower() == "chunked" ) with pytest.raises(ValueError, match="Unknown transfer encoding"): expected_http_body_size( treq(headers=Headers(transfer_encoding="qux")), ) # transfer-encoding: gzip with pytest.raises(ValueError, match="Invalid request transfer encoding"): expected_http_body_size( treq(headers=Headers(transfer_encoding="gzip")), ) assert expected_http_body_size( treq(), tresp(headers=Headers(transfer_encoding="gzip")), ) == -1 # explicit length for val in (b"foo", b"-7"): with pytest.raises(ValueError): expected_http_body_size(treq(headers=Headers(content_length=val))) assert expected_http_body_size( treq(headers=Headers(content_length="42"))) == 42 # multiple content-length headers with same value assert expected_http_body_size( treq(headers=Headers([(b'content-length', b'42'), (b'content-length', b'42')]))) == 42 # multiple content-length headers with conflicting value with pytest.raises(ValueError, match="Conflicting Content-Length headers"): expected_http_body_size( treq(headers=Headers([(b'content-length', b'42'), (b'content-length', b'45')]))) # non-int content-length with pytest.raises(ValueError, match="Invalid Content-Length header"): expected_http_body_size( treq(headers=Headers([(b'content-length', b'NaN')]))) # negative content-length with pytest.raises(ValueError, match="Negative Content-Length header"): expected_http_body_size( treq(headers=Headers([(b'content-length', b'-1')]))) # no length assert expected_http_body_size(treq(headers=Headers())) == 0 assert expected_http_body_size(treq(headers=Headers()), tresp(headers=Headers())) == -1