After merge upsream master fix

This commit is contained in:
zhang2014
2020-04-20 02:26:42 +08:00
parent 1eda48b4b1
commit 835dc4c445
30 changed files with 188 additions and 395 deletions
+116 -19
View File
@@ -1,43 +1,140 @@
#include "HTTPHandlerFactory.h"
#include "NotFoundHandler.h"
#include "HTTPRequestHandler/HTTPRootRequestHandler.h"
#include "HTTPRequestHandler/HTTPPingRequestHandler.h"
#include "HTTPRequestHandler/HTTPReplicasStatusRequestHandler.h"
namespace DB
{
HTTPRequestHandlerFactoryMain::HTTPRequestHandlerFactoryMain(IServer & server_, const std::string & name_)
namespace ErrorCodes
{
extern const int SYNTAX_ERROR;
extern const int UNKNOWN_HTTP_HANDLER_TYPE;
extern const int EMPTY_HTTP_HANDLER_IN_CONFIG;
}
InterserverIOHTTPHandlerFactory::InterserverIOHTTPHandlerFactory(IServer & server_, const std::string & name_)
: server(server_), log(&Logger::get(name_)), name(name_)
{
}
Poco::Net::HTTPRequestHandler * HTTPRequestHandlerFactoryMain::createRequestHandler(
const Poco::Net::HTTPServerRequest & request) // override
Poco::Net::HTTPRequestHandler * InterserverIOHTTPHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & request)
{
LOG_TRACE(log, "HTTP Request for " << name << ". "
<< "Method: "
<< request.getMethod()
<< ", Address: "
<< request.clientAddress().toString()
<< ", User-Agent: "
<< (request.has("User-Agent") ? request.get("User-Agent") : "none")
<< (request.hasContentLength() ? (", Length: " + std::to_string(request.getContentLength())) : (""))
<< ", Content Type: " << request.getContentType()
<< ", Transfer Encoding: " << request.getTransferEncoding());
<< "Method: " << request.getMethod()
<< ", Address: " << request.clientAddress().toString()
<< ", User-Agent: " << (request.has("User-Agent") ? request.get("User-Agent") : "none")
<< (request.hasContentLength() ? (", Length: " + std::to_string(request.getContentLength())) : (""))
<< ", Content Type: " << request.getContentType()
<< ", Transfer Encoding: " << request.getTransferEncoding());
for (auto & handler_factory : child_handler_factories)
const auto & uri = request.getURI();
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET || request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD)
{
auto handler = handler_factory->createRequestHandler(request);
if (handler != nullptr)
return handler;
if (uri == "/")
return new HTTPRootRequestHandler(server);
if (uri == "/ping")
return new HTTPPingRequestHandler(server);
else if (startsWith(uri, "/replicas_status"))
return new HTTPReplicasStatusRequestHandler(server.context());
}
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET
|| request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD
if (uri.find('?') != std::string::npos || request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
{
return new InterserverIOHTTPHandler(server);
}
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET || request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD
|| request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
{
return new NotFoundHandler;
return new NotFoundHandler(
"Use / or /ping for health checks.\n"
"Or /replicas_status for more sophisticated health checks.\n"
"Send queries from your program with POST method or GET /?query=...\n\n"
" Use clickhouse-client:\n\n"
" For interactive data analysis:\n"
" clickhouse-client\n\n"
" For batch query processing:\n"
" clickhouse-client --query='SELECT 1' > result\n"
" clickhouse-client < query > result"
);
}
return nullptr;
}
HTTPHandlerFactory::HTTPHandlerFactory(IServer & server_, const std::string & name_)
: server(server_), log(&Logger::get(name_)), name(name_)
{
updateHTTPHandlersCreator(server.config());
if (handlers_creator.empty())
throw Exception("The HTTPHandlers does not exist in the config.xml", ErrorCodes::EMPTY_HTTP_HANDLER_IN_CONFIG);
}
Poco::Net::HTTPRequestHandler * HTTPHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & request)
{
LOG_TRACE(log, "HTTP Request for " << name << ". "
<< "Method: " << request.getMethod()
<< ", Address: " << request.clientAddress().toString()
<< ", User-Agent: " << (request.has("User-Agent") ? request.get("User-Agent") : "none")
<< (request.hasContentLength() ? (", Length: " + std::to_string(request.getContentLength())) : (""))
<< ", Content Type: " << request.getContentType()
<< ", Transfer Encoding: " << request.getTransferEncoding());
for (const auto & [matcher, creator] : handlers_creator)
{
if (matcher(request))
return creator();
}
return new NotFoundHandler(no_handler_description);
}
HTTPHandlerMatcher createRootHandlerMatcher(IServer &, const String &);
HTTPHandlerMatcher createPingHandlerMatcher(IServer &, const String &);
HTTPHandlerMatcher createDynamicQueryHandlerMatcher(IServer &, const String &);
HTTPHandlerMatcher createReplicasStatusHandlerMatcher(IServer &, const String &);
HTTPHandlerMatcher createPredefinedQueryHandlerMatcher(IServer &, const String &);
HTTPHandlerCreator createRootHandlerCreator(IServer &, const String &);
HTTPHandlerCreator createPingHandlerCreator(IServer &, const String &);
HTTPHandlerCreator createDynamicQueryHandlerCreator(IServer &, const String &);
HTTPHandlerCreator createReplicasStatusHandlerCreator(IServer &, const String &);
HTTPHandlerCreator createPredefinedQueryHandlerCreator(IServer &, const String &);
void HTTPHandlerFactory::updateHTTPHandlersCreator(Poco::Util::AbstractConfiguration & configuration, const String & key)
{
Poco::Util::AbstractConfiguration::Keys http_handlers_item_key;
configuration.keys(key, http_handlers_item_key);
handlers_creator.reserve(http_handlers_item_key.size());
for (const auto & http_handler_type_name : http_handlers_item_key)
{
if (http_handler_type_name.find('.') != String::npos)
throw Exception("HTTPHandler type name with dots are not supported: '" + http_handler_type_name + "'", ErrorCodes::SYNTAX_ERROR);
const auto & handler_key = key + "." + http_handler_type_name;
if (startsWith(http_handler_type_name, "root_handler"))
handlers_creator.push_back({createRootHandlerMatcher(server, handler_key), createRootHandlerCreator(server, handler_key)});
else if (startsWith(http_handler_type_name, "ping_handler"))
handlers_creator.push_back({createPingHandlerMatcher(server, handler_key), createPingHandlerCreator(server, handler_key)});
else if (startsWith(http_handler_type_name, "dynamic_query_handler"))
handlers_creator.push_back({createDynamicQueryHandlerMatcher(server, handler_key), createDynamicQueryHandlerCreator(server, handler_key)});
else if (startsWith(http_handler_type_name, "predefined_query_handler"))
handlers_creator.push_back({createPredefinedQueryHandlerMatcher(server, handler_key), createPredefinedQueryHandlerCreator(server, handler_key)});
else if (startsWith(http_handler_type_name, "replicas_status_handler"))
handlers_creator.push_back({createReplicasStatusHandlerMatcher(server, handler_key), createReplicasStatusHandlerCreator(server, handler_key)});
else if (http_handler_type_name == "no_handler_description")
no_handler_description = configuration.getString(key + ".no_handler_description");
else
throw Exception("Unknown HTTPHandler type name: " + http_handler_type_name, ErrorCodes::UNKNOWN_HTTP_HANDLER_TYPE);
}
}
}