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

Commit ae01a7f

Browse files
committed
Don't send WINDOWUPDATEs for empty DATA frames.
The spec mandates that the minimum size of the window increment in a WINDOWUPDATE frame be 1. Stop sending the WINDOWUPDATE frame when we receive an empty DATA frame. Also, do increment the window size for the connection when data is received, or we'll stop recieving data at all.
1 parent 77f0cd8 commit ae01a7f

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

hyper/http20/connection.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,14 @@ def _recv_cb(self):
399399
)
400400

401401
# Maintain our flow control window. We don't care about flow control
402-
# really, so increment the window by however much data was sent.
402+
# really, so increment the window by however much data was sent unless
403+
# no data was sent at all, in which case we don't need to do anything.
403404
if (isinstance(frame, DataFrame) and
404-
not isinstance(frame, HeadersFrame)):
405+
not isinstance(frame, HeadersFrame) and
406+
len(frame.data)):
405407
outframe = WindowUpdateFrame(0)
406408
outframe.window_increment = len(frame.data)
409+
self._send_cb(outframe)
407410

408411
# Work out to whom this frame should go.
409412
if frame.stream_id != 0:

hyper/http20/stream.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,12 @@ def listlen(list):
142142
)
143143
break
144144

145-
# Increase the window size.
146-
w = WindowUpdateFrame(self.stream_id)
147-
w.window_increment = len(frame.data)
148-
self._data_cb(w)
145+
# Increase the window size. Only do this if the data frame contains
146+
# actual data.
147+
if len(frame.data):
148+
w = WindowUpdateFrame(self.stream_id)
149+
w.window_increment = len(frame.data)
150+
self._data_cb(w)
149151

150152
return b''.join(data)
151153

test/test_hyper.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,24 @@ def test_closed_connections_are_reset(self):
842842
assert c._out_flow_control_window == 65535
843843
assert c._in_flow_control_window == 65535
844844

845+
def test_connection_doesnt_send_window_update_on_zero_length_data_frame(self):
846+
# Prepare a socket with a data frame in it that has no length.
847+
sock = DummySocket()
848+
sock.buffer = BytesIO(DataFrame(1).serialize())
849+
c = HTTP20Connection('www.google.com')
850+
c._sock = sock
851+
852+
# We open a request here just to allocate a stream, but we throw away
853+
# the frames it sends.
854+
c.request('GET', '/')
855+
sock.queue = []
856+
857+
# Read the frame.
858+
c._recv_cb()
859+
860+
# No frame should have been sent on the connection.
861+
assert len(sock.queue) == 0
862+
845863

846864
class TestHyperStream(object):
847865
def test_streams_have_ids(self):

0 commit comments

Comments
 (0)