forked from MirrorHub/synapse
Fix logging of incorrect status codes for disconnected requests (#12580)
The status code of requests must always be set, regardless of client disconnection, otherwise they will always be logged as 200!. Broken for `respond_with_json` inf48792eec4
. Broken for `respond_with_json_bytes` in3e58ce72b4
. Broken for `respond_with_html_bytes` inea26e9a98b
. Signed-off-by: Sean Quah <seanq@element.io>
This commit is contained in:
parent
629aa51743
commit
0b684b59e5
4 changed files with 36 additions and 5 deletions
1
changelog.d/12580.bugfix
Normal file
1
changelog.d/12580.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix a long standing bug where status codes would almost always get logged as 200!, irrespective of the actual status code, when clients disconnect before a request has finished processing.
|
|
@ -683,6 +683,9 @@ def respond_with_json(
|
||||||
Returns:
|
Returns:
|
||||||
twisted.web.server.NOT_DONE_YET if the request is still active.
|
twisted.web.server.NOT_DONE_YET if the request is still active.
|
||||||
"""
|
"""
|
||||||
|
# The response code must always be set, for logging purposes.
|
||||||
|
request.setResponseCode(code)
|
||||||
|
|
||||||
# could alternatively use request.notifyFinish() and flip a flag when
|
# could alternatively use request.notifyFinish() and flip a flag when
|
||||||
# the Deferred fires, but since the flag is RIGHT THERE it seems like
|
# the Deferred fires, but since the flag is RIGHT THERE it seems like
|
||||||
# a waste.
|
# a waste.
|
||||||
|
@ -697,7 +700,6 @@ def respond_with_json(
|
||||||
else:
|
else:
|
||||||
encoder = _encode_json_bytes
|
encoder = _encode_json_bytes
|
||||||
|
|
||||||
request.setResponseCode(code)
|
|
||||||
request.setHeader(b"Content-Type", b"application/json")
|
request.setHeader(b"Content-Type", b"application/json")
|
||||||
request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")
|
request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")
|
||||||
|
|
||||||
|
@ -728,13 +730,15 @@ def respond_with_json_bytes(
|
||||||
Returns:
|
Returns:
|
||||||
twisted.web.server.NOT_DONE_YET if the request is still active.
|
twisted.web.server.NOT_DONE_YET if the request is still active.
|
||||||
"""
|
"""
|
||||||
|
# The response code must always be set, for logging purposes.
|
||||||
|
request.setResponseCode(code)
|
||||||
|
|
||||||
if request._disconnected:
|
if request._disconnected:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Not sending response to request %s, already disconnected.", request
|
"Not sending response to request %s, already disconnected.", request
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
request.setResponseCode(code)
|
|
||||||
request.setHeader(b"Content-Type", b"application/json")
|
request.setHeader(b"Content-Type", b"application/json")
|
||||||
request.setHeader(b"Content-Length", b"%d" % (len(json_bytes),))
|
request.setHeader(b"Content-Length", b"%d" % (len(json_bytes),))
|
||||||
request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")
|
request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")
|
||||||
|
@ -840,6 +844,9 @@ def respond_with_html_bytes(request: Request, code: int, html_bytes: bytes) -> N
|
||||||
code: The HTTP response code.
|
code: The HTTP response code.
|
||||||
html_bytes: The HTML bytes to use as the response body.
|
html_bytes: The HTML bytes to use as the response body.
|
||||||
"""
|
"""
|
||||||
|
# The response code must always be set, for logging purposes.
|
||||||
|
request.setResponseCode(code)
|
||||||
|
|
||||||
# could alternatively use request.notifyFinish() and flip a flag when
|
# could alternatively use request.notifyFinish() and flip a flag when
|
||||||
# the Deferred fires, but since the flag is RIGHT THERE it seems like
|
# the Deferred fires, but since the flag is RIGHT THERE it seems like
|
||||||
# a waste.
|
# a waste.
|
||||||
|
@ -849,7 +856,6 @@ def respond_with_html_bytes(request: Request, code: int, html_bytes: bytes) -> N
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
request.setResponseCode(code)
|
|
||||||
request.setHeader(b"Content-Type", b"text/html; charset=utf-8")
|
request.setHeader(b"Content-Type", b"text/html; charset=utf-8")
|
||||||
request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),))
|
request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),))
|
||||||
|
|
||||||
|
|
|
@ -201,4 +201,16 @@ class CasHandlerTestCase(HomeserverTestCase):
|
||||||
|
|
||||||
def _mock_request():
|
def _mock_request():
|
||||||
"""Returns a mock which will stand in as a SynapseRequest"""
|
"""Returns a mock which will stand in as a SynapseRequest"""
|
||||||
return Mock(spec=["getClientIP", "getHeader", "_disconnected"])
|
mock = Mock(
|
||||||
|
spec=[
|
||||||
|
"finish",
|
||||||
|
"getClientIP",
|
||||||
|
"getHeader",
|
||||||
|
"setHeader",
|
||||||
|
"setResponseCode",
|
||||||
|
"write",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# `_disconnected` musn't be another `Mock`, otherwise it will be truthy.
|
||||||
|
mock._disconnected = False
|
||||||
|
return mock
|
||||||
|
|
|
@ -349,4 +349,16 @@ class SamlHandlerTestCase(HomeserverTestCase):
|
||||||
|
|
||||||
def _mock_request():
|
def _mock_request():
|
||||||
"""Returns a mock which will stand in as a SynapseRequest"""
|
"""Returns a mock which will stand in as a SynapseRequest"""
|
||||||
return Mock(spec=["getClientIP", "getHeader", "_disconnected"])
|
mock = Mock(
|
||||||
|
spec=[
|
||||||
|
"finish",
|
||||||
|
"getClientIP",
|
||||||
|
"getHeader",
|
||||||
|
"setHeader",
|
||||||
|
"setResponseCode",
|
||||||
|
"write",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# `_disconnected` musn't be another `Mock`, otherwise it will be truthy.
|
||||||
|
mock._disconnected = False
|
||||||
|
return mock
|
||||||
|
|
Loading…
Reference in a new issue