def __call__(self): if self.server_conn: self._initiate_server_conn() preamble = self.client_conn.rfile.read(24) self.client_conn.h2.initiate_connection() self.client_conn.h2.receive_data(preamble) self.client_conn.send(self.client_conn.h2.data_to_send()) while True: r = ssl_read_select(self.active_conns, 1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (conn == self.server_conn.connection) with source_conn.h2.lock: try: raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile)) except: for stream in self.streams.values(): stream.zombie = time.time() return events = source_conn.h2.receive_data(raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in events: if not self._handle_event(event, source_conn, other_conn, is_server): return self._cleanup_streams()
def __call__(self): if self.server_conn: self._initiate_server_conn() preamble = self.client_conn.rfile.read(24) self.client_conn.h2.initiate_connection() self.client_conn.h2.receive_data(preamble) self.client_conn.send(self.client_conn.h2.data_to_send()) while True: r = ssl_read_select(self.active_conns, 1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (conn == self.server_conn.connection) with source_conn.h2.lock: try: raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile)) except: # read frame failed: connection closed self._kill_all_streams() return incoming_events = source_conn.h2.receive_data(raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in incoming_events: if not self._handle_event(event, source_conn, other_conn, is_server): # connection terminated: GoAway self._kill_all_streams() return self._cleanup_streams()
def __call__(self): if self.server_conn: self._initiate_server_conn() preamble = self.client_conn.rfile.read(24) self.client_conn.h2.initiate_connection() self.client_conn.h2.receive_data(preamble) self.client_conn.send(self.client_conn.h2.data_to_send()) while True: r = ssl_read_select(self.active_conns, 1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (conn == self.server_conn.connection) with source_conn.h2.lock: try: raw_frame = b''.join( http2_read_raw_frame(source_conn.rfile)) except: for stream in self.streams.values(): stream.zombie = time.time() return events = source_conn.h2.receive_data(raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in events: if not self._handle_event(event, source_conn, other_conn, is_server): return self._cleanup_streams()
def handle(self): h2_conn = h2.connection.H2Connection(client_side=False) preamble = self.rfile.read(24) h2_conn.initiate_connection() h2_conn.receive_data(preamble) self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() done = False while not done: try: raw = b''.join(http2_read_raw_frame(self.rfile)) events = h2_conn.receive_data(raw) except: break self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() for event in events: try: if not self.server.handle_server_event( event, h2_conn, self.rfile, self.wfile): done = True break except Exception as e: print(repr(e)) print(traceback.format_exc()) done = True break
def handle(self): h2_conn = h2.connection.H2Connection(client_side=False, header_encoding=False) preamble = self.rfile.read(24) h2_conn.initiate_connection() h2_conn.receive_data(preamble) self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() done = False while not done: try: raw = b''.join(http2_read_raw_frame(self.rfile)) events = h2_conn.receive_data(raw) except: break self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() for event in events: try: if not self.server.handle_server_event(event, h2_conn, self.rfile, self.wfile): done = True break except Exception as e: print(repr(e)) print(traceback.format_exc()) done = True break
def test_connection_lost(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[(':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar')]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: raw = b''.join(http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() if len(self.master.state.flows) == 1: assert self.master.state.flows[0].response is None
def test_with_bodies(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], body='foobar with request body', ) done = False while not done: try: events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert self.master.state.flows[0].response.body == b'foobar with request body'
def test_simple(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('ClIeNt-FoO', 'client-bar-1'), ('ClIeNt-FoO', 'client-bar-2'), ], body='my request body echoed back to me') done = False while not done: try: events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.status_code == 200 assert self.master.state.flows[0].response.headers['server-foo'] == 'server-bar' assert self.master.state.flows[0].response.headers['föo'] == 'bär' assert self.master.state.flows[0].response.body == b'foobar'
def handle(self): # send magic self.wfile.write(codecs.decode('505249202a20485454502f322e300d0a0d0a534d0d0a0d0a', 'hex_codec')) self.wfile.flush() # send empty settings frame self.wfile.write(codecs.decode('000000040000000000', 'hex_codec')) self.wfile.flush() # check empty settings frame raw = utils.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('00000c040000000000000200000000000300000001', 'hex_codec') # check settings acknowledgement raw = utils.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('000000040100000000', 'hex_codec') # send settings acknowledgement self.wfile.write(codecs.decode('000000040100000000', 'hex_codec')) self.wfile.flush()
def test_push_promise_reset(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[(':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar')]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: events = h2_conn.receive_data(b''.join( http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded) and event.stream_id == 1: ended_streams += 1 elif isinstance(event, h2.events.PushedStreamReceived): pushed_streams += 1 h2_conn.reset_stream(event.pushed_stream_id, error_code=0x8) client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() elif isinstance(event, h2.events.ResponseReceived): responses += 1 if isinstance(event, h2.events.ConnectionTerminated): done = True if responses >= 1 and ended_streams >= 1 and pushed_streams == 2: done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() bodies = [ flow.response.body for flow in self.master.state.flows if flow.response ] assert len(bodies) >= 1 assert b'regular_stream' in bodies
def __call__(self): if self.server_conn: self._initiate_server_conn() preamble = self.client_conn.rfile.read(24) self.client_conn.h2.initiate_connection() self.client_conn.h2.receive_data(preamble) self.client_conn.send(self.client_conn.h2.data_to_send()) while True: r = ssl_read_select(self.active_conns, 1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (conn == self.server_conn.connection) with source_conn.h2.lock: try: raw_frame = b''.join( http2_read_raw_frame(source_conn.rfile)) except: for stream in self.streams.values(): stream.zombie = time.time() return frame, _ = hyperframe.frame.Frame.parse_frame_header( raw_frame[:9]) if is_server: list = self.server_reset_streams else: list = self.client_reset_streams if frame.stream_id in list: # this frame belongs to a reset stream - just ignore it if isinstance( frame, hyperframe.frame.HeadersFrame) or isinstance( frame, hyperframe.frame.ContinuationFrame): # we need to keep the hpack-decoder happy too source_conn.h2.decoder.decode(raw_frame[9:]) continue events = source_conn.h2.receive_data(raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in events: if not self._handle_event(event, source_conn, other_conn, is_server): return self._cleanup_streams()
def test_push_promise(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar') ]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: raw = b''.join(http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): ended_streams += 1 elif isinstance(event, h2.events.PushedStreamReceived): pushed_streams += 1 elif isinstance(event, h2.events.ResponseReceived): responses += 1 if isinstance(event, h2.events.ConnectionTerminated): done = True if responses == 3 and ended_streams == 3 and pushed_streams == 2: done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert ended_streams == 3 assert pushed_streams == 2 bodies = [flow.response.body for flow in self.master.state.flows] assert len(bodies) == 3 assert b'regular_stream' in bodies assert b'pushed_stream_foo' in bodies assert b'pushed_stream_bar' in bodies
def handle(self): # send magic self.wfile.write( codecs.decode( '505249202a20485454502f322e300d0a0d0a534d0d0a0d0a', 'hex_codec')) self.wfile.flush() # send empty settings frame self.wfile.write(codecs.decode('000000040000000000', 'hex_codec')) self.wfile.flush() # check empty settings frame raw = utils.http2_read_raw_frame(self.rfile) assert raw == codecs.decode( '00000c040000000000000200000000000300000001', 'hex_codec') # check settings acknowledgement raw = utils.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('000000040100000000', 'hex_codec') # send settings acknowledgement self.wfile.write(codecs.decode('000000040100000000', 'hex_codec')) self.wfile.flush()
def __call__(self): if self.server_conn: self._initiate_server_conn() preamble = self.client_conn.rfile.read(24) self.client_conn.h2.initiate_connection() self.client_conn.h2.receive_data(preamble) self.client_conn.send(self.client_conn.h2.data_to_send()) while True: r = ssl_read_select(self.active_conns, 1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = conn == self.server_conn.connection with source_conn.h2.lock: try: raw_frame = b"".join(http2_read_raw_frame(source_conn.rfile)) except: for stream in self.streams.values(): stream.zombie = time.time() return frame, _ = hyperframe.frame.Frame.parse_frame_header(raw_frame[:9]) if is_server: list = self.server_reset_streams else: list = self.client_reset_streams if frame.stream_id in list: # this frame belongs to a reset stream - just ignore it if isinstance(frame, hyperframe.frame.HeadersFrame) or isinstance( frame, hyperframe.frame.ContinuationFrame ): # we need to keep the hpack-decoder happy too source_conn.h2.decoder.decode(raw_frame[9:]) continue events = source_conn.h2.receive_data(raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in events: if not self._handle_event(event, source_conn, other_conn, is_server): return self._cleanup_streams()
def test_simple(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('ClIeNt-FoO', 'client-bar-1'), ('ClIeNt-FoO', 'client-bar-2'), ], body='my request body echoed back to me') done = False while not done: try: events = h2_conn.receive_data(b''.join( http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.status_code == 200 assert self.master.state.flows[0].response.headers[ 'server-foo'] == 'server-bar' assert self.master.state.flows[0].response.headers['föo'] == 'bär' assert self.master.state.flows[0].response.body == b'foobar'
def test_connection_lost(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar') ]) done = False while not done: try: raw = b''.join(http2_read_raw_frame(client.rfile)) h2_conn.receive_data(raw) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() if len(self.master.state.flows) == 1: assert self.master.state.flows[0].response is None
def test_with_bodies(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], body='foobar with request body', ) done = False while not done: try: events = h2_conn.receive_data(b''.join( http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert self.master.state.flows[ 0].response.body == b'foobar with request body'