summaryrefslogtreecommitdiff
path: root/Lib/wsgiref
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2016-06-05 06:28:55 +0000
committerMartin Panter <vadmium+py@gmail.com>2016-06-05 06:28:55 +0000
commitd1142ca8d64cd177e491d70e3c232c04be476c95 (patch)
tree22f245bfe7926c2c58bd4cee11311ff1672e8519 /Lib/wsgiref
parent40250f0c75baa23871ff609d0fdb9fabbd00c0ca (diff)
downloadcpython-d1142ca8d64cd177e491d70e3c232c04be476c95.tar.gz
Issue #24291: Avoid WSGIRequestHandler doing partial writes
If the underlying send() method indicates a partial write, such as when the call is interrupted to handle a signal, the server would silently drop the remaining data. Also add deprecated support for SimpleHandler.stdout.write() doing partial writes.
Diffstat (limited to 'Lib/wsgiref')
-rw-r--r--Lib/wsgiref/handlers.py12
-rw-r--r--Lib/wsgiref/simple_server.py17
2 files changed, 23 insertions, 6 deletions
diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py
index acb35479ab..f4300b831a 100644
--- a/Lib/wsgiref/handlers.py
+++ b/Lib/wsgiref/handlers.py
@@ -450,7 +450,17 @@ class SimpleHandler(BaseHandler):
self.environ.update(self.base_env)
def _write(self,data):
- self.stdout.write(data)
+ result = self.stdout.write(data)
+ if result is None or result == len(data):
+ return
+ from warnings import warn
+ warn("SimpleHandler.stdout.write() should not do partial writes",
+ DeprecationWarning)
+ while True:
+ data = data[result:]
+ if not data:
+ break
+ result = self.stdout.write(data)
def _flush(self):
self.stdout.flush()
diff --git a/Lib/wsgiref/simple_server.py b/Lib/wsgiref/simple_server.py
index e396788cde..7fddbe822c 100644
--- a/Lib/wsgiref/simple_server.py
+++ b/Lib/wsgiref/simple_server.py
@@ -11,6 +11,7 @@ module. See also the BaseHTTPServer module docs for other API information.
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
+from io import BufferedWriter
import sys
import urllib.parse
from wsgiref.handlers import SimpleHandler
@@ -126,11 +127,17 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):
if not self.parse_request(): # An error code has been sent, just exit
return
- handler = ServerHandler(
- self.rfile, self.wfile, self.get_stderr(), self.get_environ()
- )
- handler.request_handler = self # backpointer for logging
- handler.run(self.server.get_app())
+ # Avoid passing the raw file object wfile, which can do partial
+ # writes (Issue 24291)
+ stdout = BufferedWriter(self.wfile)
+ try:
+ handler = ServerHandler(
+ self.rfile, stdout, self.get_stderr(), self.get_environ()
+ )
+ handler.request_handler = self # backpointer for logging
+ handler.run(self.server.get_app())
+ finally:
+ stdout.detach()