예제 #1
0
파일: server.py 프로젝트: yalamber/synapse
    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)
            )
예제 #2
0
파일: _base.py 프로젝트: wuwei1972/synapse
    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)
예제 #3
0
    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.")
예제 #4
0
    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)
예제 #5
0
파일: server.py 프로젝트: yalamber/synapse
    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