示例#1
0
    def test_stream_reading_works(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))
            return inner

        s = Stream(1, send_cb, None, None, None)
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide a data frame to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read()
        assert data == b'hi there!'
        assert len(out_frames) == 0
示例#2
0
    def test_windowupdate_frames_update_windows(self):
        s = Stream(1, None, None, None, None)
        f = WindowUpdateFrame(1)
        f.window_increment = 1000
        s.receive_frame(f)

        assert s._out_flow_control_window == 65535 + 1000
示例#3
0
    def test_stream_reading_works(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        s = Stream(1, send_cb, None, None, None)
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide a data frame to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read()
        assert data == b'hi there!'
        assert len(out_frames) == 0
示例#4
0
    def test_flow_control_manager_update_includes_padding(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        start_window = 65535
        s = Stream(1, send_cb, None, None, None, None,
                   FlowControlManager(start_window))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        f.pad_length = 10
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read()
        assert data == b'hi there!'
        assert s._in_window_manager.window_size == start_window - f.pad_length - len(
            data) - 1
示例#5
0
    def test_can_read_multiple_frames_from_streams(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))
            return inner

        s = Stream(1, send_cb, None, None, None)
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        in_frames.append(f)

        f = DataFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read()
        assert data == b'hi there!hi there again!'
        assert len(out_frames) == 1
        assert isinstance(out_frames[0], WindowUpdateFrame)
        assert out_frames[0].window_increment == len(b'hi there!')
示例#6
0
    def test_receive_unexpected_frame(self):
        # SETTINGS frames are never defined on streams, so send one of those.
        s = Stream(1, None, None, None, None, None, None)
        f = SettingsFrame(0)

        with pytest.raises(ValueError):
            s.receive_frame(f)
示例#7
0
    def test_can_read_multiple_frames_from_streams(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        s = Stream(1, send_cb, None, None, None)
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        in_frames.append(f)

        f = DataFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read()
        assert data == b'hi there!hi there again!'
        assert len(out_frames) == 1
        assert isinstance(out_frames[0], WindowUpdateFrame)
        assert out_frames[0].window_increment == len(b'hi there!')
示例#8
0
    def test_windowupdate_frames_update_windows(self):
        s = Stream(1, None, None, None, None)
        f = WindowUpdateFrame(1)
        f.window_increment = 1000
        s.receive_frame(f)

        assert s._out_flow_control_window == 65535 + 1000
示例#9
0
    def test_flow_control_manager_update_includes_padding(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))
            return inner

        start_window = 65535
        s = Stream(1, send_cb, None, None, None, None, FlowControlManager(start_window))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        f.pad_length = 10
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read()
        assert data == b'hi there!'
        assert s._in_window_manager.window_size == start_window - f.pad_length - len(data) - 1
示例#10
0
    def test_receive_unexpected_frame(self):
        # SETTINGS frames are never defined on streams, so send one of those.
        s = Stream(1, None, None, None, None, None, None)
        f = SettingsFrame(0)

        with pytest.raises(ValueError):
            s.receive_frame(f)
示例#11
0
    def test_cannot_receive_three_header_blocks(self):
        first = [('a', 'b'), ('c', 'd'), (':status', '200')]

        s = Stream(1, None, None, None, None, FixedDecoder(first), None)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide the first two header frames.
        f = HeadersFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        # Provide the third. This one blows up.
        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        f.flags.add('END_HEADERS')

        with pytest.raises(ProtocolError):
            s.receive_frame(f)
示例#12
0
    def test_stream_opening_sends_headers(self):
        def data_callback(frame):
            assert isinstance(frame, HeadersFrame)
            assert frame.data == 'testkeyTestVal'
            assert frame.flags == set(['END_STREAM', 'END_HEADERS'])

        s = Stream(1, data_callback, None, NullEncoder, None)
        s.add_header("TestKey", "TestVal")
        s.open(True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
示例#13
0
    def test_can_receive_continuation_frame_after_end_stream(self):
        s = Stream(1, None, None, None, None, None, FlowControlManager(65535))
        f = HeadersFrame(1)
        f.data = 'hi there'
        f.flags = set('END_STREAM')
        f2 = ContinuationFrame(1)
        f2.data = ' sir'
        f2.flags = set('END_HEADERS')

        s.receive_frame(f)
        s.receive_frame(f2)
示例#14
0
    def test_bytestrings_can_be_sent(self):
        def data_callback(frame):
            assert isinstance(frame, DataFrame)
            assert frame.data == b'Hi there!'
            assert frame.flags == set(['END_STREAM'])

        s = Stream(1, data_callback, None, NullEncoder, None)
        s.state = STATE_OPEN
        s.send_data(b'Hi there!', True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
        assert s._out_flow_control_window == 65535 - len(b'Hi there!')
示例#15
0
    def test_file_objects_can_be_sent(self):
        def data_callback(frame):
            assert isinstance(frame, DataFrame)
            assert frame.data == b"Hi there!"
            assert frame.flags == set(["END_STREAM"])

        s = Stream(1, data_callback, None, None, NullEncoder, None, None)
        s.state = STATE_OPEN
        s.send_data(BytesIO(b"Hi there!"), True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
        assert s._out_flow_control_window == 65535 - len(b"Hi there!")
示例#16
0
    def test_bytestrings_can_be_sent(self):
        def data_callback(frame):
            assert isinstance(frame, DataFrame)
            assert frame.data == b'Hi there!'
            assert frame.flags == set(['END_STREAM'])

        s = Stream(1, data_callback, None, NullEncoder, None)
        s.state = STATE_OPEN
        s.send_data(b'Hi there!', True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
        assert s._out_flow_control_window == 65535 - len(b'Hi there!')
示例#17
0
    def test_can_receive_trailers(self):
        headers = [('a', 'b'), ('c', 'd'), (':status', '200')]
        trailers = [('e', 'f'), ('g', 'h')]

        s = Stream(1, None, None, None, None, FixedDecoder(headers), None)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide the first HEADERS frame.
        f = HeadersFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        assert s.response_headers == HTTPHeaderMap(headers)

        # Now, replace the dummy decoder to ensure we get a new header block.
        s._decoder = FixedDecoder(trailers)

        # Provide the trailers.
        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        # Now, check the trailers.
        assert s.response_trailers == HTTPHeaderMap(trailers)

        # Confirm we closed the stream.
        assert s.state == STATE_CLOSED
示例#18
0
    def test_cannot_receive_three_header_blocks(self):
        first = [('a', 'b'), ('c', 'd'), (':status', '200')]

        s = Stream(1, None, None, None, None, FixedDecoder(first), None)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide the first two header frames.
        f = HeadersFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        # Provide the third. This one blows up.
        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        f.flags.add('END_HEADERS')

        with pytest.raises(ProtocolError):
            s.receive_frame(f)
示例#19
0
    def test_can_receive_trailers(self):
        headers = [('a', 'b'), ('c', 'd'), (':status', '200')]
        trailers = [('e', 'f'), ('g', 'h')]

        s = Stream(1, None, None, None, None, FixedDecoder(headers), None)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide the first HEADERS frame.
        f = HeadersFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        assert s.response_headers == HTTPHeaderMap(headers)

        # Now, replace the dummy decoder to ensure we get a new header block.
        s._decoder = FixedDecoder(trailers)

        # Provide the trailers.
        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        f.flags.add('END_HEADERS')
        s.receive_frame(f)

        # Now, check the trailers.
        assert s.response_trailers == HTTPHeaderMap(trailers)

        # Confirm we closed the stream.
        assert s.state == STATE_CLOSED
示例#20
0
    def test_long_bytestrings_are_split(self):
        frame_count = [0]
        recent_frame = [None]

        def data_callback(frame):
            assert isinstance(frame, DataFrame)
            assert len(frame.data) <= MAX_CHUNK
            frame_count[0] += 1
            recent_frame[0] = frame

        data = b'test' * (MAX_CHUNK + 1)

        s = Stream(1, data_callback, None, NullEncoder, None)
        s.state = STATE_OPEN
        s.send_data(data, True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
        assert recent_frame[0].flags == set(['END_STREAM'])
        assert frame_count[0] == 5
        assert s._out_flow_control_window == 65535 - len(data)
示例#21
0
    def test_long_bytestrings_are_split(self):
        frame_count = [0]
        recent_frame = [None]

        def data_callback(frame):
            assert isinstance(frame, DataFrame)
            assert len(frame.data) <= MAX_CHUNK
            frame_count[0] += 1
            recent_frame[0] = frame

        data = b'test' * (MAX_CHUNK + 1)

        s = Stream(1, data_callback, None, NullEncoder, None)
        s.state = STATE_OPEN
        s.send_data(data, True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
        assert recent_frame[0].flags == set(['END_STREAM'])
        assert frame_count[0] == 5
        assert s._out_flow_control_window == 65535 - len(data)
示例#22
0
    def test_large_file_objects_are_broken_into_chunks(self):
        frame_count = [0]
        recent_frame = [None]

        def data_callback(frame):
            assert isinstance(frame, DataFrame)
            assert len(frame.data) <= MAX_CHUNK
            frame_count[0] += 1
            recent_frame[0] = frame

        data = b"test" * (MAX_CHUNK + 1)

        s = Stream(1, data_callback, None, None, NullEncoder, None, None)
        s.state = STATE_OPEN
        s.send_data(BytesIO(data), True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
        assert recent_frame[0].flags == set(["END_STREAM"])
        assert frame_count[0] == 5
        assert s._out_flow_control_window == 65535 - len(data)
示例#23
0
    def test_blocked_frames_cause_window_updates(self):
        out_frames = []

        def send_cb(frame, *args):
            out_frames.append(frame)

        start_window = 65535
        s = Stream(1, send_cb, None, None, None, None, FlowControlManager(start_window))
        s._data_cb = send_cb
        s.state = STATE_HALF_CLOSED_LOCAL

        # Change the window size.
        s._in_window_manager.window_size = 60000

        # Provide a BLOCKED frame.
        f = BlockedFrame(1)
        s.receive_frame(f)

        assert len(out_frames) == 1
        assert out_frames[0].type == WindowUpdateFrame.type
        assert out_frames[0].window_increment == 5535
示例#24
0
    def test_partial_reads_from_streams(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        s = Stream(1, send_cb, None, None, None, None, FlowControlManager(65535))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b"hi there!"
        in_frames.append(f)

        f = DataFrame(1)
        f.data = b"hi there again!"
        f.flags.add("END_STREAM")
        in_frames.append(f)

        # We'll get the entire first frame.
        data = s._read(4)
        assert data == b"hi there!"
        assert len(out_frames) == 1

        # Now we'll get the entire of the second frame.
        data = s._read(4)
        assert data == b"hi there again!"
        assert len(out_frames) == 1
        assert s.state == STATE_CLOSED
示例#25
0
    def test_can_receive_continuation_frame_after_end_stream(self):
        s = Stream(1, None, None, None, None, None, FlowControlManager(65535))
        f = HeadersFrame(1)
        f.data = 'hi there'
        f.flags = set('END_STREAM')
        f2 = ContinuationFrame(1)
        f2.data = ' sir'
        f2.flags = set('END_HEADERS')

        s.receive_frame(f)
        s.receive_frame(f2)
示例#26
0
    def test_stream_opening_sends_headers(self):
        def data_callback(frame):
            assert isinstance(frame, HeadersFrame)
            assert frame.data == 'testkeyTestVal'
            assert frame.flags == set(['END_STREAM', 'END_HEADERS'])

        s = Stream(1, data_callback, None, NullEncoder, None)
        s.add_header("TestKey", "TestVal")
        s.open(True)

        assert s.state == STATE_HALF_CLOSED_LOCAL
示例#27
0
    def test_reading_trailers_early_reads_all_data(self):
        in_frames = []
        headers = [('a', 'b'), ('c', 'd'), (':status', '200')]
        trailers = [('e', 'f'), ('g', 'h')]

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        s = Stream(1, None, None, None, None, FixedDecoder(headers),
                   FlowControlManager(65535))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide the first HEADERS frame.
        f = HeadersFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_HEADERS')
        in_frames.append(f)

        # Provide some data.
        f = DataFrame(1)
        f.data = b'testdata'
        in_frames.append(f)

        # Provide the trailers.
        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        f.flags.add('END_HEADERS')
        in_frames.append(f)

        # Begin by reading the first headers.
        assert s.getheaders() == HTTPHeaderMap(headers)

        # Now, replace the dummy decoder to ensure we get a new header block.
        s._decoder = FixedDecoder(trailers)

        # Ask for the trailers. This should also read the data frames.
        assert s.gettrailers() == HTTPHeaderMap(trailers)
        assert s.data == [b'testdata']
示例#28
0
    def test_can_read_single_frames_from_streams(self):
        out_frames = []
        in_frames = []

        def send_cb(frame, tolerate_peer_gone=False):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        s = Stream(1, send_cb, None, None, None, None, FlowControlManager(800))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        in_frames.append(f)

        f = DataFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read_one_frame()
        assert data == b'hi there!'

        data = s._read_one_frame()
        assert data == b'hi there again!'

        data = s._read_one_frame()
        assert data is None

        data = s._read()
        assert data == b''
示例#29
0
    def test_can_read_single_frames_from_streams(self):
        out_frames = []
        in_frames = []

        def send_cb(frame, tolerate_peer_gone=False):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))
            return inner

        s = Stream(1, send_cb, None, None, None, None, FlowControlManager(800))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        in_frames.append(f)

        f = DataFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        data = s._read_one_frame()
        assert data == b'hi there!'

        data = s._read_one_frame()
        assert data == b'hi there again!'

        data = s._read_one_frame()
        assert data is None

        data = s._read()
        assert data == b''
示例#30
0
    def test_reading_trailers_early_reads_all_data(self):
        in_frames = []
        headers = [('a', 'b'), ('c', 'd'), (':status', '200')]
        trailers = [('e', 'f'), ('g', 'h')]

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))
            return inner

        s = Stream(1, None, None, None, None, FixedDecoder(headers), FlowControlManager(65535))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide the first HEADERS frame.
        f = HeadersFrame(1)
        f.data = b'hi there!'
        f.flags.add('END_HEADERS')
        in_frames.append(f)

        # Provide some data.
        f = DataFrame(1)
        f.data = b'testdata'
        in_frames.append(f)

        # Provide the trailers.
        f = HeadersFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        f.flags.add('END_HEADERS')
        in_frames.append(f)

        # Begin by reading the first headers.
        assert s.getheaders() == HTTPHeaderMap(headers)

        # Now, replace the dummy decoder to ensure we get a new header block.
        s._decoder = FixedDecoder(trailers)

        # Ask for the trailers. This should also read the data frames.
        assert s.gettrailers() == HTTPHeaderMap(trailers)
        assert s.data == [b'testdata']
示例#31
0
    def test_blocked_frames_cause_window_updates(self):
        out_frames = []

        def send_cb(frame, *args):
            out_frames.append(frame)

        start_window = 65535
        s = Stream(1, send_cb, None, None, None, None,
                   FlowControlManager(start_window))
        s._data_cb = send_cb
        s.state = STATE_HALF_CLOSED_LOCAL

        # Change the window size.
        s._in_window_manager.window_size = 60000

        # Provide a BLOCKED frame.
        f = BlockedFrame(1)
        s.receive_frame(f)

        assert len(out_frames) == 1
        assert out_frames[0].type == WindowUpdateFrame.type
        assert out_frames[0].window_increment == 5535
示例#32
0
    def test_partial_reads_from_streams(self):
        out_frames = []
        in_frames = []

        def send_cb(frame):
            out_frames.append(frame)

        def recv_cb(s):
            def inner():
                s.receive_frame(in_frames.pop(0))

            return inner

        s = Stream(1, send_cb, None, None, None, None,
                   FlowControlManager(65535))
        s._recv_cb = recv_cb(s)
        s.state = STATE_HALF_CLOSED_LOCAL

        # Provide two data frames to read.
        f = DataFrame(1)
        f.data = b'hi there!'
        in_frames.append(f)

        f = DataFrame(1)
        f.data = b'hi there again!'
        f.flags.add('END_STREAM')
        in_frames.append(f)

        # We'll get the entire first frame.
        data = s._read(4)
        assert data == b'hi there!'
        assert len(out_frames) == 1

        # Now we'll get the entire of the second frame.
        data = s._read(4)
        assert data == b'hi there again!'
        assert len(out_frames) == 1
        assert s.state == STATE_CLOSED
示例#33
0
 def test_receiving_a_frame_queues_it(self):
     s = Stream(1, None, None, None, None)
     s.receive_frame(Frame(0))
     assert len(s._queued_frames) == 1
示例#34
0
 def test_streams_can_have_headers(self):
     s = Stream(1, None, None, None, None)
     s.add_header("name", "value")
     assert s.headers == [("name", "value")]
示例#35
0
 def test_streams_can_have_headers(self):
     s = Stream(1, None, None, None, None)
     s.add_header("name", "value")
     assert s.headers == [("name", "value")]
示例#36
0
 def test_streams_initially_have_no_headers(self):
     s = Stream(1, None, None, None, None)
     assert s.headers == []
示例#37
0
 def test_streams_have_ids(self):
     s = Stream(1, None, None, None, None)
     assert s.stream_id == 1
示例#38
0
 def test_receiving_a_frame_queues_it(self):
     s = Stream(1, None, None, None, None)
     s.receive_frame(Frame(0))
     assert len(s._queued_frames) == 1