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

Commit 4b6f079

Browse files
committed
Confirm we correctly increment flow windows for streams.
1 parent 4cee8c3 commit 4b6f079

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

hyper/http20/stream.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
Each stream is identified by a monotonically increasing integer, assigned to
1414
the stream by the endpoint that initiated the stream.
1515
"""
16+
from h2.exceptions import StreamClosedError
17+
1618
from ..common.headers import HTTPHeaderMap
1719
from .exceptions import ProtocolError, StreamResetError
1820
from .util import h2_safe_headers
@@ -194,7 +196,7 @@ def receive_data(self, event):
194196
# Append the data to the buffer.
195197
self.data.append(event.data)
196198

197-
if increment:
199+
if increment and not self.remote_closed:
198200
self._conn.increment_flow_control_window(
199201
increment, stream_id=self.stream_id
200202
)

test/test_hyper.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ def sendall(self, data):
351351
c._sock = DummySocket()
352352
c._send_cb(f, True) # shouldn't raise an error
353353

354-
def test_window_increments_appropriately(self, frame_buffer):
354+
def test_connection_window_increments_appropriately(self, frame_buffer):
355355
e = Encoder()
356356
h = HeadersFrame(1)
357357
h.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
@@ -380,6 +380,36 @@ def test_window_increments_appropriately(self, frame_buffer):
380380
assert isinstance(queue[2], WindowUpdateFrame)
381381
assert queue[2].window_increment == len(b'hi there sir again')
382382

383+
def test_stream_window_increments_appropriately(self, frame_buffer):
384+
e = Encoder()
385+
h = HeadersFrame(1)
386+
h.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
387+
h.flags = set(['END_HEADERS'])
388+
d = DataFrame(1)
389+
d.data = b'hi there sir'
390+
d2 = DataFrame(1)
391+
d2.data = b'hi there sir again'
392+
#d2.flags = set(['END_STREAM'])
393+
sock = DummySocket()
394+
sock.buffer = BytesIO(h.serialize() + d.serialize() + d2.serialize())
395+
396+
c = HTTP20Connection('www.google.com')
397+
c._sock = sock
398+
c.request('GET', '/')
399+
c.streams[1]._in_window_manager.window_size = 1000
400+
c.streams[1]._in_window_manager.initial_window_size = 1000
401+
resp = c.get_response()
402+
resp.read(len(b'hi there sir'))
403+
resp.read(len(b'hi there sir again'))
404+
405+
frame_buffer.add_data(b''.join(sock.queue))
406+
queue = list(frame_buffer)
407+
assert len(queue) == 3 # one headers frame, two window update frames.
408+
assert isinstance(queue[1], WindowUpdateFrame)
409+
assert queue[1].window_increment == len(b'hi there sir')
410+
assert isinstance(queue[2], WindowUpdateFrame)
411+
assert queue[2].window_increment == len(b'hi there sir again')
412+
383413
def test_that_using_proxy_keeps_http_headers_intact(self):
384414
sock = DummySocket()
385415
c = HTTP20Connection('www.google.com', secure=False, proxy_host='localhost')
@@ -917,18 +947,19 @@ class DummySocket(object):
917947
def __init__(self):
918948
self.queue = []
919949
self._buffer = BytesIO()
950+
self._read_counter = 0
920951
self.can_read = False
921952

922953
@property
923954
def buffer(self):
924-
return memoryview(self._buffer.getvalue())
955+
return memoryview(self._buffer.getvalue()[self._read_counter:])
925956

926957
@buffer.setter
927958
def buffer(self, value):
928959
self._buffer = value
929960

930961
def advance_buffer(self, amt):
931-
self._buffer.read(amt)
962+
self._read_counter += amt
932963

933964
def send(self, data):
934965
self.queue.append(data)

0 commit comments

Comments
 (0)