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.
This commit is contained in:
Martin Panter 2016-06-05 06:28:55 +00:00
parent 889f914edb
commit ed0425c60a
5 changed files with 111 additions and 7 deletions

View file

@ -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()

View file

@ -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()