mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
save compiled regex
This commit is contained in:
parent
e72a484beb
commit
9d43c2f6c2
@ -757,7 +757,7 @@ std::string DynamicQueryHandler::getQuery(Poco::Net::HTTPServerRequest & request
|
||||
|
||||
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_)
|
||||
, const CompiledRegexPtr & url_regex_, const std::unordered_map<String, CompiledRegexPtr> & header_name_with_regex_)
|
||||
: HTTPHandler(server, "PredefinedQueryHandler"), receive_params(receive_params_), predefined_query(predefined_query_)
|
||||
, url_regex(url_regex_), header_name_with_capture_regex(header_name_with_regex_)
|
||||
{
|
||||
@ -779,14 +779,8 @@ void PredefinedQueryHandler::customizeContext(Poco::Net::HTTPServerRequest & req
|
||||
/// 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
|
||||
|
||||
const auto & set_query_params = [&](const char * begin, const char * end, const std::string & regex)
|
||||
const auto & set_query_params = [&](const char * begin, const char * end, const CompiledRegexPtr & compiled_regex)
|
||||
{
|
||||
auto compiled_regex = std::make_shared<re2_st::RE2>(regex);
|
||||
|
||||
if (!compiled_regex->ok())
|
||||
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;
|
||||
|
||||
re2_st::StringPiece matches[num_captures];
|
||||
@ -806,7 +800,7 @@ void PredefinedQueryHandler::customizeContext(Poco::Net::HTTPServerRequest & req
|
||||
if (url_regex)
|
||||
{
|
||||
const auto & uri = request.getURI();
|
||||
set_query_params(uri.data(), find_first_symbols<'?'>(uri.data(), uri.data() + uri.size()), *url_regex);
|
||||
set_query_params(uri.data(), find_first_symbols<'?'>(uri.data(), uri.data() + uri.size()), url_regex);
|
||||
}
|
||||
|
||||
for (const auto & [header_name, regex] : header_name_with_capture_regex)
|
||||
@ -834,14 +828,8 @@ Poco::Net::HTTPRequestHandlerFactory * createDynamicHandlerFactory(IServer & ser
|
||||
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 CompiledRegexPtr & compiled_regex)
|
||||
{
|
||||
auto compiled_regex = std::make_shared<re2_st::RE2>(expression);
|
||||
|
||||
if (!compiled_regex->ok())
|
||||
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();
|
||||
return std::count_if(capturing_names.begin(), capturing_names.end(), [&](const auto & iterator)
|
||||
{
|
||||
@ -850,6 +838,17 @@ static inline bool capturingNamedQueryParam(NameSet receive_params, const std::s
|
||||
});
|
||||
}
|
||||
|
||||
static inline CompiledRegexPtr getCompiledRegex(const std::string & expression)
|
||||
{
|
||||
auto compiled_regex = std::make_shared<const re2_st::RE2>(expression);
|
||||
|
||||
if (!compiled_regex->ok())
|
||||
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);
|
||||
|
||||
return compiled_regex;
|
||||
}
|
||||
|
||||
Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer & server, const std::string & config_prefix)
|
||||
{
|
||||
Poco::Util::AbstractConfiguration & configuration = server.config();
|
||||
@ -860,7 +859,7 @@ Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer &
|
||||
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;
|
||||
std::unordered_map<String, CompiledRegexPtr> headers_name_with_regex;
|
||||
Poco::Util::AbstractConfiguration::Keys headers_name;
|
||||
configuration.keys(config_prefix + ".headers", headers_name);
|
||||
|
||||
@ -872,8 +871,9 @@ Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer &
|
||||
continue;
|
||||
|
||||
expression = expression.substr(6);
|
||||
if (capturingNamedQueryParam(analyze_receive_params, expression))
|
||||
headers_name_with_regex.emplace(std::make_pair(header_name, expression));
|
||||
auto regex = getCompiledRegex(expression);
|
||||
if (capturingNamedQueryParam(analyze_receive_params, regex))
|
||||
headers_name_with_regex.emplace(std::make_pair(header_name, regex));
|
||||
}
|
||||
|
||||
if (configuration.has(config_prefix + ".url"))
|
||||
@ -883,14 +883,15 @@ Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer &
|
||||
if (startsWith(url_expression, "regex:"))
|
||||
url_expression = url_expression.substr(6);
|
||||
|
||||
if (capturingNamedQueryParam(analyze_receive_params, url_expression))
|
||||
auto regex = getCompiledRegex(url_expression);
|
||||
if (capturingNamedQueryParam(analyze_receive_params, regex))
|
||||
return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<PredefinedQueryHandler>(
|
||||
server, std::move(analyze_receive_params), std::move(predefined_query), std::optional<String>(url_expression),
|
||||
server, std::move(analyze_receive_params), std::move(predefined_query), std::move(regex),
|
||||
std::move(headers_name_with_regex)), configuration, config_prefix);
|
||||
}
|
||||
|
||||
return addFiltersFromConfig(new HandlingRuleHTTPHandlerFactory<PredefinedQueryHandler>(
|
||||
server, std::move(analyze_receive_params), std::move(predefined_query), std::optional<String>{} ,std::move(headers_name_with_regex)),
|
||||
server, std::move(analyze_receive_params), std::move(predefined_query), CompiledRegexPtr{} ,std::move(headers_name_with_regex)),
|
||||
configuration, config_prefix);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,12 @@
|
||||
#include <Common/CurrentMetrics.h>
|
||||
#include <Common/HTMLForm.h>
|
||||
|
||||
#include <re2/re2.h>
|
||||
#if USE_RE2_ST
|
||||
#include <re2_st/re2.h>
|
||||
#else
|
||||
#define re2_st re2
|
||||
#endif
|
||||
|
||||
namespace CurrentMetrics
|
||||
{
|
||||
@ -20,6 +26,7 @@ namespace DB
|
||||
|
||||
class WriteBufferFromHTTPServerResponse;
|
||||
|
||||
typedef std::shared_ptr<const re2_st::RE2> CompiledRegexPtr;
|
||||
|
||||
class HTTPHandler : public Poco::Net::HTTPRequestHandler
|
||||
{
|
||||
@ -101,12 +108,12 @@ class PredefinedQueryHandler : public HTTPHandler
|
||||
private:
|
||||
NameSet receive_params;
|
||||
std::string predefined_query;
|
||||
std::optional<String> url_regex;
|
||||
std::unordered_map<String, String> header_name_with_capture_regex;
|
||||
CompiledRegexPtr url_regex;
|
||||
std::unordered_map<String, CompiledRegexPtr> header_name_with_capture_regex;
|
||||
public:
|
||||
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_);
|
||||
, const CompiledRegexPtr & url_regex_, const std::unordered_map<String, CompiledRegexPtr> & header_name_with_regex_);
|
||||
|
||||
virtual void customizeContext(Poco::Net::HTTPServerRequest & request, Context & context) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user