summaryrefslogtreecommitdiff
path: root/src/waitress/channel.py
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2020-05-20 15:59:18 -0500
committerMichael Merickel <michael@merickel.org>2020-05-20 15:59:18 -0500
commit561735bc8be151dd1f04c459d5c6ebfa451bc951 (patch)
treeaabfdbd0f40d3b5a06962cbbf8ab23d916980634 /src/waitress/channel.py
parentd9384f456a881f7d6362595f3a6f48021e14eca6 (diff)
downloadwaitress-561735bc8be151dd1f04c459d5c6ebfa451bc951.tar.gz
stabilize buffer behavior with multiple requests on the same connection
previous to this change, a buffer may be reused across requests, and would cause data to be written to disk even if each individual request was not returning much data fixes #265
Diffstat (limited to 'src/waitress/channel.py')
-rw-r--r--src/waitress/channel.py16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/waitress/channel.py b/src/waitress/channel.py
index a8bc76f..bc9a2bb 100644
--- a/src/waitress/channel.py
+++ b/src/waitress/channel.py
@@ -174,9 +174,10 @@ class HTTPChannel(wasyncore.dispatcher, object):
# there's no current task, so we don't need to try to
# lock the outbuf to append to it.
outbuf_payload = b"HTTP/1.1 100 Continue\r\n\r\n"
+ num_bytes = len(outbuf_payload)
self.outbufs[-1].append(outbuf_payload)
- self.current_outbuf_count += len(outbuf_payload)
- self.total_outbufs_len += len(outbuf_payload)
+ self.current_outbuf_count += num_bytes
+ self.total_outbufs_len += num_bytes
self.sent_continue = True
self._flush_some()
request.completed = False
@@ -311,7 +312,7 @@ class HTTPChannel(wasyncore.dispatcher, object):
self.outbufs.append(nextbuf)
self.current_outbuf_count = 0
else:
- if self.current_outbuf_count > self.adj.outbuf_high_watermark:
+ if self.current_outbuf_count >= self.adj.outbuf_high_watermark:
# rotate to a new buffer if the current buffer has hit
# the watermark to avoid it growing unbounded
nextbuf = OverflowableBuffer(self.adj.outbuf_overflow)
@@ -399,6 +400,15 @@ class HTTPChannel(wasyncore.dispatcher, object):
# at the end to account for consecutive service() calls
if len(self.requests) > 1:
self._flush_outbufs_below_high_watermark()
+
+ # this is a little hacky but basically it's forcing the
+ # next request to create a new outbuf to avoid sharing
+ # outbufs across requests which can cause outbufs to
+ # not be deallocated regularly when a connection is open
+ # for a long time
+ if self.current_outbuf_count > 0:
+ self.current_outbuf_count = self.adj.outbuf_high_watermark
+
request = self.requests.pop(0)
request.close()