summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2015-08-25 00:33:14 +0000
committerBarry Warsaw2015-08-25 00:33:14 +0000
commit352096f9903961915921ba2adfbe80d0467fdfb5 (patch)
tree52b074c8de5e81cf2019b036022aa779a069c01c
parentc265a58eea8bb7abbdaa4cdbc0f25cafb1d78626 (diff)
parent43627ee55a8bb9e876c8fcda3878326f72c8a5fa (diff)
downloadmailman-352096f9903961915921ba2adfbe80d0467fdfb5.tar.gz
mailman-352096f9903961915921ba2adfbe80d0467fdfb5.tar.zst
mailman-352096f9903961915921ba2adfbe80d0467fdfb5.zip
Merge branch 'issue142' into 'master'
Send REST server stderr to the http log file when the client hangs up When the client hangs up, we can't actually catch the BrokenPipeError because of the way Python stdlib's wsgiref.simple_server is structured. However, we can ensure that the error messages won't get printed to stderr, but to our http log file instead. Closes #142 See merge request !36
-rw-r--r--src/mailman/rest/wsgiapp.py28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py
index 94f654217..40757ee31 100644
--- a/src/mailman/rest/wsgiapp.py
+++ b/src/mailman/rest/wsgiapp.py
@@ -32,16 +32,27 @@ from falcon.routing import create_http_method_map
from mailman.config import config
from mailman.database.transaction import transactional
from mailman.rest.root import Root
-from wsgiref.simple_server import WSGIRequestHandler
+from wsgiref.simple_server import WSGIRequestHandler, WSGIServer
from wsgiref.simple_server import make_server as wsgi_server
log = logging.getLogger('mailman.http')
_missing = object()
SLASH = '/'
+EMPTYSTRING = ''
+class AdminWSGIServer(WSGIServer):
+ """Server class that integrates error handling with our log files."""
+
+ def handle_error(self, request, client_address):
+ # Interpose base class method so that the exception gets printed to
+ # our log file rather than stderr.
+ log.exception('REST server exception during request from %s',
+ client_address)
+
+
class AdminWebServiceWSGIRequestHandler(WSGIRequestHandler):
"""Handler class which just logs output to the right place."""
@@ -49,6 +60,20 @@ class AdminWebServiceWSGIRequestHandler(WSGIRequestHandler):
"""See `BaseHTTPRequestHandler`."""
log.info('%s - - %s', self.address_string(), format % args)
+ def get_stderr(self):
+ # Return a fake stderr object that will actually write its output to
+ # the log file.
+ class StderrLogger:
+ def __init__(self):
+ self._buffer = []
+ def write(self, message):
+ self._buffer.append(message)
+ def flush(self):
+ self._buffer.insert(0, 'REST request handler error:\n')
+ log.error(EMPTYSTRING.join(self._buffer))
+ self._buffer = []
+ return StderrLogger()
+
class SetAPIVersion:
"""Falcon middleware object that sets the api_version on resources."""
@@ -176,5 +201,6 @@ def make_server():
port = int(config.webservice.port)
server = wsgi_server(
host, port, make_application(),
+ server_class=AdminWSGIServer,
handler_class=AdminWebServiceWSGIRequestHandler)
return server