diff --git a/synapse/http/site.py b/synapse/http/site.py
index df5274c177..167293c46d 100644
--- a/synapse/http/site.py
+++ b/synapse/http/site.py
@@ -14,7 +14,9 @@
import contextlib
import logging
import time
+from typing import Optional
+from twisted.python.failure import Failure
from twisted.web.server import Request, Site
from synapse.http import redact_uri
@@ -44,18 +46,18 @@ class SynapseRequest(Request):
request even after the client has disconnected.
Attributes:
- logcontext(LoggingContext) : the log context for this request
+ logcontext: the log context for this request
"""
- def __init__(self, site, channel, *args, **kw):
+ def __init__(self, channel, *args, **kw):
Request.__init__(self, channel, *args, **kw)
- self.site = site
+ self.site = channel.site
self._channel = channel # this is used by the tests
self.authenticated_entity = None
- self.start_time = 0
+ self.start_time = 0.0
# we can't yet create the logcontext, as we don't know the method.
- self.logcontext = None
+ self.logcontext = None # type: Optional[LoggingContext]
global _next_request_seq
self.request_seq = _next_request_seq
@@ -88,7 +90,7 @@ class SynapseRequest(Request):
def get_redacted_uri(self):
uri = self.uri
if isinstance(uri, bytes):
- uri = self.uri.decode("ascii")
+ uri = self.uri.decode("ascii", errors="replace")
return redact_uri(uri)
def get_method(self):
@@ -181,6 +183,7 @@ class SynapseRequest(Request):
self.finish_time = time.time()
Request.finish(self)
if not self._is_processing:
+ assert self.logcontext is not None
with PreserveLoggingContext(self.logcontext):
self._finished_processing()
@@ -190,16 +193,28 @@ class SynapseRequest(Request):
Overrides twisted.web.server.Request.connectionLost to record the finish time and
do logging.
"""
+ # There is a bug in Twisted where reason is not wrapped in a Failure object
+ # Detect this and wrap it manually as a workaround
+ # More information: https://github.com/matrix-org/synapse/issues/7441
+ if not isinstance(reason, Failure):
+ reason = Failure(reason)
+
self.finish_time = time.time()
Request.connectionLost(self, reason)
+ if self.logcontext is None:
+ logger.info(
+ "Connection from %s lost before request headers were read", self.client
+ )
+ return
+
# we only get here if the connection to the client drops before we send
# the response.
#
# It's useful to log it here so that we can get an idea of when
# the client disconnects.
with PreserveLoggingContext(self.logcontext):
- logger.warn(
+ logger.warning(
"Error processing request %r: %s %s", self, reason.type, reason.value
)
@@ -225,7 +240,7 @@ class SynapseRequest(Request):
self.start_time, name=servlet_name, method=self.get_method()
)
- self.site.access_logger.info(
+ self.site.access_logger.debug(
"%s - %s - Received request: %s %s",
self.getClientIP(),
self.site.site_tag,
@@ -236,13 +251,7 @@ class SynapseRequest(Request):
def _finished_processing(self):
"""Log the completion of this request and update the metrics
"""
-
- if self.logcontext is None:
- # this can happen if the connection closed before we read the
- # headers (so render was never called). In that case we'll already
- # have logged a warning, so just bail out.
- return
-
+ assert self.logcontext is not None
usage = self.logcontext.get_resource_usage()
if self._processing_finished_time is None:
@@ -305,7 +314,7 @@ class SynapseRequest(Request):
try:
self.request_metrics.stop(self.finish_time, self.code, self.sentLength)
except Exception as e:
- logger.warn("Failed to stop metrics: %r", e)
+ logger.warning("Failed to stop metrics: %r", e)
class XForwardedForRequest(SynapseRequest):
@@ -331,18 +340,6 @@ class XForwardedForRequest(SynapseRequest):
)
-class SynapseRequestFactory(object):
- def __init__(self, site, x_forwarded_for):
- self.site = site
- self.x_forwarded_for = x_forwarded_for
-
- def __call__(self, *args, **kwargs):
- if self.x_forwarded_for:
- return XForwardedForRequest(self.site, *args, **kwargs)
- else:
- return SynapseRequest(self.site, *args, **kwargs)
-
-
class SynapseSite(Site):
"""
Subclass of a twisted http Site that does access logging with python's
@@ -364,7 +361,7 @@ class SynapseSite(Site):
self.site_tag = site_tag
proxied = config.get("x_forwarded", False)
- self.requestFactory = SynapseRequestFactory(self, proxied)
+ self.requestFactory = XForwardedForRequest if proxied else SynapseRequest
self.access_logger = logging.getLogger(logger_name)
self.server_version_string = server_version_string.encode("ascii")
|