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;
}
PredefineQueryHandler::PredefineQueryHandler(
IServer & server, const NameSet & receive_params_, const std::string & predefine_query_
PredefinedQueryHandler::PredefinedQueryHandler(
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_)
: 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_)
{
}
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))
{
@ -774,7 +774,7 @@ bool PredefineQueryHandler::customizeQueryParam(Context & context, const std::st
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
/// 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);
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);
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")))
{
@ -825,13 +825,13 @@ std::string PredefineQueryHandler::getQuery(Poco::Net::HTTPServerRequest & reque
params.load(request, request.stream(), handler);
}
return predefine_query;
return predefined_query;
}
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");
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)
@ -839,7 +839,7 @@ static inline bool capturingNamedQueryParam(NameSet receive_params, const std::s
auto compiled_regex = std::make_shared<re2_st::RE2>(expression);
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);
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();
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);
std::string predefine_query = configuration.getString(config_prefix + ".handler.query");
NameSet analyze_receive_params = analyzeReceiveQueryParams(predefine_query);
std::string predefined_query = configuration.getString(config_prefix + ".handler.query");
NameSet analyze_receive_params = analyzeReceiveQueryParams(predefined_query);
std::unordered_map<String, String> headers_name_with_regex;
Poco::Util::AbstractConfiguration::Keys headers_name;
@ -884,13 +884,13 @@ Poco::Net::HTTPRequestHandlerFactory * createPredefineHandlerFactory(IServer & s
url_expression = url_expression.substr(6);
if (capturingNamedQueryParam(analyze_receive_params, url_expression))
return addFiltersFromConfig(new RoutingRuleHTTPHandlerFactory<PredefineQueryHandler>(
server, std::move(analyze_receive_params), std::move(predefine_query), std::optional<String>(url_expression),
return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<PredefinedQueryHandler>(
server, std::move(analyze_receive_params), std::move(predefined_query), std::optional<String>(url_expression),
std::move(headers_name_with_regex)), configuration, config_prefix);
}
return addFiltersFromConfig(new RoutingRuleHTTPHandlerFactory<PredefineQueryHandler>(
server, std::move(analyze_receive_params), std::move(predefine_query), std::optional<String>{} ,std::move(headers_name_with_regex)),
return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<PredefinedQueryHandler>(
server, std::move(analyze_receive_params), std::move(predefined_query), std::optional<String>{} ,std::move(headers_name_with_regex)),
configuration, config_prefix);
}

View File

@ -29,7 +29,7 @@ public:
void handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response) override;
/// 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;
@ -96,16 +96,16 @@ public:
bool customizeQueryParam(Context &context, const std::string &key, const std::string &value) override;
};
class PredefineQueryHandler : public HTTPHandler
class PredefinedQueryHandler : public HTTPHandler
{
private:
NameSet receive_params;
std::string predefine_query;
std::string predefined_query;
std::optional<String> url_regex;
std::unordered_map<String, String> header_name_with_capture_regex;
public:
explicit PredefineQueryHandler(
IServer & server, const NameSet & receive_params_, const std::string & predefine_query_
explicit PredefinedQueryHandler(
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_);
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 UNKNOWN_ELEMENT_IN_CONFIG;
extern const int INVALID_CONFIG_PARAMETER;
}
HTTPRequestHandlerFactoryMain::HTTPRequestHandlerFactoryMain(const std::string & name_)
@ -63,7 +64,10 @@ Poco::Net::HTTPRequestHandler * HTTPRequestHandlerFactoryMain::createRequestHand
HTTPRequestHandlerFactoryMain::~HTTPRequestHandlerFactoryMain()
{
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)
@ -83,8 +87,8 @@ static inline auto createHandlersFactoryFromConfig(IServer & server, const std::
for (const auto & key : keys)
{
if (!startsWith(key, "routing_rule"))
throw Exception("Unknown element in config: " + prefix + "." + key + ", must be 'routing_rule'", ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG);
if (!startsWith(key, "rule"))
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", "");
@ -92,10 +96,14 @@ static inline auto createHandlersFactoryFromConfig(IServer & server, const std::
main_handler_factory->addHandler(createStaticHandlerFactory(server, prefix + "." + key));
else if (handler_type == "dynamic_query_handler")
main_handler_factory->addHandler(createDynamicHandlerFactory(server, prefix + "." + key));
else if (handler_type == "predefine_query_handler")
main_handler_factory->addHandler(createPredefineHandlerFactory(server, prefix + "." + key));
else if (handler_type == "predefined_query_handler")
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
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;
@ -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)
{
if (server.config().has("routing_rules"))
return createHandlersFactoryFromConfig(server, name, "routing_rules");
if (server.config().has("http_handlers"))
return createHandlersFactoryFromConfig(server, name, "http_handlers");
else
{
auto factory = (new HTTPRequestHandlerFactoryMain(name))
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression))
->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression))
->attachStrictPath("/")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression))
->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression))
->attachStrictPath("/ping")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server))
->addHandler((new HandlingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server))
->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)
factory->addHandler((new RoutingRuleHTTPHandlerFactory<PrometheusRequestHandler>(
factory->addHandler((new HandlingRuleHTTPHandlerFactory<PrometheusRequestHandler>(
server, PrometheusMetricsWriter(server.config(), "prometheus", async_metrics)))
->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)
{
return (new HTTPRequestHandlerFactoryMain(name))
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression))
->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, root_response_expression))
->attachStrictPath("/")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression))
->addHandler((new HandlingRuleHTTPHandlerFactory<StaticRequestHandler>(server, ping_response_expression))
->attachStrictPath("/ping")->allowGetAndHeadRequest())
->addHandler((new RoutingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server))
->addHandler((new HandlingRuleHTTPHandlerFactory<ReplicasStatusHandler>(server))
->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)
@ -153,11 +161,11 @@ Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, As
else if (name == "InterserverIOHTTPHandler-factory" || name == "InterserverIOHTTPSHandler-factory")
return createInterserverHTTPHandlerFactory(server, name);
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)))
->attachStrictPath(server.config().getString("prometheus.endpoint", "/metrics"))->allowGetAndHeadRequest());
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
class HTTPRequestHandlerFactoryMain : public Poco::Net::HTTPRequestHandlerFactory
class HTTPRequestHandlerFactoryMain : public Poco::Net::HTTPRequestHandlerFactory, boost::noncopyable
{
private:
using TThis = HTTPRequestHandlerFactoryMain;
@ -34,14 +34,14 @@ public:
};
template <typename TEndpoint>
class RoutingRuleHTTPHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
class HandlingRuleHTTPHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
{
public:
using TThis = RoutingRuleHTTPHandlerFactory<TEndpoint>;
using TThis = HandlingRuleHTTPHandlerFactory<TEndpoint>;
using Filter = std::function<bool(const Poco::Net::HTTPServerRequest &)>;
template <typename... TArgs>
RoutingRuleHTTPHandlerFactory(TArgs &&... args)
HandlingRuleHTTPHandlerFactory(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 * 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);

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);
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);
int num_captures = compiled_regex->NumberOfCapturingGroups() + 1;
@ -99,7 +99,7 @@ static inline auto headersFilter(Poco::Util::AbstractConfiguration & config, con
template <typename TEndpoint>
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;
config.keys(prefix, filters_type);

View File

@ -140,7 +140,7 @@ void StaticRequestHandler::writeResponse(WriteBuffer & out)
else if (startsWith(response_expression, config_prefix))
{
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);
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_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);
}

View File

@ -525,21 +525,21 @@
</query_masking_rules>
-->
<!-- Uncomment to use custom http routing.
routing_rule are checked from top to bottom, first match runs the handler
<!-- Uncomment to use custom http handlers.
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)
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)
handler is request handler
type - supported types: static, dynamic_query_handler, predefine_query_handler
query - use with predefine_query_handler type, executes query when the handler is called
type - supported types: static, dynamic_query_handler, predefined_query_handler
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
status - use with static type, response status code
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.
<routing_rules>
<routing_rule>
<http_handlers>
<rule>
<url>/</url>
<methods>POST,GET</methods>
<headers><pragma>no-cache</pragma></headers>
@ -547,26 +547,26 @@
<type>dynamic_query_handler</type>
<query_param_name>query</query_param_name>
</handler>
</routing_rule>
</rule>
<routing_rule>
<url>/predefine_query</url>
<rule>
<url>/predefined_query</url>
<methods>POST,GET</methods>
<handler>
<type>predefine_query_handler</type>
<type>predefined_query_handler</type>
<query>SELECT * FROM system.settings</query>
</handler>
</routing_rule>
</rule>
<routing_rule>
<rule>
<handler>
<type>static</type>
<status>200</status>
<content_type>text/plain; charset=UTF-8</content_type>
<response_content>config://http_server_default_response</response_content>
</handler>
</routing_rule>
</routing_rules>
</rule>
</http_handlers>
-->
<!-- Uncomment to disable ClickHouse internal DNS caching. -->

View File

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

View File

@ -37,17 +37,17 @@ def test_dynamic_query_handler():
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:
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(
'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"?>
<yandex>
<routing_rules>
<routing_rule>
<http_handlers>
<rule>
<headers><XXX>xxx</XXX></headers>
<methods>GET</methods>
<url>/test_dynamic_handler_get</url>
@ -10,6 +10,6 @@
<type>dynamic_query_handler</type>
<query_param_name>get_dynamic_handler_query</query_param_name>
</handler>
</routing_rule>
</routing_rules>
</rule>
</http_handlers>
</yandex>

View File

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

View File

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