minor fixes

This commit is contained in:
Alexander Tokmakov 2020-04-27 23:51:39 +03:00
parent d56002b81f
commit e72a484beb
12 changed files with 100 additions and 97 deletions

View File

@ -755,15 +755,15 @@ std::string DynamicQueryHandler::getQuery(Poco::Net::HTTPServerRequest & request
return full_query; return full_query;
} }
PredefineQueryHandler::PredefineQueryHandler( PredefinedQueryHandler::PredefinedQueryHandler(
IServer & server, const NameSet & receive_params_, const std::string & predefine_query_ IServer & server, const NameSet & receive_params_, const std::string & predefined_query_
, const std::optional<String> & url_regex_, const std::unordered_map<String, String> & header_name_with_regex_) , const std::optional<String> & url_regex_, const std::unordered_map<String, String> & header_name_with_regex_)
: HTTPHandler(server, "PredefineQueryHandler"), receive_params(receive_params_), predefine_query(predefine_query_) : HTTPHandler(server, "PredefinedQueryHandler"), receive_params(receive_params_), predefined_query(predefined_query_)
, url_regex(url_regex_), header_name_with_capture_regex(header_name_with_regex_) , url_regex(url_regex_), header_name_with_capture_regex(header_name_with_regex_)
{ {
} }
bool PredefineQueryHandler::customizeQueryParam(Context & context, const std::string & key, const std::string & value) bool PredefinedQueryHandler::customizeQueryParam(Context & context, const std::string & key, const std::string & value)
{ {
if (receive_params.count(key)) if (receive_params.count(key))
{ {
@ -774,7 +774,7 @@ bool PredefineQueryHandler::customizeQueryParam(Context & context, const std::st
return false; return false;
} }
void PredefineQueryHandler::customizeContext(Poco::Net::HTTPServerRequest & request, DB::Context & context) void PredefinedQueryHandler::customizeContext(Poco::Net::HTTPServerRequest & request, DB::Context & context)
{ {
/// If in the configuration file, the handler's header is regex and contains named capture group /// If in the configuration file, the handler's header is regex and contains named capture group
/// We will extract regex named capture groups as query parameters /// We will extract regex named capture groups as query parameters
@ -784,7 +784,7 @@ void PredefineQueryHandler::customizeContext(Poco::Net::HTTPServerRequest & requ
auto compiled_regex = std::make_shared<re2_st::RE2>(regex); auto compiled_regex = std::make_shared<re2_st::RE2>(regex);
if (!compiled_regex->ok()) if (!compiled_regex->ok())
throw Exception("cannot compile re2: " + regex + " for routing_rule, error: " + compiled_regex->error() + throw Exception("cannot compile re2: " + regex + " for http handling rule, error: " + compiled_regex->error() +
". Look at https://github.com/google/re2/wiki/Syntax for reference.", ErrorCodes::CANNOT_COMPILE_REGEXP); ". Look at https://github.com/google/re2/wiki/Syntax for reference.", ErrorCodes::CANNOT_COMPILE_REGEXP);
int num_captures = compiled_regex->NumberOfCapturingGroups() + 1; int num_captures = compiled_regex->NumberOfCapturingGroups() + 1;
@ -816,7 +816,7 @@ void PredefineQueryHandler::customizeContext(Poco::Net::HTTPServerRequest & requ
} }
} }
std::string PredefineQueryHandler::getQuery(Poco::Net::HTTPServerRequest & request, HTMLForm & params, Context & context) std::string PredefinedQueryHandler::getQuery(Poco::Net::HTTPServerRequest & request, HTMLForm & params, Context & context)
{ {
if (unlikely(startsWith(request.getContentType(), "multipart/form-data"))) if (unlikely(startsWith(request.getContentType(), "multipart/form-data")))
{ {
@ -825,13 +825,13 @@ std::string PredefineQueryHandler::getQuery(Poco::Net::HTTPServerRequest & reque
params.load(request, request.stream(), handler); params.load(request, request.stream(), handler);
} }
return predefine_query; return predefined_query;
} }
Poco::Net::HTTPRequestHandlerFactory * createDynamicHandlerFactory(IServer & server, const std::string & config_prefix) Poco::Net::HTTPRequestHandlerFactory * createDynamicHandlerFactory(IServer & server, const std::string & config_prefix)
{ {
std::string query_param_name = server.config().getString(config_prefix + ".handler.query_param_name", "query"); std::string query_param_name = server.config().getString(config_prefix + ".handler.query_param_name", "query");
return addFiltersFromConfig(new RoutingRuleHTTPHandlerFactory<DynamicQueryHandler>(server, std::move(query_param_name)), server.config(), config_prefix); return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<DynamicQueryHandler>(server, std::move(query_param_name)), server.config(), config_prefix);
} }
static inline bool capturingNamedQueryParam(NameSet receive_params, const std::string & expression) static inline bool capturingNamedQueryParam(NameSet receive_params, const std::string & expression)
@ -839,7 +839,7 @@ static inline bool capturingNamedQueryParam(NameSet receive_params, const std::s
auto compiled_regex = std::make_shared<re2_st::RE2>(expression); auto compiled_regex = std::make_shared<re2_st::RE2>(expression);
if (!compiled_regex->ok()) if (!compiled_regex->ok())
throw Exception("Cannot compile re2: " + expression + " for routing_rule, error: " + throw Exception("Cannot compile re2: " + expression + " for http handling rule, error: " +
compiled_regex->error() + ". Look at https://github.com/google/re2/wiki/Syntax for reference.", ErrorCodes::CANNOT_COMPILE_REGEXP); compiled_regex->error() + ". Look at https://github.com/google/re2/wiki/Syntax for reference.", ErrorCodes::CANNOT_COMPILE_REGEXP);
const auto & capturing_names = compiled_regex->NamedCapturingGroups(); const auto & capturing_names = compiled_regex->NamedCapturingGroups();
@ -850,15 +850,15 @@ static inline bool capturingNamedQueryParam(NameSet receive_params, const std::s
}); });
} }
Poco::Net::HTTPRequestHandlerFactory * createPredefineHandlerFactory(IServer & server, const std::string & config_prefix) Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer & server, const std::string & config_prefix)
{ {
Poco::Util::AbstractConfiguration & configuration = server.config(); Poco::Util::AbstractConfiguration & configuration = server.config();
if (!configuration.has(config_prefix + ".handler.query")) if (!configuration.has(config_prefix + ".handler.query"))
throw Exception("There is no path '" + config_prefix + ".handler.query" + "' in configuration file.", ErrorCodes::NO_ELEMENTS_IN_CONFIG); throw Exception("There is no path '" + config_prefix + ".handler.query" + "' in configuration file.", ErrorCodes::NO_ELEMENTS_IN_CONFIG);
std::string predefine_query = configuration.getString(config_prefix + ".handler.query"); std::string predefined_query = configuration.getString(config_prefix + ".handler.query");
NameSet analyze_receive_params = analyzeReceiveQueryParams(predefine_query); NameSet analyze_receive_params = analyzeReceiveQueryParams(predefined_query);
std::unordered_map<String, String> headers_name_with_regex; std::unordered_map<String, String> headers_name_with_regex;
Poco::Util::AbstractConfiguration::Keys headers_name; Poco::Util::AbstractConfiguration::Keys headers_name;
@ -884,13 +884,13 @@ Poco::Net::HTTPRequestHandlerFactory * createPredefineHandlerFactory(IServer & s
url_expression = url_expression.substr(6); url_expression = url_expression.substr(6);
if (capturingNamedQueryParam(analyze_receive_params, url_expression)) if (capturingNamedQueryParam(analyze_receive_params, url_expression))
return addFiltersFromConfig(new RoutingRuleHTTPHandlerFactory<PredefineQueryHandler>( return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<PredefinedQueryHandler>(
server, std::move(analyze_receive_params), std::move(predefine_query), std::optional<String>(url_expression), server, std::move(analyze_receive_params), std::move(predefined_query), std::optional<String>(url_expression),
std::move(headers_name_with_regex)), configuration, config_prefix); std::move(headers_name_with_regex)), configuration, config_prefix);
} }
return addFiltersFromConfig(new RoutingRuleHTTPHandlerFactory<PredefineQueryHandler>( return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<PredefinedQueryHandler>(
server, std::move(analyze_receive_params), std::move(predefine_query), std::optional<String>{} ,std::move(headers_name_with_regex)), server, std::move(analyze_receive_params), std::move(predefined_query), std::optional<String>{} ,std::move(headers_name_with_regex)),
configuration, config_prefix); configuration, config_prefix);
} }

View File

@ -29,7 +29,7 @@ public:
void handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response) override; void handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response) override;
/// This method is called right before the query execution. /// This method is called right before the query execution.
virtual void customizeContext(Poco::Net::HTTPServerRequest & request, Context & /* context */) {} virtual void customizeContext(Poco::Net::HTTPServerRequest & /*request*/, Context & /* context */) {}
virtual bool customizeQueryParam(Context & context, const std::string & key, const std::string & value) = 0; virtual bool customizeQueryParam(Context & context, const std::string & key, const std::string & value) = 0;
@ -96,16 +96,16 @@ public:
bool customizeQueryParam(Context &context, const std::string &key, const std::string &value) override; bool customizeQueryParam(Context &context, const std::string &key, const std::string &value) override;
}; };
class PredefineQueryHandler : public HTTPHandler class PredefinedQueryHandler : public HTTPHandler
{ {
private: private:
NameSet receive_params; NameSet receive_params;
std::string predefine_query; std::string predefined_query;
std::optional<String> url_regex; std::optional<String> url_regex;
std::unordered_map<String, String> header_name_with_capture_regex; std::unordered_map<String, String> header_name_with_capture_regex;
public: public:
explicit PredefineQueryHandler( explicit PredefinedQueryHandler(
IServer & server, const NameSet & receive_params_, const std::string & predefine_query_ IServer & server, const NameSet & receive_params_, const std::string & predefined_query_
, const std::optional<String> & url_regex_, const std::unordered_map<String, String> & header_name_with_regex_); , const std::optional<String> & url_regex_, const std::unordered_map<String, String> & header_name_with_regex_);
virtual void customizeContext(Poco::Net::HTTPServerRequest & request, Context & context) override; virtual void customizeContext(Poco::Net::HTTPServerRequest & request, Context & context) override;

View File

@ -26,6 +26,7 @@ namespace ErrorCodes
{ {
extern const int LOGICAL_ERROR; extern const int LOGICAL_ERROR;
extern const int UNKNOWN_ELEMENT_IN_CONFIG; extern const int UNKNOWN_ELEMENT_IN_CONFIG;
extern const int INVALID_CONFIG_PARAMETER;
} }
HTTPRequestHandlerFactoryMain::HTTPRequestHandlerFactoryMain(const std::string & name_) HTTPRequestHandlerFactoryMain::HTTPRequestHandlerFactoryMain(const std::string & name_)
@ -63,7 +64,10 @@ Poco::Net::HTTPRequestHandler * HTTPRequestHandlerFactoryMain::createRequestHand
HTTPRequestHandlerFactoryMain::~HTTPRequestHandlerFactoryMain() HTTPRequestHandlerFactoryMain::~HTTPRequestHandlerFactoryMain()
{ {
while (!child_factories.empty()) while (!child_factories.empty())
delete child_factories.back(), child_factories.pop_back(); {
delete child_factories.back();
child_factories.pop_back();
}
} }
HTTPRequestHandlerFactoryMain::TThis * HTTPRequestHandlerFactoryMain::addHandler(Poco::Net::HTTPRequestHandlerFactory * child_factory) HTTPRequestHandlerFactoryMain::TThis * HTTPRequestHandlerFactoryMain::addHandler(Poco::Net::HTTPRequestHandlerFactory * child_factory)
@ -83,8 +87,8 @@ static inline auto createHandlersFactoryFromConfig(IServer & server, const std::
for (const auto & key : keys) for (const auto & key : keys)
{ {
if (!startsWith(key, "routing_rule")) if (!startsWith(key, "rule"))
throw Exception("Unknown element in config: " + prefix + "." + key + ", must be 'routing_rule'", ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG); throw Exception("Unknown element in config: " + prefix + "." + key + ", must be 'rule'", ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG);
const auto & handler_type = server.config().getString(prefix + "." + key + ".handler.type", ""); const auto & handler_type = server.config().getString(prefix + "." + key + ".handler.type", "");
@ -92,10 +96,14 @@ static inline auto createHandlersFactoryFromConfig(IServer & server, const std::
main_handler_factory->addHandler(createStaticHandlerFactory(server, prefix + "." + key)); main_handler_factory->addHandler(createStaticHandlerFactory(server, prefix + "." + key));
else if (handler_type == "dynamic_query_handler") else if (handler_type == "dynamic_query_handler")
main_handler_factory->addHandler(createDynamicHandlerFactory(server, prefix + "." + key)); main_handler_factory->addHandler(createDynamicHandlerFactory(server, prefix + "." + key));
else if (handler_type == "predefine_query_handler") else if (handler_type == "predefined_query_handler")
main_handler_factory->addHandler(createPredefineHandlerFactory(server, prefix + "." + key)); main_handler_factory->addHandler(createPredefinedHandlerFactory(server, prefix + "." + key));
else if (handler_type.empty())
throw Exception("Handler type in config is not specified here: " +
prefix + "." + key + ".handler.type", ErrorCodes::INVALID_CONFIG_PARAMETER);
else else
throw Exception("Unknown element in config: " + prefix + "." + key + ", must be 'routing_rule'", ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG); throw Exception("Unknown handler type '" + handler_type +"' in config here: " +
prefix + "." + key + ".handler.type",ErrorCodes::INVALID_CONFIG_PARAMETER);
} }
return main_handler_factory; return main_handler_factory;
@ -112,21 +120,21 @@ static const auto root_response_expression = "config://http_server_default_respo
static inline Poco::Net::HTTPRequestHandlerFactory * createHTTPHandlerFactory(IServer & server, const std::string & name, AsynchronousMetrics & async_metrics) static inline Poco::Net::HTTPRequestHandlerFactory * createHTTPHandlerFactory(IServer & server, const std::string & name, AsynchronousMetrics & async_metrics)
{ {
if (server.config().has("routing_rules")) if (server.config().has("http_handlers"))
return createHandlersFactoryFromConfig(server, name, "routing_rules"); return createHandlersFactoryFromConfig(server, name, "http_handlers");
else else
{ {
auto factory = (new HTTPRequestHandlerFactoryMain(name)) auto factory = (new HTTPRequestHandlerFactoryMain(name))
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression)) ->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression))
->attachStrictPath("/")->allowGetAndHeadRequest()) ->attachStrictPath("/")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression)) ->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression))
->attachStrictPath("/ping")->allowGetAndHeadRequest()) ->attachStrictPath("/ping")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server)) ->addHandler((new HandlingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server))
->attachNonStrictPath("/replicas_status")->allowGetAndHeadRequest()) ->attachNonStrictPath("/replicas_status")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<DynamicQueryHandler>(server, "query"))->allowPostAndGetParamsRequest()); ->addHandler((new HandlingRuleHTTPHandlerFactory<DynamicQueryHandler>(server, "query"))->allowPostAndGetParamsRequest());
if (server.config().has("prometheus") && server.config().getInt("prometheus.port", 0) == 0) if (server.config().has("prometheus") && server.config().getInt("prometheus.port", 0) == 0)
factory->addHandler((new RoutingRuleHTTPHandlerFactory<PrometheusRequestHandler>( factory->addHandler((new HandlingRuleHTTPHandlerFactory<PrometheusRequestHandler>(
server, PrometheusMetricsWriter(server.config(), "prometheus", async_metrics))) server, PrometheusMetricsWriter(server.config(), "prometheus", async_metrics)))
->attachStrictPath(server.config().getString("prometheus.endpoint", "/metrics"))->allowGetAndHeadRequest()); ->attachStrictPath(server.config().getString("prometheus.endpoint", "/metrics"))->allowGetAndHeadRequest());
@ -137,13 +145,13 @@ static inline Poco::Net::HTTPRequestHandlerFactory * createHTTPHandlerFactory(IS
static inline Poco::Net::HTTPRequestHandlerFactory * createInterserverHTTPHandlerFactory(IServer & server, const std::string & name) static inline Poco::Net::HTTPRequestHandlerFactory * createInterserverHTTPHandlerFactory(IServer & server, const std::string & name)
{ {
return (new HTTPRequestHandlerFactoryMain(name)) return (new HTTPRequestHandlerFactoryMain(name))
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression)) ->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression))
->attachStrictPath("/")->allowGetAndHeadRequest()) ->attachStrictPath("/")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression)) ->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression))
->attachStrictPath("/ping")->allowGetAndHeadRequest()) ->attachStrictPath("/ping")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server)) ->addHandler((new HandlingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server))
->attachNonStrictPath("/replicas_status")->allowGetAndHeadRequest()) ->attachNonStrictPath("/replicas_status")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<InterserverIOHTTPHandler>(server))->allowPostAndGetParamsRequest()); ->addHandler((new HandlingRuleHTTPHandlerFactory<InterserverIOHTTPHandler>(server))->allowPostAndGetParamsRequest());
} }
Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, AsynchronousMetrics & async_metrics, const std::string & name) Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, AsynchronousMetrics & async_metrics, const std::string & name)
@ -153,11 +161,11 @@ Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, As
else if (name == "InterserverIOHTTPHandler-factory" || name == "InterserverIOHTTPSHandler-factory") else if (name == "InterserverIOHTTPHandler-factory" || name == "InterserverIOHTTPSHandler-factory")
return createInterserverHTTPHandlerFactory(server, name); return createInterserverHTTPHandlerFactory(server, name);
else if (name == "PrometheusHandler-factory") else if (name == "PrometheusHandler-factory")
return (new HTTPRequestHandlerFactoryMain(name))->addHandler((new RoutingRuleHTTPHandlerFactory<PrometheusRequestHandler>( return (new HTTPRequestHandlerFactoryMain(name))->addHandler((new HandlingRuleHTTPHandlerFactory<PrometheusRequestHandler>(
server, PrometheusMetricsWriter(server.config(), "prometheus", async_metrics))) server, PrometheusMetricsWriter(server.config(), "prometheus", async_metrics)))
->attachStrictPath(server.config().getString("prometheus.endpoint", "/metrics"))->allowGetAndHeadRequest()); ->attachStrictPath(server.config().getString("prometheus.endpoint", "/metrics"))->allowGetAndHeadRequest());
throw Exception("LOGICAL ERROR: Unknown HTTP handler factory name.", ErrorCodes::LOGICAL_ERROR); throw Exception("LOGICAL ERROR: Unknown HTTP handler factory name.", ErrorCodes::LOGICAL_ERROR);
} }
} }

View File

@ -13,7 +13,7 @@ namespace DB
{ {
/// Handle request using child handlers /// Handle request using child handlers
class HTTPRequestHandlerFactoryMain : public Poco::Net::HTTPRequestHandlerFactory class HTTPRequestHandlerFactoryMain : public Poco::Net::HTTPRequestHandlerFactory, boost::noncopyable
{ {
private: private:
using TThis = HTTPRequestHandlerFactoryMain; using TThis = HTTPRequestHandlerFactoryMain;
@ -34,14 +34,14 @@ public:
}; };
template <typename TEndpoint> template <typename TEndpoint>
class RoutingRuleHTTPHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory class HandlingRuleHTTPHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
{ {
public: public:
using TThis = RoutingRuleHTTPHandlerFactory<TEndpoint>; using TThis = HandlingRuleHTTPHandlerFactory<TEndpoint>;
using Filter = std::function<bool(const Poco::Net::HTTPServerRequest &)>; using Filter = std::function<bool(const Poco::Net::HTTPServerRequest &)>;
template <typename... TArgs> template <typename... TArgs>
RoutingRuleHTTPHandlerFactory(TArgs &&... args) HandlingRuleHTTPHandlerFactory(TArgs &&... args)
{ {
creator = [args = std::tuple<TArgs...>(std::forward<TArgs>(args) ...)]() creator = [args = std::tuple<TArgs...>(std::forward<TArgs>(args) ...)]()
{ {
@ -107,7 +107,7 @@ Poco::Net::HTTPRequestHandlerFactory * createStaticHandlerFactory(IServer & serv
Poco::Net::HTTPRequestHandlerFactory * createDynamicHandlerFactory(IServer & server, const std::string & config_prefix); Poco::Net::HTTPRequestHandlerFactory * createDynamicHandlerFactory(IServer & server, const std::string & config_prefix);
Poco::Net::HTTPRequestHandlerFactory * createPredefineHandlerFactory(IServer & server, const std::string & config_prefix); Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer & server, const std::string & config_prefix);
Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, AsynchronousMetrics & async_metrics, const std::string & name); Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, AsynchronousMetrics & async_metrics, const std::string & name);

View File

@ -31,7 +31,7 @@ static inline bool checkRegexExpression(const StringRef & match_str, const Strin
auto compiled_regex = std::make_shared<re2_st::RE2>(regex); auto compiled_regex = std::make_shared<re2_st::RE2>(regex);
if (!compiled_regex->ok()) if (!compiled_regex->ok())
throw Exception("cannot compile re2: " + expression.toString() + " for routing_rule, error: " + compiled_regex->error() + throw Exception("cannot compile re2: " + expression.toString() + " for http handling rule, error: " + compiled_regex->error() +
". Look at https://github.com/google/re2/wiki/Syntax for reference.", ErrorCodes::CANNOT_COMPILE_REGEXP); ". Look at https://github.com/google/re2/wiki/Syntax for reference.", ErrorCodes::CANNOT_COMPILE_REGEXP);
int num_captures = compiled_regex->NumberOfCapturingGroups() + 1; int num_captures = compiled_regex->NumberOfCapturingGroups() + 1;
@ -99,7 +99,7 @@ static inline auto headersFilter(Poco::Util::AbstractConfiguration & config, con
template <typename TEndpoint> template <typename TEndpoint>
static inline Poco::Net::HTTPRequestHandlerFactory * addFiltersFromConfig( static inline Poco::Net::HTTPRequestHandlerFactory * addFiltersFromConfig(
RoutingRuleHTTPHandlerFactory <TEndpoint> * factory, Poco::Util::AbstractConfiguration & config, const std::string & prefix) HandlingRuleHTTPHandlerFactory <TEndpoint> * factory, Poco::Util::AbstractConfiguration & config, const std::string & prefix)
{ {
Poco::Util::AbstractConfiguration::Keys filters_type; Poco::Util::AbstractConfiguration::Keys filters_type;
config.keys(prefix, filters_type); config.keys(prefix, filters_type);

View File

@ -140,7 +140,7 @@ void StaticRequestHandler::writeResponse(WriteBuffer & out)
else if (startsWith(response_expression, config_prefix)) else if (startsWith(response_expression, config_prefix))
{ {
if (response_expression.size() <= config_prefix.size()) if (response_expression.size() <= config_prefix.size())
throw Exception( "Static routing rule handler must contain a complete configuration path, for example: config://config_key", throw Exception( "Static handling rule handler must contain a complete configuration path, for example: config://config_key",
ErrorCodes::INVALID_CONFIG_PARAMETER); ErrorCodes::INVALID_CONFIG_PARAMETER);
const auto & config_path = response_expression.substr(config_prefix.size(), response_expression.size() - config_prefix.size()); const auto & config_path = response_expression.substr(config_prefix.size(), response_expression.size() - config_prefix.size());
@ -161,7 +161,7 @@ Poco::Net::HTTPRequestHandlerFactory * createStaticHandlerFactory(IServer & serv
std::string response_content = server.config().getRawString(config_prefix + ".handler.response_content", "Ok.\n"); std::string response_content = server.config().getRawString(config_prefix + ".handler.response_content", "Ok.\n");
std::string response_content_type = server.config().getString(config_prefix + ".handler.content_type", "text/plain; charset=UTF-8"); std::string response_content_type = server.config().getString(config_prefix + ".handler.content_type", "text/plain; charset=UTF-8");
return addFiltersFromConfig(new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>( return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(
server, std::move(response_content), std::move(status), std::move(response_content_type)), server.config(), config_prefix); server, std::move(response_content), std::move(status), std::move(response_content_type)), server.config(), config_prefix);
} }

View File

@ -525,21 +525,21 @@
</query_masking_rules> </query_masking_rules>
--> -->
<!-- Uncomment to use custom http routing. <!-- Uncomment to use custom http handlers.
routing_rule are checked from top to bottom, first match runs the handler rules are checked from top to bottom, first match runs the handler
url - to match request URL, you can use 'regex:' prefix to use regex match(optional) url - to match request URL, you can use 'regex:' prefix to use regex match(optional)
methods - to match request method, you can use commas to separate multiple method matches(optional) methods - to match request method, you can use commas to separate multiple method matches(optional)
headers - to match request headers, match each child element(child element name is header name), you can use 'regex:' prefix to use regex match(optional) headers - to match request headers, match each child element(child element name is header name), you can use 'regex:' prefix to use regex match(optional)
handler is request handler handler is request handler
type - supported types: static, dynamic_query_handler, predefine_query_handler type - supported types: static, dynamic_query_handler, predefined_query_handler
query - use with predefine_query_handler type, executes query when the handler is called query - use with predefined_query_handler type, executes query when the handler is called
query_param_name - use with dynamic_query_handler type, extracts and executes the value corresponding to the <query_param_name> value in HTTP request params query_param_name - use with dynamic_query_handler type, extracts and executes the value corresponding to the <query_param_name> value in HTTP request params
status - use with static type, response status code status - use with static type, response status code
content_type - use with static type, response content-type content_type - use with static type, response content-type
response_content - use with static type, Response content sent to client, when using the prefix 'file://' or 'config://', find the content from the file or configuration send to client. response_content - use with static type, Response content sent to client, when using the prefix 'file://' or 'config://', find the content from the file or configuration send to client.
<routing_rules> <http_handlers>
<routing_rule> <rule>
<url>/</url> <url>/</url>
<methods>POST,GET</methods> <methods>POST,GET</methods>
<headers><pragma>no-cache</pragma></headers> <headers><pragma>no-cache</pragma></headers>
@ -547,26 +547,26 @@
<type>dynamic_query_handler</type> <type>dynamic_query_handler</type>
<query_param_name>query</query_param_name> <query_param_name>query</query_param_name>
</handler> </handler>
</routing_rule> </rule>
<routing_rule> <rule>
<url>/predefine_query</url> <url>/predefined_query</url>
<methods>POST,GET</methods> <methods>POST,GET</methods>
<handler> <handler>
<type>predefine_query_handler</type> <type>predefined_query_handler</type>
<query>SELECT * FROM system.settings</query> <query>SELECT * FROM system.settings</query>
</handler> </handler>
</routing_rule> </rule>
<routing_rule> <rule>
<handler> <handler>
<type>static</type> <type>static</type>
<status>200</status> <status>200</status>
<content_type>text/plain; charset=UTF-8</content_type> <content_type>text/plain; charset=UTF-8</content_type>
<response_content>config://http_server_default_response</response_content> <response_content>config://http_server_default_response</response_content>
</handler> </handler>
</routing_rule> </rule>
</routing_rules> </http_handlers>
--> -->
<!-- Uncomment to disable ClickHouse internal DNS caching. --> <!-- Uncomment to disable ClickHouse internal DNS caching. -->

View File

@ -113,11 +113,6 @@ public:
compress = enable_compression; compress = enable_compression;
} }
bool getCompression()
{
return compress;
}
/// Set compression level if the compression is turned on. /// Set compression level if the compression is turned on.
/// The setting has any effect only if HTTP headers haven't been sent yet. /// The setting has any effect only if HTTP headers haven't been sent yet.
void setCompressionLevel(int level) void setCompressionLevel(int level)

View File

@ -37,17 +37,17 @@ def test_dynamic_query_handler():
method='GET', headers={'XXX': 'xxx'}).status_code method='GET', headers={'XXX': 'xxx'}).status_code
def test_predefine_query_handler(): def test_predefined_query_handler():
with contextlib.closing(SimpleCluster(ClickHouseCluster(__file__), "predefined_handler", "test_predefined_handler")) as cluster: with contextlib.closing(SimpleCluster(ClickHouseCluster(__file__), "predefined_handler", "test_predefined_handler")) as cluster:
assert 404 == cluster.instance.http_request('?max_threads=1', method='GET', headers={'XXX': 'xxx'}).status_code assert 404 == cluster.instance.http_request('?max_threads=1', method='GET', headers={'XXX': 'xxx'}).status_code
assert 404 == cluster.instance.http_request('test_predefine_handler_get?max_threads=1', method='GET', headers={'XXX': 'bad'}).status_code assert 404 == cluster.instance.http_request('test_predefined_handler_get?max_threads=1', method='GET', headers={'XXX': 'bad'}).status_code
assert 404 == cluster.instance.http_request('test_predefine_handler_get?max_threads=1', method='POST', headers={'XXX': 'xxx'}).status_code assert 404 == cluster.instance.http_request('test_predefined_handler_get?max_threads=1', method='POST', headers={'XXX': 'xxx'}).status_code
assert 500 == cluster.instance.http_request('test_predefine_handler_get?max_threads=1', method='GET', headers={'XXX': 'xxx'}).status_code assert 500 == cluster.instance.http_request('test_predefined_handler_get?max_threads=1', method='GET', headers={'XXX': 'xxx'}).status_code
assert 'max_threads\t1\n' == cluster.instance.http_request('test_predefine_handler_get?max_threads=1&setting_name=max_threads', method='GET', headers={'XXX': 'xxx'}).content assert 'max_threads\t1\n' == cluster.instance.http_request('test_predefined_handler_get?max_threads=1&setting_name=max_threads', method='GET', headers={'XXX': 'xxx'}).content
assert 'max_threads\t1\nmax_alter_threads\t1\n' == cluster.instance.http_request( assert 'max_threads\t1\nmax_alter_threads\t1\n' == cluster.instance.http_request(
'query_param_with_url/max_threads?max_threads=1&max_alter_threads=1', headers={'XXX': 'max_alter_threads'}).content 'query_param_with_url/max_threads?max_threads=1&max_alter_threads=1', headers={'XXX': 'max_alter_threads'}).content

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<yandex> <yandex>
<routing_rules> <http_handlers>
<routing_rule> <rule>
<headers><XXX>xxx</XXX></headers> <headers><XXX>xxx</XXX></headers>
<methods>GET</methods> <methods>GET</methods>
<url>/test_dynamic_handler_get</url> <url>/test_dynamic_handler_get</url>
@ -10,6 +10,6 @@
<type>dynamic_query_handler</type> <type>dynamic_query_handler</type>
<query_param_name>get_dynamic_handler_query</query_param_name> <query_param_name>get_dynamic_handler_query</query_param_name>
</handler> </handler>
</routing_rule> </rule>
</routing_rules> </http_handlers>
</yandex> </yandex>

View File

@ -1,25 +1,25 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<yandex> <yandex>
<routing_rules> <http_handlers>
<routing_rule> <rule>
<methods>GET</methods> <methods>GET</methods>
<headers><XXX>xxx</XXX></headers> <headers><XXX>xxx</XXX></headers>
<url>/test_predefine_handler_get</url> <url>/test_predefined_handler_get</url>
<handler> <handler>
<type>predefine_query_handler</type> <type>predefined_query_handler</type>
<query>SELECT name, value FROM system.settings WHERE name = {setting_name:String}</query> <query>SELECT name, value FROM system.settings WHERE name = {setting_name:String}</query>
</handler> </handler>
</routing_rule> </rule>
<routing_rule> <rule>
<url><![CDATA[regex:/query_param_with_url/(?P<setting_name_1>[^/]+)]]></url> <url><![CDATA[regex:/query_param_with_url/(?P<setting_name_1>[^/]+)]]></url>
<headers> <headers>
<XXX><![CDATA[regex:(?P<setting_name_2>.+)]]></XXX> <XXX><![CDATA[regex:(?P<setting_name_2>.+)]]></XXX>
</headers> </headers>
<handler> <handler>
<type>predefine_query_handler</type> <type>predefined_query_handler</type>
<query>SELECT name, value FROM system.settings WHERE name = {setting_name_1:String} OR name = {setting_name_2:String}</query> <query>SELECT name, value FROM system.settings WHERE name = {setting_name_1:String} OR name = {setting_name_2:String}</query>
</handler> </handler>
</routing_rule> </rule>
</routing_rules> </http_handlers>
</yandex> </yandex>

View File

@ -3,8 +3,8 @@
<yandex> <yandex>
<test_get_config_static_handler>Test get static handler and config content</test_get_config_static_handler> <test_get_config_static_handler>Test get static handler and config content</test_get_config_static_handler>
<routing_rules> <http_handlers>
<routing_rule> <rule>
<methods>GET</methods> <methods>GET</methods>
<headers><XXX>xxx</XXX></headers> <headers><XXX>xxx</XXX></headers>
<url>/test_get_fixed_static_handler</url> <url>/test_get_fixed_static_handler</url>
@ -14,9 +14,9 @@
<content_type>text/html; charset=UTF-8</content_type> <content_type>text/html; charset=UTF-8</content_type>
<response_content>Test get static handler and fix content</response_content> <response_content>Test get static handler and fix content</response_content>
</handler> </handler>
</routing_rule> </rule>
<routing_rule> <rule>
<methods>GET</methods> <methods>GET</methods>
<headers><XXX>xxx</XXX></headers> <headers><XXX>xxx</XXX></headers>
<url>/test_get_config_static_handler</url> <url>/test_get_config_static_handler</url>
@ -24,9 +24,9 @@
<type>static</type> <type>static</type>
<response_content>config://test_get_config_static_handler</response_content> <response_content>config://test_get_config_static_handler</response_content>
</handler> </handler>
</routing_rule> </rule>
<routing_rule> <rule>
<methods>GET</methods> <methods>GET</methods>
<headers><XXX>xxx</XXX></headers> <headers><XXX>xxx</XXX></headers>
<url>/test_get_absolute_path_static_handler</url> <url>/test_get_absolute_path_static_handler</url>
@ -35,9 +35,9 @@
<content_type>text/html; charset=UTF-8</content_type> <content_type>text/html; charset=UTF-8</content_type>
<response_content>file:///absolute_path_file.html</response_content> <response_content>file:///absolute_path_file.html</response_content>
</handler> </handler>
</routing_rule> </rule>
<routing_rule> <rule>
<methods>GET</methods> <methods>GET</methods>
<headers><XXX>xxx</XXX></headers> <headers><XXX>xxx</XXX></headers>
<url>/test_get_relative_path_static_handler</url> <url>/test_get_relative_path_static_handler</url>
@ -46,7 +46,7 @@
<content_type>text/html; charset=UTF-8</content_type> <content_type>text/html; charset=UTF-8</content_type>
<response_content>file://./relative_path_file.html</response_content> <response_content>file://./relative_path_file.html</response_content>
</handler> </handler>
</routing_rule> </rule>
</routing_rules> </http_handlers>
</yandex> </yandex>