Example #1
0
 def wrapped_request_handler(self, request):
     global _next_request_id
     request_id = "%s-%s" % (request.method, _next_request_id)
     _next_request_id += 1
     with LoggingContext(request_id) as request_context:
         request_context.request = request_id
         with request.processing():
             try:
                 d = request_handler(self, request)
                 with PreserveLoggingContext():
                     yield d
             except CodeMessageException as e:
                 code = e.code
                 if isinstance(e, SynapseError):
                     logger.info("%s SynapseError: %s - %s", request, code,
                                 e.msg)
                 else:
                     logger.exception(e)
                 outgoing_responses_counter.inc(request.method, str(code))
                 respond_with_json(
                     request,
                     code,
                     cs_exception(e),
                     send_cors=True,
                     pretty_print=_request_user_agent_is_curl(request),
                     version_string=self.version_string,
                 )
             except:
                 logger.exception("Failed handle request %s.%s on %r: %r",
                                  request_handler.__module__,
                                  request_handler.__name__, self, request)
                 respond_with_json(request,
                                   500, {"error": "Internal server error"},
                                   send_cors=True)
Example #2
0
    def wrapped_request_handler(self, request):
        global _next_request_id
        request_id = "%s-%s" % (request.method, _next_request_id)
        _next_request_id += 1

        with LoggingContext(request_id) as request_context:
            with Measure(self.clock, "wrapped_request_handler"):
                request_metrics = RequestMetrics()
                request_metrics.start(self.clock, name=self.__class__.__name__)

                request_context.request = request_id
                with request.processing():
                    try:
                        with PreserveLoggingContext(request_context):
                            if include_metrics:
                                yield request_handler(self, request, request_metrics)
                            else:
                                yield request_handler(self, request)
                    except CodeMessageException as e:
                        code = e.code
                        if isinstance(e, SynapseError):
                            logger.info(
                                "%s SynapseError: %s - %s", request, code, e.msg
                            )
                        else:
                            logger.exception(e)
                        outgoing_responses_counter.inc(request.method, str(code))
                        respond_with_json(
                            request, code, cs_exception(e), send_cors=True,
                            pretty_print=_request_user_agent_is_curl(request),
                            version_string=self.version_string,
                        )
                    except Exception:
                        logger.exception(
                            "Failed handle request %s.%s on %r: %r",
                            request_handler.__module__,
                            request_handler.__name__,
                            self,
                            request
                        )
                        respond_with_json(
                            request,
                            500,
                            {
                                "error": "Internal server error",
                                "errcode": Codes.UNKNOWN,
                            },
                            send_cors=True,
                            pretty_print=_request_user_agent_is_curl(request),
                            version_string=self.version_string,
                        )
                    finally:
                        try:
                            request_metrics.stop(
                                self.clock, request
                            )
                        except Exception as e:
                            logger.warn("Failed to stop metrics: %r", e)
Example #3
0
    def _async_render(self, request):
        """ This get's called by twisted every time someone sends us a request.
            This checks if anyone has registered a callback for that method and
            path.
        """
        code = None
        start = self.clock.time_msec()
        try:
            # Just say yes to OPTIONS.
            if request.method == "OPTIONS":
                self._send_response(request, 200, {})
                return

            # Loop through all the registered callbacks to check if the method
            # and path regex match
            for path_entry in self.path_regexs.get(request.method, []):
                m = path_entry.pattern.match(request.path)
                if m:
                    # We found a match! Trigger callback and then return the
                    # returned response. We pass both the request and any
                    # matched groups from the regex to the callback.

                    args = [
                        urllib.unquote(u).decode("UTF-8") for u in m.groups()
                    ]

                    logger.info("Received request: %s %s", request.method,
                                request.path)

                    code, response = yield path_entry.callback(request, *args)

                    self._send_response(request, code, response)
                    return

            # Huh. No one wanted to handle that? Fiiiiiine. Send 400.
            raise UnrecognizedRequestError()
        except CodeMessageException as e:
            if isinstance(e, SynapseError):
                logger.info("%s SynapseError: %s - %s", request, e.code, e.msg)
            else:
                logger.exception(e)

            code = e.code
            self._send_response(request,
                                code,
                                cs_exception(e),
                                response_code_message=e.response_code_message)
        except Exception as e:
            logger.exception(e)
            self._send_response(request, 500,
                                {"error": "Internal server error"})
        finally:
            code = str(code) if code else "-"

            end = self.clock.time_msec()
            logger.info("Processed request: %dms %s %s %s", end - start, code,
                        request.method, request.path)
Example #4
0
    def wrapped_request_handler(self, request):
        global _next_request_id
        request_id = "%s-%s" % (request.method, _next_request_id)
        _next_request_id += 1

        with LoggingContext(request_id) as request_context:
            with Measure(self.clock, "wrapped_request_handler"):
                request_metrics = RequestMetrics()
                request_metrics.start(self.clock, name=self.__class__.__name__)

                request_context.request = request_id
                with request.processing():
                    try:
                        with PreserveLoggingContext(request_context):
                            if include_metrics:
                                yield request_handler(self, request, request_metrics)
                            else:
                                yield request_handler(self, request)
                    except CodeMessageException as e:
                        code = e.code
                        if isinstance(e, SynapseError):
                            logger.info(
                                "%s SynapseError: %s - %s", request, code, e.msg
                            )
                        else:
                            logger.exception(e)
                        outgoing_responses_counter.inc(request.method, str(code))
                        respond_with_json(
                            request, code, cs_exception(e), send_cors=True,
                            pretty_print=_request_user_agent_is_curl(request),
                            version_string=self.version_string,
                        )
                    except:
                        logger.exception(
                            "Failed handle request %s.%s on %r: %r",
                            request_handler.__module__,
                            request_handler.__name__,
                            self,
                            request
                        )
                        respond_with_json(
                            request,
                            500,
                            {
                                "error": "Internal server error",
                                "errcode": Codes.UNKNOWN,
                            },
                            send_cors=True
                        )
                    finally:
                        try:
                            request_metrics.stop(
                                self.clock, request
                            )
                        except Exception as e:
                            logger.warn("Failed to stop metrics: %r", e)
Example #5
0
    def _async_render(self, request):
        """ This get's called by twisted every time someone sends us a request.
            This checks if anyone has registered a callback for that method and
            path.
        """
        try:
            # Just say yes to OPTIONS.
            if request.method == "OPTIONS":
                self._send_response(request, 200, {})
                return

            # Loop through all the registered callbacks to check if the method
            # and path regex match
            for path_entry in self.path_regexs.get(request.method, []):
                m = path_entry.pattern.match(request.path)
                if m:
                    # We found a match! Trigger callback and then return the
                    # returned response. We pass both the request and any
                    # matched groups from the regex to the callback.

                    args = [
                        urllib.unquote(u).decode("UTF-8") for u in m.groups()
                    ]

                    code, response = yield path_entry.callback(
                        request,
                        *args
                    )

                    self._send_response(request, code, response)
                    return

            # Huh. No one wanted to handle that? Fiiiiiine. Send 400.
            self._send_response(
                request,
                400,
                {"error": "Unrecognized request"}
            )
        except CodeMessageException as e:
            if isinstance(e, SynapseError):
                logger.info("%s SynapseError: %s - %s", request, e.code, e.msg)
            else:
                logger.exception(e)
            self._send_response(
                request,
                e.code,
                cs_exception(e),
                response_code_message=e.response_code_message
            )
        except Exception as e:
            logger.exception(e)
            self._send_response(
                request,
                500,
                {"error": "Internal server error"}
            )
Example #6
0
 def wrapped_request_handler(self, request):
     global _next_request_id
     request_id = "%s-%s" % (request.method, _next_request_id)
     _next_request_id += 1
     with LoggingContext(request_id) as request_context:
         request_context.request = request_id
         code = None
         start = self.clock.time_msec()
         try:
             logger.info(
                 "Received request: %s %s",
                 request.method, request.path
             )
             d = request_handler(self, request)
             with PreserveLoggingContext():
                 yield d
             code = request.code
         except CodeMessageException as e:
             code = e.code
             if isinstance(e, SynapseError):
                 logger.info(
                     "%s SynapseError: %s - %s", request, code, e.msg
                 )
             else:
                 logger.exception(e)
             outgoing_responses_counter.inc(request.method, str(code))
             respond_with_json(
                 request, code, cs_exception(e), send_cors=True,
                 pretty_print=_request_user_agent_is_curl(request),
                 version_string=self.version_string,
             )
         except:
             code = 500
             logger.exception(
                 "Failed handle request %s.%s on %r: %r",
                 request_handler.__module__,
                 request_handler.__name__,
                 self,
                 request
             )
             respond_with_json(
                 request,
                 500,
                 {"error": "Internal server error"},
                 send_cors=True
             )
         finally:
             code = str(code) if code else "-"
             end = self.clock.time_msec()
             logger.info(
                 "Processed request: %dms %s %s %s",
                 end-start, code, request.method, request.path
             )
Example #7
0
    def _async_render(self, request):
        """ This get's called by twisted every time someone sends us a request.
            This checks if anyone has registered a callback for that method and
            path.
        """
        try:
            # Just say yes to OPTIONS.
            if request.method == "OPTIONS":
                self._send_response(request, 200, {})
                return

            # Loop through all the registered callbacks to check if the method
            # and path regex match
            for path_entry in self.path_regexs.get(request.method, []):
                m = path_entry.pattern.match(request.path)
                if m:
                    # We found a match! Trigger callback and then return the
                    # returned response. We pass both the request and any
                    # matched groups from the regex to the callback.
                    code, response = yield path_entry.callback(
                        request,
                        *m.groups()
                    )

                    self._send_response(request, code, response)
                    return

            # Huh. No one wanted to handle that? Fiiiiiine. Send 400.
            self._send_response(
                request,
                400,
                {"error": "Unrecognized request"}
            )
        except CodeMessageException as e:
            if isinstance(e, SynapseError):
                logger.error("%s SynapseError: %s - %s", request, e.code,
                             e.msg)
            else:
                logger.exception(e)
            self._send_response(
                request,
                e.code,
                cs_exception(e),
                response_code_message=e.response_code_message
            )
        except Exception as e:
            logger.exception(e)
            self._send_response(
                request,
                500,
                {"error": "Internal server error"}
            )
Example #8
0
 def wrapped_request_handler(self, request):
     global _next_request_id
     request_id = "%s-%s" % (request.method, _next_request_id)
     _next_request_id += 1
     with LoggingContext(request_id) as request_context:
         request_context.request = request_id
         code = None
         start = self.clock.time_msec()
         try:
             logger.info(
                 "Received request: %s %s",
                 request.method, request.path
             )
             yield request_handler(self, request)
             code = request.code
         except CodeMessageException as e:
             code = e.code
             if isinstance(e, SynapseError):
                 logger.info(
                     "%s SynapseError: %s - %s", request, code, e.msg
                 )
             else:
                 logger.exception(e)
             outgoing_responses_counter.inc(request.method, str(code))
             respond_with_json(
                 request, code, cs_exception(e), send_cors=True,
                 pretty_print=_request_user_agent_is_curl(request),
                 version_string=self.version_string,
             )
         except:
             code = 500
             logger.exception(
                 "Failed handle request %s.%s on %r: %r",
                 request_handler.__module__,
                 request_handler.__name__,
                 self,
                 request
             )
             respond_with_json(
                 request,
                 500,
                 {"error": "Internal server error"},
                 send_cors=True
             )
         finally:
             code = str(code) if code else "-"
             end = self.clock.time_msec()
             logger.info(
                 "Processed request: %dms %s %s %s",
                 end-start, code, request.method, request.path
             )
Example #9
0
    def _async_render_POST(self, request):
        try:
            auth_user, client = yield self.auth.get_user_by_req(request)
            # TODO: The checks here are a bit late. The content will have
            # already been uploaded to a tmp file at this point
            content_length = request.getHeader("Content-Length")
            if content_length is None:
                raise SynapseError(
                    msg="Request must specify a Content-Length", code=400
                )
            if int(content_length) > self.max_upload_size:
                raise SynapseError(
                    msg="Upload request body is too large",
                    code=413,
                )

            headers = request.requestHeaders

            if headers.hasHeader("Content-Type"):
                media_type = headers.getRawHeaders("Content-Type")[0]
            else:
                raise SynapseError(
                    msg="Upload request missing 'Content-Type'",
                    code=400,
                )

            # if headers.hasHeader("Content-Disposition"):
            #     disposition = headers.getRawHeaders("Content-Disposition")[0]
            # TODO(markjh): parse content-dispostion

            content_uri = yield self.create_content(
                media_type, None, request.content.read(),
                content_length, auth_user
            )

            respond_with_json(
                request, 200, {"content_uri": content_uri}, send_cors=True
            )
        except CodeMessageException as e:
            logger.exception(e)
            respond_with_json(request, e.code, cs_exception(e), send_cors=True)
        except:
            logger.exception("Failed to store file")
            respond_with_json(
                request,
                500,
                {"error": "Internal server error"},
                send_cors=True
            )
    def _async_render(self, request):
        try:
            # TODO: The checks here are a bit late. The content will have
            # already been uploaded to a tmp file at this point
            content_length = request.getHeader("Content-Length")
            if content_length is None:
                raise SynapseError(
                    msg="Request must specify a Content-Length", code=400
                )
            if int(content_length) > self.max_upload_size:
                raise SynapseError(
                    msg="Upload request body is too large",
                    code=413,
                )

            fname = yield self.map_request_to_name(request)

            # TODO I have a suspcious feeling this is just going to block
            with open(fname, "wb") as f:
                f.write(request.content.read())


            # FIXME (erikj): These should use constants.
            file_name = os.path.basename(fname)
            # FIXME: we can't assume what the public mounted path of the repo is
            # ...plus self-signed SSL won't work to remote clients anyway
            # ...and we can't assume that it's SSL anyway, as we might want to
            # server it via the non-SSL listener...
            url = "%s/_matrix/content/%s" % (
                self.external_addr, file_name
            )

            respond_with_json_bytes(request, 200,
                                    json.dumps({"content_token": url}),
                                    send_cors=True)

        except CodeMessageException as e:
            logger.exception(e)
            respond_with_json_bytes(request, e.code,
                                    json.dumps(cs_exception(e)))
        except Exception as e:
            logger.error("Failed to store file: %s" % e)
            respond_with_json_bytes(
                request,
                500,
                json.dumps({"error": "Internal server error"}),
                send_cors=True)
Example #11
0
    def _async_render(self, request):
        try:
            # TODO: The checks here are a bit late. The content will have
            # already been uploaded to a tmp file at this point
            content_length = request.getHeader("Content-Length")
            if content_length is None:
                raise SynapseError(
                    msg="Request must specify a Content-Length", code=400
                )
            if int(content_length) > self.max_upload_size:
                raise SynapseError(
                    msg="Upload request body is too large",
                    code=413,
                )

            fname = yield self.map_request_to_name(request)

            # TODO I have a suspicious feeling this is just going to block
            with open(fname, "wb") as f:
                f.write(request.content.read())

            # FIXME (erikj): These should use constants.
            file_name = os.path.basename(fname)
            # FIXME: we can't assume what the repo's public mounted path is
            # ...plus self-signed SSL won't work to remote clients anyway
            # ...and we can't assume that it's SSL anyway, as we might want to
            # serve it via the non-SSL listener...
            url = "%s/_matrix/content/%s" % (
                self.external_addr, file_name
            )

            respond_with_json_bytes(request, 200,
                                    json.dumps({"content_token": url}),
                                    send_cors=True)

        except CodeMessageException as e:
            logger.exception(e)
            respond_with_json_bytes(request, e.code,
                                    json.dumps(cs_exception(e)))
        except Exception as e:
            logger.error("Failed to store file: %s" % e)
            respond_with_json_bytes(
                request,
                500,
                json.dumps({"error": "Internal server error"}),
                send_cors=True)
Example #12
0
    def _async_render_POST(self, request):
        try:
            auth_user, client = yield self.auth.get_user_by_req(request)
            # TODO: The checks here are a bit late. The content will have
            # already been uploaded to a tmp file at this point
            content_length = request.getHeader("Content-Length")
            if content_length is None:
                raise SynapseError(msg="Request must specify a Content-Length",
                                   code=400)
            if int(content_length) > self.max_upload_size:
                raise SynapseError(
                    msg="Upload request body is too large",
                    code=413,
                )

            headers = request.requestHeaders

            if headers.hasHeader("Content-Type"):
                media_type = headers.getRawHeaders("Content-Type")[0]
            else:
                raise SynapseError(
                    msg="Upload request missing 'Content-Type'",
                    code=400,
                )

            # if headers.hasHeader("Content-Disposition"):
            #     disposition = headers.getRawHeaders("Content-Disposition")[0]
            # TODO(markjh): parse content-dispostion

            content_uri = yield self.create_content(media_type, None,
                                                    request.content.read(),
                                                    content_length, auth_user)

            respond_with_json(request,
                              200, {"content_uri": content_uri},
                              send_cors=True)
        except CodeMessageException as e:
            logger.exception(e)
            respond_with_json(request, e.code, cs_exception(e), send_cors=True)
        except:
            logger.exception("Failed to store file")
            respond_with_json(request,
                              500, {"error": "Internal server error"},
                              send_cors=True)
Example #13
0
 def wrapped_request_handler(self, request):
     try:
         yield request_handler(self, request)
     except CodeMessageException as e:
         logger.exception(e)
         respond_with_json(request,
                           e.code,
                           cs_exception(e),
                           send_cors=True)
     except:
         logger.exception(
             "Failed handle request %s.%s on %r",
             request_handler.__module__,
             request_handler.__name__,
             self,
         )
         respond_with_json(request,
                           500, {"error": "Internal server error"},
                           send_cors=True)
Example #14
0
 def wrapped_request_handler(self, request):
     global _next_request_id
     request_id = "%s-%s" % (request.method, _next_request_id)
     _next_request_id += 1
     with LoggingContext(request_id) as request_context:
         request_context.request = request_id
         with request.processing():
             try:
                 d = request_handler(self, request)
                 with PreserveLoggingContext():
                     yield d
             except CodeMessageException as e:
                 code = e.code
                 if isinstance(e, SynapseError):
                     logger.info(
                         "%s SynapseError: %s - %s", request, code, e.msg
                     )
                 else:
                     logger.exception(e)
                 outgoing_responses_counter.inc(request.method, str(code))
                 respond_with_json(
                     request, code, cs_exception(e), send_cors=True,
                     pretty_print=_request_user_agent_is_curl(request),
                     version_string=self.version_string,
                 )
             except:
                 logger.exception(
                     "Failed handle request %s.%s on %r: %r",
                     request_handler.__module__,
                     request_handler.__name__,
                     self,
                     request
                 )
                 respond_with_json(
                     request,
                     500,
                     {
                         "error": "Internal server error",
                         "errcode": Codes.UNKNOWN,
                     },
                     send_cors=True
                 )
Example #15
0
 def wrapped_request_handler(self, request):
     try:
         yield request_handler(self, request)
     except CodeMessageException as e:
         logger.exception(e)
         respond_with_json(
             request, e.code, cs_exception(e), send_cors=True
         )
     except:
         logger.exception(
             "Failed handle request %s.%s on %r",
             request_handler.__module__,
             request_handler.__name__,
             self,
         )
         respond_with_json(
             request,
             500,
             {"error": "Internal server error"},
             send_cors=True
         )
Example #16
0
    def wrapped_request_handler(self, request):
        try:
            yield h(self, request)
        except CodeMessageException as e:
            code = e.code
            if isinstance(e, SynapseError):
                logger.info("%s SynapseError: %s - %s", request, code, e.msg)
            else:
                logger.exception(e)
            respond_with_json(
                request,
                code,
                cs_exception(e),
                send_cors=True,
                pretty_print=_request_user_agent_is_curl(request),
            )

        except Exception:
            # failure.Failure() fishes the original Failure out
            # of our stack, and thus gives us a sensible stack
            # trace.
            f = failure.Failure()
            logger.error(
                "Failed handle request via %r: %r: %s",
                h,
                request,
                f.getTraceback().rstrip(),
            )
            respond_with_json(
                request,
                500,
                {
                    "error": "Internal server error",
                    "errcode": Codes.UNKNOWN,
                },
                send_cors=True,
                pretty_print=_request_user_agent_is_curl(request),
            )
Example #17
0
    def wrapped_request_handler(self, request):
        global _next_request_id
        request_id = "%s-%s" % (request.method, _next_request_id)
        _next_request_id += 1

        with LoggingContext(request_id) as request_context:
            with Measure(self.clock, "wrapped_request_handler"):
                request_metrics = RequestMetrics()
                # we start the request metrics timer here with an initial stab
                # at the servlet name. For most requests that name will be
                # JsonResource (or a subclass), and JsonResource._async_render
                # will update it once it picks a servlet.
                servlet_name = self.__class__.__name__
                request_metrics.start(self.clock, name=servlet_name)

                request_context.request = request_id
                with request.processing():
                    try:
                        with PreserveLoggingContext(request_context):
                            if include_metrics:
                                yield request_handler(self, request,
                                                      request_metrics)
                            else:
                                requests_counter.inc(request.method,
                                                     servlet_name)
                                yield request_handler(self, request)
                    except CodeMessageException as e:
                        code = e.code
                        if isinstance(e, SynapseError):
                            logger.info("%s SynapseError: %s - %s", request,
                                        code, e.msg)
                        else:
                            logger.exception(e)
                        outgoing_responses_counter.inc(request.method,
                                                       str(code))
                        respond_with_json(
                            request,
                            code,
                            cs_exception(e),
                            send_cors=True,
                            pretty_print=_request_user_agent_is_curl(request),
                            version_string=self.version_string,
                        )
                    except Exception:
                        # failure.Failure() fishes the original Failure out
                        # of our stack, and thus gives us a sensible stack
                        # trace.
                        f = failure.Failure()
                        logger.error(
                            "Failed handle request %s.%s on %r: %r: %s",
                            request_handler.__module__,
                            request_handler.__name__,
                            self,
                            request,
                            f.getTraceback().rstrip(),
                        )
                        respond_with_json(
                            request,
                            500,
                            {
                                "error": "Internal server error",
                                "errcode": Codes.UNKNOWN,
                            },
                            send_cors=True,
                            pretty_print=_request_user_agent_is_curl(request),
                            version_string=self.version_string,
                        )
                    finally:
                        try:
                            request_metrics.stop(self.clock, request)
                        except Exception as e:
                            logger.warn("Failed to stop metrics: %r", e)
Example #18
0
    def _async_render_POST(self, request):
        try:
            auth_user = yield self.auth.get_user_by_req(request)
            # TODO: The checks here are a bit late. The content will have
            # already been uploaded to a tmp file at this point
            content_length = request.getHeader("Content-Length")
            if content_length is None:
                raise SynapseError(msg="Request must specify a Content-Length",
                                   code=400)
            if int(content_length) > self.max_upload_size:
                raise SynapseError(
                    msg="Upload request body is too large",
                    code=413,
                )

            headers = request.requestHeaders

            if headers.hasHeader("Content-Type"):
                media_type = headers.getRawHeaders("Content-Type")[0]
            else:
                raise SynapseError(
                    msg="Upload request missing 'Content-Type'",
                    code=400,
                )

            #if headers.hasHeader("Content-Disposition"):
            #    disposition = headers.getRawHeaders("Content-Disposition")[0]
            # TODO(markjh): parse content-dispostion

            media_id = random_string(24)

            fname = self.filepaths.local_media_filepath(media_id)
            self._makedirs(fname)

            # This shouldn't block for very long because the content will have
            # already been uploaded at this point.
            with open(fname, "wb") as f:
                f.write(request.content.read())

            yield self.store.store_local_media(
                media_id=media_id,
                media_type=media_type,
                time_now_ms=self.clock.time_msec(),
                upload_name=None,
                media_length=content_length,
                user_id=auth_user,
            )
            media_info = {
                "media_type": media_type,
                "media_length": content_length,
            }

            yield self._generate_local_thumbnails(media_id, media_info)

            content_uri = "mxc://%s/%s" % (self.server_name, media_id)

            respond_with_json(request,
                              200, {"content_uri": content_uri},
                              send_cors=True)
        except CodeMessageException as e:
            logger.exception(e)
            respond_with_json(request, e.code, cs_exception(e), send_cors=True)
        except:
            logger.exception("Failed to store file")
            respond_with_json(request,
                              500, {"error": "Internal server error"},
                              send_cors=True)
Example #19
0
    def _async_render(self, request):
        """ This get's called by twisted every time someone sends us a request.
            This checks if anyone has registered a callback for that method and
            path.
        """
        code = None
        start = self.clock.time_msec()
        try:
            # Just say yes to OPTIONS.
            if request.method == "OPTIONS":
                self._send_response(request, 200, {})
                return

            # Loop through all the registered callbacks to check if the method
            # and path regex match
            for path_entry in self.path_regexs.get(request.method, []):
                m = path_entry.pattern.match(request.path)
                if not m:
                    continue

                # We found a match! Trigger callback and then return the
                # returned response. We pass both the request and any
                # matched groups from the regex to the callback.

                callback = path_entry.callback

                servlet_instance = getattr(callback, "__self__", None)
                if servlet_instance is not None:
                    servlet_classname = servlet_instance.__class__.__name__
                else:
                    servlet_classname = "%r" % callback
                incoming_requests_counter.inc(request.method, servlet_classname)

                args = [
                    urllib.unquote(u).decode("UTF-8") for u in m.groups()
                ]

                logger.info(
                    "Received request: %s %s",
                    request.method, request.path
                )

                code, response = yield callback(request, *args)

                self._send_response(request, code, response)
                response_timer.inc_by(
                    self.clock.time_msec() - start, request.method, servlet_classname
                )

                return

            # Huh. No one wanted to handle that? Fiiiiiine. Send 400.
            raise UnrecognizedRequestError()
        except CodeMessageException as e:
            if isinstance(e, SynapseError):
                logger.info("%s SynapseError: %s - %s", request, e.code, e.msg)
            else:
                logger.exception(e)

            code = e.code
            self._send_response(
                request,
                code,
                cs_exception(e),
                response_code_message=e.response_code_message
            )
        except Exception as e:
            logger.exception(e)
            self._send_response(
                request,
                500,
                {"error": "Internal server error"}
            )
        finally:
            code = str(code) if code else "-"

            end = self.clock.time_msec()
            logger.info(
                "Processed request: %dms %s %s %s",
                end-start, code, request.method, request.path
            )