def recv_frame(self, frame): if isinstance(frame, DataFrame): self.recv_data(frame.data) if frame.is_end_stream: self.end_stream() elif isinstance(frame, HeaderFrame): self.recv_header(frame.get_all()) if frame.is_end_header: self.is_recv_end_header = True if frame.is_end_stream: self.end_stream() elif isinstance(frame, PingFrame): if not frame.ack: ping = PingFrame(frame.opaque, True) self.conn.write(ping.get_frame_bin()) elif isinstance(frame, WindowUpdateFrame): logger.debug('window update %d in stream %d', frame.window_size, self.stream_id) if self.stream_id == StreamHTTP2.CONNECTION_STREAM_ID: self.conn.send_initial_window_size += frame.window_size self.send_window_size += frame.window_size elif isinstance(frame, SettingFrame): for setting in frame.setting_list: if setting[0] == SettingFrame.SETTINGS_MAX_FRAME_SIZE: self.conn.send_initial_window_size = setting[1] elif isinstance(frame, RSTFrame): self.close() logger.error('user reset stream %s' % error_codes[frame.error_code])
def run(self): while True: raw_frame_header = self.rfile.read( HTTP2Connection.STREAM_HEADER_SIZE ) if len(raw_frame_header) == 0: # user close connection logger.debug('user close connection') return try: frame_header = Frame.parse_header( raw_frame_header[:HTTP2Connection.STREAM_HEADER_SIZE] ) (frame_len, frame_type, frame_flag, frame_id) = frame_header try: target_stream = self.get_stream(frame_id) except StreamClosedError: # if closed error if not (frame_type == FrameType.WINDOW_UPDATE or frame_type == FrameType.RST_STREAM or frame_type == FrameType.PRIORITY): logger.debug('User send frame in closed stream(frame_type: %d)', frame_type) raise StreamClosedError('User send frame in closed stream(frame_type: %d)' % frame_type) # close connection if not target_stream.run_stream(self.rfile, frame_header): break sleep(0) except HTTP2Error as e: if self.server_setting['debug']: import traceback traceback.format_exc() logger.error('Goaway id %d debug data: %s', e.code, e.debug_data) goaway = GoawayFrame(frame_id, e.code, e.debug_data) self.write(goaway.get_frame_bin()) print("close connection") return