Skip to content

Commit

Permalink
add more upstream tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BYK authored and Kriechi committed Dec 18, 2024
1 parent c71e301 commit 7fa6a5d
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 251 deletions.
50 changes: 28 additions & 22 deletions test/test_h2_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"""
import base64

from h2.utilities import utf8_encode_headers
import pytest

import h2.config
Expand All @@ -18,16 +19,23 @@
import h2.exceptions


EXAMPLE_REQUEST_HEADERS = [
(':authority', 'example.com'),
(':path', '/'),
(':scheme', 'https'),
(':method', 'GET'),
]
EXAMPLE_REQUEST_HEADERS_BYTES = [
(b':authority', b'example.com'),
(b':path', b'/'),
(b':scheme', b'https'),
(b':method', b'GET'),
]

class TestClientUpgrade(object):
"""
Tests of the client-side of the HTTP/2 upgrade dance.
"""
example_request_headers = [
(b':authority', b'example.com'),
(b':path', b'/'),
(b':scheme', b'https'),
(b':method', b'GET'),
]
example_response_headers = [
(b':status', b'200'),
(b'server', b'fake-serv/0.1.0')
Expand Down Expand Up @@ -97,7 +105,8 @@ def test_can_receive_response(self, frame_factory):

assert not c.data_to_send()

def test_can_receive_pushed_stream(self, frame_factory):
@pytest.mark.parametrize("headers", [EXAMPLE_REQUEST_HEADERS, EXAMPLE_REQUEST_HEADERS_BYTES])
def test_can_receive_pushed_stream(self, frame_factory, headers):
"""
After upgrading, we can safely receive a pushed stream.
"""
Expand All @@ -108,17 +117,18 @@ def test_can_receive_pushed_stream(self, frame_factory):
f = frame_factory.build_push_promise_frame(
stream_id=1,
promised_stream_id=2,
headers=self.example_request_headers,
headers=headers
)
events = c.receive_data(f.serialize())
assert len(events) == 1

assert isinstance(events[0], h2.events.PushedStreamReceived)
assert events[0].headers == self.example_request_headers
assert events[0].headers == utf8_encode_headers(headers)
assert events[0].parent_stream_id == 1
assert events[0].pushed_stream_id == 2

def test_cannot_send_headers_stream_1(self, frame_factory):
@pytest.mark.parametrize("headers", [EXAMPLE_REQUEST_HEADERS, EXAMPLE_REQUEST_HEADERS_BYTES])
def test_cannot_send_headers_stream_1(self, frame_factory, headers):
"""
After upgrading, we cannot send headers on stream 1.
"""
Expand All @@ -127,7 +137,7 @@ def test_cannot_send_headers_stream_1(self, frame_factory):
c.clear_outbound_data_buffer()

with pytest.raises(h2.exceptions.ProtocolError):
c.send_headers(stream_id=1, headers=self.example_request_headers)
c.send_headers(stream_id=1, headers=headers)

def test_cannot_send_data_stream_1(self, frame_factory):
"""
Expand All @@ -145,12 +155,6 @@ class TestServerUpgrade(object):
"""
Tests of the server-side of the HTTP/2 upgrade dance.
"""
example_request_headers = [
(b':authority', b'example.com'),
(b':path', b'/'),
(b':scheme', b'https'),
(b':method', b'GET'),
]
example_response_headers = [
(b':status', b'200'),
(b'server', b'fake-serv/0.1.0')
Expand Down Expand Up @@ -203,7 +207,8 @@ def test_can_send_response(self, frame_factory):
expected_data = f1.serialize() + f2.serialize()
assert c.data_to_send() == expected_data

def test_can_push_stream(self, frame_factory):
@pytest.mark.parametrize("headers", [EXAMPLE_REQUEST_HEADERS, EXAMPLE_REQUEST_HEADERS_BYTES])
def test_can_push_stream(self, frame_factory, headers):
"""
After upgrading, we can safely push a stream.
"""
Expand All @@ -214,17 +219,18 @@ def test_can_push_stream(self, frame_factory):
c.push_stream(
stream_id=1,
promised_stream_id=2,
request_headers=self.example_request_headers
request_headers=headers
)

f = frame_factory.build_push_promise_frame(
stream_id=1,
promised_stream_id=2,
headers=self.example_request_headers,
headers=headers,
)
assert c.data_to_send() == f.serialize()

def test_cannot_receive_headers_stream_1(self, frame_factory):
@pytest.mark.parametrize("headers", [EXAMPLE_REQUEST_HEADERS, EXAMPLE_REQUEST_HEADERS_BYTES])
def test_cannot_receive_headers_stream_1(self, frame_factory, headers):
"""
After upgrading, we cannot receive headers on stream 1.
"""
Expand All @@ -235,7 +241,7 @@ def test_cannot_receive_headers_stream_1(self, frame_factory):

f = frame_factory.build_headers_frame(
stream_id=1,
headers=self.example_request_headers,
headers=headers,
)
c.receive_data(f.serialize())

Expand Down
32 changes: 20 additions & 12 deletions test/test_head_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,32 @@
import pytest


class TestHeadRequest(object):
example_request_headers = [
(b':authority', b'example.com'),
(b':path', b'/'),
(b':scheme', b'https'),
(b':method', b'HEAD'),
]
EXAMPLE_REQUEST_HEADERS_BYTES = [
(b':authority', b'example.com'),
(b':path', b'/'),
(b':scheme', b'https'),
(b':method', b'HEAD'),
]

EXAMPLE_REQUEST_HEADERS = [
(':authority', 'example.com'),
(':path', '/'),
(':scheme', 'https'),
(':method', 'HEAD'),
]

class TestHeadRequest(object):
example_response_headers = [
(b':status', b'200'),
(b'server', b'fake-serv/0.1.0'),
(b'content_length', b'1'),
]

def test_non_zero_content_and_no_body(self, frame_factory):

@pytest.mark.parametrize('headers', [EXAMPLE_REQUEST_HEADERS, EXAMPLE_REQUEST_HEADERS_BYTES])
def test_non_zero_content_and_no_body(self, frame_factory, headers):
c = h2.connection.H2Connection()
c.initiate_connection()
c.send_headers(1, self.example_request_headers, end_stream=True)
c.send_headers(1, headers, end_stream=True)

f = frame_factory.build_headers_frame(
self.example_response_headers,
Expand All @@ -40,10 +47,11 @@ def test_non_zero_content_and_no_body(self, frame_factory):
assert event.stream_id == 1
assert event.headers == self.example_response_headers

def test_reject_non_zero_content_and_body(self, frame_factory):
@pytest.mark.parametrize('headers', [EXAMPLE_REQUEST_HEADERS, EXAMPLE_REQUEST_HEADERS_BYTES])
def test_reject_non_zero_content_and_body(self, frame_factory, headers):
c = h2.connection.H2Connection()
c.initiate_connection()
c.send_headers(1, self.example_request_headers)
c.send_headers(1, headers)

headers = frame_factory.build_headers_frame(
self.example_response_headers
Expand Down
106 changes: 53 additions & 53 deletions test/test_header_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ class TestHeaderIndexing(object):
the appropriate hpack data structures.
"""
example_request_headers = [
HeaderTuple(u':authority', u'example.com'),
HeaderTuple(u':path', u'/'),
HeaderTuple(u':scheme', u'https'),
HeaderTuple(u':method', u'GET'),
HeaderTuple(':authority', 'example.com'),
HeaderTuple(':path', '/'),
HeaderTuple(':scheme', 'https'),
HeaderTuple(':method', 'GET'),
]
bytes_example_request_headers = [
HeaderTuple(b':authority', b'example.com'),
Expand All @@ -45,11 +45,11 @@ class TestHeaderIndexing(object):
]

extended_request_headers = [
HeaderTuple(u':authority', u'example.com'),
HeaderTuple(u':path', u'/'),
HeaderTuple(u':scheme', u'https'),
HeaderTuple(u':method', u'GET'),
NeverIndexedHeaderTuple(u'authorization', u'realpassword'),
HeaderTuple(':authority', 'example.com'),
HeaderTuple(':path', '/'),
HeaderTuple(':scheme', 'https'),
HeaderTuple(':method', 'GET'),
NeverIndexedHeaderTuple('authorization', 'realpassword'),
]
bytes_extended_request_headers = [
HeaderTuple(b':authority', b'example.com'),
Expand All @@ -60,18 +60,18 @@ class TestHeaderIndexing(object):
]

example_response_headers = [
HeaderTuple(u':status', u'200'),
HeaderTuple(u'server', u'fake-serv/0.1.0')
HeaderTuple(':status', '200'),
HeaderTuple('server', 'fake-serv/0.1.0')
]
bytes_example_response_headers = [
HeaderTuple(b':status', b'200'),
HeaderTuple(b'server', b'fake-serv/0.1.0')
]

extended_response_headers = [
HeaderTuple(u':status', u'200'),
HeaderTuple(u'server', u'fake-serv/0.1.0'),
NeverIndexedHeaderTuple(u'secure', u'you-bet'),
HeaderTuple(':status', '200'),
HeaderTuple('server', 'fake-serv/0.1.0'),
NeverIndexedHeaderTuple('secure', 'you-bet'),
]
bytes_extended_response_headers = [
HeaderTuple(b':status', b'200'),
Expand Down Expand Up @@ -228,7 +228,7 @@ def test_header_tuples_are_decoded_info_response(self,
# to avoid breaking the example headers.
headers = headers[:]
if encoding:
headers[0] = HeaderTuple(u':status', u'100')
headers[0] = HeaderTuple(':status', '100')
else:
headers[0] = HeaderTuple(b':status', b'100')

Expand Down Expand Up @@ -334,10 +334,10 @@ class TestSecureHeaders(object):
Certain headers should always be transformed to their never-indexed form.
"""
example_request_headers = [
(u':authority', u'example.com'),
(u':path', u'/'),
(u':scheme', u'https'),
(u':method', u'GET'),
(':authority', 'example.com'),
(':path', '/'),
(':scheme', 'https'),
(':method', 'GET'),
]
bytes_example_request_headers = [
(b':authority', b'example.com'),
Expand All @@ -346,15 +346,15 @@ class TestSecureHeaders(object):
(b':method', b'GET'),
]
possible_auth_headers = [
(u'authorization', u'test'),
(u'Authorization', u'test'),
(u'authorization', u'really long test'),
HeaderTuple(u'authorization', u'test'),
HeaderTuple(u'Authorization', u'test'),
HeaderTuple(u'authorization', u'really long test'),
NeverIndexedHeaderTuple(u'authorization', u'test'),
NeverIndexedHeaderTuple(u'Authorization', u'test'),
NeverIndexedHeaderTuple(u'authorization', u'really long test'),
('authorization', 'test'),
('Authorization', 'test'),
('authorization', 'really long test'),
HeaderTuple('authorization', 'test'),
HeaderTuple('Authorization', 'test'),
HeaderTuple('authorization', 'really long test'),
NeverIndexedHeaderTuple('authorization', 'test'),
NeverIndexedHeaderTuple('Authorization', 'test'),
NeverIndexedHeaderTuple('authorization', 'really long test'),
(b'authorization', b'test'),
(b'Authorization', b'test'),
(b'authorization', b'really long test'),
Expand All @@ -364,15 +364,15 @@ class TestSecureHeaders(object):
NeverIndexedHeaderTuple(b'authorization', b'test'),
NeverIndexedHeaderTuple(b'Authorization', b'test'),
NeverIndexedHeaderTuple(b'authorization', b'really long test'),
(u'proxy-authorization', u'test'),
(u'Proxy-Authorization', u'test'),
(u'proxy-authorization', u'really long test'),
HeaderTuple(u'proxy-authorization', u'test'),
HeaderTuple(u'Proxy-Authorization', u'test'),
HeaderTuple(u'proxy-authorization', u'really long test'),
NeverIndexedHeaderTuple(u'proxy-authorization', u'test'),
NeverIndexedHeaderTuple(u'Proxy-Authorization', u'test'),
NeverIndexedHeaderTuple(u'proxy-authorization', u'really long test'),
('proxy-authorization', 'test'),
('Proxy-Authorization', 'test'),
('proxy-authorization', 'really long test'),
HeaderTuple('proxy-authorization', 'test'),
HeaderTuple('Proxy-Authorization', 'test'),
HeaderTuple('proxy-authorization', 'really long test'),
NeverIndexedHeaderTuple('proxy-authorization', 'test'),
NeverIndexedHeaderTuple('Proxy-Authorization', 'test'),
NeverIndexedHeaderTuple('proxy-authorization', 'really long test'),
(b'proxy-authorization', b'test'),
(b'Proxy-Authorization', b'test'),
(b'proxy-authorization', b'really long test'),
Expand All @@ -384,16 +384,16 @@ class TestSecureHeaders(object):
NeverIndexedHeaderTuple(b'proxy-authorization', b'really long test'),
]
secured_cookie_headers = [
(u'cookie', u'short'),
(u'Cookie', u'short'),
(u'cookie', u'nineteen byte cooki'),
HeaderTuple(u'cookie', u'short'),
HeaderTuple(u'Cookie', u'short'),
HeaderTuple(u'cookie', u'nineteen byte cooki'),
NeverIndexedHeaderTuple(u'cookie', u'short'),
NeverIndexedHeaderTuple(u'Cookie', u'short'),
NeverIndexedHeaderTuple(u'cookie', u'nineteen byte cooki'),
NeverIndexedHeaderTuple(u'cookie', u'longer manually secured cookie'),
('cookie', 'short'),
('Cookie', 'short'),
('cookie', 'nineteen byte cooki'),
HeaderTuple('cookie', 'short'),
HeaderTuple('Cookie', 'short'),
HeaderTuple('cookie', 'nineteen byte cooki'),
NeverIndexedHeaderTuple('cookie', 'short'),
NeverIndexedHeaderTuple('Cookie', 'short'),
NeverIndexedHeaderTuple('cookie', 'nineteen byte cooki'),
NeverIndexedHeaderTuple('cookie', 'longer manually secured cookie'),
(b'cookie', b'short'),
(b'Cookie', b'short'),
(b'cookie', b'nineteen byte cooki'),
Expand All @@ -406,12 +406,12 @@ class TestSecureHeaders(object):
NeverIndexedHeaderTuple(b'cookie', b'longer manually secured cookie'),
]
unsecured_cookie_headers = [
(u'cookie', u'twenty byte cookie!!'),
(u'Cookie', u'twenty byte cookie!!'),
(u'cookie', u'substantially longer than 20 byte cookie'),
HeaderTuple(u'cookie', u'twenty byte cookie!!'),
HeaderTuple(u'cookie', u'twenty byte cookie!!'),
HeaderTuple(u'Cookie', u'twenty byte cookie!!'),
('cookie', 'twenty byte cookie!!'),
('Cookie', 'twenty byte cookie!!'),
('cookie', 'substantially longer than 20 byte cookie'),
HeaderTuple('cookie', 'twenty byte cookie!!'),
HeaderTuple('cookie', 'twenty byte cookie!!'),
HeaderTuple('Cookie', 'twenty byte cookie!!'),
(b'cookie', b'twenty byte cookie!!'),
(b'Cookie', b'twenty byte cookie!!'),
(b'cookie', b'substantially longer than 20 byte cookie'),
Expand Down
Loading

0 comments on commit 7fa6a5d

Please sign in to comment.