# -*- coding: utf-8 -*-
"""
test_basic_logic
~~~~~~~~~~~~~~~~

Test the basic logic of the h2 state machines.
"""
import random
import sys

import hyperframe
import pytest

import h2.config
import h2.connection
import h2.errors
import h2.events
import h2.exceptions
import h2.frame_buffer
import h2.settings
import h2.stream

import helpers

from hypothesis import given
from hypothesis.strategies import integers


IS_PYTHON3 = sys.version_info >= (3, 0)


class TestBasicClient(object):
    """
    Basic client-side tests.
    """
    example_request_headers = [
        (u':authority', u'example.com'),
        (u':path', u'/'),
        (u':scheme', u'https'),
        (u':method', u'GET'),
    ]
    bytes_example_request_headers = [
        (b':authority', b'example.com'),
        (b':path', b'/'),
        (b':scheme', b'https'),
        (b':method', b'GET'),
    ]
    example_response_headers = [
        (u':status', u'200'),
        (u'server', u'fake-serv/0.1.0')
    ]
    bytes_example_response_headers = [
        (b':status', b'200'),
        (b'server', b'fake-serv/0.1.0')
    ]

    def test_begin_connection(self, frame_factory):
        """
        Client connections emit the HTTP/2 preamble.
        """
        c = h2.connection.H2Connection()
        expected_settings = frame_factory.build_settings_frame(
            c.local_settings
        )
        expected_data = (
            b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n' + expected_settings.serialize()
        )

        events = c.initiate_connection()
        assert not events
        assert c.data_to_send() == expected_data

    def test_sending_headers(self):
        """
        Single headers frames are correctly encoded.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()

        # Clear the data, then send headers.
        c.clear_outbound_data_buffer()
        events = c.send_headers(1, self.example_request_headers)
        assert not events
        assert c.data_to_send() == (
            b'\x00\x00\r\x01\x04\x00\x00\x00\x01'
            b'A\x88/\x91\xd3]\x05\\\x87\xa7\x84\x87\x82'
        )

    def test_sending_data(self):
        """
        Single data frames are encoded correctly.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)

        # Clear the data, then send some data.
        c.clear_outbound_data_buffer()
        events = c.send_data(1, b'some data')
        assert not events
        data_to_send = c.data_to_send()
        assert (
            data_to_send == b'\x00\x00\t\x00\x00\x00\x00\x00\x01some data'
        )

        buffer = h2.frame_buffer.FrameBuffer(server=False)
        buffer.max_frame_size = 65535
        buffer.add_data(data_to_send)
        data_frame = list(buffer)[0]
        sanity_check_data_frame(
            data_frame=data_frame,
            expected_flow_controlled_length=len(b'some data'),
            expect_padded_flag=False,
            expected_data_frame_pad_length=0
        )

    def test_sending_data_with_padding(self):
        """
        Single data frames with padding are encoded correctly.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)

        # Clear the data, then send some data.
        c.clear_outbound_data_buffer()
        events = c.send_data(1, b'some data', pad_length=5)
        assert not events
        data_to_send = c.data_to_send()
        assert data_to_send == (
            b'\x00\x00\x0f\x00\x08\x00\x00\x00\x01'
            b'\x05some data\x00\x00\x00\x00\x00'
        )

        buffer = h2.frame_buffer.FrameBuffer(server=False)
        buffer.max_frame_size = 65535
        buffer.add_data(data_to_send)
        data_frame = list(buffer)[0]
        sanity_check_data_frame(
            data_frame=data_frame,
            expected_flow_controlled_length=len(b'some data') + 1 + 5,
            expect_padded_flag=True,
            expected_data_frame_pad_length=5
        )

    def test_sending_data_with_zero_length_padding(self):
        """
        Single data frames with zero-length padding are encoded
        correctly.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)

        # Clear the data, then send some data.
        c.clear_outbound_data_buffer()
        events = c.send_data(1, b'some data', pad_length=0)
        assert not events
        data_to_send = c.data_to_send()
        assert data_to_send == (
            b'\x00\x00\x0a\x00\x08\x00\x00\x00\x01'
            b'\x00some data'
        )

        buffer = h2.frame_buffer.FrameBuffer(server=False)
        buffer.max_frame_size = 65535
        buffer.add_data(data_to_send)
        data_frame = list(buffer)[0]
        sanity_check_data_frame(
            data_frame=data_frame,
            expected_flow_controlled_length=len(b'some data') + 1,
            expect_padded_flag=True,
            expected_data_frame_pad_length=0
        )

    @pytest.mark.parametrize("expected_error,pad_length", [
        (None,  0),
        (None, 255),
        (None, None),
        (ValueError, -1),
        (ValueError, 256),
        (TypeError, 'invalid'),
        (TypeError, ''),
        (TypeError, '10'),
        (TypeError, {}),
        (TypeError, ['1', '2', '3']),
        (TypeError, []),
        (TypeError, 1.5),
        (TypeError, 1.0),
        (TypeError, -1.0),
    ])
    def test_sending_data_with_invalid_padding_length(self,
                                                      expected_error,
                                                      pad_length):
        """
        ``send_data`` with a ``pad_length`` parameter that is an integer
        outside the range of [0, 255] throws a ``ValueError``, and a
        ``pad_length`` parameter which is not an ``integer`` type
        throws a ``TypeError``.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)

        c.clear_outbound_data_buffer()
        if expected_error is not None:
            with pytest.raises(expected_error):
                c.send_data(1, b'some data', pad_length=pad_length)
        else:
            c.send_data(1, b'some data', pad_length=pad_length)

    def test_closing_stream_sending_data(self, frame_factory):
        """
        We can close a stream with a data frame.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)

        f = frame_factory.build_data_frame(
            data=b'some data',
            flags=['END_STREAM'],
        )

        # Clear the data, then send some data.
        c.clear_outbound_data_buffer()
        events = c.send_data(1, b'some data', end_stream=True)
        assert not events
        assert c.data_to_send() == f.serialize()

    def test_receiving_a_response(self, frame_factory):
        """
        When receiving a response, the ResponseReceived event fires.
        """
        config = h2.config.H2Configuration(header_encoding='utf-8')
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)

        # Clear the data
        f = frame_factory.build_headers_frame(
            self.example_response_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ResponseReceived)
        assert event.stream_id == 1
        assert event.headers == self.example_response_headers

    def test_receiving_a_response_bytes(self, frame_factory):
        """
        When receiving a response, the ResponseReceived event fires with bytes
        headers if the encoding is set appropriately.
        """
        config = h2.config.H2Configuration(header_encoding=False)
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)

        # Clear the data
        f = frame_factory.build_headers_frame(
            self.example_response_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ResponseReceived)
        assert event.stream_id == 1
        assert event.headers == self.bytes_example_response_headers

    def test_receiving_a_response_change_encoding(self, frame_factory):
        """
        When receiving a response, the ResponseReceived event fires with bytes
        headers if the encoding is set appropriately, but if this changes then
        the change reflects it.
        """
        config = h2.config.H2Configuration(header_encoding=False)
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)

        f = frame_factory.build_headers_frame(
            self.example_response_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ResponseReceived)
        assert event.stream_id == 1
        assert event.headers == self.bytes_example_response_headers

        c.send_headers(3, self.example_request_headers, end_stream=True)
        c.config.header_encoding = 'utf-8'
        f = frame_factory.build_headers_frame(
            self.example_response_headers,
            stream_id=3,
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ResponseReceived)
        assert event.stream_id == 3
        assert event.headers == self.example_response_headers

    def test_end_stream_without_data(self, frame_factory):
        """
        Ending a stream without data emits a zero-length DATA frame with
        END_STREAM set.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=False)

        # Clear the data
        c.clear_outbound_data_buffer()
        f = frame_factory.build_data_frame(b'', flags=['END_STREAM'])
        events = c.end_stream(1)

        assert not events
        assert c.data_to_send() == f.serialize()

    def test_cannot_send_headers_on_lower_stream_id(self):
        """
        Once stream ID x has been used, cannot use stream ID y where y < x.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(3, self.example_request_headers, end_stream=False)

        with pytest.raises(h2.exceptions.StreamIDTooLowError) as e:
            c.send_headers(1, self.example_request_headers, end_stream=True)

        assert e.value.stream_id == 1
        assert e.value.max_stream_id == 3

    def test_receiving_pushed_stream(self, frame_factory):
        """
        Pushed streams fire a PushedStreamReceived event, followed by
        ResponseReceived when the response headers are received.
        """
        config = h2.config.H2Configuration(header_encoding='utf-8')
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=False)

        f1 = frame_factory.build_headers_frame(
            self.example_response_headers
        )
        f2 = frame_factory.build_push_promise_frame(
            stream_id=1,
            promised_stream_id=2,
            headers=self.example_request_headers,
            flags=['END_HEADERS'],
        )
        f3 = frame_factory.build_headers_frame(
            self.example_response_headers,
            stream_id=2,
        )
        data = b''.join(x.serialize() for x in [f1, f2, f3])

        events = c.receive_data(data)

        assert len(events) == 3
        stream_push_event = events[1]
        response_event = events[2]
        assert isinstance(stream_push_event, h2.events.PushedStreamReceived)
        assert isinstance(response_event, h2.events.ResponseReceived)

        assert stream_push_event.pushed_stream_id == 2
        assert stream_push_event.parent_stream_id == 1
        assert (
            stream_push_event.headers == self.example_request_headers
        )
        assert response_event.stream_id == 2
        assert response_event.headers == self.example_response_headers

    def test_receiving_pushed_stream_bytes(self, frame_factory):
        """
        Pushed headers are not decoded if the header encoding is set to False.
        """
        config = h2.config.H2Configuration(header_encoding=False)
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=False)

        f1 = frame_factory.build_headers_frame(
            self.example_response_headers
        )
        f2 = frame_factory.build_push_promise_frame(
            stream_id=1,
            promised_stream_id=2,
            headers=self.example_request_headers,
            flags=['END_HEADERS'],
        )
        f3 = frame_factory.build_headers_frame(
            self.example_response_headers,
            stream_id=2,
        )
        data = b''.join(x.serialize() for x in [f1, f2, f3])

        events = c.receive_data(data)

        assert len(events) == 3
        stream_push_event = events[1]
        response_event = events[2]
        assert isinstance(stream_push_event, h2.events.PushedStreamReceived)
        assert isinstance(response_event, h2.events.ResponseReceived)

        assert stream_push_event.pushed_stream_id == 2
        assert stream_push_event.parent_stream_id == 1
        assert (
            stream_push_event.headers == self.bytes_example_request_headers
        )
        assert response_event.stream_id == 2
        assert response_event.headers == self.bytes_example_response_headers

    def test_cannot_receive_pushed_stream_when_enable_push_is_0(self,
                                                                frame_factory):
        """
        If we have set SETTINGS_ENABLE_PUSH to 0, receiving PUSH_PROMISE frames
        triggers the connection to be closed.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.local_settings.enable_push = 0
        c.send_headers(1, self.example_request_headers, end_stream=False)

        f1 = frame_factory.build_settings_frame({}, ack=True)
        f2 = frame_factory.build_headers_frame(
            self.example_response_headers
        )
        f3 = frame_factory.build_push_promise_frame(
            stream_id=1,
            promised_stream_id=2,
            headers=self.example_request_headers,
            flags=['END_HEADERS'],
        )
        c.receive_data(f1.serialize())
        c.receive_data(f2.serialize())
        c.clear_outbound_data_buffer()

        with pytest.raises(h2.exceptions.ProtocolError):
            c.receive_data(f3.serialize())

        expected_frame = frame_factory.build_goaway_frame(
            0, h2.errors.ErrorCodes.PROTOCOL_ERROR
        )
        assert c.data_to_send() == expected_frame.serialize()

    def test_receiving_response_no_body(self, frame_factory):
        """
        Receiving a response without a body fires two events, ResponseReceived
        and StreamEnded.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)

        f = frame_factory.build_headers_frame(
            self.example_response_headers,
            flags=['END_STREAM']
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 2
        response_event = events[0]
        end_stream = events[1]

        assert isinstance(response_event, h2.events.ResponseReceived)
        assert isinstance(end_stream, h2.events.StreamEnded)

    def test_oversize_headers(self):
        """
        Sending headers that are oversized generates a stream of CONTINUATION
        frames.
        """
        all_bytes = [chr(x) for x in range(0, 256)]
        if IS_PYTHON3:
            all_bytes = [x.encode('latin1') for x in all_bytes]

        large_binary_string = b''.join(
            random.choice(all_bytes) for _ in range(0, 256)
        )
        test_headers = [
            (':authority', 'example.com'),
            (':path', '/'),
            (':method', 'GET'),
            (':scheme', 'https'),
            ('key', large_binary_string)
        ]
        c = h2.connection.H2Connection()

        # Greatly shrink the max frame size to force us over.
        c.max_outbound_frame_size = 48
        c.initiate_connection()
        c.send_headers(1, test_headers, end_stream=True)

        # Use the frame buffer here, because we don't care about decoding
        # the headers. Don't send all the data in because that will force the
        # frame buffer to stop caching the CONTINUATION frames, so instead
        # send all but one byte.
        buffer = h2.frame_buffer.FrameBuffer(server=True)
        buffer.max_frame_size = 65535
        data = c.data_to_send()
        buffer.add_data(data[:-1])

        # Drain the buffer, confirming that it only provides a single frame
        # (the settings frame)
        assert len(list(buffer)) == 1

        # Get the cached frames.
        frames = buffer._headers_buffer

        # Split the frames up.
        headers_frame = frames[0]
        continuation_frames = frames[1:]

        assert isinstance(headers_frame, hyperframe.frame.HeadersFrame)
        assert all(
            map(
                lambda f: isinstance(f, hyperframe.frame.ContinuationFrame),
                continuation_frames)
        )
        assert all(
            map(lambda f: len(f.data) <= c.max_outbound_frame_size, frames)
        )

        assert frames[0].flags == {'END_STREAM'}

        buffer.add_data(data[-1:])
        headers = list(buffer)[0]
        assert isinstance(headers, hyperframe.frame.HeadersFrame)

    def test_handle_stream_reset(self, frame_factory):
        """
        Streams being remotely reset fires a StreamReset event.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)
        c.clear_outbound_data_buffer()

        f = frame_factory.build_rst_stream_frame(
            stream_id=1,
            error_code=h2.errors.ErrorCodes.STREAM_CLOSED,
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.StreamReset)
        assert event.stream_id == 1
        assert event.error_code is h2.errors.ErrorCodes.STREAM_CLOSED
        assert isinstance(event.error_code, h2.errors.ErrorCodes)
        assert event.remote_reset

    def test_handle_stream_reset_with_unknown_erorr_code(self, frame_factory):
        """
        Streams being remotely reset with unknown error codes behave exactly as
        they do with known error codes, but the error code on the event is an
        int, instead of being an ErrorCodes.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)
        c.clear_outbound_data_buffer()

        f = frame_factory.build_rst_stream_frame(stream_id=1, error_code=0xFA)
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.StreamReset)
        assert event.stream_id == 1
        assert event.error_code == 250
        assert not isinstance(event.error_code, h2.errors.ErrorCodes)
        assert event.remote_reset

    def test_can_consume_partial_data_from_connection(self):
        """
        We can do partial reads from the connection.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()

        assert len(c.data_to_send(2)) == 2
        assert len(c.data_to_send(3)) == 3
        assert 0 < len(c.data_to_send(500)) < 500
        assert len(c.data_to_send(10)) == 0
        assert len(c.data_to_send()) == 0

    def test_we_can_update_settings(self, frame_factory):
        """
        Updating the settings emits a SETTINGS frame.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.clear_outbound_data_buffer()

        new_settings = {
            h2.settings.SettingCodes.HEADER_TABLE_SIZE: 52,
            h2.settings.SettingCodes.ENABLE_PUSH: 0,
        }
        events = c.update_settings(new_settings)
        assert not events

        f = frame_factory.build_settings_frame(new_settings)
        assert c.data_to_send() == f.serialize()

    def test_settings_get_acked_correctly(self, frame_factory):
        """
        When settings changes are ACKed, they contain the changed settings.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()

        new_settings = {
            h2.settings.SettingCodes.HEADER_TABLE_SIZE: 52,
            h2.settings.SettingCodes.ENABLE_PUSH: 0,
        }
        c.update_settings(new_settings)

        f = frame_factory.build_settings_frame({}, ack=True)
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.SettingsAcknowledged)
        assert len(event.changed_settings) == len(new_settings)
        for setting, value in new_settings.items():
            assert event.changed_settings[setting].new_value == value

    def test_cannot_create_new_outbound_stream_over_limit(self, frame_factory):
        """
        When the number of outbound streams exceeds the remote peer's
        MAX_CONCURRENT_STREAMS setting, attempting to open new streams fails.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()

        f = frame_factory.build_settings_frame(
            {h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 1}
        )
        c.receive_data(f.serialize())[0]

        c.send_headers(1, self.example_request_headers)

        with pytest.raises(h2.exceptions.TooManyStreamsError):
            c.send_headers(3, self.example_request_headers)

    def test_can_receive_trailers(self, frame_factory):
        """
        When two HEADERS blocks are received in the same stream from a
        server, the second set are trailers.
        """
        config = h2.config.H2Configuration(header_encoding='utf-8')
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)
        f = frame_factory.build_headers_frame(self.example_response_headers)
        c.receive_data(f.serialize())

        # Send in trailers.
        trailers = [('content-length', '0')]
        f = frame_factory.build_headers_frame(
            trailers,
            flags=['END_STREAM'],
        )
        events = c.receive_data(f.serialize())
        assert len(events) == 2

        event = events[0]
        assert isinstance(event, h2.events.TrailersReceived)
        assert event.headers == trailers
        assert event.stream_id == 1

    def test_reject_trailers_not_ending_stream(self, frame_factory):
        """
        When trailers are received without the END_STREAM flag being present,
        this is a ProtocolError.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers)
        f = frame_factory.build_headers_frame(self.example_response_headers)
        c.receive_data(f.serialize())

        # Send in trailers.
        c.clear_outbound_data_buffer()
        trailers = [('content-length', '0')]
        f = frame_factory.build_headers_frame(
            trailers,
            flags=[],
        )

        with pytest.raises(h2.exceptions.ProtocolError):
            c.receive_data(f.serialize())

        expected_frame = frame_factory.build_goaway_frame(
            last_stream_id=0, error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
        )
        assert c.data_to_send() == expected_frame.serialize()

    def test_can_send_trailers(self, frame_factory):
        """
        When a second set of headers are sent, they are properly trailers.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.clear_outbound_data_buffer()
        c.send_headers(1, self.example_request_headers)

        # Now send trailers.
        trailers = [('content-length', '0')]
        c.send_headers(1, trailers, end_stream=True)

        frame_factory.refresh_encoder()
        f1 = frame_factory.build_headers_frame(
            self.example_request_headers,
        )
        f2 = frame_factory.build_headers_frame(
            trailers,
            flags=['END_STREAM'],
        )
        assert c.data_to_send() == f1.serialize() + f2.serialize()

    def test_trailers_must_have_end_stream(self, frame_factory):
        """
        A set of trailers must carry the END_STREAM flag.
        """
        c = h2.connection.H2Connection()
        c.initiate_connection()

        # Send headers.
        c.send_headers(1, self.example_request_headers)

        # Now send trailers.
        trailers = [('content-length', '0')]

        with pytest.raises(h2.exceptions.ProtocolError):
            c.send_headers(1, trailers)

    def test_headers_are_lowercase(self, frame_factory):
        """
        When headers are sent, they are forced to lower-case.
        """
        weird_headers = self.example_request_headers + [
            ('ChAnGiNg-CaSe', 'AlsoHere'),
            ('alllowercase', 'alllowercase'),
            ('ALLCAPS', 'ALLCAPS'),
        ]
        expected_headers = self.example_request_headers + [
            ('changing-case', 'AlsoHere'),
            ('alllowercase', 'alllowercase'),
            ('allcaps', 'ALLCAPS'),
        ]

        c = h2.connection.H2Connection()
        c.initiate_connection()
        c.clear_outbound_data_buffer()

        c.send_headers(1, weird_headers)
        expected_frame = frame_factory.build_headers_frame(
            headers=expected_headers
        )

        assert c.data_to_send() == expected_frame.serialize()

    @given(frame_size=integers(min_value=2**14, max_value=(2**24 - 1)))
    def test_changing_max_frame_size(self, frame_factory, frame_size):
        """
        When the user changes the max frame size and the change is ACKed, the
        remote peer is now bound by the new frame size.
        """
        # We need to refresh the encoder because hypothesis has a problem with
        # integrating with py.test, meaning that we use the same frame factory
        # for all tests.
        # See https://github.com/HypothesisWorks/hypothesis-python/issues/377
        frame_factory.refresh_encoder()

        c = h2.connection.H2Connection()
        c.initiate_connection()

        # Set up the stream.
        c.send_headers(1, self.example_request_headers, end_stream=True)
        headers_frame = frame_factory.build_headers_frame(
            headers=self.example_response_headers,
        )
        c.receive_data(headers_frame.serialize())

        # Change the max frame size.
        c.update_settings(
            {h2.settings.SettingCodes.MAX_FRAME_SIZE: frame_size}
        )
        settings_ack = frame_factory.build_settings_frame({}, ack=True)
        c.receive_data(settings_ack.serialize())

        # Greatly increase the flow control windows: we're not here to test
        # flow control today.
        c.increment_flow_control_window(increment=(2 * frame_size) + 1)
        c.increment_flow_control_window(
            increment=(2 * frame_size) + 1, stream_id=1
        )

        # Send one DATA frame that is exactly the max frame size: confirm it's
        # fine.
        data = frame_factory.build_data_frame(
            data=(b'\x00' * frame_size),
        )
        events = c.receive_data(data.serialize())
        assert len(events) == 1
        assert isinstance(events[0], h2.events.DataReceived)
        assert events[0].flow_controlled_length == frame_size

        # Send one that is one byte too large: confirm a protocol error is
        # raised.
        data.data += b'\x00'
        with pytest.raises(h2.exceptions.ProtocolError):
            c.receive_data(data.serialize())

    def test_cookies_are_joined_on_push(self, frame_factory):
        """
        RFC 7540 Section 8.1.2.5 requires that we join multiple Cookie headers
        in a header block together when they're received on a push.
        """
        # This is a moderately varied set of cookie headers: some combined,
        # some split.
        cookie_headers = [
            ('cookie',
                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
            ('cookie', 'path=1'),
            ('cookie', 'test1=val1; test2=val2')
        ]
        expected = (
            'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; '
            'path=1; test1=val1; test2=val2'
        )

        config = h2.config.H2Configuration(header_encoding='utf-8')
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)

        f = frame_factory.build_push_promise_frame(
            stream_id=1,
            promised_stream_id=2,
            headers=self.example_request_headers + cookie_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        e = events[0]

        cookie_fields = [(n, v) for n, v in e.headers if n == 'cookie']
        assert len(cookie_fields) == 1

        _, v = cookie_fields[0]
        assert v == expected

    def test_cookies_arent_joined_without_normalization(self, frame_factory):
        """
        If inbound header normalization is disabled, cookie headers aren't
        joined.
        """
        # This is a moderately varied set of cookie headers: some combined,
        # some split.
        cookie_headers = [
            ('cookie',
                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
            ('cookie', 'path=1'),
            ('cookie', 'test1=val1; test2=val2')
        ]

        config = h2.config.H2Configuration(
            client_side=True,
            normalize_inbound_headers=False,
            header_encoding='utf-8'
        )
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.send_headers(1, self.example_request_headers, end_stream=True)

        f = frame_factory.build_push_promise_frame(
            stream_id=1,
            promised_stream_id=2,
            headers=self.example_request_headers + cookie_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        e = events[0]

        received_cookies = [(n, v) for n, v in e.headers if n == 'cookie']
        assert len(received_cookies) == 3
        assert cookie_headers == received_cookies


class TestBasicServer(object):
    """
    Basic server-side tests.
    """
    example_request_headers = [
        (u':authority', u'example.com'),
        (u':path', u'/'),
        (u':scheme', u'https'),
        (u':method', u'GET'),
    ]
    bytes_example_request_headers = [
        (b':authority', b'example.com'),
        (b':path', b'/'),
        (b':scheme', b'https'),
        (b':method', b'GET'),
    ]
    example_response_headers = [
        (':status', '200'),
        ('server', 'hyper-h2/0.1.0')
    ]
    server_config = h2.config.H2Configuration(
        client_side=False, header_encoding='utf-8'
    )

    def test_ignores_preamble(self):
        """
        The preamble does not cause any events or frames to be written.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        preamble = b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'

        events = c.receive_data(preamble)
        assert not events
        assert not c.data_to_send()

    @pytest.mark.parametrize("chunk_size", range(1, 24))
    def test_drip_feed_preamble(self, chunk_size):
        """
        The preamble can be sent in in less than a single buffer.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        preamble = b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'
        events = []

        for i in range(0, len(preamble), chunk_size):
            events += c.receive_data(preamble[i:i+chunk_size])

        assert not events
        assert not c.data_to_send()

    def test_initiate_connection_sends_server_preamble(self, frame_factory):
        """
        For server-side connections, initiate_connection sends a server
        preamble.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        expected_settings = frame_factory.build_settings_frame(
            c.local_settings
        )
        expected_data = expected_settings.serialize()

        events = c.initiate_connection()
        assert not events
        assert c.data_to_send() == expected_data

    def test_headers_event(self, frame_factory):
        """
        When a headers frame is received a RequestReceived event fires.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_headers_frame(self.example_request_headers)
        data = f.serialize()
        events = c.receive_data(data)

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.RequestReceived)
        assert event.stream_id == 1
        assert event.headers == self.example_request_headers

    def test_headers_event_bytes(self, frame_factory):
        """
        When a headers frame is received a RequestReceived event fires with
        bytes headers if the encoding is set appropriately.
        """
        config = h2.config.H2Configuration(
            client_side=False, header_encoding=False
        )
        c = h2.connection.H2Connection(config=config)
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_headers_frame(self.example_request_headers)
        data = f.serialize()
        events = c.receive_data(data)

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.RequestReceived)
        assert event.stream_id == 1
        assert event.headers == self.bytes_example_request_headers

    def test_data_event(self, frame_factory):
        """
        Test that data received on a stream fires a DataReceived event.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        f1 = frame_factory.build_headers_frame(
            self.example_request_headers, stream_id=3
        )
        f2 = frame_factory.build_data_frame(
            b'some request data',
            stream_id=3,
        )
        data = b''.join(map(lambda f: f.serialize(), [f1, f2]))
        events = c.receive_data(data)

        assert len(events) == 2
        event = events[1]

        assert isinstance(event, h2.events.DataReceived)
        assert event.stream_id == 3
        assert event.data == b'some request data'
        assert event.flow_controlled_length == 17

    def test_data_event_with_padding(self, frame_factory):
        """
        Test that data received on a stream fires a DataReceived event that
        accounts for padding.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        f1 = frame_factory.build_headers_frame(
            self.example_request_headers, stream_id=3
        )
        f2 = frame_factory.build_data_frame(
            b'some request data',
            stream_id=3,
            padding_len=20
        )
        data = b''.join(map(lambda f: f.serialize(), [f1, f2]))
        events = c.receive_data(data)

        assert len(events) == 2
        event = events[1]

        assert isinstance(event, h2.events.DataReceived)
        assert event.stream_id == 3
        assert event.data == b'some request data'
        assert event.flow_controlled_length == 17 + 20 + 1

    def test_receiving_ping_frame(self, frame_factory):
        """
        Ping frames should be immediately ACKed.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        ping_data = b'\x01' * 8
        sent_frame = frame_factory.build_ping_frame(ping_data)
        expected_frame = frame_factory.build_ping_frame(
            ping_data, flags=["ACK"]
        )
        expected_data = expected_frame.serialize()

        c.clear_outbound_data_buffer()
        events = c.receive_data(sent_frame.serialize())

        assert not events
        assert c.data_to_send() == expected_data

    def test_receiving_settings_frame_event(self, frame_factory):
        """
        Settings frames should cause a RemoteSettingsChanged event to fire.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_settings_frame(
            settings=helpers.SAMPLE_SETTINGS
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.RemoteSettingsChanged)
        assert len(event.changed_settings) == len(helpers.SAMPLE_SETTINGS)

    def test_acknowledging_settings(self, frame_factory):
        """
        Acknowledging settings causes appropriate Settings frame to be emitted.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        received_frame = frame_factory.build_settings_frame(
            settings=helpers.SAMPLE_SETTINGS
        )
        expected_frame = frame_factory.build_settings_frame(
            settings={}, ack=True
        )
        expected_data = expected_frame.serialize()

        c.clear_outbound_data_buffer()
        events = c.receive_data(received_frame.serialize())

        assert len(events) == 1
        assert c.data_to_send() == expected_data

    def test_close_connection(self, frame_factory):
        """
        Closing the connection with no error code emits a GOAWAY frame with
        error code 0.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_goaway_frame(last_stream_id=0)
        expected_data = f.serialize()

        c.clear_outbound_data_buffer()
        events = c.close_connection()

        assert not events
        assert c.data_to_send() == expected_data

    @pytest.mark.parametrize("error_code", h2.errors.ErrorCodes)
    def test_close_connection_with_error_code(self, frame_factory, error_code):
        """
        Closing the connection with an error code emits a GOAWAY frame with
        that error code.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_goaway_frame(
            error_code=error_code, last_stream_id=0
        )
        expected_data = f.serialize()

        c.clear_outbound_data_buffer()
        events = c.close_connection(error_code)

        assert not events
        assert c.data_to_send() == expected_data

    @pytest.mark.parametrize("last_stream_id,output", [
        (None, 23),
        (0, 0),
        (42, 42)
    ])
    def test_close_connection_with_last_stream_id(self, frame_factory,
                                                  last_stream_id, output):
        """
        Closing the connection with last_stream_id set emits a GOAWAY frame
        with that value.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        headers_frame = frame_factory.build_headers_frame(
            [
                (':authority', 'example.com'),
                (':path', '/'),
                (':scheme', 'https'),
                (':method', 'GET'),
            ],
            stream_id=23)
        c.receive_data(headers_frame.serialize())

        f = frame_factory.build_goaway_frame(
            last_stream_id=output
        )
        expected_data = f.serialize()

        c.clear_outbound_data_buffer()
        events = c.close_connection(last_stream_id=last_stream_id)

        assert not events
        assert c.data_to_send() == expected_data

    @pytest.mark.parametrize("additional_data,output", [
        (None, b''),
        (b'', b''),
        (b'foobar', b'foobar')
    ])
    def test_close_connection_with_additional_data(self, frame_factory,
                                                   additional_data, output):
        """
        Closing the connection with additional debug data emits a GOAWAY frame
        with that data attached.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_goaway_frame(
            last_stream_id=0, additional_data=output
        )
        expected_data = f.serialize()

        c.clear_outbound_data_buffer()
        events = c.close_connection(additional_data=additional_data)

        assert not events
        assert c.data_to_send() == expected_data

    def test_reset_stream(self, frame_factory):
        """
        Resetting a stream with no error code emits a RST_STREAM frame with
        error code 0.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(f.serialize())
        c.clear_outbound_data_buffer()

        expected_frame = frame_factory.build_rst_stream_frame(stream_id=1)
        expected_data = expected_frame.serialize()

        events = c.reset_stream(stream_id=1)

        assert not events
        assert c.data_to_send() == expected_data

    @pytest.mark.parametrize("error_code", h2.errors.ErrorCodes)
    def test_reset_stream_with_error_code(self, frame_factory, error_code):
        """
        Resetting a stream with an error code emits a RST_STREAM frame with
        that error code.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(
            self.example_request_headers,
            stream_id=3
        )
        c.receive_data(f.serialize())
        c.clear_outbound_data_buffer()

        expected_frame = frame_factory.build_rst_stream_frame(
            stream_id=3, error_code=error_code
        )
        expected_data = expected_frame.serialize()

        events = c.reset_stream(stream_id=3, error_code=error_code)

        assert not events
        assert c.data_to_send() == expected_data

    def test_cannot_reset_nonexistent_stream(self, frame_factory):
        """
        Resetting nonexistent streams raises NoSuchStreamError.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(
            self.example_request_headers,
            stream_id=3
        )
        c.receive_data(f.serialize())

        with pytest.raises(h2.exceptions.NoSuchStreamError) as e:
            c.reset_stream(stream_id=1)

        assert e.value.stream_id == 1

        with pytest.raises(h2.exceptions.NoSuchStreamError) as e:
            c.reset_stream(stream_id=5)

        assert e.value.stream_id == 5

    def test_basic_sending_ping_frame_logic(self, frame_factory):
        """
        Sending ping frames serializes a ping frame on stream 0 with
        approriate opaque data.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        c.clear_outbound_data_buffer()

        ping_data = b'\x01\x02\x03\x04\x05\x06\x07\x08'

        expected_frame = frame_factory.build_ping_frame(ping_data)
        expected_data = expected_frame.serialize()

        events = c.ping(ping_data)

        assert not events
        assert c.data_to_send() == expected_data

    @pytest.mark.parametrize(
        'opaque_data',
        [
            b'',
            b'\x01\x02\x03\x04\x05\x06\x07',
            u'abcdefgh',
            b'too many bytes',
        ]
    )
    def test_ping_frame_opaque_data_must_be_length_8_bytestring(self,
                                                                frame_factory,
                                                                opaque_data):
        """
        Sending a ping frame only works with 8-byte bytestrings.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        with pytest.raises(ValueError):
            c.ping(opaque_data)

    def test_receiving_ping_acknowledgement(self, frame_factory):
        """
        Receiving a PING acknolwedgement fires a PingAcknolwedged event.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        ping_data = b'\x01\x02\x03\x04\x05\x06\x07\x08'

        f = frame_factory.build_ping_frame(
            ping_data, flags=['ACK']
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.PingAcknowledged)
        assert event.ping_data == ping_data

    def test_stream_ended_remotely(self, frame_factory):
        """
        When the remote stream ends with a non-empty data frame a DataReceived
        event and a StreamEnded event are fired.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        f1 = frame_factory.build_headers_frame(
            self.example_request_headers, stream_id=3
        )
        f2 = frame_factory.build_data_frame(
            b'some request data',
            flags=['END_STREAM'],
            stream_id=3,
        )
        data = b''.join(map(lambda f: f.serialize(), [f1, f2]))
        events = c.receive_data(data)

        assert len(events) == 3
        data_event = events[1]
        stream_ended_event = events[2]

        assert isinstance(data_event, h2.events.DataReceived)
        assert isinstance(stream_ended_event, h2.events.StreamEnded)
        stream_ended_event.stream_id == 3

    def test_can_push_stream(self, frame_factory):
        """
        Pushing a stream causes a PUSH_PROMISE frame to be emitted.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(
            self.example_request_headers
        )
        c.receive_data(f.serialize())

        frame_factory.refresh_encoder()
        expected_frame = frame_factory.build_push_promise_frame(
            stream_id=1,
            promised_stream_id=2,
            headers=self.example_request_headers,
            flags=['END_HEADERS'],
        )

        c.clear_outbound_data_buffer()
        c.push_stream(
            stream_id=1,
            promised_stream_id=2,
            request_headers=self.example_request_headers
        )

        assert c.data_to_send() == expected_frame.serialize()

    def test_cannot_push_streams_when_disabled(self, frame_factory):
        """
        When the remote peer has disabled stream pushing, we should fail.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_settings_frame(
            {h2.settings.SettingCodes.ENABLE_PUSH: 0}
        )
        c.receive_data(f.serialize())

        f = frame_factory.build_headers_frame(
            self.example_request_headers
        )
        c.receive_data(f.serialize())

        with pytest.raises(h2.exceptions.ProtocolError):
            c.push_stream(
                stream_id=1,
                promised_stream_id=2,
                request_headers=self.example_request_headers
            )

    def test_settings_remote_change_header_table_size(self, frame_factory):
        """
        Acknowledging a remote HEADER_TABLE_SIZE settings change causes us to
        change the header table size of our encoder.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        assert c.encoder.header_table_size == 4096

        received_frame = frame_factory.build_settings_frame(
            {h2.settings.SettingCodes.HEADER_TABLE_SIZE: 80}
        )
        c.receive_data(received_frame.serialize())[0]

        assert c.encoder.header_table_size == 80

    def test_settings_local_change_header_table_size(self, frame_factory):
        """
        The remote peer acknowledging a local HEADER_TABLE_SIZE settings change
        does not cause us to change the header table size of our decoder.

        For an explanation of why this test is this way around, see issue #37.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())

        assert c.decoder.header_table_size == 4096

        expected_frame = frame_factory.build_settings_frame({}, ack=True)
        c.update_settings(
            {h2.settings.SettingCodes.HEADER_TABLE_SIZE: 80}
        )
        c.receive_data(expected_frame.serialize())
        c.clear_outbound_data_buffer()

        assert c.decoder.header_table_size == 4096

    def test_restricting_outbound_frame_size_by_settings(self, frame_factory):
        """
        The remote peer can shrink the maximum outbound frame size using
        settings.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.initiate_connection()
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(f.serialize())
        c.clear_outbound_data_buffer()

        with pytest.raises(h2.exceptions.FrameTooLargeError):
            c.send_data(1, b'\x01' * 17000)

        received_frame = frame_factory.build_settings_frame(
            {h2.settings.SettingCodes.MAX_FRAME_SIZE: 17001}
        )
        c.receive_data(received_frame.serialize())

        c.send_data(1, b'\x01' * 17000)
        assert c.data_to_send()

    def test_restricting_inbound_frame_size_by_settings(self, frame_factory):
        """
        We throw ProtocolErrors and tear down connections if oversize frames
        are received.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        h = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(h.serialize())
        c.clear_outbound_data_buffer()

        data_frame = frame_factory.build_data_frame(b'\x01' * 17000)

        with pytest.raises(h2.exceptions.ProtocolError):
            c.receive_data(data_frame.serialize())

        expected_frame = frame_factory.build_goaway_frame(
            last_stream_id=1, error_code=h2.errors.ErrorCodes.FRAME_SIZE_ERROR
        )
        assert c.data_to_send() == expected_frame.serialize()

    def test_cannot_receive_new_streams_over_limit(self, frame_factory):
        """
        When the number of inbound streams exceeds our MAX_CONCURRENT_STREAMS
        setting, their attempt to open new streams fails.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        c.update_settings(
            {h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 1}
        )
        f = frame_factory.build_settings_frame({}, ack=True)
        c.receive_data(f.serialize())

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

        f = frame_factory.build_headers_frame(
            stream_id=3,
            headers=self.example_request_headers,
        )
        with pytest.raises(h2.exceptions.TooManyStreamsError):
            c.receive_data(f.serialize())

        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_can_receive_trailers(self, frame_factory):
        """
        When two HEADERS blocks are received in the same stream from a
        client, the second set are trailers.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(f.serialize())

        # Send in trailers.
        trailers = [('content-length', '0')]
        f = frame_factory.build_headers_frame(
            trailers,
            flags=['END_STREAM'],
        )
        events = c.receive_data(f.serialize())
        assert len(events) == 2

        event = events[0]
        assert isinstance(event, h2.events.TrailersReceived)
        assert event.headers == trailers
        assert event.stream_id == 1

    def test_reject_trailers_not_ending_stream(self, frame_factory):
        """
        When trailers are received without the END_STREAM flag being present,
        this is a ProtocolError.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(f.serialize())

        # Send in trailers.
        c.clear_outbound_data_buffer()
        trailers = [('content-length', '0')]
        f = frame_factory.build_headers_frame(
            trailers,
            flags=[],
        )

        with pytest.raises(h2.exceptions.ProtocolError):
            c.receive_data(f.serialize())

        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_can_send_trailers(self, frame_factory):
        """
        When a second set of headers are sent, they are properly trailers.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(f.serialize())

        # Send headers.
        c.clear_outbound_data_buffer()
        c.send_headers(1, self.example_response_headers)

        # Now send trailers.
        trailers = [('content-length', '0')]
        c.send_headers(1, trailers, end_stream=True)

        frame_factory.refresh_encoder()
        f1 = frame_factory.build_headers_frame(
            self.example_response_headers,
        )
        f2 = frame_factory.build_headers_frame(
            trailers,
            flags=['END_STREAM'],
        )
        assert c.data_to_send() == f1.serialize() + f2.serialize()

    def test_trailers_must_have_end_stream(self, frame_factory):
        """
        A set of trailers must carry the END_STREAM flag.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        f = frame_factory.build_headers_frame(self.example_request_headers)
        c.receive_data(f.serialize())

        # Send headers.
        c.send_headers(1, self.example_response_headers)

        # Now send trailers.
        trailers = [('content-length', '0')]

        with pytest.raises(h2.exceptions.ProtocolError):
            c.send_headers(1, trailers)

    @pytest.mark.parametrize("frame_id", range(12, 256))
    def test_unknown_frames_are_ignored(self, frame_factory, frame_id):
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        c.clear_outbound_data_buffer()

        f = frame_factory.build_data_frame(data=b'abcdefghtdst')
        f.type = frame_id

        events = c.receive_data(f.serialize())
        assert not c.data_to_send()
        assert len(events) == 1
        assert isinstance(events[0], h2.events.UnknownFrameReceived)
        assert isinstance(events[0].frame, hyperframe.frame.ExtensionFrame)

    def test_can_send_goaway_repeatedly(self, frame_factory):
        """
        We can send a GOAWAY frame as many times as we like.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        c.clear_outbound_data_buffer()

        c.close_connection()
        c.close_connection()
        c.close_connection()

        f = frame_factory.build_goaway_frame(last_stream_id=0)

        assert c.data_to_send() == (f.serialize() * 3)

    def test_receiving_goaway_frame(self, frame_factory):
        """
        Receiving a GOAWAY frame causes a ConnectionTerminated event to be
        fired and transitions the connection to the CLOSED state, and clears
        the outbound data buffer.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.initiate_connection()
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_goaway_frame(
            last_stream_id=5, error_code=h2.errors.ErrorCodes.SETTINGS_TIMEOUT
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ConnectionTerminated)
        assert event.error_code == h2.errors.ErrorCodes.SETTINGS_TIMEOUT
        assert isinstance(event.error_code, h2.errors.ErrorCodes)
        assert event.last_stream_id == 5
        assert event.additional_data is None
        assert c.state_machine.state == h2.connection.ConnectionState.CLOSED

        assert not c.data_to_send()

    def test_receiving_multiple_goaway_frames(self, frame_factory):
        """
        Multiple GOAWAY frames can be received at once, and are allowed. Each
        one fires a ConnectionTerminated event.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.receive_data(frame_factory.preamble())
        c.clear_outbound_data_buffer()

        f = frame_factory.build_goaway_frame(last_stream_id=0)
        events = c.receive_data(f.serialize() * 3)

        assert len(events) == 3
        assert all(
            isinstance(event, h2.events.ConnectionTerminated)
            for event in events
        )

    def test_receiving_goaway_frame_with_additional_data(self, frame_factory):
        """
        GOAWAY frame can contain additional data,
        it should be available via ConnectionTerminated event.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.initiate_connection()
        c.receive_data(frame_factory.preamble())

        additional_data = b'debug data'
        f = frame_factory.build_goaway_frame(last_stream_id=0,
                                             additional_data=additional_data)
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ConnectionTerminated)
        assert event.additional_data == additional_data

    def test_receiving_goaway_frame_with_unknown_error(self, frame_factory):
        """
        Receiving a GOAWAY frame with an unknown error code behaves exactly the
        same as receiving one we know about, but the code is reported as an
        integer instead of as an ErrorCodes.
        """
        c = h2.connection.H2Connection(config=self.server_config)
        c.initiate_connection()
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_goaway_frame(
            last_stream_id=5, error_code=0xFA
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        event = events[0]

        assert isinstance(event, h2.events.ConnectionTerminated)
        assert event.error_code == 250
        assert not isinstance(event.error_code, h2.errors.ErrorCodes)
        assert event.last_stream_id == 5
        assert event.additional_data is None
        assert c.state_machine.state == h2.connection.ConnectionState.CLOSED

        assert not c.data_to_send()

    def test_cookies_are_joined(self, frame_factory):
        """
        RFC 7540 Section 8.1.2.5 requires that we join multiple Cookie headers
        in a header block together.
        """
        # This is a moderately varied set of cookie headers: some combined,
        # some split.
        cookie_headers = [
            ('cookie',
                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
            ('cookie', 'path=1'),
            ('cookie', 'test1=val1; test2=val2')
        ]
        expected = (
            'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; '
            'path=1; test1=val1; test2=val2'
        )

        c = h2.connection.H2Connection(config=self.server_config)
        c.initiate_connection()
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_headers_frame(
            self.example_request_headers + cookie_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        e = events[0]

        cookie_fields = [(n, v) for n, v in e.headers if n == 'cookie']
        assert len(cookie_fields) == 1

        _, v = cookie_fields[0]
        assert v == expected

    def test_cookies_arent_joined_without_normalization(self, frame_factory):
        """
        If inbound header normalization is disabled, cookie headers aren't
        joined.
        """
        # This is a moderately varied set of cookie headers: some combined,
        # some split.
        cookie_headers = [
            ('cookie',
                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
            ('cookie', 'path=1'),
            ('cookie', 'test1=val1; test2=val2')
        ]

        config = h2.config.H2Configuration(
            client_side=False,
            normalize_inbound_headers=False,
            header_encoding='utf-8'
        )
        c = h2.connection.H2Connection(config=config)
        c.initiate_connection()
        c.receive_data(frame_factory.preamble())

        f = frame_factory.build_headers_frame(
            self.example_request_headers + cookie_headers
        )
        events = c.receive_data(f.serialize())

        assert len(events) == 1
        e = events[0]

        received_cookies = [(n, v) for n, v in e.headers if n == 'cookie']
        assert len(received_cookies) == 3
        assert cookie_headers == received_cookies

    def test_stream_repr(self):
        """
        Ensure stream string representation is appropriate.
        """
        s = h2.stream.H2Stream(4, None, 12, 14)
        assert repr(s) == "<H2Stream id:4 state:<StreamState.IDLE: 0>>"


def sanity_check_data_frame(data_frame,
                            expected_flow_controlled_length,
                            expect_padded_flag,
                            expected_data_frame_pad_length):
    """
    ``data_frame`` is a frame of type ``hyperframe.frame.DataFrame``,
    and the ``flags`` and ``flow_controlled_length`` of ``data_frame``
    match expectations.
    """

    assert isinstance(data_frame, hyperframe.frame.DataFrame)

    assert data_frame.flow_controlled_length == expected_flow_controlled_length

    if expect_padded_flag:
        assert 'PADDED' in data_frame.flags
    else:
        assert 'PADDED' not in data_frame.flags

    assert data_frame.pad_length == expected_data_frame_pad_length
