def test_no_data_on_closed_stream(self, tctx): frame_factory = FrameFactory() req = Request.make("GET", "http://example.com/") resp = {":status": 200} assert ( Playbook(Http2Client(tctx)) << SendData( tctx.server, Placeholder(bytes)) # preamble + initial settings frame >> DataReceived( tctx.server, frame_factory.build_settings_frame({}, ack=True).serialize()) >> http.RequestHeaders(1, req, end_stream=True) << SendData( tctx.server, b"\x00\x00\x06\x01\x05\x00\x00\x00\x01\x82\x86\x84\\\x81\x07") >> http.RequestEndOfMessage(1) >> DataReceived( tctx.server, frame_factory.build_headers_frame(resp).serialize()) << http.ReceiveHttp(Placeholder( http.ResponseHeaders)) >> http.RequestProtocolError( 1, "cancelled", code=status_codes.CLIENT_CLOSED_REQUEST) << SendData( tctx.server, frame_factory.build_rst_stream_frame( 1, ErrorCodes.CANCEL).serialize()) >> DataReceived( tctx.server, frame_factory.build_data_frame(b"foo").serialize()) << SendData( tctx.server, frame_factory.build_rst_stream_frame( 1, ErrorCodes.STREAM_CLOSED).serialize()) ) # important: no ResponseData event here!
def h2_frames(draw): ff = FrameFactory() headers1 = ff.build_headers_frame(headers=draw(h2_headers())) headers1.flags.clear() headers1.flags |= draw(h2_flags) headers2 = ff.build_headers_frame(headers=draw(h2_headers()), depends_on=draw(h2_stream_ids), stream_weight=draw(integers(0, 255)), exclusive=draw(booleans())) headers2.flags.clear() headers2.flags |= draw(h2_flags) settings = ff.build_settings_frame(settings=draw( dictionaries( keys=sampled_from(SettingCodes), values=integers(0, 2**32 - 1), max_size=5, )), ack=draw(booleans())) continuation = ff.build_continuation_frame(header_block=ff.encoder.encode( draw(h2_headers())), flags=draw(h2_flags)) goaway = ff.build_goaway_frame(draw(h2_stream_ids)) push_promise = ff.build_push_promise_frame( stream_id=draw(h2_stream_ids_nonzero), promised_stream_id=draw(h2_stream_ids), headers=draw(h2_headers())) rst = ff.build_rst_stream_frame(draw(h2_stream_ids_nonzero)) prio = ff.build_priority_frame( stream_id=draw(h2_stream_ids_nonzero), weight=draw(integers(0, 255)), depends_on=draw(h2_stream_ids), exclusive=draw(booleans()), ) data1 = ff.build_data_frame(draw(binary()), draw(h2_flags)) data2 = ff.build_data_frame(draw(binary()), draw(h2_flags), stream_id=draw(h2_stream_ids_nonzero)) window_update = ff.build_window_update_frame(draw(h2_stream_ids), draw(integers(0, 2**32 - 1))) frames = draw( lists(sampled_from([ headers1, headers2, settings, continuation, goaway, push_promise, rst, prio, data1, data2, window_update ]), min_size=1, max_size=11)) return b"".join(x.serialize() for x in frames)