#pragma once #include "IServer.h" #include #include #include #include #include #include #include namespace DB { /// Handle request using child handlers class HTTPRequestHandlerFactoryMain : public Poco::Net::HTTPRequestHandlerFactory { private: using TThis = HTTPRequestHandlerFactoryMain; Logger * log; std::string name; std::vector child_factories; public: ~HTTPRequestHandlerFactoryMain(); HTTPRequestHandlerFactoryMain(const std::string & name_); TThis * addHandler(Poco::Net::HTTPRequestHandlerFactory * child_factory); Poco::Net::HTTPRequestHandler * createRequestHandler(const Poco::Net::HTTPServerRequest & request) override; }; template class RoutingRuleHTTPHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory { public: using TThis = RoutingRuleHTTPHandlerFactory; using Filter = std::function; template RoutingRuleHTTPHandlerFactory(TArgs &&... args) { creator = [args = std::tuple(std::forward(args) ...)]() { return std::apply([&](auto && ... endpoint_args) { return new TEndpoint(std::forward(endpoint_args)...); }, std::move(args)); }; } TThis * addFilter(Filter cur_filter) { Filter prev_filter = filter; filter = [prev_filter, cur_filter](const auto & request) { return prev_filter ? prev_filter(request) && cur_filter(request) : cur_filter(request); }; return this; } TThis * attachStrictPath(const String & strict_path) { return addFilter([strict_path](const auto & request) { return request.getURI() == strict_path; }); } TThis * attachNonStrictPath(const String & non_strict_path) { return addFilter([non_strict_path](const auto & request) { return startsWith(request.getURI(), non_strict_path); }); } /// Handle GET or HEAD endpoint on specified path TThis * allowGetAndHeadRequest() { return addFilter([](const auto & request) { return request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET || request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD; }); } /// Handle POST or GET with params TThis * allowPostAndGetParamsRequest() { return addFilter([](const auto & request) { return request.getURI().find('?') != std::string::npos || request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST; }); } Poco::Net::HTTPRequestHandler * createRequestHandler(const Poco::Net::HTTPServerRequest & request) override { return filter(request) ? creator() : nullptr; } private: Filter filter; std::function creator; }; Poco::Net::HTTPRequestHandlerFactory * createStaticHandlerFactory(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 * createHandlerFactory(IServer & server, AsynchronousMetrics & async_metrics, const std::string & name); }