Fix logcontext handling in verify_json_objects_for_server

preserve_context_over_fn is essentially broken, because (a) it pointlessly
drops the current logcontext before calling its wrapped function, which means
we don't get any useful logcontexts for _handle_key_deferred; (b) it wraps the
resulting deferred in a _PreservingContextDeferred, which is very dangerous
because you then can't yield on it without leaking context back into the
reactor.

Instead, let's specify that the resultant deferreds call their callbacks with
no logcontext.
This commit is contained in:
Richard van der Hoff 2017-09-20 01:32:42 +01:00
parent c5b0e9f485
commit c5c24c239b

View File

@ -18,7 +18,7 @@ from synapse.crypto.keyclient import fetch_server_key
from synapse.api.errors import SynapseError, Codes from synapse.api.errors import SynapseError, Codes
from synapse.util import unwrapFirstError, logcontext from synapse.util import unwrapFirstError, logcontext
from synapse.util.logcontext import ( from synapse.util.logcontext import (
preserve_context_over_fn, PreserveLoggingContext, PreserveLoggingContext,
preserve_fn preserve_fn
) )
from synapse.util.metrics import Measure from synapse.util.metrics import Measure
@ -83,9 +83,11 @@ class Keyring(object):
self.key_downloads = {} self.key_downloads = {}
def verify_json_for_server(self, server_name, json_object): def verify_json_for_server(self, server_name, json_object):
return self.verify_json_objects_for_server( return logcontext.make_deferred_yieldable(
[(server_name, json_object)] self.verify_json_objects_for_server(
)[0] [(server_name, json_object)]
)[0]
)
def verify_json_objects_for_server(self, server_and_json): def verify_json_objects_for_server(self, server_and_json):
"""Bulk verifies signatures of json objects, bulk fetching keys as """Bulk verifies signatures of json objects, bulk fetching keys as
@ -95,8 +97,10 @@ class Keyring(object):
server_and_json (list): List of pairs of (server_name, json_object) server_and_json (list): List of pairs of (server_name, json_object)
Returns: Returns:
list of deferreds indicating success or failure to verify each List<Deferred>: for each input pair, a deferred indicating success
json object's signature for the given server_name. or failure to verify each json object's signature for the given
server_name. The deferreds run their callbacks in the sentinel
logcontext.
""" """
verify_requests = [] verify_requests = []
@ -127,9 +131,9 @@ class Keyring(object):
# Pass those keys to handle_key_deferred so that the json object # Pass those keys to handle_key_deferred so that the json object
# signatures can be verified # signatures can be verified
handle = preserve_fn(_handle_key_deferred)
return [ return [
preserve_context_over_fn(_handle_key_deferred, rq) handle(rq) for rq in verify_requests
for rq in verify_requests
] ]
@defer.inlineCallbacks @defer.inlineCallbacks