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
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 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', '/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_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.__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, 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.warning(str(exn)) import traceback traceback.print_exc() ex = TApplicationException(TApplicationException.INTERNAL_ERROR, str(exn)) 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