Source code

Revision control

Copy as Markdown

Other Tools

# -*- coding: utf-8 -*-
"""
test_invalid_content_lengths.py
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module contains tests that use invalid content lengths, and validates that
they fail appropriately.
"""
import pytest
import h2.config
import h2.connection
import h2.errors
import h2.events
import h2.exceptions
class TestInvalidContentLengths(object):
"""
Hyper-h2 raises Protocol Errors when the content-length sent by a remote
peer is not valid.
"""
example_request_headers = [
(':authority', 'example.com'),
(':path', '/'),
(':scheme', 'https'),
(':method', 'POST'),
('content-length', '15'),
]
example_response_headers = [
(':status', '200'),
('server', 'fake-serv/0.1.0')
]
server_config = h2.config.H2Configuration(client_side=False)
def test_too_much_data(self, frame_factory):
"""
Remote peers sending data in excess of content-length causes Protocol
Errors.
"""
c = h2.connection.H2Connection(config=self.server_config)
c.initiate_connection()
c.receive_data(frame_factory.preamble())
headers = frame_factory.build_headers_frame(
headers=self.example_request_headers
)
first_data = frame_factory.build_data_frame(data=b'\x01'*15)
c.receive_data(headers.serialize() + first_data.serialize())
c.clear_outbound_data_buffer()
second_data = frame_factory.build_data_frame(data=b'\x01')
with pytest.raises(h2.exceptions.InvalidBodyLengthError) as exp:
c.receive_data(second_data.serialize())
assert exp.value.expected_length == 15
assert exp.value.actual_length == 16
assert str(exp.value) == (
"InvalidBodyLengthError: Expected 15 bytes, received 16"
)
expected_frame = frame_factory.build_goaway_frame(
last_stream_id=1,
error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
)
assert c.data_to_send() == expected_frame.serialize()
def test_insufficient_data(self, frame_factory):
"""
Remote peers sending less data than content-length causes Protocol
Errors.
"""
c = h2.connection.H2Connection(config=self.server_config)
c.initiate_connection()
c.receive_data(frame_factory.preamble())
headers = frame_factory.build_headers_frame(
headers=self.example_request_headers
)
first_data = frame_factory.build_data_frame(data=b'\x01'*13)
c.receive_data(headers.serialize() + first_data.serialize())
c.clear_outbound_data_buffer()
second_data = frame_factory.build_data_frame(
data=b'\x01',
flags=['END_STREAM'],
)
with pytest.raises(h2.exceptions.InvalidBodyLengthError) as exp:
c.receive_data(second_data.serialize())
assert exp.value.expected_length == 15
assert exp.value.actual_length == 14
assert str(exp.value) == (
"InvalidBodyLengthError: Expected 15 bytes, received 14"
)
expected_frame = frame_factory.build_goaway_frame(
last_stream_id=1,
error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
)
assert c.data_to_send() == expected_frame.serialize()
def test_insufficient_data_empty_frame(self, frame_factory):
"""
Remote peers sending less data than content-length where the last data
frame is empty causes Protocol Errors.
"""
c = h2.connection.H2Connection(config=self.server_config)
c.initiate_connection()
c.receive_data(frame_factory.preamble())
headers = frame_factory.build_headers_frame(
headers=self.example_request_headers
)
first_data = frame_factory.build_data_frame(data=b'\x01'*14)
c.receive_data(headers.serialize() + first_data.serialize())
c.clear_outbound_data_buffer()
second_data = frame_factory.build_data_frame(
data=b'',
flags=['END_STREAM'],
)
with pytest.raises(h2.exceptions.InvalidBodyLengthError) as exp:
c.receive_data(second_data.serialize())
assert exp.value.expected_length == 15
assert exp.value.actual_length == 14
assert str(exp.value) == (
"InvalidBodyLengthError: Expected 15 bytes, received 14"
)
expected_frame = frame_factory.build_goaway_frame(
last_stream_id=1,
error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
)
assert c.data_to_send() == expected_frame.serialize()