Beispiel #1
0
    def do_POST(self):
        """
        Handles POST queries, which are usually Thrift messages.
        """

        client_host, client_port = self.client_address
        auth_session = self.__check_session_cookie()
        LOG.debug("%s:%s -- [%s] POST %s", client_host, str(client_port),
                  auth_session.user if auth_session else "Anonymous",
                  self.path)

        # Create new thrift handler.
        checker_md_docs = self.server.checker_md_docs
        checker_md_docs_map = self.server.checker_md_docs_map
        suppress_handler = self.server.suppress_handler
        version = self.server.version

        protocol_factory = TJSONProtocol.TJSONProtocolFactory()
        input_protocol_factory = protocol_factory
        output_protocol_factory = protocol_factory

        itrans = TTransport.TFileObjectTransport(self.rfile)
        itrans = TTransport.TBufferedTransport(
            itrans, int(self.headers['Content-Length']))
        otrans = TTransport.TMemoryBuffer()

        iprot = input_protocol_factory.getProtocol(itrans)
        oprot = output_protocol_factory.getProtocol(otrans)

        if self.server.manager.is_enabled and \
                not self.path.endswith('/Authentication') and \
                not auth_session:
            # Bail out if the user is not authenticated...
            # This response has the possibility of melting down Thrift clients,
            # but the user is expected to properly authenticate first.

            LOG.debug(client_host + ":" + str(client_port) +
                      " Invalid access, credentials not found " +
                      "- session refused.")
            self.send_error(401)
            return

        # Authentication is handled, we may now respond to the user.
        try:
            product_endpoint, api_ver, request_endpoint = \
                routing.split_client_POST_request(self.path)

            product = None
            if product_endpoint:
                # The current request came through a product route, and not
                # to the main endpoint.
                product = self.server.get_product(product_endpoint)
                self.__check_prod_db(product)

            version_supported = routing.is_supported_version(api_ver)
            if version_supported:
                major_version, _ = version_supported

                if major_version == 6:
                    if request_endpoint == 'Authentication':
                        auth_handler = AuthHandler_v6(
                            self.server.manager, auth_session,
                            self.server.config_session)
                        processor = AuthAPI_v6.Processor(auth_handler)
                    elif request_endpoint == 'Products':
                        prod_handler = ProductHandler_v6(
                            self.server, auth_session,
                            self.server.config_session, product, version)
                        processor = ProductAPI_v6.Processor(prod_handler)
                    elif request_endpoint == 'CodeCheckerService':
                        # This endpoint is a product's report_server.
                        if not product:
                            error_msg = "Requested CodeCheckerService on a " \
                                         "nonexistent product: '{0}'." \
                                        .format(product_endpoint)
                            LOG.error(error_msg)
                            raise ValueError(error_msg)

                        if product_endpoint:
                            # The current request came through a
                            # product route, and not to the main endpoint.
                            product = self.server.get_product(product_endpoint)
                            self.__check_prod_db(product)

                        acc_handler = ReportHandler_v6(
                            self.server.manager, product.session_factory,
                            product, auth_session, self.server.config_session,
                            checker_md_docs, checker_md_docs_map,
                            suppress_handler, version)
                        processor = ReportAPI_v6.Processor(acc_handler)
                    else:
                        LOG.debug("This API endpoint does not exist.")
                        error_msg = "No API endpoint named '{0}'." \
                                    .format(self.path)
                        raise ValueError(error_msg)

            else:
                if request_endpoint == 'Authentication':
                    # API-version checking is supported on the auth endpoint.
                    handler = BadAPIHandler(api_ver)
                    processor = AuthAPI_v6.Processor(handler)
                else:
                    # Send a custom, but valid Thrift error message to the
                    # client requesting this action.
                    error_msg = "Incompatible client/server API." \
                                "API versions supported by this server {0}." \
                                .format(get_version_str())

                    raise ValueError(error_msg)

            processor.process(iprot, oprot)
            result = otrans.getvalue()

            self.send_response(200)
            self.send_header("content-type", "application/x-thrift")
            self.send_header("Content-Length", len(result))
            self.end_headers()
            self.wfile.write(result)
            return

        except Exception as exn:
            # Convert every Exception to the proper format which can be parsed
            # by the Thrift clients expecting JSON responses.
            LOG.error(exn.message)
            import traceback
            traceback.print_exc()
            ex = TApplicationException(TApplicationException.INTERNAL_ERROR,
                                       exn.message)
            fname, _, seqid = iprot.readMessageBegin()
            oprot.writeMessageBegin(fname, TMessageType.EXCEPTION, seqid)
            ex.write(oprot)
            oprot.writeMessageEnd()
            oprot.trans.flush()
            result = otrans.getvalue()
            self.send_response(200)
            self.send_header("content-type", "application/x-thrift")
            self.send_header("Content-Length", len(result))
            self.end_headers()
            self.wfile.write(result)
            return
Beispiel #2
0
    def do_POST(self):
        """
        Handles POST queries, which are usually Thrift messages.
        """

        client_host, client_port = self.client_address
        self.auth_session = self.__check_session_cookie()
        LOG.info("%s:%s -- [%s] POST %s", client_host, str(client_port),
                 self.auth_session.user if self.auth_session else "Anonymous",
                 self.path)

        # Create new thrift handler.
        checker_md_docs = self.server.checker_md_docs
        checker_md_docs_map = self.server.checker_md_docs_map
        version = self.server.version

        protocol_factory = TJSONProtocol.TJSONProtocolFactory()
        input_protocol_factory = protocol_factory
        output_protocol_factory = protocol_factory

        itrans = TTransport.TFileObjectTransport(self.rfile)
        itrans = TTransport.TBufferedTransport(
            itrans, int(self.headers['Content-Length']))
        otrans = TTransport.TMemoryBuffer()

        iprot = input_protocol_factory.getProtocol(itrans)
        oprot = output_protocol_factory.getProtocol(otrans)

        if self.server.manager.is_enabled and \
                not self.path.endswith(('/Authentication',
                                        '/Configuration')) and \
                not self.auth_session:
            # Bail out if the user is not authenticated...
            # This response has the possibility of melting down Thrift clients,
            # but the user is expected to properly authenticate first.
            LOG.debug(
                "%s:%s Invalid access, credentials not found "
                "- session refused.", client_host, str(client_port))

            self.send_thrift_exception("Error code 401: Unauthorized!", iprot,
                                       oprot, otrans)
            return

        # Authentication is handled, we may now respond to the user.
        try:
            product_endpoint, api_ver, request_endpoint = \
                routing.split_client_POST_request(self.path)

            product = None
            if product_endpoint:
                # The current request came through a product route, and not
                # to the main endpoint.
                product = self.__check_prod_db(product_endpoint)

            version_supported = routing.is_supported_version(api_ver)
            if version_supported:
                major_version, _ = version_supported

                if major_version == 6:
                    if request_endpoint == 'Authentication':
                        auth_handler = AuthHandler_v6(
                            self.server.manager, self.auth_session,
                            self.server.config_session)
                        processor = AuthAPI_v6.Processor(auth_handler)
                    elif request_endpoint == 'Configuration':
                        conf_handler = ConfigHandler_v6(
                            self.auth_session, self.server.config_session)
                        processor = ConfigAPI_v6.Processor(conf_handler)
                    elif request_endpoint == 'Products':
                        prod_handler = ProductHandler_v6(
                            self.server, self.auth_session,
                            self.server.config_session, product, version)
                        processor = ProductAPI_v6.Processor(prod_handler)
                    elif request_endpoint == 'CodeCheckerService':
                        # This endpoint is a product's report_server.
                        if not product:
                            error_msg = "Requested CodeCheckerService on a " \
                                         "nonexistent product: '{0}'." \
                                        .format(product_endpoint)
                            LOG.error(error_msg)
                            raise ValueError(error_msg)

                        if product_endpoint:
                            # The current request came through a
                            # product route, and not to the main endpoint.
                            product = self.__check_prod_db(product_endpoint)

                        acc_handler = ReportHandler_v6(
                            self.server.manager, product.session_factory,
                            product, self.auth_session,
                            self.server.config_session, checker_md_docs,
                            checker_md_docs_map, version, self.server.context)
                        processor = ReportAPI_v6.Processor(acc_handler)
                    else:
                        LOG.debug("This API endpoint does not exist.")
                        error_msg = "No API endpoint named '{0}'." \
                                    .format(self.path)
                        raise ValueError(error_msg)

            else:
                error_msg = "The API version you are using is not supported " \
                            "by this server (server API version: {0})!".format(
                                get_version_str())
                self.send_thrift_exception(error_msg, iprot, oprot, otrans)
                return

            processor.process(iprot, oprot)
            result = otrans.getvalue()

            self.send_response(200)
            self.send_header("content-type", "application/x-thrift")
            self.send_header("Content-Length", len(result))
            self.end_headers()
            self.wfile.write(result)
            return

        except Exception as exn:
            LOG.warning(str(exn))
            import traceback
            traceback.print_exc()
            self.send_thrift_exception(str(exn), iprot, oprot, otrans)
            return
Beispiel #3
0
    def do_POST(self):
        """
        Handles POST queries, which are usually Thrift messages.
        """

        client_host, client_port = self.client_address
        auth_session = self.__check_auth_in_request()
        LOG.info("{0}:{1} -- [{2}] POST {3}"
                 .format(client_host,
                         str(client_port),
                         auth_session.user if auth_session else "Anonymous",
                         self.path))

        # Create new thrift handler.
        checker_md_docs = self.server.checker_md_docs
        checker_md_docs_map = self.server.checker_md_docs_map
        suppress_handler = self.server.suppress_handler
        version = self.server.version

        protocol_factory = TJSONProtocol.TJSONProtocolFactory()
        input_protocol_factory = protocol_factory
        output_protocol_factory = protocol_factory

        itrans = TTransport.TFileObjectTransport(self.rfile)
        itrans = TTransport.TBufferedTransport(itrans,
                                               int(self.headers[
                                                   'Content-Length']))
        otrans = TTransport.TMemoryBuffer()

        iprot = input_protocol_factory.getProtocol(itrans)
        oprot = output_protocol_factory.getProtocol(otrans)

        if self.server.manager.isEnabled() and \
                not self.path.endswith('/Authentication') and \
                not auth_session:
            # Bail out if the user is not authenticated...
            # This response has the possibility of melting down Thrift clients,
            # but the user is expected to properly authenticate first.

            LOG.debug(client_host + ":" + str(client_port) +
                      " Invalid access, credentials not found " +
                      "- session refused.")
            self.send_error(401)
            return

        # Authentication is handled, we may now respond to the user.
        try:
            product_endpoint, api_ver, request_endpoint = \
                routing.split_client_POST_request(self.path)

            product = None
            if product_endpoint:
                # The current request came through a product route, and not
                # to the main endpoint.
                product = self.server.get_product(product_endpoint)
                if product and not product.connected:
                    # If the product is not connected, try reconnecting...
                    LOG.debug("Request's product '{0}' is not connected! "
                              "Attempting reconnect..."
                              .format(product_endpoint))
                    product.connect()

                    if not product.connected:
                        # If the reconnection fails, send an error to the user.
                        LOG.debug("Product reconnection failed.")
                        self.send_error(  # 500 Internal Server Error
                            500, "Product '{0}' database connection failed!"
                                 .format(product_endpoint))
                        return
                elif not product:
                    LOG.debug("Requested product does not exist.")
                    self.send_error(
                        404, "The product {0} does not exist."
                             .format(product_endpoint))
                    return

            version_supported = routing.is_supported_version(api_ver)
            if version_supported:
                major_version, _ = version_supported

                if major_version == 6:
                    if request_endpoint == 'Authentication':
                        auth_handler = AuthHandler_v6(
                            self.server.manager,
                            auth_session,
                            self.server.config_session)
                        processor = AuthAPI_v6.Processor(auth_handler)
                    elif request_endpoint == 'Products':
                        prod_handler = ProductHandler_v6(
                            self.server,
                            auth_session,
                            self.server.config_session,
                            product,
                            version)
                        processor = ProductAPI_v6.Processor(prod_handler)
                    elif request_endpoint == 'CodeCheckerService':
                        # This endpoint is a product's report_server.
                        if not product:
                            LOG.debug("Requested CodeCheckerService on a "
                                      "nonexistent product.")
                            self.send_error(  # 404 Not Found
                                404,
                                "The specified product '{0}' does not exist!"
                                .format(product_endpoint))
                            return

                        acc_handler = ReportHandler_v6(
                            product.session_factory,
                            product,
                            auth_session,
                            self.server.config_session,
                            checker_md_docs,
                            checker_md_docs_map,
                            suppress_handler,
                            version)
                        processor = ReportAPI_v6.Processor(acc_handler)
                    else:
                        LOG.debug("This API endpoint does not exist.")
                        self.send_error(404,  # 404 Not Fount
                                        "No API endpoint named '{0}'."
                                        .format(self.path))
                        return
            else:
                if request_endpoint == 'Authentication':
                    # API-version checking is supported on the auth endpoint.
                    handler = BadAPIHandler(api_ver)
                    processor = AuthAPI_v6.Processor(handler)
                else:
                    # Send a custom, but valid Thrift error message to the
                    # client requesting this action.
                    LOG.debug("API version v{0} not supported by server."
                              .format(api_ver))
                    self.send_error(400,  # 400 Bad Request
                                    "This API version 'v{0}' is not supported."
                                    .format(api_ver))
                    return

            processor.process(iprot, oprot)
            result = otrans.getvalue()

            self.send_response(200)
            self.send_header("content-type", "application/x-thrift")
            self.send_header("Content-Length", len(result))
            self.end_headers()
            self.wfile.write(result)
            return

        except Exception as exn:
            import traceback
            traceback.print_exc()
            LOG.error(str(exn))
            self.send_error(404, "Request failed.")
            return