From d9b721c8055b791ca27fa2e3c188bb687f0639fb Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 26 Oct 2017 12:58:22 +0200 Subject: [PATCH] [FIX] server: avoid partial HTTP responses in worker mode Python 3 (before 3.6) is affected by outstanding issue 24291: https://bugs.python.org/issue24291 In Python 3.6 the issue is gone thanks to this patch: https://bugs.python.org/issue26721 The base StreamRequestHandler class does not properly deal with raw IO output streams. This affects most HTTP servers that use it, including werkzeug. It causes large HTTP responses to be truncated when the output socket is unbuffered and in non-blocking mode. This is the case in multi-process mode (workers > 0) due to the socket timeout configured to avoid worker deadlocks. Typically, large file downloads (2MB+) and large JSON responses will be truncated and cause corrupted files or errors on the client side. As a workaround, we turn on the buffering on the output stream by default in multi-process mode (it is already turned on for the input stream) when running on Python 3.5. See also the socket.makefile() method and the docstring of `socketserver.StreamRequestHandler` at https://github.com/python/cpython/blob/dcb101e7f078f12fc3d2bf1730410798a880bfe3/Lib/socketserver.py#L707 Fixes #20158 opw-777120 --- odoo/service/server.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/odoo/service/server.py b/odoo/service/server.py index 12a1256bda7..0a1c2d71763 100644 --- a/odoo/service/server.py +++ b/odoo/service/server.py @@ -972,6 +972,11 @@ def start(preload=None, stop=False): _logger.warning("Unit testing in workers mode could fail; use --workers 0.") server = PreforkServer(odoo.service.wsgi_server.application) + + # Workaround for Python issue24291, fixed in 3.6 (see Python issue26721) + if sys.version_info[:2] == (3,5): + # turn on buffering also for wfile, to avoid partial writes (Default buffer = 8k) + werkzeug.serving.WSGIRequestHandler.wbufsize = -1 else: server = ThreadedServer(odoo.service.wsgi_server.application)