Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

Commit

Permalink
Merge pull request #80 from t2y/development
Browse files Browse the repository at this point in the history
Fixed to read out all data for buffering in BufferedSocket when Data Frame payload is quite large
  • Loading branch information
Lukasa committed Jan 28, 2015
2 parents 7978b2a + 40d65b5 commit 82a2f33
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
25 changes: 22 additions & 3 deletions hyper/http20/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,11 +483,30 @@ def _consume_single_frame(self):
frame, length = Frame.parse_frame_header(header)

# Read the remaining data from the socket.
if length:
data = self._recv_payload(length)
self._consume_frame_payload(frame, data)

def _recv_payload(self, length):
if not length:
return memoryview(b'')

buffer = bytearray(length)
buffer_view = memoryview(buffer)
index = 0
data_length = -1
# _sock.recv(length) might not read out all data if the given length
# is very large. So it should be to retrieve from socket repeatedly.
while length and data_length:
data = self._sock.recv(length)
else:
data = memoryview(b'')
data_length = len(data)
end = index + data_length
buffer_view[index:end] = data[:]
length -= data_length
index = end

return buffer_view[:end]

def _consume_frame_payload(self, frame, data):
frame.parse_body(data)

log.info(
Expand Down
26 changes: 26 additions & 0 deletions test/test_hyper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,23 @@ def test_we_can_read_from_the_socket(self):
s = c.recent_stream
assert s.data == [b'testdata']

def test_we_can_read_fitfully_from_the_socket(self):
sock = DummyFitfullySocket()
sock.buffer = BytesIO(
b'\x00\x00\x18\x00\x01\x00\x00\x00\x01'
b'testdata'
b'+payload'
)

c = HTTP20Connection('www.google.com')
c._sock = sock
c.putrequest('GET', '/')
c.endheaders()
c._recv_cb()

s = c.recent_stream
assert s.data == [b'testdata+payload']

def test_putrequest_sends_data(self):
sock = DummySocket()

Expand Down Expand Up @@ -2045,6 +2062,15 @@ def recv(self, l):
def close(self):
pass


class DummyFitfullySocket(DummySocket):
def recv(self, l):
length = l
if l != 9 and l >= 4:
length = int(round(l / 2))
return memoryview(self.buffer.read(length))


class DummyStream(object):
def __init__(self, data, trailers=None):
self.data = data
Expand Down

0 comments on commit 82a2f33

Please sign in to comment.