mirror of
https://mau.dev/maunium/synapse.git
synced 2024-10-01 01:36:05 -04:00
Catch the exceptions thrown by twisted when you write to a closed connection
This commit is contained in:
parent
ec0f3836ff
commit
58c9f20692
@ -367,10 +367,29 @@ def respond_with_json_bytes(request, code, json_bytes, send_cors=False,
|
|||||||
"Origin, X-Requested-With, Content-Type, Accept")
|
"Origin, X-Requested-With, Content-Type, Accept")
|
||||||
|
|
||||||
request.write(json_bytes)
|
request.write(json_bytes)
|
||||||
request.finish()
|
finish_request(request)
|
||||||
return NOT_DONE_YET
|
return NOT_DONE_YET
|
||||||
|
|
||||||
|
|
||||||
|
def finish_request(request):
|
||||||
|
""" Finish writing the response to the request.
|
||||||
|
|
||||||
|
Twisted throws a RuntimeException if the connection closed before the
|
||||||
|
response was written but doesn't provide a convenient or reliable way to
|
||||||
|
determine if the connection was closed. So we catch and log the RuntimeException
|
||||||
|
|
||||||
|
You might think that ``request.notifyFinish`` could be used to tell if the
|
||||||
|
request was finished. However the deferred it returns won't fire if the
|
||||||
|
connection was already closed, meaning we'd have to have called the method
|
||||||
|
right at the start of the request. By the time we want to write the response
|
||||||
|
it will already be too late.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
request.finish()
|
||||||
|
except RuntimeError as e:
|
||||||
|
logger.info("Connection disconnected before response was written: %r", e)
|
||||||
|
|
||||||
|
|
||||||
def _request_user_agent_is_curl(request):
|
def _request_user_agent_is_curl(request):
|
||||||
user_agents = request.requestHeaders.getRawHeaders(
|
user_agents = request.requestHeaders.getRawHeaders(
|
||||||
"User-Agent", default=[]
|
"User-Agent", default=[]
|
||||||
|
@ -17,6 +17,8 @@ from twisted.internet import defer
|
|||||||
|
|
||||||
from synapse.api.errors import SynapseError, LoginError, Codes
|
from synapse.api.errors import SynapseError, LoginError, Codes
|
||||||
from synapse.types import UserID
|
from synapse.types import UserID
|
||||||
|
from synapse.http.server import finish_request
|
||||||
|
|
||||||
from base import ClientV1RestServlet, client_path_patterns
|
from base import ClientV1RestServlet, client_path_patterns
|
||||||
|
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
@ -263,7 +265,7 @@ class SAML2RestServlet(ClientV1RestServlet):
|
|||||||
'?status=authenticated&access_token=' +
|
'?status=authenticated&access_token=' +
|
||||||
token + '&user_id=' + user_id + '&ava=' +
|
token + '&user_id=' + user_id + '&ava=' +
|
||||||
urllib.quote(json.dumps(saml2_auth.ava)))
|
urllib.quote(json.dumps(saml2_auth.ava)))
|
||||||
request.finish()
|
finish_request(request)
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
defer.returnValue((200, {"status": "authenticated",
|
defer.returnValue((200, {"status": "authenticated",
|
||||||
"user_id": user_id, "token": token,
|
"user_id": user_id, "token": token,
|
||||||
@ -272,7 +274,7 @@ class SAML2RestServlet(ClientV1RestServlet):
|
|||||||
request.redirect(urllib.unquote(
|
request.redirect(urllib.unquote(
|
||||||
request.args['RelayState'][0]) +
|
request.args['RelayState'][0]) +
|
||||||
'?status=not_authenticated')
|
'?status=not_authenticated')
|
||||||
request.finish()
|
finish_request(request)
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
defer.returnValue((200, {"status": "not_authenticated"}))
|
defer.returnValue((200, {"status": "not_authenticated"}))
|
||||||
|
|
||||||
@ -309,7 +311,7 @@ class CasRedirectServlet(ClientV1RestServlet):
|
|||||||
"service": "%s?%s" % (hs_redirect_url, client_redirect_url_param)
|
"service": "%s?%s" % (hs_redirect_url, client_redirect_url_param)
|
||||||
})
|
})
|
||||||
request.redirect("%s?%s" % (self.cas_server_url, service_param))
|
request.redirect("%s?%s" % (self.cas_server_url, service_param))
|
||||||
request.finish()
|
finish_request(request)
|
||||||
|
|
||||||
|
|
||||||
class CasTicketServlet(ClientV1RestServlet):
|
class CasTicketServlet(ClientV1RestServlet):
|
||||||
@ -362,7 +364,7 @@ class CasTicketServlet(ClientV1RestServlet):
|
|||||||
redirect_url = self.add_login_token_to_redirect_url(client_redirect_url,
|
redirect_url = self.add_login_token_to_redirect_url(client_redirect_url,
|
||||||
login_token)
|
login_token)
|
||||||
request.redirect(redirect_url)
|
request.redirect(redirect_url)
|
||||||
request.finish()
|
finish_request(request)
|
||||||
|
|
||||||
def add_login_token_to_redirect_url(self, url, token):
|
def add_login_token_to_redirect_url(self, url, token):
|
||||||
url_parts = list(urlparse.urlparse(url))
|
url_parts = list(urlparse.urlparse(url))
|
||||||
|
@ -18,6 +18,7 @@ from twisted.internet import defer
|
|||||||
from synapse.api.constants import LoginType
|
from synapse.api.constants import LoginType
|
||||||
from synapse.api.errors import SynapseError
|
from synapse.api.errors import SynapseError
|
||||||
from synapse.api.urls import CLIENT_V2_ALPHA_PREFIX
|
from synapse.api.urls import CLIENT_V2_ALPHA_PREFIX
|
||||||
|
from synapse.http.server import finish_request
|
||||||
from synapse.http.servlet import RestServlet
|
from synapse.http.servlet import RestServlet
|
||||||
|
|
||||||
from ._base import client_v2_patterns
|
from ._base import client_v2_patterns
|
||||||
@ -130,7 +131,7 @@ class AuthRestServlet(RestServlet):
|
|||||||
request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),))
|
request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),))
|
||||||
|
|
||||||
request.write(html_bytes)
|
request.write(html_bytes)
|
||||||
request.finish()
|
finish_request(request)
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
else:
|
else:
|
||||||
raise SynapseError(404, "Unknown auth stage type")
|
raise SynapseError(404, "Unknown auth stage type")
|
||||||
@ -176,7 +177,7 @@ class AuthRestServlet(RestServlet):
|
|||||||
request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),))
|
request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),))
|
||||||
|
|
||||||
request.write(html_bytes)
|
request.write(html_bytes)
|
||||||
request.finish()
|
finish_request(request)
|
||||||
|
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
else:
|
else:
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from synapse.http.server import respond_with_json_bytes
|
from synapse.http.server import respond_with_json_bytes, finish_request
|
||||||
|
|
||||||
from synapse.util.stringutils import random_string
|
from synapse.util.stringutils import random_string
|
||||||
from synapse.api.errors import (
|
from synapse.api.errors import (
|
||||||
@ -144,7 +144,7 @@ class ContentRepoResource(resource.Resource):
|
|||||||
# after the file has been sent, clean up and finish the request
|
# after the file has been sent, clean up and finish the request
|
||||||
def cbFinished(ignored):
|
def cbFinished(ignored):
|
||||||
f.close()
|
f.close()
|
||||||
request.finish()
|
finish_request(request)
|
||||||
d.addCallback(cbFinished)
|
d.addCallback(cbFinished)
|
||||||
else:
|
else:
|
||||||
respond_with_json_bytes(
|
respond_with_json_bytes(
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
from .thumbnailer import Thumbnailer
|
from .thumbnailer import Thumbnailer
|
||||||
|
|
||||||
from synapse.http.matrixfederationclient import MatrixFederationHttpClient
|
from synapse.http.matrixfederationclient import MatrixFederationHttpClient
|
||||||
from synapse.http.server import respond_with_json
|
from synapse.http.server import respond_with_json, finish_request
|
||||||
from synapse.util.stringutils import random_string
|
from synapse.util.stringutils import random_string
|
||||||
from synapse.api.errors import (
|
from synapse.api.errors import (
|
||||||
cs_error, Codes, SynapseError
|
cs_error, Codes, SynapseError
|
||||||
@ -238,7 +238,7 @@ class BaseMediaResource(Resource):
|
|||||||
with open(file_path, "rb") as f:
|
with open(file_path, "rb") as f:
|
||||||
yield FileSender().beginFileTransfer(f, request)
|
yield FileSender().beginFileTransfer(f, request)
|
||||||
|
|
||||||
request.finish()
|
finish_request(request)
|
||||||
else:
|
else:
|
||||||
self._respond_404(request)
|
self._respond_404(request)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user