def _consume_frame_payload(self, frame, data): frame.parse_body(data) # xlog.debug("%s Recv:%s", self.ip, str(frame)) # Maintain our flow control window. We do this by delegating to the # chosen WindowManager. if frame.type == DataFrame.type: size = frame.flow_controlled_length increment = self.local_window_manager._handle_frame(size) if increment: #xlog.debug("%s frame size:%d increase win:%d", self.ip, size, increment) w = WindowUpdateFrame(0) w.window_increment = increment self._send_cb(w) elif frame.type == PushPromiseFrame.type: xlog.error( "%s receive push frame", self.ip, ) # Work out to whom this frame should go. if frame.stream_id != 0: try: self.streams[frame.stream_id].receive_frame(frame) self.last_active_time = time.time() except KeyError: xlog.error("%s Unexpected stream identifier %d", self.ip, frame.stream_id) else: self.receive_frame(frame)
def _consume_frame_payload(self, frame, data): frame.parse_body(data) # xlog.debug("%s Recv:%s", self.ip, str(frame)) # Maintain our flow control window. We do this by delegating to the # chosen WindowManager. if frame.type == DataFrame.type: size = frame.flow_controlled_length increment = self.local_window_manager._handle_frame(size) if increment: #xlog.debug("%s frame size:%d increase win:%d", self.ip, size, increment) w = WindowUpdateFrame(0) w.window_increment = increment self._send_cb(w) elif frame.type == PushPromiseFrame.type: xlog.error("%s receive push frame", self.ip,) # Work out to whom this frame should go. if frame.stream_id != 0: try: self.streams[frame.stream_id].receive_frame(frame) except KeyError: xlog.error("%s Unexpected stream identifier %d", self.ip, frame.stream_id) else: self.receive_frame(frame)
def test_windowupdate_frames_update_windows(self): s = Stream(1, None, None, None, None, None, None) f = WindowUpdateFrame(1) f.window_increment = 1000 s.receive_frame(f) assert s._out_flow_control_window == 65535 + 1000
def _consume_frame_payload(self, frame, data): frame.parse_body(data) if self.config.http2_show_debug: self.logger.debug("%s Recv:%s", self.ip_str, str(frame)) # Maintain our flow control window. We do this by delegating to the # chosen WindowManager. if frame.type == DataFrame.type: size = frame.flow_controlled_length increment = self.local_window_manager._handle_frame(size) if increment < 0: self.logger.warn("increment:%d", increment) elif increment: #self.logger.debug("%s frame size:%d increase win:%d", self.ip, size, increment) w = WindowUpdateFrame(0) w.window_increment = increment self._send_cb(w) elif frame.type == PushPromiseFrame.type: self.logger.error("%s receive push frame", self.ip_str, ) # Work out to whom this frame should go. if frame.stream_id != 0: try: stream = self.streams[frame.stream_id] stream.receive_frame(frame) except KeyError as e: if frame.type not in [WindowUpdateFrame.type]: self.logger.exception("%s Unexpected stream identifier %d, frame.type:%s e:%r", self.ip_str, frame.stream_id, frame, e) else: self.receive_frame(frame)
def test_connections_increment_send_window_properly(self): f = WindowUpdateFrame(0) f.window_increment = 1000 c = HTTP20Connection('www.google.com') c._sock = DummySocket() # 'Receive' the WINDOWUPDATE frame. c.receive_frame(f) assert c._out_flow_control_window == 65535 + 1000
def receive_frame(self, frame): """ Handle a frame received on this stream. called by connection. """ # xlog.debug("stream %d recved frame %r", self.stream_id, frame) if frame.type == WindowUpdateFrame.type: self.remote_window_size += frame.window_increment self.send_left_body() elif frame.type == HeadersFrame.type: # Begin the header block for the response headers. self.response_header_datas = [frame.data] elif frame.type == PushPromiseFrame.type: xlog.error("%s receive PushPromiseFrame:%d", self.ip, frame.stream_id) elif frame.type == ContinuationFrame.type: # Continue a header block begun with either HEADERS or PUSH_PROMISE. self.response_header_datas.append(frame.data) elif frame.type == DataFrame.type: # Append the data to the buffer. if not self.task.finished: self.task.put_data(frame.data) if 'END_STREAM' not in frame.flags: # Increase the window size. Only do this if the data frame contains # actual data. # don't do it if stream is closed. size = frame.flow_controlled_length increment = self.receive_window_manager._handle_frame(size) #if increment: # xlog.debug("stream:%d frame size:%d increase win:%d", self.stream_id, size, increment) #content_len = int(self.request_headers.get("Content-Length")[0]) #xlog.debug("%s get:%d s:%d", self.ip, self.response_body_len, size) if increment and not self._remote_closed: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == BlockedFrame.type: # If we've been blocked we may want to fixup the window. increment = self.receive_window_manager._blocked() if increment: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == RstStreamFrame.type: # Rest Frame send from server is not define in RFC # but GAE server will not work on this connection anymore inactive_time = time.time() - self.connection.last_active_time xlog.debug( "%s Stream %d Rest by server, inactive:%d. error code:%d", self.ip, self.stream_id, inactive_time, frame.error_code) self.connection.close("RESET") elif frame.type in FRAMES: # This frame isn't valid at this point. #raise ValueError("Unexpected frame %s." % frame) xlog.error("%s Unexpected frame %s.", self.ip, frame) else: # pragma: no cover # Unknown frames belong to extensions. Just drop it on the # floor, but log so that users know that something happened. xlog.error("%s Received unknown frame, type %d", self.ip, frame.type) pass if 'END_HEADERS' in frame.flags: # Begin by decoding the header block. If this fails, we need to # tear down the entire connection. headers = self._decoder.decode(b''.join( self.response_header_datas)) self._handle_header_block(headers) # We've handled the headers, zero them out. self.response_header_datas = None self.get_head_time = time.time() length = self.response_headers.get("Content-Length", None) if isinstance(length, list): length = int(length[0]) if not self.task.finished: self.task.content_length = length self.task.set_state("h2_get_head") self.send_response() if 'END_STREAM' in frame.flags: #xlog.debug("%s Closing remote side of stream:%d", self.ip, self.stream_id) time_now = time.time() time_cost = time_now - self.get_head_time if time_cost > 0 and \ isinstance(self.task.content_length, int) and \ not self.task.finished: speed = self.task.content_length / time_cost self.task.set_state("h2_finish[SP:%d]" % speed) self._close_remote() self.close("end stream")
def receive_frame(self, frame): """ Handle a frame received on this stream. called by connection. """ # self.logger.debug("stream %d recved frame %r", self.stream_id, frame) if frame.type == WindowUpdateFrame.type: self.remote_window_size += frame.window_increment self.send_left_body() elif frame.type == HeadersFrame.type: # Begin the header block for the response headers. #self.response_header_datas = [frame.data] self.response_header_datas.append(frame.data) elif frame.type == PushPromiseFrame.type: self.logger.error("%s receive PushPromiseFrame:%d", self.ip, frame.stream_id) elif frame.type == ContinuationFrame.type: # Continue a header block begun with either HEADERS or PUSH_PROMISE. self.response_header_datas.append(frame.data) elif frame.type == DataFrame.type: # Append the data to the buffer. if not self.task.finished: self.task.put_data(frame.data) if 'END_STREAM' not in frame.flags: # Increase the window size. Only do this if the data frame contains # actual data. # don't do it if stream is closed. size = frame.flow_controlled_length increment = self.receive_window_manager._handle_frame(size) #if increment: # self.logger.debug("stream:%d frame size:%d increase win:%d", self.stream_id, size, increment) #content_len = int(self.request_headers.get("Content-Length")[0]) #self.logger.debug("%s get:%d s:%d", self.ip, self.response_body_len, size) if increment and not self._remote_closed: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == BlockedFrame.type: # If we've been blocked we may want to fixup the window. increment = self.receive_window_manager._blocked() if increment: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == RstStreamFrame.type: # Rest Frame send from server is not define in RFC inactive_time = time.time() - self.connection.last_active_time self.logger.debug("%s Stream %d Rest by server, inactive:%d. error code:%d", self.ip, self.stream_id, inactive_time, frame.error_code) self.connection.close("RESET") elif frame.type in FRAMES: # This frame isn't valid at this point. #raise ValueError("Unexpected frame %s." % frame) self.logger.error("%s Unexpected frame %s.", self.ip, frame) else: # pragma: no cover # Unknown frames belong to extensions. Just drop it on the # floor, but log so that users know that something happened. self.logger.error("%s Received unknown frame, type %d", self.ip, frame.type) pass if 'END_HEADERS' in frame.flags: if self.response_headers is not None: raise ProtocolError("Too many header blocks.") # Begin by decoding the header block. If this fails, we need to # tear down the entire connection. if len(self.response_header_datas) == 1: header_data = self.response_header_datas[0] else: header_data = b''.join(self.response_header_datas) try: headers = self._decoder.decode(header_data) except Exception as e: self.logger.exception("decode h2 header %s fail:%r", header_data, e) raise e self.response_headers = HTTPHeaderMap(headers) # We've handled the headers, zero them out. self.response_header_datas = None self.get_head_time = time.time() length = self.response_headers.get("Content-Length", None) if isinstance(length, list): length = int(length[0]) if not self.task.finished: self.task.content_length = length self.task.set_state("h2_get_head") self.send_response() if 'END_STREAM' in frame.flags: #self.logger.debug("%s Closing remote side of stream:%d", self.ip, self.stream_id) time_now = time.time() time_cost = time_now - self.get_head_time if time_cost > 0 and \ isinstance(self.task.content_length, int) and \ not self.task.finished: speed = self.task.content_length / time_cost self.task.set_state("h2_finish[SP:%d]" % speed) self._close_remote() self.close("end stream") if not self.task.finished: self.connection.continue_timeout = 0
def receive_frame(self, frame): """ Handle a frame received on this stream. called by connection. """ if frame.type == WindowUpdateFrame.type: self.remote_window_size += frame.window_increment self.send_left_body() elif frame.type == HeadersFrame.type: # Begin the header block for the response headers. self.response_header_datas = [frame.data] elif frame.type == PushPromiseFrame.type: xlog.error("%s receive PushPromiseFrame:%d", self.ip, frame.stream_id) elif frame.type == ContinuationFrame.type: # Continue a header block begun with either HEADERS or PUSH_PROMISE. self.response_header_datas.append(frame.data) elif frame.type == DataFrame.type: # Append the data to the buffer. self.response_body.append(frame.data) self.response_body_len += len(frame.data) if 'END_STREAM' not in frame.flags: # Increase the window size. Only do this if the data frame contains # actual data. # don't do it if stream is closed. size = frame.flow_controlled_length increment = self.receive_window_manager._handle_frame(size) #if increment: # xlog.debug("stream:%d frame size:%d increase win:%d", self.stream_id, size, increment) #content_len = int(self.request_headers.get("Content-Length")[0]) #xlog.debug("%s get:%d s:%d", self.ip, self.response_body_len, size) if increment and not self._remote_closed: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == BlockedFrame.type: # If we've been blocked we may want to fixup the window. increment = self.receive_window_manager._blocked() if increment: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == RstStreamFrame.type: xlog.warn("%s Stream %d forcefully closed.", self.ip, self.stream_id) self.close("RESET") elif frame.type in FRAMES: # This frame isn't valid at this point. #raise ValueError("Unexpected frame %s." % frame) xlog.error("%s Unexpected frame %s.", self.ip, frame) else: # pragma: no cover # Unknown frames belong to extensions. Just drop it on the # floor, but log so that users know that something happened. xlog.error("%s Received unknown frame, type %d", self.ip, frame.type) pass if 'END_HEADERS' in frame.flags: # Begin by decoding the header block. If this fails, we need to # tear down the entire connection. TODO: actually do that. headers = self._decoder.decode(b''.join(self.response_header_datas)) self._handle_header_block(headers) # We've handled the headers, zero them out. self.response_header_datas = None if 'END_STREAM' in frame.flags: #xlog.debug("%s Closing remote side of stream:%d", self.ip, self.stream_id) self._close_remote() self.send_response() self.close("end stream")
def receive_frame(self, frame): """ Handle a frame received on this stream. called by connection. """ if frame.type == WindowUpdateFrame.type: self.remote_window_size += frame.window_increment self.send_left_body() elif frame.type == HeadersFrame.type: # Begin the header block for the response headers. self.response_header_datas = [frame.data] elif frame.type == PushPromiseFrame.type: xlog.error("%s receive PushPromiseFrame:%d", self.ip, frame.stream_id) elif frame.type == ContinuationFrame.type: # Continue a header block begun with either HEADERS or PUSH_PROMISE. self.response_header_datas.append(frame.data) elif frame.type == DataFrame.type: # Append the data to the buffer. self.response_body.append(frame.data) self.response_body_len += len(frame.data) if 'END_STREAM' not in frame.flags: # Increase the window size. Only do this if the data frame contains # actual data. # don't do it if stream is closed. size = frame.flow_controlled_length increment = self.receive_window_manager._handle_frame(size) if increment: xlog.debug("stream:%d frame size:%d increase win:%d", self.stream_id, size, increment) #content_len = int(self.request_headers.get("Content-Length")[0]) #xlog.debug("%s get:%d s:%d", self.ip, self.response_body_len, size) if increment and not self._remote_closed: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == BlockedFrame.type: # If we've been blocked we may want to fixup the window. increment = self.receive_window_manager._blocked() if increment: w = WindowUpdateFrame(self.stream_id) w.window_increment = increment self._send_cb(w) elif frame.type == RstStreamFrame.type: xlog.warn("%s Stream %d forcefully closed.", self.ip, self.stream_id) self.close("RESET") elif frame.type in FRAMES: # This frame isn't valid at this point. #raise ValueError("Unexpected frame %s." % frame) xlog.error("%s Unexpected frame %s.", self.ip, frame) else: # pragma: no cover # Unknown frames belong to extensions. Just drop it on the # floor, but log so that users know that something happened. xlog.warning("%s Received unknown frame, type %d", self.ip, frame.type) pass if 'END_HEADERS' in frame.flags: # Begin by decoding the header block. If this fails, we need to # tear down the entire connection. TODO: actually do that. headers = self._decoder.decode(b''.join( self.response_header_datas)) self._handle_header_block(headers) # We've handled the headers, zero them out. self.response_header_datas = None if 'END_STREAM' in frame.flags: #xlog.debug("%s Closing remote side of stream:%d", self.ip, self.stream_id) self._close_remote() self.send_response() self.close("end stream")