From c479c5455cd7f01ab237a3bca8da70c997d52407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 17 Nov 2017 12:06:17 +0100 Subject: [PATCH] Don't log request on uncaught errors in tornado Might leak information if logs are shared. Still stick to the old logging verbosity however if running in debug mode. --- src/octoprint/server/__init__.py | 4 +++- src/octoprint/server/util/tornado.py | 34 ++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 8b5dfd18..a6cc60b1 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -393,7 +393,7 @@ class Server(object): pluginManager.implementation_post_inits=[settings_plugin_config_migration_and_cleanup] pluginManager.log_all_plugins() - + # log environment data now self._environment_detector.log_detected_environment() @@ -488,6 +488,8 @@ class Server(object): joined.update(d) return joined + util.tornado.RequestlessExceptionLoggingMixin.LOG_REQUEST = debug + server_routes = self._router.urls + [ # various downloads # .mpg and .mp4 timelapses: diff --git a/src/octoprint/server/util/tornado.py b/src/octoprint/server/util/tornado.py index 5565ecc3..e21a4dfd 100644 --- a/src/octoprint/server/util/tornado.py +++ b/src/octoprint/server/util/tornado.py @@ -59,11 +59,34 @@ def fix_ioloop_scheduling(): tornado.ioloop.PeriodicCallback._schedule_next = _schedule_next +#~~ More sensible logging + + +class RequestlessExceptionLoggingMixin(tornado.web.RequestHandler): + + LOG_REQUEST = False + + def log_exception(self, typ, value, tb, *args, **kwargs): + if isinstance(value, tornado.web.HTTPError): + if value.log_message: + format = "%d %s: " + value.log_message + args = ([value.status_code, self._request_summary()] + + list(value.args)) + tornado.web.gen_log.warning(format, *args) + else: + if self.LOG_REQUEST: + tornado.web.app_log.error("Uncaught exception %s\n%r", self._request_summary(), + self.request, exc_info=(typ, value, tb)) + else: + tornado.web.app_log.error("Uncaught exception %s", self._request_summary(), + exc_info=(typ, value, tb)) + + #~~ WSGI middleware @tornado.web.stream_request_body -class UploadStorageFallbackHandler(tornado.web.RequestHandler): +class UploadStorageFallbackHandler(RequestlessExceptionLoggingMixin): """ A ``RequestHandler`` similar to ``tornado.web.FallbackHandler`` which fetches any files contained in the request bodies of content type ``multipart``, stores them in temporary files and supplies the ``fallback`` with the file's ``name``, @@ -852,7 +875,7 @@ class CustomHTTP1ConnectionParameters(tornado.http1connection.HTTP1ConnectionPar #~~ customized large response handler -class LargeResponseHandler(tornado.web.StaticFileHandler): +class LargeResponseHandler(RequestlessExceptionLoggingMixin, tornado.web.StaticFileHandler): """ Customized `tornado.web.StaticFileHandler `_ that allows delivery of the requested resource as attachment and access and request path validation through @@ -913,7 +936,7 @@ class LargeResponseHandler(tornado.web.StaticFileHandler): filename = self._name_generator(path) if filename is None: filename = os.path.basename(path) - + filename = tornado.escape.url_escape(filename, plus=False) self.set_header("Content-Disposition", "attachment; filename=\"{}\"; filename*=UTF-8''{}".format(filename, filename)) @@ -942,10 +965,11 @@ class LargeResponseHandler(tornado.web.StaticFileHandler): import stat return os.stat(abspath)[stat.ST_MTIME] + ##~~ URL Forward Handler for forwarding requests to a preconfigured static URL -class UrlProxyHandler(tornado.web.RequestHandler): +class UrlProxyHandler(RequestlessExceptionLoggingMixin, tornado.web.RequestHandler): """ `tornado.web.RequestHandler `_ that proxies requests to a preconfigured url and returns the response. Allows delivery of the requested content as attachment @@ -1038,7 +1062,7 @@ class UrlProxyHandler(tornado.web.RequestHandler): return "%s%s" % (self._basename, extension) -class StaticDataHandler(tornado.web.RequestHandler): +class StaticDataHandler(RequestlessExceptionLoggingMixin, tornado.web.RequestHandler): def initialize(self, data="", content_type="text/plain"): self.data = data self.content_type = content_type