1# -*- coding: utf-8 -*-
2"""
3test_basic_logic
4~~~~~~~~~~~~~~~~
5
6Test the basic logic of the h2 state machines.
7"""
8import random
9import sys
10
11import hyperframe
12import pytest
13
14import h2.config
15import h2.connection
16import h2.errors
17import h2.events
18import h2.exceptions
19import h2.frame_buffer
20import h2.settings
21import h2.stream
22
23import helpers
24
25from hypothesis import given
26from hypothesis.strategies import integers
27
28
29IS_PYTHON3 = sys.version_info >= (3, 0)
30
31
32class TestBasicClient(object):
33    """
34    Basic client-side tests.
35    """
36    example_request_headers = [
37        (u':authority', u'example.com'),
38        (u':path', u'/'),
39        (u':scheme', u'https'),
40        (u':method', u'GET'),
41    ]
42    bytes_example_request_headers = [
43        (b':authority', b'example.com'),
44        (b':path', b'/'),
45        (b':scheme', b'https'),
46        (b':method', b'GET'),
47    ]
48    example_response_headers = [
49        (u':status', u'200'),
50        (u'server', u'fake-serv/0.1.0')
51    ]
52    bytes_example_response_headers = [
53        (b':status', b'200'),
54        (b'server', b'fake-serv/0.1.0')
55    ]
56
57    def test_begin_connection(self, frame_factory):
58        """
59        Client connections emit the HTTP/2 preamble.
60        """
61        c = h2.connection.H2Connection()
62        expected_settings = frame_factory.build_settings_frame(
63            c.local_settings
64        )
65        expected_data = (
66            b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n' + expected_settings.serialize()
67        )
68
69        events = c.initiate_connection()
70        assert not events
71        assert c.data_to_send() == expected_data
72
73    def test_sending_headers(self):
74        """
75        Single headers frames are correctly encoded.
76        """
77        c = h2.connection.H2Connection()
78        c.initiate_connection()
79
80        # Clear the data, then send headers.
81        c.clear_outbound_data_buffer()
82        events = c.send_headers(1, self.example_request_headers)
83        assert not events
84        assert c.data_to_send() == (
85            b'\x00\x00\r\x01\x04\x00\x00\x00\x01'
86            b'A\x88/\x91\xd3]\x05\\\x87\xa7\x84\x87\x82'
87        )
88
89    def test_sending_data(self):
90        """
91        Single data frames are encoded correctly.
92        """
93        c = h2.connection.H2Connection()
94        c.initiate_connection()
95        c.send_headers(1, self.example_request_headers)
96
97        # Clear the data, then send some data.
98        c.clear_outbound_data_buffer()
99        events = c.send_data(1, b'some data')
100        assert not events
101        data_to_send = c.data_to_send()
102        assert (
103            data_to_send == b'\x00\x00\t\x00\x00\x00\x00\x00\x01some data'
104        )
105
106        buffer = h2.frame_buffer.FrameBuffer(server=False)
107        buffer.max_frame_size = 65535
108        buffer.add_data(data_to_send)
109        data_frame = list(buffer)[0]
110        sanity_check_data_frame(
111            data_frame=data_frame,
112            expected_flow_controlled_length=len(b'some data'),
113            expect_padded_flag=False,
114            expected_data_frame_pad_length=0
115        )
116
117    def test_sending_data_in_memoryview(self):
118        """
119        Support memoryview for sending data.
120        """
121        c = h2.connection.H2Connection()
122        c.initiate_connection()
123        c.send_headers(1, self.example_request_headers)
124
125        # Clear the data, then send some data.
126        c.clear_outbound_data_buffer()
127        events = c.send_data(1, memoryview(b'some data'))
128        assert not events
129        data_to_send = c.data_to_send()
130        assert (
131            data_to_send == b'\x00\x00\t\x00\x00\x00\x00\x00\x01some data'
132        )
133
134    def test_sending_data_with_padding(self):
135        """
136        Single data frames with padding are encoded correctly.
137        """
138        c = h2.connection.H2Connection()
139        c.initiate_connection()
140        c.send_headers(1, self.example_request_headers)
141
142        # Clear the data, then send some data.
143        c.clear_outbound_data_buffer()
144        events = c.send_data(1, b'some data', pad_length=5)
145        assert not events
146        data_to_send = c.data_to_send()
147        assert data_to_send == (
148            b'\x00\x00\x0f\x00\x08\x00\x00\x00\x01'
149            b'\x05some data\x00\x00\x00\x00\x00'
150        )
151
152        buffer = h2.frame_buffer.FrameBuffer(server=False)
153        buffer.max_frame_size = 65535
154        buffer.add_data(data_to_send)
155        data_frame = list(buffer)[0]
156        sanity_check_data_frame(
157            data_frame=data_frame,
158            expected_flow_controlled_length=len(b'some data') + 1 + 5,
159            expect_padded_flag=True,
160            expected_data_frame_pad_length=5
161        )
162
163    def test_sending_data_with_zero_length_padding(self):
164        """
165        Single data frames with zero-length padding are encoded
166        correctly.
167        """
168        c = h2.connection.H2Connection()
169        c.initiate_connection()
170        c.send_headers(1, self.example_request_headers)
171
172        # Clear the data, then send some data.
173        c.clear_outbound_data_buffer()
174        events = c.send_data(1, b'some data', pad_length=0)
175        assert not events
176        data_to_send = c.data_to_send()
177        assert data_to_send == (
178            b'\x00\x00\x0a\x00\x08\x00\x00\x00\x01'
179            b'\x00some data'
180        )
181
182        buffer = h2.frame_buffer.FrameBuffer(server=False)
183        buffer.max_frame_size = 65535
184        buffer.add_data(data_to_send)
185        data_frame = list(buffer)[0]
186        sanity_check_data_frame(
187            data_frame=data_frame,
188            expected_flow_controlled_length=len(b'some data') + 1,
189            expect_padded_flag=True,
190            expected_data_frame_pad_length=0
191        )
192
193    @pytest.mark.parametrize("expected_error,pad_length", [
194        (None,  0),
195        (None, 255),
196        (None, None),
197        (ValueError, -1),
198        (ValueError, 256),
199        (TypeError, 'invalid'),
200        (TypeError, ''),
201        (TypeError, '10'),
202        (TypeError, {}),
203        (TypeError, ['1', '2', '3']),
204        (TypeError, []),
205        (TypeError, 1.5),
206        (TypeError, 1.0),
207        (TypeError, -1.0),
208    ])
209    def test_sending_data_with_invalid_padding_length(self,
210                                                      expected_error,
211                                                      pad_length):
212        """
213        ``send_data`` with a ``pad_length`` parameter that is an integer
214        outside the range of [0, 255] throws a ``ValueError``, and a
215        ``pad_length`` parameter which is not an ``integer`` type
216        throws a ``TypeError``.
217        """
218        c = h2.connection.H2Connection()
219        c.initiate_connection()
220        c.send_headers(1, self.example_request_headers)
221
222        c.clear_outbound_data_buffer()
223        if expected_error is not None:
224            with pytest.raises(expected_error):
225                c.send_data(1, b'some data', pad_length=pad_length)
226        else:
227            c.send_data(1, b'some data', pad_length=pad_length)
228
229    def test_closing_stream_sending_data(self, frame_factory):
230        """
231        We can close a stream with a data frame.
232        """
233        c = h2.connection.H2Connection()
234        c.initiate_connection()
235        c.send_headers(1, self.example_request_headers)
236
237        f = frame_factory.build_data_frame(
238            data=b'some data',
239            flags=['END_STREAM'],
240        )
241
242        # Clear the data, then send some data.
243        c.clear_outbound_data_buffer()
244        events = c.send_data(1, b'some data', end_stream=True)
245        assert not events
246        assert c.data_to_send() == f.serialize()
247
248    def test_receiving_a_response(self, frame_factory):
249        """
250        When receiving a response, the ResponseReceived event fires.
251        """
252        config = h2.config.H2Configuration(header_encoding='utf-8')
253        c = h2.connection.H2Connection(config=config)
254        c.initiate_connection()
255        c.send_headers(1, self.example_request_headers, end_stream=True)
256
257        # Clear the data
258        f = frame_factory.build_headers_frame(
259            self.example_response_headers
260        )
261        events = c.receive_data(f.serialize())
262
263        assert len(events) == 1
264        event = events[0]
265
266        assert isinstance(event, h2.events.ResponseReceived)
267        assert event.stream_id == 1
268        assert event.headers == self.example_response_headers
269
270    def test_receiving_a_response_bytes(self, frame_factory):
271        """
272        When receiving a response, the ResponseReceived event fires with bytes
273        headers if the encoding is set appropriately.
274        """
275        config = h2.config.H2Configuration(header_encoding=False)
276        c = h2.connection.H2Connection(config=config)
277        c.initiate_connection()
278        c.send_headers(1, self.example_request_headers, end_stream=True)
279
280        # Clear the data
281        f = frame_factory.build_headers_frame(
282            self.example_response_headers
283        )
284        events = c.receive_data(f.serialize())
285
286        assert len(events) == 1
287        event = events[0]
288
289        assert isinstance(event, h2.events.ResponseReceived)
290        assert event.stream_id == 1
291        assert event.headers == self.bytes_example_response_headers
292
293    def test_receiving_a_response_change_encoding(self, frame_factory):
294        """
295        When receiving a response, the ResponseReceived event fires with bytes
296        headers if the encoding is set appropriately, but if this changes then
297        the change reflects it.
298        """
299        config = h2.config.H2Configuration(header_encoding=False)
300        c = h2.connection.H2Connection(config=config)
301        c.initiate_connection()
302        c.send_headers(1, self.example_request_headers, end_stream=True)
303
304        f = frame_factory.build_headers_frame(
305            self.example_response_headers
306        )
307        events = c.receive_data(f.serialize())
308
309        assert len(events) == 1
310        event = events[0]
311
312        assert isinstance(event, h2.events.ResponseReceived)
313        assert event.stream_id == 1
314        assert event.headers == self.bytes_example_response_headers
315
316        c.send_headers(3, self.example_request_headers, end_stream=True)
317        c.config.header_encoding = 'utf-8'
318        f = frame_factory.build_headers_frame(
319            self.example_response_headers,
320            stream_id=3,
321        )
322        events = c.receive_data(f.serialize())
323
324        assert len(events) == 1
325        event = events[0]
326
327        assert isinstance(event, h2.events.ResponseReceived)
328        assert event.stream_id == 3
329        assert event.headers == self.example_response_headers
330
331    def test_end_stream_without_data(self, frame_factory):
332        """
333        Ending a stream without data emits a zero-length DATA frame with
334        END_STREAM set.
335        """
336        c = h2.connection.H2Connection()
337        c.initiate_connection()
338        c.send_headers(1, self.example_request_headers, end_stream=False)
339
340        # Clear the data
341        c.clear_outbound_data_buffer()
342        f = frame_factory.build_data_frame(b'', flags=['END_STREAM'])
343        events = c.end_stream(1)
344
345        assert not events
346        assert c.data_to_send() == f.serialize()
347
348    def test_cannot_send_headers_on_lower_stream_id(self):
349        """
350        Once stream ID x has been used, cannot use stream ID y where y < x.
351        """
352        c = h2.connection.H2Connection()
353        c.initiate_connection()
354        c.send_headers(3, self.example_request_headers, end_stream=False)
355
356        with pytest.raises(h2.exceptions.StreamIDTooLowError) as e:
357            c.send_headers(1, self.example_request_headers, end_stream=True)
358
359        assert e.value.stream_id == 1
360        assert e.value.max_stream_id == 3
361
362    def test_receiving_pushed_stream(self, frame_factory):
363        """
364        Pushed streams fire a PushedStreamReceived event, followed by
365        ResponseReceived when the response headers are received.
366        """
367        config = h2.config.H2Configuration(header_encoding='utf-8')
368        c = h2.connection.H2Connection(config=config)
369        c.initiate_connection()
370        c.send_headers(1, self.example_request_headers, end_stream=False)
371
372        f1 = frame_factory.build_headers_frame(
373            self.example_response_headers
374        )
375        f2 = frame_factory.build_push_promise_frame(
376            stream_id=1,
377            promised_stream_id=2,
378            headers=self.example_request_headers,
379            flags=['END_HEADERS'],
380        )
381        f3 = frame_factory.build_headers_frame(
382            self.example_response_headers,
383            stream_id=2,
384        )
385        data = b''.join(x.serialize() for x in [f1, f2, f3])
386
387        events = c.receive_data(data)
388
389        assert len(events) == 3
390        stream_push_event = events[1]
391        response_event = events[2]
392        assert isinstance(stream_push_event, h2.events.PushedStreamReceived)
393        assert isinstance(response_event, h2.events.ResponseReceived)
394
395        assert stream_push_event.pushed_stream_id == 2
396        assert stream_push_event.parent_stream_id == 1
397        assert (
398            stream_push_event.headers == self.example_request_headers
399        )
400        assert response_event.stream_id == 2
401        assert response_event.headers == self.example_response_headers
402
403    def test_receiving_pushed_stream_bytes(self, frame_factory):
404        """
405        Pushed headers are not decoded if the header encoding is set to False.
406        """
407        config = h2.config.H2Configuration(header_encoding=False)
408        c = h2.connection.H2Connection(config=config)
409        c.initiate_connection()
410        c.send_headers(1, self.example_request_headers, end_stream=False)
411
412        f1 = frame_factory.build_headers_frame(
413            self.example_response_headers
414        )
415        f2 = frame_factory.build_push_promise_frame(
416            stream_id=1,
417            promised_stream_id=2,
418            headers=self.example_request_headers,
419            flags=['END_HEADERS'],
420        )
421        f3 = frame_factory.build_headers_frame(
422            self.example_response_headers,
423            stream_id=2,
424        )
425        data = b''.join(x.serialize() for x in [f1, f2, f3])
426
427        events = c.receive_data(data)
428
429        assert len(events) == 3
430        stream_push_event = events[1]
431        response_event = events[2]
432        assert isinstance(stream_push_event, h2.events.PushedStreamReceived)
433        assert isinstance(response_event, h2.events.ResponseReceived)
434
435        assert stream_push_event.pushed_stream_id == 2
436        assert stream_push_event.parent_stream_id == 1
437        assert (
438            stream_push_event.headers == self.bytes_example_request_headers
439        )
440        assert response_event.stream_id == 2
441        assert response_event.headers == self.bytes_example_response_headers
442
443    def test_cannot_receive_pushed_stream_when_enable_push_is_0(self,
444                                                                frame_factory):
445        """
446        If we have set SETTINGS_ENABLE_PUSH to 0, receiving PUSH_PROMISE frames
447        triggers the connection to be closed.
448        """
449        c = h2.connection.H2Connection()
450        c.initiate_connection()
451        c.local_settings.enable_push = 0
452        c.send_headers(1, self.example_request_headers, end_stream=False)
453
454        f1 = frame_factory.build_settings_frame({}, ack=True)
455        f2 = frame_factory.build_headers_frame(
456            self.example_response_headers
457        )
458        f3 = frame_factory.build_push_promise_frame(
459            stream_id=1,
460            promised_stream_id=2,
461            headers=self.example_request_headers,
462            flags=['END_HEADERS'],
463        )
464        c.receive_data(f1.serialize())
465        c.receive_data(f2.serialize())
466        c.clear_outbound_data_buffer()
467
468        with pytest.raises(h2.exceptions.ProtocolError):
469            c.receive_data(f3.serialize())
470
471        expected_frame = frame_factory.build_goaway_frame(
472            0, h2.errors.ErrorCodes.PROTOCOL_ERROR
473        )
474        assert c.data_to_send() == expected_frame.serialize()
475
476    def test_receiving_response_no_body(self, frame_factory):
477        """
478        Receiving a response without a body fires two events, ResponseReceived
479        and StreamEnded.
480        """
481        c = h2.connection.H2Connection()
482        c.initiate_connection()
483        c.send_headers(1, self.example_request_headers, end_stream=True)
484
485        f = frame_factory.build_headers_frame(
486            self.example_response_headers,
487            flags=['END_STREAM']
488        )
489        events = c.receive_data(f.serialize())
490
491        assert len(events) == 2
492        response_event = events[0]
493        end_stream = events[1]
494
495        assert isinstance(response_event, h2.events.ResponseReceived)
496        assert isinstance(end_stream, h2.events.StreamEnded)
497
498    def test_oversize_headers(self):
499        """
500        Sending headers that are oversized generates a stream of CONTINUATION
501        frames.
502        """
503        all_bytes = [chr(x) for x in range(0, 256)]
504        if IS_PYTHON3:
505            all_bytes = [x.encode('latin1') for x in all_bytes]
506
507        large_binary_string = b''.join(
508            random.choice(all_bytes) for _ in range(0, 256)
509        )
510        test_headers = [
511            (':authority', 'example.com'),
512            (':path', '/'),
513            (':method', 'GET'),
514            (':scheme', 'https'),
515            ('key', large_binary_string)
516        ]
517        c = h2.connection.H2Connection()
518
519        # Greatly shrink the max frame size to force us over.
520        c.max_outbound_frame_size = 48
521        c.initiate_connection()
522        c.send_headers(1, test_headers, end_stream=True)
523
524        # Use the frame buffer here, because we don't care about decoding
525        # the headers. Don't send all the data in because that will force the
526        # frame buffer to stop caching the CONTINUATION frames, so instead
527        # send all but one byte.
528        buffer = h2.frame_buffer.FrameBuffer(server=True)
529        buffer.max_frame_size = 65535
530        data = c.data_to_send()
531        buffer.add_data(data[:-1])
532
533        # Drain the buffer, confirming that it only provides a single frame
534        # (the settings frame)
535        assert len(list(buffer)) == 1
536
537        # Get the cached frames.
538        frames = buffer._headers_buffer
539
540        # Split the frames up.
541        headers_frame = frames[0]
542        continuation_frames = frames[1:]
543
544        assert isinstance(headers_frame, hyperframe.frame.HeadersFrame)
545        assert all(
546            map(
547                lambda f: isinstance(f, hyperframe.frame.ContinuationFrame),
548                continuation_frames)
549        )
550        assert all(
551            map(lambda f: len(f.data) <= c.max_outbound_frame_size, frames)
552        )
553
554        assert frames[0].flags == {'END_STREAM'}
555
556        buffer.add_data(data[-1:])
557        headers = list(buffer)[0]
558        assert isinstance(headers, hyperframe.frame.HeadersFrame)
559
560    def test_handle_stream_reset(self, frame_factory):
561        """
562        Streams being remotely reset fires a StreamReset event.
563        """
564        c = h2.connection.H2Connection()
565        c.initiate_connection()
566        c.send_headers(1, self.example_request_headers, end_stream=True)
567        c.clear_outbound_data_buffer()
568
569        f = frame_factory.build_rst_stream_frame(
570            stream_id=1,
571            error_code=h2.errors.ErrorCodes.STREAM_CLOSED,
572        )
573        events = c.receive_data(f.serialize())
574
575        assert len(events) == 1
576        event = events[0]
577
578        assert isinstance(event, h2.events.StreamReset)
579        assert event.stream_id == 1
580        assert event.error_code is h2.errors.ErrorCodes.STREAM_CLOSED
581        assert isinstance(event.error_code, h2.errors.ErrorCodes)
582        assert event.remote_reset
583
584    def test_handle_stream_reset_with_unknown_erorr_code(self, frame_factory):
585        """
586        Streams being remotely reset with unknown error codes behave exactly as
587        they do with known error codes, but the error code on the event is an
588        int, instead of being an ErrorCodes.
589        """
590        c = h2.connection.H2Connection()
591        c.initiate_connection()
592        c.send_headers(1, self.example_request_headers, end_stream=True)
593        c.clear_outbound_data_buffer()
594
595        f = frame_factory.build_rst_stream_frame(stream_id=1, error_code=0xFA)
596        events = c.receive_data(f.serialize())
597
598        assert len(events) == 1
599        event = events[0]
600
601        assert isinstance(event, h2.events.StreamReset)
602        assert event.stream_id == 1
603        assert event.error_code == 250
604        assert not isinstance(event.error_code, h2.errors.ErrorCodes)
605        assert event.remote_reset
606
607    def test_can_consume_partial_data_from_connection(self):
608        """
609        We can do partial reads from the connection.
610        """
611        c = h2.connection.H2Connection()
612        c.initiate_connection()
613
614        assert len(c.data_to_send(2)) == 2
615        assert len(c.data_to_send(3)) == 3
616        assert 0 < len(c.data_to_send(500)) < 500
617        assert len(c.data_to_send(10)) == 0
618        assert len(c.data_to_send()) == 0
619
620    def test_we_can_update_settings(self, frame_factory):
621        """
622        Updating the settings emits a SETTINGS frame.
623        """
624        c = h2.connection.H2Connection()
625        c.initiate_connection()
626        c.clear_outbound_data_buffer()
627
628        new_settings = {
629            h2.settings.SettingCodes.HEADER_TABLE_SIZE: 52,
630            h2.settings.SettingCodes.ENABLE_PUSH: 0,
631        }
632        events = c.update_settings(new_settings)
633        assert not events
634
635        f = frame_factory.build_settings_frame(new_settings)
636        assert c.data_to_send() == f.serialize()
637
638    def test_settings_get_acked_correctly(self, frame_factory):
639        """
640        When settings changes are ACKed, they contain the changed settings.
641        """
642        c = h2.connection.H2Connection()
643        c.initiate_connection()
644
645        new_settings = {
646            h2.settings.SettingCodes.HEADER_TABLE_SIZE: 52,
647            h2.settings.SettingCodes.ENABLE_PUSH: 0,
648        }
649        c.update_settings(new_settings)
650
651        f = frame_factory.build_settings_frame({}, ack=True)
652        events = c.receive_data(f.serialize())
653
654        assert len(events) == 1
655        event = events[0]
656
657        assert isinstance(event, h2.events.SettingsAcknowledged)
658        assert len(event.changed_settings) == len(new_settings)
659        for setting, value in new_settings.items():
660            assert event.changed_settings[setting].new_value == value
661
662    def test_cannot_create_new_outbound_stream_over_limit(self, frame_factory):
663        """
664        When the number of outbound streams exceeds the remote peer's
665        MAX_CONCURRENT_STREAMS setting, attempting to open new streams fails.
666        """
667        c = h2.connection.H2Connection()
668        c.initiate_connection()
669
670        f = frame_factory.build_settings_frame(
671            {h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 1}
672        )
673        c.receive_data(f.serialize())[0]
674
675        c.send_headers(1, self.example_request_headers)
676
677        with pytest.raises(h2.exceptions.TooManyStreamsError):
678            c.send_headers(3, self.example_request_headers)
679
680    def test_can_receive_trailers(self, frame_factory):
681        """
682        When two HEADERS blocks are received in the same stream from a
683        server, the second set are trailers.
684        """
685        config = h2.config.H2Configuration(header_encoding='utf-8')
686        c = h2.connection.H2Connection(config=config)
687        c.initiate_connection()
688        c.send_headers(1, self.example_request_headers)
689        f = frame_factory.build_headers_frame(self.example_response_headers)
690        c.receive_data(f.serialize())
691
692        # Send in trailers.
693        trailers = [('content-length', '0')]
694        f = frame_factory.build_headers_frame(
695            trailers,
696            flags=['END_STREAM'],
697        )
698        events = c.receive_data(f.serialize())
699        assert len(events) == 2
700
701        event = events[0]
702        assert isinstance(event, h2.events.TrailersReceived)
703        assert event.headers == trailers
704        assert event.stream_id == 1
705
706    def test_reject_trailers_not_ending_stream(self, frame_factory):
707        """
708        When trailers are received without the END_STREAM flag being present,
709        this is a ProtocolError.
710        """
711        c = h2.connection.H2Connection()
712        c.initiate_connection()
713        c.send_headers(1, self.example_request_headers)
714        f = frame_factory.build_headers_frame(self.example_response_headers)
715        c.receive_data(f.serialize())
716
717        # Send in trailers.
718        c.clear_outbound_data_buffer()
719        trailers = [('content-length', '0')]
720        f = frame_factory.build_headers_frame(
721            trailers,
722            flags=[],
723        )
724
725        with pytest.raises(h2.exceptions.ProtocolError):
726            c.receive_data(f.serialize())
727
728        expected_frame = frame_factory.build_goaway_frame(
729            last_stream_id=0, error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
730        )
731        assert c.data_to_send() == expected_frame.serialize()
732
733    def test_can_send_trailers(self, frame_factory):
734        """
735        When a second set of headers are sent, they are properly trailers.
736        """
737        c = h2.connection.H2Connection()
738        c.initiate_connection()
739        c.clear_outbound_data_buffer()
740        c.send_headers(1, self.example_request_headers)
741
742        # Now send trailers.
743        trailers = [('content-length', '0')]
744        c.send_headers(1, trailers, end_stream=True)
745
746        frame_factory.refresh_encoder()
747        f1 = frame_factory.build_headers_frame(
748            self.example_request_headers,
749        )
750        f2 = frame_factory.build_headers_frame(
751            trailers,
752            flags=['END_STREAM'],
753        )
754        assert c.data_to_send() == f1.serialize() + f2.serialize()
755
756    def test_trailers_must_have_end_stream(self, frame_factory):
757        """
758        A set of trailers must carry the END_STREAM flag.
759        """
760        c = h2.connection.H2Connection()
761        c.initiate_connection()
762
763        # Send headers.
764        c.send_headers(1, self.example_request_headers)
765
766        # Now send trailers.
767        trailers = [('content-length', '0')]
768
769        with pytest.raises(h2.exceptions.ProtocolError):
770            c.send_headers(1, trailers)
771
772    def test_headers_are_lowercase(self, frame_factory):
773        """
774        When headers are sent, they are forced to lower-case.
775        """
776        weird_headers = self.example_request_headers + [
777            ('ChAnGiNg-CaSe', 'AlsoHere'),
778            ('alllowercase', 'alllowercase'),
779            ('ALLCAPS', 'ALLCAPS'),
780        ]
781        expected_headers = self.example_request_headers + [
782            ('changing-case', 'AlsoHere'),
783            ('alllowercase', 'alllowercase'),
784            ('allcaps', 'ALLCAPS'),
785        ]
786
787        c = h2.connection.H2Connection()
788        c.initiate_connection()
789        c.clear_outbound_data_buffer()
790
791        c.send_headers(1, weird_headers)
792        expected_frame = frame_factory.build_headers_frame(
793            headers=expected_headers
794        )
795
796        assert c.data_to_send() == expected_frame.serialize()
797
798    @given(frame_size=integers(min_value=2**14, max_value=(2**24 - 1)))
799    def test_changing_max_frame_size(self, frame_factory, frame_size):
800        """
801        When the user changes the max frame size and the change is ACKed, the
802        remote peer is now bound by the new frame size.
803        """
804        # We need to refresh the encoder because hypothesis has a problem with
805        # integrating with py.test, meaning that we use the same frame factory
806        # for all tests.
807        # See https://github.com/HypothesisWorks/hypothesis-python/issues/377
808        frame_factory.refresh_encoder()
809
810        c = h2.connection.H2Connection()
811        c.initiate_connection()
812
813        # Set up the stream.
814        c.send_headers(1, self.example_request_headers, end_stream=True)
815        headers_frame = frame_factory.build_headers_frame(
816            headers=self.example_response_headers,
817        )
818        c.receive_data(headers_frame.serialize())
819
820        # Change the max frame size.
821        c.update_settings(
822            {h2.settings.SettingCodes.MAX_FRAME_SIZE: frame_size}
823        )
824        settings_ack = frame_factory.build_settings_frame({}, ack=True)
825        c.receive_data(settings_ack.serialize())
826
827        # Greatly increase the flow control windows: we're not here to test
828        # flow control today.
829        c.increment_flow_control_window(increment=(2 * frame_size) + 1)
830        c.increment_flow_control_window(
831            increment=(2 * frame_size) + 1, stream_id=1
832        )
833
834        # Send one DATA frame that is exactly the max frame size: confirm it's
835        # fine.
836        data = frame_factory.build_data_frame(
837            data=(b'\x00' * frame_size),
838        )
839        events = c.receive_data(data.serialize())
840        assert len(events) == 1
841        assert isinstance(events[0], h2.events.DataReceived)
842        assert events[0].flow_controlled_length == frame_size
843
844        # Send one that is one byte too large: confirm a protocol error is
845        # raised.
846        data.data += b'\x00'
847        with pytest.raises(h2.exceptions.ProtocolError):
848            c.receive_data(data.serialize())
849
850    def test_cookies_are_joined_on_push(self, frame_factory):
851        """
852        RFC 7540 Section 8.1.2.5 requires that we join multiple Cookie headers
853        in a header block together when they're received on a push.
854        """
855        # This is a moderately varied set of cookie headers: some combined,
856        # some split.
857        cookie_headers = [
858            ('cookie',
859                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
860            ('cookie', 'path=1'),
861            ('cookie', 'test1=val1; test2=val2')
862        ]
863        expected = (
864            'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; '
865            'path=1; test1=val1; test2=val2'
866        )
867
868        config = h2.config.H2Configuration(header_encoding='utf-8')
869        c = h2.connection.H2Connection(config=config)
870        c.initiate_connection()
871        c.send_headers(1, self.example_request_headers, end_stream=True)
872
873        f = frame_factory.build_push_promise_frame(
874            stream_id=1,
875            promised_stream_id=2,
876            headers=self.example_request_headers + cookie_headers
877        )
878        events = c.receive_data(f.serialize())
879
880        assert len(events) == 1
881        e = events[0]
882
883        cookie_fields = [(n, v) for n, v in e.headers if n == 'cookie']
884        assert len(cookie_fields) == 1
885
886        _, v = cookie_fields[0]
887        assert v == expected
888
889    def test_cookies_arent_joined_without_normalization(self, frame_factory):
890        """
891        If inbound header normalization is disabled, cookie headers aren't
892        joined.
893        """
894        # This is a moderately varied set of cookie headers: some combined,
895        # some split.
896        cookie_headers = [
897            ('cookie',
898                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
899            ('cookie', 'path=1'),
900            ('cookie', 'test1=val1; test2=val2')
901        ]
902
903        config = h2.config.H2Configuration(
904            client_side=True,
905            normalize_inbound_headers=False,
906            header_encoding='utf-8'
907        )
908        c = h2.connection.H2Connection(config=config)
909        c.initiate_connection()
910        c.send_headers(1, self.example_request_headers, end_stream=True)
911
912        f = frame_factory.build_push_promise_frame(
913            stream_id=1,
914            promised_stream_id=2,
915            headers=self.example_request_headers + cookie_headers
916        )
917        events = c.receive_data(f.serialize())
918
919        assert len(events) == 1
920        e = events[0]
921
922        received_cookies = [(n, v) for n, v in e.headers if n == 'cookie']
923        assert len(received_cookies) == 3
924        assert cookie_headers == received_cookies
925
926
927class TestBasicServer(object):
928    """
929    Basic server-side tests.
930    """
931    example_request_headers = [
932        (u':authority', u'example.com'),
933        (u':path', u'/'),
934        (u':scheme', u'https'),
935        (u':method', u'GET'),
936    ]
937    bytes_example_request_headers = [
938        (b':authority', b'example.com'),
939        (b':path', b'/'),
940        (b':scheme', b'https'),
941        (b':method', b'GET'),
942    ]
943    example_response_headers = [
944        (':status', '200'),
945        ('server', 'hyper-h2/0.1.0')
946    ]
947    server_config = h2.config.H2Configuration(
948        client_side=False, header_encoding='utf-8'
949    )
950
951    def test_ignores_preamble(self):
952        """
953        The preamble does not cause any events or frames to be written.
954        """
955        c = h2.connection.H2Connection(config=self.server_config)
956        preamble = b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'
957
958        events = c.receive_data(preamble)
959        assert not events
960        assert not c.data_to_send()
961
962    @pytest.mark.parametrize("chunk_size", range(1, 24))
963    def test_drip_feed_preamble(self, chunk_size):
964        """
965        The preamble can be sent in in less than a single buffer.
966        """
967        c = h2.connection.H2Connection(config=self.server_config)
968        preamble = b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'
969        events = []
970
971        for i in range(0, len(preamble), chunk_size):
972            events += c.receive_data(preamble[i:i+chunk_size])
973
974        assert not events
975        assert not c.data_to_send()
976
977    def test_initiate_connection_sends_server_preamble(self, frame_factory):
978        """
979        For server-side connections, initiate_connection sends a server
980        preamble.
981        """
982        c = h2.connection.H2Connection(config=self.server_config)
983        expected_settings = frame_factory.build_settings_frame(
984            c.local_settings
985        )
986        expected_data = expected_settings.serialize()
987
988        events = c.initiate_connection()
989        assert not events
990        assert c.data_to_send() == expected_data
991
992    def test_headers_event(self, frame_factory):
993        """
994        When a headers frame is received a RequestReceived event fires.
995        """
996        c = h2.connection.H2Connection(config=self.server_config)
997        c.receive_data(frame_factory.preamble())
998
999        f = frame_factory.build_headers_frame(self.example_request_headers)
1000        data = f.serialize()
1001        events = c.receive_data(data)
1002
1003        assert len(events) == 1
1004        event = events[0]
1005
1006        assert isinstance(event, h2.events.RequestReceived)
1007        assert event.stream_id == 1
1008        assert event.headers == self.example_request_headers
1009
1010    def test_headers_event_bytes(self, frame_factory):
1011        """
1012        When a headers frame is received a RequestReceived event fires with
1013        bytes headers if the encoding is set appropriately.
1014        """
1015        config = h2.config.H2Configuration(
1016            client_side=False, header_encoding=False
1017        )
1018        c = h2.connection.H2Connection(config=config)
1019        c.receive_data(frame_factory.preamble())
1020
1021        f = frame_factory.build_headers_frame(self.example_request_headers)
1022        data = f.serialize()
1023        events = c.receive_data(data)
1024
1025        assert len(events) == 1
1026        event = events[0]
1027
1028        assert isinstance(event, h2.events.RequestReceived)
1029        assert event.stream_id == 1
1030        assert event.headers == self.bytes_example_request_headers
1031
1032    def test_data_event(self, frame_factory):
1033        """
1034        Test that data received on a stream fires a DataReceived event.
1035        """
1036        c = h2.connection.H2Connection(config=self.server_config)
1037        c.receive_data(frame_factory.preamble())
1038
1039        f1 = frame_factory.build_headers_frame(
1040            self.example_request_headers, stream_id=3
1041        )
1042        f2 = frame_factory.build_data_frame(
1043            b'some request data',
1044            stream_id=3,
1045        )
1046        data = b''.join(map(lambda f: f.serialize(), [f1, f2]))
1047        events = c.receive_data(data)
1048
1049        assert len(events) == 2
1050        event = events[1]
1051
1052        assert isinstance(event, h2.events.DataReceived)
1053        assert event.stream_id == 3
1054        assert event.data == b'some request data'
1055        assert event.flow_controlled_length == 17
1056
1057    def test_data_event_with_padding(self, frame_factory):
1058        """
1059        Test that data received on a stream fires a DataReceived event that
1060        accounts for padding.
1061        """
1062        c = h2.connection.H2Connection(config=self.server_config)
1063        c.receive_data(frame_factory.preamble())
1064
1065        f1 = frame_factory.build_headers_frame(
1066            self.example_request_headers, stream_id=3
1067        )
1068        f2 = frame_factory.build_data_frame(
1069            b'some request data',
1070            stream_id=3,
1071            padding_len=20
1072        )
1073        data = b''.join(map(lambda f: f.serialize(), [f1, f2]))
1074        events = c.receive_data(data)
1075
1076        assert len(events) == 2
1077        event = events[1]
1078
1079        assert isinstance(event, h2.events.DataReceived)
1080        assert event.stream_id == 3
1081        assert event.data == b'some request data'
1082        assert event.flow_controlled_length == 17 + 20 + 1
1083
1084    def test_receiving_ping_frame(self, frame_factory):
1085        """
1086        Ping frames should be immediately ACKed.
1087        """
1088        c = h2.connection.H2Connection(config=self.server_config)
1089        c.receive_data(frame_factory.preamble())
1090
1091        ping_data = b'\x01' * 8
1092        sent_frame = frame_factory.build_ping_frame(ping_data)
1093        expected_frame = frame_factory.build_ping_frame(
1094            ping_data, flags=["ACK"]
1095        )
1096        expected_data = expected_frame.serialize()
1097
1098        c.clear_outbound_data_buffer()
1099        events = c.receive_data(sent_frame.serialize())
1100
1101        assert len(events) == 1
1102        event = events[0]
1103
1104        assert isinstance(event, h2.events.PingReceived)
1105        assert event.ping_data == ping_data
1106
1107        assert c.data_to_send() == expected_data
1108
1109    def test_receiving_settings_frame_event(self, frame_factory):
1110        """
1111        Settings frames should cause a RemoteSettingsChanged event to fire.
1112        """
1113        c = h2.connection.H2Connection(config=self.server_config)
1114        c.receive_data(frame_factory.preamble())
1115
1116        f = frame_factory.build_settings_frame(
1117            settings=helpers.SAMPLE_SETTINGS
1118        )
1119        events = c.receive_data(f.serialize())
1120
1121        assert len(events) == 1
1122        event = events[0]
1123
1124        assert isinstance(event, h2.events.RemoteSettingsChanged)
1125        assert len(event.changed_settings) == len(helpers.SAMPLE_SETTINGS)
1126
1127    def test_acknowledging_settings(self, frame_factory):
1128        """
1129        Acknowledging settings causes appropriate Settings frame to be emitted.
1130        """
1131        c = h2.connection.H2Connection(config=self.server_config)
1132        c.receive_data(frame_factory.preamble())
1133
1134        received_frame = frame_factory.build_settings_frame(
1135            settings=helpers.SAMPLE_SETTINGS
1136        )
1137        expected_frame = frame_factory.build_settings_frame(
1138            settings={}, ack=True
1139        )
1140        expected_data = expected_frame.serialize()
1141
1142        c.clear_outbound_data_buffer()
1143        events = c.receive_data(received_frame.serialize())
1144
1145        assert len(events) == 1
1146        assert c.data_to_send() == expected_data
1147
1148    def test_close_connection(self, frame_factory):
1149        """
1150        Closing the connection with no error code emits a GOAWAY frame with
1151        error code 0.
1152        """
1153        c = h2.connection.H2Connection(config=self.server_config)
1154        c.receive_data(frame_factory.preamble())
1155        f = frame_factory.build_goaway_frame(last_stream_id=0)
1156        expected_data = f.serialize()
1157
1158        c.clear_outbound_data_buffer()
1159        events = c.close_connection()
1160
1161        assert not events
1162        assert c.data_to_send() == expected_data
1163
1164    @pytest.mark.parametrize("error_code", h2.errors.ErrorCodes)
1165    def test_close_connection_with_error_code(self, frame_factory, error_code):
1166        """
1167        Closing the connection with an error code emits a GOAWAY frame with
1168        that error code.
1169        """
1170        c = h2.connection.H2Connection(config=self.server_config)
1171        c.receive_data(frame_factory.preamble())
1172        f = frame_factory.build_goaway_frame(
1173            error_code=error_code, last_stream_id=0
1174        )
1175        expected_data = f.serialize()
1176
1177        c.clear_outbound_data_buffer()
1178        events = c.close_connection(error_code)
1179
1180        assert not events
1181        assert c.data_to_send() == expected_data
1182
1183    @pytest.mark.parametrize("last_stream_id,output", [
1184        (None, 23),
1185        (0, 0),
1186        (42, 42)
1187    ])
1188    def test_close_connection_with_last_stream_id(self, frame_factory,
1189                                                  last_stream_id, output):
1190        """
1191        Closing the connection with last_stream_id set emits a GOAWAY frame
1192        with that value.
1193        """
1194        c = h2.connection.H2Connection(config=self.server_config)
1195        c.receive_data(frame_factory.preamble())
1196        headers_frame = frame_factory.build_headers_frame(
1197            [
1198                (':authority', 'example.com'),
1199                (':path', '/'),
1200                (':scheme', 'https'),
1201                (':method', 'GET'),
1202            ],
1203            stream_id=23)
1204        c.receive_data(headers_frame.serialize())
1205
1206        f = frame_factory.build_goaway_frame(
1207            last_stream_id=output
1208        )
1209        expected_data = f.serialize()
1210
1211        c.clear_outbound_data_buffer()
1212        events = c.close_connection(last_stream_id=last_stream_id)
1213
1214        assert not events
1215        assert c.data_to_send() == expected_data
1216
1217    @pytest.mark.parametrize("additional_data,output", [
1218        (None, b''),
1219        (b'', b''),
1220        (b'foobar', b'foobar')
1221    ])
1222    def test_close_connection_with_additional_data(self, frame_factory,
1223                                                   additional_data, output):
1224        """
1225        Closing the connection with additional debug data emits a GOAWAY frame
1226        with that data attached.
1227        """
1228        c = h2.connection.H2Connection(config=self.server_config)
1229        c.receive_data(frame_factory.preamble())
1230        f = frame_factory.build_goaway_frame(
1231            last_stream_id=0, additional_data=output
1232        )
1233        expected_data = f.serialize()
1234
1235        c.clear_outbound_data_buffer()
1236        events = c.close_connection(additional_data=additional_data)
1237
1238        assert not events
1239        assert c.data_to_send() == expected_data
1240
1241    def test_reset_stream(self, frame_factory):
1242        """
1243        Resetting a stream with no error code emits a RST_STREAM frame with
1244        error code 0.
1245        """
1246        c = h2.connection.H2Connection(config=self.server_config)
1247        c.receive_data(frame_factory.preamble())
1248        f = frame_factory.build_headers_frame(self.example_request_headers)
1249        c.receive_data(f.serialize())
1250        c.clear_outbound_data_buffer()
1251
1252        expected_frame = frame_factory.build_rst_stream_frame(stream_id=1)
1253        expected_data = expected_frame.serialize()
1254
1255        events = c.reset_stream(stream_id=1)
1256
1257        assert not events
1258        assert c.data_to_send() == expected_data
1259
1260    @pytest.mark.parametrize("error_code", h2.errors.ErrorCodes)
1261    def test_reset_stream_with_error_code(self, frame_factory, error_code):
1262        """
1263        Resetting a stream with an error code emits a RST_STREAM frame with
1264        that error code.
1265        """
1266        c = h2.connection.H2Connection(config=self.server_config)
1267        c.receive_data(frame_factory.preamble())
1268        f = frame_factory.build_headers_frame(
1269            self.example_request_headers,
1270            stream_id=3
1271        )
1272        c.receive_data(f.serialize())
1273        c.clear_outbound_data_buffer()
1274
1275        expected_frame = frame_factory.build_rst_stream_frame(
1276            stream_id=3, error_code=error_code
1277        )
1278        expected_data = expected_frame.serialize()
1279
1280        events = c.reset_stream(stream_id=3, error_code=error_code)
1281
1282        assert not events
1283        assert c.data_to_send() == expected_data
1284
1285    def test_cannot_reset_nonexistent_stream(self, frame_factory):
1286        """
1287        Resetting nonexistent streams raises NoSuchStreamError.
1288        """
1289        c = h2.connection.H2Connection(config=self.server_config)
1290        c.receive_data(frame_factory.preamble())
1291        f = frame_factory.build_headers_frame(
1292            self.example_request_headers,
1293            stream_id=3
1294        )
1295        c.receive_data(f.serialize())
1296
1297        with pytest.raises(h2.exceptions.NoSuchStreamError) as e:
1298            c.reset_stream(stream_id=1)
1299
1300        assert e.value.stream_id == 1
1301
1302        with pytest.raises(h2.exceptions.NoSuchStreamError) as e:
1303            c.reset_stream(stream_id=5)
1304
1305        assert e.value.stream_id == 5
1306
1307    def test_basic_sending_ping_frame_logic(self, frame_factory):
1308        """
1309        Sending ping frames serializes a ping frame on stream 0 with
1310        approriate opaque data.
1311        """
1312        c = h2.connection.H2Connection(config=self.server_config)
1313        c.receive_data(frame_factory.preamble())
1314        c.clear_outbound_data_buffer()
1315
1316        ping_data = b'\x01\x02\x03\x04\x05\x06\x07\x08'
1317
1318        expected_frame = frame_factory.build_ping_frame(ping_data)
1319        expected_data = expected_frame.serialize()
1320
1321        events = c.ping(ping_data)
1322
1323        assert not events
1324        assert c.data_to_send() == expected_data
1325
1326    @pytest.mark.parametrize(
1327        'opaque_data',
1328        [
1329            b'',
1330            b'\x01\x02\x03\x04\x05\x06\x07',
1331            u'abcdefgh',
1332            b'too many bytes',
1333        ]
1334    )
1335    def test_ping_frame_opaque_data_must_be_length_8_bytestring(self,
1336                                                                frame_factory,
1337                                                                opaque_data):
1338        """
1339        Sending a ping frame only works with 8-byte bytestrings.
1340        """
1341        c = h2.connection.H2Connection(config=self.server_config)
1342        c.receive_data(frame_factory.preamble())
1343
1344        with pytest.raises(ValueError):
1345            c.ping(opaque_data)
1346
1347    def test_receiving_ping_acknowledgement(self, frame_factory):
1348        """
1349        Receiving a PING acknowledgement fires a PingAckReceived event.
1350        """
1351        c = h2.connection.H2Connection(config=self.server_config)
1352        c.receive_data(frame_factory.preamble())
1353
1354        ping_data = b'\x01\x02\x03\x04\x05\x06\x07\x08'
1355
1356        f = frame_factory.build_ping_frame(
1357            ping_data, flags=['ACK']
1358        )
1359        events = c.receive_data(f.serialize())
1360
1361        assert len(events) == 1
1362        event = events[0]
1363
1364        assert isinstance(event, h2.events.PingAckReceived)
1365        assert isinstance(event, h2.events.PingAcknowledged)  # deprecated
1366        assert event.ping_data == ping_data
1367
1368    def test_stream_ended_remotely(self, frame_factory):
1369        """
1370        When the remote stream ends with a non-empty data frame a DataReceived
1371        event and a StreamEnded event are fired.
1372        """
1373        c = h2.connection.H2Connection(config=self.server_config)
1374        c.receive_data(frame_factory.preamble())
1375
1376        f1 = frame_factory.build_headers_frame(
1377            self.example_request_headers, stream_id=3
1378        )
1379        f2 = frame_factory.build_data_frame(
1380            b'some request data',
1381            flags=['END_STREAM'],
1382            stream_id=3,
1383        )
1384        data = b''.join(map(lambda f: f.serialize(), [f1, f2]))
1385        events = c.receive_data(data)
1386
1387        assert len(events) == 3
1388        data_event = events[1]
1389        stream_ended_event = events[2]
1390
1391        assert isinstance(data_event, h2.events.DataReceived)
1392        assert isinstance(stream_ended_event, h2.events.StreamEnded)
1393        stream_ended_event.stream_id == 3
1394
1395    def test_can_push_stream(self, frame_factory):
1396        """
1397        Pushing a stream causes a PUSH_PROMISE frame to be emitted.
1398        """
1399        c = h2.connection.H2Connection(config=self.server_config)
1400        c.receive_data(frame_factory.preamble())
1401        f = frame_factory.build_headers_frame(
1402            self.example_request_headers
1403        )
1404        c.receive_data(f.serialize())
1405
1406        frame_factory.refresh_encoder()
1407        expected_frame = frame_factory.build_push_promise_frame(
1408            stream_id=1,
1409            promised_stream_id=2,
1410            headers=self.example_request_headers,
1411            flags=['END_HEADERS'],
1412        )
1413
1414        c.clear_outbound_data_buffer()
1415        c.push_stream(
1416            stream_id=1,
1417            promised_stream_id=2,
1418            request_headers=self.example_request_headers
1419        )
1420
1421        assert c.data_to_send() == expected_frame.serialize()
1422
1423    def test_cannot_push_streams_when_disabled(self, frame_factory):
1424        """
1425        When the remote peer has disabled stream pushing, we should fail.
1426        """
1427        c = h2.connection.H2Connection(config=self.server_config)
1428        c.receive_data(frame_factory.preamble())
1429        f = frame_factory.build_settings_frame(
1430            {h2.settings.SettingCodes.ENABLE_PUSH: 0}
1431        )
1432        c.receive_data(f.serialize())
1433
1434        f = frame_factory.build_headers_frame(
1435            self.example_request_headers
1436        )
1437        c.receive_data(f.serialize())
1438
1439        with pytest.raises(h2.exceptions.ProtocolError):
1440            c.push_stream(
1441                stream_id=1,
1442                promised_stream_id=2,
1443                request_headers=self.example_request_headers
1444            )
1445
1446    def test_settings_remote_change_header_table_size(self, frame_factory):
1447        """
1448        Acknowledging a remote HEADER_TABLE_SIZE settings change causes us to
1449        change the header table size of our encoder.
1450        """
1451        c = h2.connection.H2Connection(config=self.server_config)
1452        c.receive_data(frame_factory.preamble())
1453
1454        assert c.encoder.header_table_size == 4096
1455
1456        received_frame = frame_factory.build_settings_frame(
1457            {h2.settings.SettingCodes.HEADER_TABLE_SIZE: 80}
1458        )
1459        c.receive_data(received_frame.serialize())[0]
1460
1461        assert c.encoder.header_table_size == 80
1462
1463    def test_settings_local_change_header_table_size(self, frame_factory):
1464        """
1465        The remote peer acknowledging a local HEADER_TABLE_SIZE settings change
1466        does not cause us to change the header table size of our decoder.
1467
1468        For an explanation of why this test is this way around, see issue #37.
1469        """
1470        c = h2.connection.H2Connection(config=self.server_config)
1471        c.receive_data(frame_factory.preamble())
1472
1473        assert c.decoder.header_table_size == 4096
1474
1475        expected_frame = frame_factory.build_settings_frame({}, ack=True)
1476        c.update_settings(
1477            {h2.settings.SettingCodes.HEADER_TABLE_SIZE: 80}
1478        )
1479        c.receive_data(expected_frame.serialize())
1480        c.clear_outbound_data_buffer()
1481
1482        assert c.decoder.header_table_size == 4096
1483
1484    def test_restricting_outbound_frame_size_by_settings(self, frame_factory):
1485        """
1486        The remote peer can shrink the maximum outbound frame size using
1487        settings.
1488        """
1489        c = h2.connection.H2Connection(config=self.server_config)
1490        c.initiate_connection()
1491        c.receive_data(frame_factory.preamble())
1492
1493        f = frame_factory.build_headers_frame(self.example_request_headers)
1494        c.receive_data(f.serialize())
1495        c.clear_outbound_data_buffer()
1496
1497        with pytest.raises(h2.exceptions.FrameTooLargeError):
1498            c.send_data(1, b'\x01' * 17000)
1499
1500        received_frame = frame_factory.build_settings_frame(
1501            {h2.settings.SettingCodes.MAX_FRAME_SIZE: 17001}
1502        )
1503        c.receive_data(received_frame.serialize())
1504
1505        c.send_data(1, b'\x01' * 17000)
1506        assert c.data_to_send()
1507
1508    def test_restricting_inbound_frame_size_by_settings(self, frame_factory):
1509        """
1510        We throw ProtocolErrors and tear down connections if oversize frames
1511        are received.
1512        """
1513        c = h2.connection.H2Connection(config=self.server_config)
1514        c.receive_data(frame_factory.preamble())
1515        h = frame_factory.build_headers_frame(self.example_request_headers)
1516        c.receive_data(h.serialize())
1517        c.clear_outbound_data_buffer()
1518
1519        data_frame = frame_factory.build_data_frame(b'\x01' * 17000)
1520
1521        with pytest.raises(h2.exceptions.ProtocolError):
1522            c.receive_data(data_frame.serialize())
1523
1524        expected_frame = frame_factory.build_goaway_frame(
1525            last_stream_id=1, error_code=h2.errors.ErrorCodes.FRAME_SIZE_ERROR
1526        )
1527        assert c.data_to_send() == expected_frame.serialize()
1528
1529    def test_cannot_receive_new_streams_over_limit(self, frame_factory):
1530        """
1531        When the number of inbound streams exceeds our MAX_CONCURRENT_STREAMS
1532        setting, their attempt to open new streams fails.
1533        """
1534        c = h2.connection.H2Connection(config=self.server_config)
1535        c.receive_data(frame_factory.preamble())
1536        c.update_settings(
1537            {h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 1}
1538        )
1539        f = frame_factory.build_settings_frame({}, ack=True)
1540        c.receive_data(f.serialize())
1541
1542        f = frame_factory.build_headers_frame(
1543            stream_id=1,
1544            headers=self.example_request_headers,
1545        )
1546        c.receive_data(f.serialize())
1547        c.clear_outbound_data_buffer()
1548
1549        f = frame_factory.build_headers_frame(
1550            stream_id=3,
1551            headers=self.example_request_headers,
1552        )
1553        with pytest.raises(h2.exceptions.TooManyStreamsError):
1554            c.receive_data(f.serialize())
1555
1556        expected_frame = frame_factory.build_goaway_frame(
1557            last_stream_id=1, error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
1558        )
1559        assert c.data_to_send() == expected_frame.serialize()
1560
1561    def test_can_receive_trailers(self, frame_factory):
1562        """
1563        When two HEADERS blocks are received in the same stream from a
1564        client, the second set are trailers.
1565        """
1566        c = h2.connection.H2Connection(config=self.server_config)
1567        c.receive_data(frame_factory.preamble())
1568        f = frame_factory.build_headers_frame(self.example_request_headers)
1569        c.receive_data(f.serialize())
1570
1571        # Send in trailers.
1572        trailers = [('content-length', '0')]
1573        f = frame_factory.build_headers_frame(
1574            trailers,
1575            flags=['END_STREAM'],
1576        )
1577        events = c.receive_data(f.serialize())
1578        assert len(events) == 2
1579
1580        event = events[0]
1581        assert isinstance(event, h2.events.TrailersReceived)
1582        assert event.headers == trailers
1583        assert event.stream_id == 1
1584
1585    def test_reject_trailers_not_ending_stream(self, frame_factory):
1586        """
1587        When trailers are received without the END_STREAM flag being present,
1588        this is a ProtocolError.
1589        """
1590        c = h2.connection.H2Connection(config=self.server_config)
1591        c.receive_data(frame_factory.preamble())
1592        f = frame_factory.build_headers_frame(self.example_request_headers)
1593        c.receive_data(f.serialize())
1594
1595        # Send in trailers.
1596        c.clear_outbound_data_buffer()
1597        trailers = [('content-length', '0')]
1598        f = frame_factory.build_headers_frame(
1599            trailers,
1600            flags=[],
1601        )
1602
1603        with pytest.raises(h2.exceptions.ProtocolError):
1604            c.receive_data(f.serialize())
1605
1606        expected_frame = frame_factory.build_goaway_frame(
1607            last_stream_id=1, error_code=h2.errors.ErrorCodes.PROTOCOL_ERROR,
1608        )
1609        assert c.data_to_send() == expected_frame.serialize()
1610
1611    def test_can_send_trailers(self, frame_factory):
1612        """
1613        When a second set of headers are sent, they are properly trailers.
1614        """
1615        c = h2.connection.H2Connection(config=self.server_config)
1616        c.receive_data(frame_factory.preamble())
1617        f = frame_factory.build_headers_frame(self.example_request_headers)
1618        c.receive_data(f.serialize())
1619
1620        # Send headers.
1621        c.clear_outbound_data_buffer()
1622        c.send_headers(1, self.example_response_headers)
1623
1624        # Now send trailers.
1625        trailers = [('content-length', '0')]
1626        c.send_headers(1, trailers, end_stream=True)
1627
1628        frame_factory.refresh_encoder()
1629        f1 = frame_factory.build_headers_frame(
1630            self.example_response_headers,
1631        )
1632        f2 = frame_factory.build_headers_frame(
1633            trailers,
1634            flags=['END_STREAM'],
1635        )
1636        assert c.data_to_send() == f1.serialize() + f2.serialize()
1637
1638    def test_trailers_must_have_end_stream(self, frame_factory):
1639        """
1640        A set of trailers must carry the END_STREAM flag.
1641        """
1642        c = h2.connection.H2Connection(config=self.server_config)
1643        c.receive_data(frame_factory.preamble())
1644        f = frame_factory.build_headers_frame(self.example_request_headers)
1645        c.receive_data(f.serialize())
1646
1647        # Send headers.
1648        c.send_headers(1, self.example_response_headers)
1649
1650        # Now send trailers.
1651        trailers = [('content-length', '0')]
1652
1653        with pytest.raises(h2.exceptions.ProtocolError):
1654            c.send_headers(1, trailers)
1655
1656    @pytest.mark.parametrize("frame_id", range(12, 256))
1657    def test_unknown_frames_are_ignored(self, frame_factory, frame_id):
1658        c = h2.connection.H2Connection(config=self.server_config)
1659        c.receive_data(frame_factory.preamble())
1660        c.clear_outbound_data_buffer()
1661
1662        f = frame_factory.build_data_frame(data=b'abcdefghtdst')
1663        f.type = frame_id
1664
1665        events = c.receive_data(f.serialize())
1666        assert not c.data_to_send()
1667        assert len(events) == 1
1668        assert isinstance(events[0], h2.events.UnknownFrameReceived)
1669        assert isinstance(events[0].frame, hyperframe.frame.ExtensionFrame)
1670
1671    def test_can_send_goaway_repeatedly(self, frame_factory):
1672        """
1673        We can send a GOAWAY frame as many times as we like.
1674        """
1675        c = h2.connection.H2Connection(config=self.server_config)
1676        c.receive_data(frame_factory.preamble())
1677        c.clear_outbound_data_buffer()
1678
1679        c.close_connection()
1680        c.close_connection()
1681        c.close_connection()
1682
1683        f = frame_factory.build_goaway_frame(last_stream_id=0)
1684
1685        assert c.data_to_send() == (f.serialize() * 3)
1686
1687    def test_receiving_goaway_frame(self, frame_factory):
1688        """
1689        Receiving a GOAWAY frame causes a ConnectionTerminated event to be
1690        fired and transitions the connection to the CLOSED state, and clears
1691        the outbound data buffer.
1692        """
1693        c = h2.connection.H2Connection(config=self.server_config)
1694        c.initiate_connection()
1695        c.receive_data(frame_factory.preamble())
1696
1697        f = frame_factory.build_goaway_frame(
1698            last_stream_id=5, error_code=h2.errors.ErrorCodes.SETTINGS_TIMEOUT
1699        )
1700        events = c.receive_data(f.serialize())
1701
1702        assert len(events) == 1
1703        event = events[0]
1704
1705        assert isinstance(event, h2.events.ConnectionTerminated)
1706        assert event.error_code == h2.errors.ErrorCodes.SETTINGS_TIMEOUT
1707        assert isinstance(event.error_code, h2.errors.ErrorCodes)
1708        assert event.last_stream_id == 5
1709        assert event.additional_data is None
1710        assert c.state_machine.state == h2.connection.ConnectionState.CLOSED
1711
1712        assert not c.data_to_send()
1713
1714    def test_receiving_multiple_goaway_frames(self, frame_factory):
1715        """
1716        Multiple GOAWAY frames can be received at once, and are allowed. Each
1717        one fires a ConnectionTerminated event.
1718        """
1719        c = h2.connection.H2Connection(config=self.server_config)
1720        c.receive_data(frame_factory.preamble())
1721        c.clear_outbound_data_buffer()
1722
1723        f = frame_factory.build_goaway_frame(last_stream_id=0)
1724        events = c.receive_data(f.serialize() * 3)
1725
1726        assert len(events) == 3
1727        assert all(
1728            isinstance(event, h2.events.ConnectionTerminated)
1729            for event in events
1730        )
1731
1732    def test_receiving_goaway_frame_with_additional_data(self, frame_factory):
1733        """
1734        GOAWAY frame can contain additional data,
1735        it should be available via ConnectionTerminated event.
1736        """
1737        c = h2.connection.H2Connection(config=self.server_config)
1738        c.initiate_connection()
1739        c.receive_data(frame_factory.preamble())
1740
1741        additional_data = b'debug data'
1742        f = frame_factory.build_goaway_frame(last_stream_id=0,
1743                                             additional_data=additional_data)
1744        events = c.receive_data(f.serialize())
1745
1746        assert len(events) == 1
1747        event = events[0]
1748
1749        assert isinstance(event, h2.events.ConnectionTerminated)
1750        assert event.additional_data == additional_data
1751
1752    def test_receiving_goaway_frame_with_unknown_error(self, frame_factory):
1753        """
1754        Receiving a GOAWAY frame with an unknown error code behaves exactly the
1755        same as receiving one we know about, but the code is reported as an
1756        integer instead of as an ErrorCodes.
1757        """
1758        c = h2.connection.H2Connection(config=self.server_config)
1759        c.initiate_connection()
1760        c.receive_data(frame_factory.preamble())
1761
1762        f = frame_factory.build_goaway_frame(
1763            last_stream_id=5, error_code=0xFA
1764        )
1765        events = c.receive_data(f.serialize())
1766
1767        assert len(events) == 1
1768        event = events[0]
1769
1770        assert isinstance(event, h2.events.ConnectionTerminated)
1771        assert event.error_code == 250
1772        assert not isinstance(event.error_code, h2.errors.ErrorCodes)
1773        assert event.last_stream_id == 5
1774        assert event.additional_data is None
1775        assert c.state_machine.state == h2.connection.ConnectionState.CLOSED
1776
1777        assert not c.data_to_send()
1778
1779    def test_cookies_are_joined(self, frame_factory):
1780        """
1781        RFC 7540 Section 8.1.2.5 requires that we join multiple Cookie headers
1782        in a header block together.
1783        """
1784        # This is a moderately varied set of cookie headers: some combined,
1785        # some split.
1786        cookie_headers = [
1787            ('cookie',
1788                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
1789            ('cookie', 'path=1'),
1790            ('cookie', 'test1=val1; test2=val2')
1791        ]
1792        expected = (
1793            'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; '
1794            'path=1; test1=val1; test2=val2'
1795        )
1796
1797        c = h2.connection.H2Connection(config=self.server_config)
1798        c.initiate_connection()
1799        c.receive_data(frame_factory.preamble())
1800
1801        f = frame_factory.build_headers_frame(
1802            self.example_request_headers + cookie_headers
1803        )
1804        events = c.receive_data(f.serialize())
1805
1806        assert len(events) == 1
1807        e = events[0]
1808
1809        cookie_fields = [(n, v) for n, v in e.headers if n == 'cookie']
1810        assert len(cookie_fields) == 1
1811
1812        _, v = cookie_fields[0]
1813        assert v == expected
1814
1815    def test_cookies_arent_joined_without_normalization(self, frame_factory):
1816        """
1817        If inbound header normalization is disabled, cookie headers aren't
1818        joined.
1819        """
1820        # This is a moderately varied set of cookie headers: some combined,
1821        # some split.
1822        cookie_headers = [
1823            ('cookie',
1824                'username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC'),
1825            ('cookie', 'path=1'),
1826            ('cookie', 'test1=val1; test2=val2')
1827        ]
1828
1829        config = h2.config.H2Configuration(
1830            client_side=False,
1831            normalize_inbound_headers=False,
1832            header_encoding='utf-8'
1833        )
1834        c = h2.connection.H2Connection(config=config)
1835        c.initiate_connection()
1836        c.receive_data(frame_factory.preamble())
1837
1838        f = frame_factory.build_headers_frame(
1839            self.example_request_headers + cookie_headers
1840        )
1841        events = c.receive_data(f.serialize())
1842
1843        assert len(events) == 1
1844        e = events[0]
1845
1846        received_cookies = [(n, v) for n, v in e.headers if n == 'cookie']
1847        assert len(received_cookies) == 3
1848        assert cookie_headers == received_cookies
1849
1850    def test_stream_repr(self):
1851        """
1852        Ensure stream string representation is appropriate.
1853        """
1854        s = h2.stream.H2Stream(4, None, 12, 14)
1855        assert repr(s) == "<H2Stream id:4 state:<StreamState.IDLE: 0>>"
1856
1857
1858def sanity_check_data_frame(data_frame,
1859                            expected_flow_controlled_length,
1860                            expect_padded_flag,
1861                            expected_data_frame_pad_length):
1862    """
1863    ``data_frame`` is a frame of type ``hyperframe.frame.DataFrame``,
1864    and the ``flags`` and ``flow_controlled_length`` of ``data_frame``
1865    match expectations.
1866    """
1867
1868    assert isinstance(data_frame, hyperframe.frame.DataFrame)
1869
1870    assert data_frame.flow_controlled_length == expected_flow_controlled_length
1871
1872    if expect_padded_flag:
1873        assert 'PADDED' in data_frame.flags
1874    else:
1875        assert 'PADDED' not in data_frame.flags
1876
1877    assert data_frame.pad_length == expected_data_frame_pad_length
1878