def register_paths( self, method, path_patterns, callback, servlet_classname, trace=True ): """ Registers a request handler against a regular expression. Later request URLs are checked against these regular expressions in order to identify an appropriate handler for that request. Args: method (str): GET, POST etc path_patterns (Iterable[str]): A list of regular expressions to which the request URLs are compared. callback (function): The handler for the request. Usually a Servlet servlet_classname (str): The name of the handler to be used in prometheus and opentracing logs. trace (bool): Whether we should start a span to trace the servlet. """ method = method.encode("utf-8") # method is bytes on py3 if trace: # We don't extract the context from the servlet because we can't # trust the sender callback = trace_servlet(servlet_classname)(callback) for path_pattern in path_patterns: logger.debug("Registering for %s %s", method, path_pattern.pattern) self.path_regexs.setdefault(method, []).append( self._PathEntry(path_pattern, callback, servlet_classname) )
def register(self, http_server): """Called by the server to register this as a handler to the appropriate path. """ url_args = list(self.PATH_ARGS) handler = self._handle_request method = self.METHOD if self.CACHE: handler = self._cached_handler url_args.append("txn_id") args = "/".join("(?P<%s>[^/]+)" % (arg, ) for arg in url_args) pattern = re.compile("^/_synapse/replication/%s/%s$" % (self.NAME, args)) handler = trace_servlet(self.__class__.__name__, extract_context=True)(handler) # We don't let register paths trace this servlet using the default tracing # options because we wish to extract the context explicitly. http_server.register_paths(method, [pattern], handler, self.__class__.__name__, trace=False)
def register(self, http_server): """ Register this servlet with the given HTTP server. """ if hasattr(self, "PATTERNS"): patterns = self.PATTERNS for method in ("GET", "PUT", "POST", "OPTIONS", "DELETE"): if hasattr(self, "on_%s" % (method, )): servlet_classname = self.__class__.__name__ method_handler = getattr(self, "on_%s" % (method, )) http_server.register_paths( method, patterns, trace_servlet(servlet_classname, method_handler), servlet_classname, ) else: raise NotImplementedError("RestServlet must register something.")
async def _async_render_wrapper(self, request: SynapseRequest) -> None: """This is a wrapper that delegates to `_async_render` and handles exceptions, return values, metrics, etc. """ try: request.request_metrics.name = self.__class__.__name__ with trace_servlet(request, self._extract_context): callback_return = await self._async_render(request) if callback_return is not None: code, response = callback_return self._send_response(request, code, response) except Exception: # failure.Failure() fishes the original Failure out # of our stack, and thus gives us a sensible stack # trace. f = failure.Failure() self._send_error_response(f, request)
def render(self, request): """ Render the request, using an asynchronous render handler if it exists. """ async_render_callback_name = "_async_render_" + request.method.decode("ascii") # Try and get the async renderer callback = getattr(self, async_render_callback_name, None) # No async renderer for this request method. if not callback: return super().render(request) resp = trace_servlet(self.__class__.__name__)(callback)(request) # If it's a coroutine, turn it into a Deferred if isinstance(resp, types.CoroutineType): defer.ensureDeferred(resp) return NOT_DONE_YET