def socket_handler(listener): sock = listener.accept()[0] # Dispose of the first packet. sock.recv(65535) # Send a Settings frame that reduces the flow-control window to # 64 bytes. f = SettingsFrame(0) f.settings[SettingsFrame.INITIAL_WINDOW_SIZE] = 64 sock.send(f.serialize()) # Grab three frames, the settings ACK, the initial headers frame, # and the first data frame. for x in range(0, 3): data.append(sock.recv(65535)) # Send a WindowUpdate giving more window room to the stream. f = WindowUpdateFrame(1) f.window_increment = 64 sock.send(f.serialize()) # Send one that gives more room to the connection. f = WindowUpdateFrame(0) f.window_increment = 64 sock.send(f.serialize()) # Reeive the remaining frame. data.append(sock.recv(65535)) send_event.set() # We're done. sock.close()
def test_incrementing_window_after_close(self): """ Hyper does not attempt to increment the flow control window once the stream is closed. """ # For this test, we want to send a response that has three frames at # the default max frame size (16,384 bytes). That will, on the third # frame, trigger the processing to increment the flow control window, # which should then not happen. f = SettingsFrame(0, settings={h2.settings.INITIAL_WINDOW_SIZE: 100}) c = HTTP20Connection('www.google.com') c._sock = DummySocket() c._sock.buffer = BytesIO(f.serialize()) # Open stream 1. c.request('GET', '/') # Check what data we've sent right now. originally_sent_data = c._sock.queue[:] # Swap out the buffer to get a GoAway frame. length = 16384 total_length = (3 * 16384) + len(b'some more data') e = Encoder() h1 = HeadersFrame(1) h1.data = e.encode( [(':status', 200), ('content-length', '%d' % total_length)] ) h1.flags |= set(['END_HEADERS']) d1 = DataFrame(1) d1.data = b'\x00' * length d2 = d1 d3 = d1 d4 = DataFrame(1) d4.data = b'some more data' d4.flags |= set(['END_STREAM']) buffer = BytesIO( b''.join(f.serialize() for f in [h1, d1, d2, d3, d4]) ) c._sock.buffer = buffer # Read the response resp = c.get_response(stream_id=1) assert resp.status == 200 assert resp.read() == b''.join( [b'\x00' * (3 * length), b'some more data'] ) # We should have sent only one extra frame assert len(originally_sent_data) + 1 == len(c._sock.queue)
def test_settings_frame_serializes_properly(self): f = SettingsFrame(0) f.parse_flags(0xFF) f.settings = self.settings s = f.serialize() assert s == self.serialized
def test_settings_frame_serializes_properly(self): f = SettingsFrame() f.parse_flags(0xFF) f.settings = self.settings s = f.serialize() assert s == self.serialized
def socket_handler(listener): sock = listener.accept()[0] # We should get one big chunk. first = sock.recv(65535) data.append(first) # We need to send back a SettingsFrame. f = SettingsFrame(0) sock.send(f.serialize()) send_event.set() sock.close()
def test_resetting_streams_after_close(self): """ Attempts to reset streams when the connection is torn down are tolerated. """ f = SettingsFrame(0) c = HTTP20Connection('www.google.com') c._sock = DummySocket() c._sock.buffer = BytesIO(f.serialize()) # Open stream 1. c.request('GET', '/') # Swap out the buffer to get a GoAway frame. f = GoAwayFrame(0) f.error_code = 1 c._sock.buffer = BytesIO(f.serialize()) # "Read" the GoAway with pytest.raises(ConnectionError): c._single_read()
def initiate_connection(self): """ Provides any data that needs to be sent at the start of the connection. Must be called for both clients and servers. """ self.state_machine.process_input(ConnectionInputs.SEND_SETTINGS) if self.client_side: preamble = b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n' else: preamble = b'' f = SettingsFrame(0) for setting, value in self.local_settings.items(): f.settings[setting] = value self._data_to_send += preamble + f.serialize()