2017-08-09 14:33:07 +00:00
|
|
|
#pragma once
|
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
#include "IServer.h"
|
|
|
|
#include <common/logger_useful.h>
|
2020-04-21 11:30:45 +00:00
|
|
|
#include <Common/HTMLForm.h>
|
2020-04-04 08:57:16 +00:00
|
|
|
#include <Common/StringUtils/StringUtils.h>
|
2017-08-09 14:33:07 +00:00
|
|
|
#include <Poco/Net/HTTPServerRequest.h>
|
|
|
|
#include <Poco/Net/HTTPServerResponse.h>
|
2020-04-03 09:09:19 +00:00
|
|
|
#include <Poco/Net/HTTPRequestHandlerFactory.h>
|
2020-04-21 11:30:45 +00:00
|
|
|
#include <Interpreters/AsynchronousMetrics.h>
|
2017-08-09 14:33:07 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
/// Handle request using child handlers
|
2020-04-27 20:51:39 +00:00
|
|
|
class HTTPRequestHandlerFactoryMain : public Poco::Net::HTTPRequestHandlerFactory, boost::noncopyable
|
2017-08-09 14:33:07 +00:00
|
|
|
{
|
2019-11-24 15:43:53 +00:00
|
|
|
private:
|
2020-04-04 08:57:16 +00:00
|
|
|
using TThis = HTTPRequestHandlerFactoryMain;
|
|
|
|
|
2020-05-30 21:57:37 +00:00
|
|
|
Poco::Logger * log;
|
2020-04-03 09:09:19 +00:00
|
|
|
std::string name;
|
2019-11-24 15:43:53 +00:00
|
|
|
|
2020-04-21 11:30:45 +00:00
|
|
|
std::vector<Poco::Net::HTTPRequestHandlerFactory *> child_factories;
|
2020-04-04 08:57:16 +00:00
|
|
|
public:
|
|
|
|
|
2020-05-09 22:59:34 +00:00
|
|
|
~HTTPRequestHandlerFactoryMain() override;
|
2019-11-24 15:43:53 +00:00
|
|
|
|
2020-04-20 04:49:17 +00:00
|
|
|
HTTPRequestHandlerFactoryMain(const std::string & name_);
|
2020-04-04 08:57:16 +00:00
|
|
|
|
|
|
|
TThis * addHandler(Poco::Net::HTTPRequestHandlerFactory * child_factory);
|
|
|
|
|
|
|
|
Poco::Net::HTTPRequestHandler * createRequestHandler(const Poco::Net::HTTPServerRequest & request) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename TEndpoint>
|
2020-04-27 20:51:39 +00:00
|
|
|
class HandlingRuleHTTPHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
|
2019-11-24 15:43:53 +00:00
|
|
|
{
|
|
|
|
public:
|
2020-04-27 20:51:39 +00:00
|
|
|
using TThis = HandlingRuleHTTPHandlerFactory<TEndpoint>;
|
2020-04-04 08:57:16 +00:00
|
|
|
using Filter = std::function<bool(const Poco::Net::HTTPServerRequest &)>;
|
2017-08-09 14:33:07 +00:00
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
template <typename... TArgs>
|
2020-04-27 20:51:39 +00:00
|
|
|
HandlingRuleHTTPHandlerFactory(TArgs &&... args)
|
2020-04-04 08:57:16 +00:00
|
|
|
{
|
|
|
|
creator = [args = std::tuple<TArgs...>(std::forward<TArgs>(args) ...)]()
|
|
|
|
{
|
|
|
|
return std::apply([&](auto && ... endpoint_args)
|
|
|
|
{
|
|
|
|
return new TEndpoint(std::forward<decltype(endpoint_args)>(endpoint_args)...);
|
|
|
|
}, std::move(args));
|
|
|
|
};
|
|
|
|
}
|
2019-11-24 15:43:53 +00:00
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
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);
|
|
|
|
};
|
2019-11-24 15:43:53 +00:00
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
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); });
|
|
|
|
}
|
2019-11-24 15:43:53 +00:00
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
/// 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<Poco::Net::HTTPRequestHandler * ()> creator;
|
2019-11-24 15:43:53 +00:00
|
|
|
};
|
|
|
|
|
2020-04-04 08:57:16 +00:00
|
|
|
Poco::Net::HTTPRequestHandlerFactory * createStaticHandlerFactory(IServer & server, const std::string & config_prefix);
|
|
|
|
|
|
|
|
Poco::Net::HTTPRequestHandlerFactory * createDynamicHandlerFactory(IServer & server, const std::string & config_prefix);
|
|
|
|
|
2020-04-27 20:51:39 +00:00
|
|
|
Poco::Net::HTTPRequestHandlerFactory * createPredefinedHandlerFactory(IServer & server, const std::string & config_prefix);
|
2020-04-04 08:57:16 +00:00
|
|
|
|
2020-04-21 11:30:45 +00:00
|
|
|
Poco::Net::HTTPRequestHandlerFactory * createHandlerFactory(IServer & server, AsynchronousMetrics & async_metrics, const std::string & name);
|
|
|
|
|
2017-08-09 14:33:07 +00:00
|
|
|
}
|