Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_new_values_work(self):
"""
New values initially don't appear
"""
s = h2.settings.Settings(client=True)
s[80] = 81
with pytest.raises(KeyError):
s[80]
def test_cannot_set_invalid_initial_values(self, setting, value):
"""
The Settings object can be provided initial values that override the
defaults.
"""
overrides = {setting: value}
with pytest.raises(h2.exceptions.InvalidSettingsValueError):
h2.settings.Settings(initial_values=overrides)
def test_single_values_arent_affected_by_acknowledgement(self):
"""
When acknowledged, unchanged settings remain unchanged.
"""
s = h2.settings.Settings(client=True)
assert s[h2.settings.SettingCodes.HEADER_TABLE_SIZE] == 4096
s.acknowledge()
assert s[h2.settings.SettingCodes.HEADER_TABLE_SIZE] == 4096
def test_settings_defaults_server(self):
"""
The Settings object begins with the appropriate defaults for servers.
"""
s = h2.settings.Settings(client=False)
assert s[h2.settings.SettingCodes.HEADER_TABLE_SIZE] == 4096
assert s[h2.settings.SettingCodes.ENABLE_PUSH] == 0
assert s[h2.settings.SettingCodes.INITIAL_WINDOW_SIZE] == 65535
assert s[h2.settings.SettingCodes.MAX_FRAME_SIZE] == 16384
assert s[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL] == 0
with pytest.raises(h2.exceptions.InvalidSettingsValueError) as e:
s[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL] = val
s.acknowledge()
assert e.value.error_code == h2.errors.ErrorCodes.PROTOCOL_ERROR
assert s[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL] == 0
class TestSettingsEquality(object):
"""
A class defining tests for the standard implementation of == and != .
"""
SettingsStrategy = builds(
h2.settings.Settings,
client=booleans(),
initial_values=fixed_dictionaries({
h2.settings.SettingCodes.HEADER_TABLE_SIZE:
integers(0, 2**32 - 1),
h2.settings.SettingCodes.ENABLE_PUSH: integers(0, 1),
h2.settings.SettingCodes.INITIAL_WINDOW_SIZE:
integers(0, 2**31 - 1),
h2.settings.SettingCodes.MAX_FRAME_SIZE:
integers(2**14, 2**24 - 1),
h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS:
integers(0, 2**32 - 1),
h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE:
integers(0, 2**32 - 1),
})
)
def test_settings_defaults_client(self):
"""
The Settings object begins with the appropriate defaults for clients.
"""
s = h2.settings.Settings(client=True)
assert s[h2.settings.SettingCodes.HEADER_TABLE_SIZE] == 4096
assert s[h2.settings.SettingCodes.ENABLE_PUSH] == 1
assert s[h2.settings.SettingCodes.INITIAL_WINDOW_SIZE] == 65535
assert s[h2.settings.SettingCodes.MAX_FRAME_SIZE] == 16384
assert s[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL] == 0
def test_settings_setters(self):
"""
Setters exist for well-known settings.
"""
s = h2.settings.Settings(client=True)
s.header_table_size = 0
s.enable_push = 1
s.initial_window_size = 2
s.max_frame_size = 16385
s.max_concurrent_streams = 4
s.max_header_list_size = 2**16
s.enable_connect_protocol = 1
s.acknowledge()
assert s[h2.settings.SettingCodes.HEADER_TABLE_SIZE] == 0
assert s[h2.settings.SettingCodes.ENABLE_PUSH] == 1
assert s[h2.settings.SettingCodes.INITIAL_WINDOW_SIZE] == 2
assert s[h2.settings.SettingCodes.MAX_FRAME_SIZE] == 16385
assert s[h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS] == 4
assert s[h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE] == 2**16
async def send_connection_init(self, timeout: Timeout) -> None:
"""
The HTTP/2 connection requires some initial setup before we can start
using individual request/response streams on it.
"""
# Need to set these manually here instead of manipulating via
# __setitem__() otherwise the H2Connection will emit SettingsUpdate
# frames in addition to sending the undesired defaults.
self.state.local_settings = Settings(
client=True,
initial_values={
# Disable PUSH_PROMISE frames from the server since we don't do anything
# with them for now. Maybe when we support caching?
SettingCodes.ENABLE_PUSH: 0,
# These two are taken from h2 for safe defaults
SettingCodes.MAX_CONCURRENT_STREAMS: 100,
SettingCodes.MAX_HEADER_LIST_SIZE: 65536,
},
)
# Some websites (*cough* Yahoo *cough*) balk at this setting being
# present in the initial handshake since it's not defined in the original
# RFC despite the RFC mandating ignoring settings you don't know about.
del self.state.local_settings[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL]
ssl: bool,
client: Optional[Tuple[str, int]],
server: Optional[Tuple[str, int]],
send: Callable[[Event], Awaitable[None]],
spawn_app: Callable[[dict, Callable], Awaitable[Callable]],
event_class: Type[IOEvent],
) -> None:
self.client = client
self.closed = False
self.config = config
self.connection = h2.connection.H2Connection(
config=h2.config.H2Configuration(client_side=False, header_encoding=None)
)
self.connection.DEFAULT_MAX_INBOUND_FRAME_SIZE = config.h2_max_inbound_frame_size
self.connection.local_settings = h2.settings.Settings(
client=False,
initial_values={
h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: config.h2_max_concurrent_streams,
h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: config.h2_max_header_list_size,
h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL: 1,
},
)
self.event_class = event_class
self.send = send
self.server = server
self.spawn_app = spawn_app
self.ssl = ssl
self.streams: Dict[int, Union[HTTPStream, WSStream]] = {}
# The below are used by the sending task
self.has_data = event_class()
host = url.hostname
port = url.port or 443
ssl_context = ssl if ssl else create_ssl_context()
if (
OP_NO_TLSv1 not in ssl_context.options # type: ignore # https://github.com/python/typeshed/issues/3920
or OP_NO_TLSv1_1 not in ssl_context.options # type: ignore
):
raise ValueError("SSL Context cannot allow TLS 1.0 or 1.1")
# https://bugs.python.org/issue40111 validate context h2 alpn
protocol = h2.connection.H2Connection(
h2.config.H2Configuration(client_side=True, header_encoding="utf-8")
)
protocol.local_settings = h2.settings.Settings(
client=True,
initial_values={
# Apple server settings:
# HEADER_TABLE_SIZE 4096
# MAX_CONCURRENT_STREAMS 1000
# INITIAL_WINDOW_SIZE 65535
# MAX_FRAME_SIZE 16384
# MAX_HEADER_LIST_SIZE 8000
h2.settings.SettingCodes.ENABLE_PUSH: 0,
h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 2 ** 20,
h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: 2 ** 16 - 1,
h2.settings.SettingCodes.INITIAL_WINDOW_SIZE: MAX_RESPONSE_SIZE,
},
)
protocol.initiate_connection()