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
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 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