diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 99502261aa9..017bc82a475 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "common/logger_useful.h" #include #include #include @@ -111,10 +112,11 @@ namespace ErrorCodes namespace { - /// Process options request. Usefull for CORS. + /// Process options request. Useful for CORS. void processOptionsRequest(HTTPServerResponse & response, const Poco::Util::LayeredConfiguration & config) { - /// If answer for options request was not defined, return 501 to client. + /// If response for options request was not defined, return 501 to client. + /// TODO should it be here? if (!config.has("http_options_response")) { response.setStatusAndReason(HTTPResponse::HTTP_NOT_IMPLEMENTED); @@ -129,12 +131,17 @@ namespace { if (config_key == "header" || config_key.starts_with("header[")) { - response.add(config.getString("http_options_response." + config_key + ".name", "Empty header"), - config.getString("http_options_response." + config_key + ".value", "")); - response.setKeepAlive(false); + /// If there is empty header name, it will not be processed and message about it will be in logs + if (config.getString("http_options_response." + config_key + ".name", "").empty()) + LOG_WARNING(&Poco::Logger::get("processOptionsRequest"), "Empty header was found in config. It will not be processed."); + else + response.add(config.getString("http_options_response." + config_key + ".name", ""), + config.getString("http_options_response." + config_key + ".value", "")); + } } - response.setStatusAndReason(HTTPResponse::HTTP_NO_CONTENT); + response.setKeepAlive(false); + response.setStatusAndReason(HTTPResponse::HTTP_OK); response.send(); } } diff --git a/src/Server/HTTPHandlerFactory.cpp b/src/Server/HTTPHandlerFactory.cpp index 1e3d02b85ab..526b86a5c28 100644 --- a/src/Server/HTTPHandlerFactory.cpp +++ b/src/Server/HTTPHandlerFactory.cpp @@ -123,7 +123,7 @@ static inline HTTPRequestHandlerFactoryPtr createInterserverHTTPHandlerFactory(I addCommonDefaultHandlersFactory(*factory, server); auto main_handler = std::make_shared>(server); - main_handler->allowPostAndGetParamsRequest(); + main_handler->allowPostAndGetParamsAndOptionsRequest(); factory->addHandler(main_handler); return factory; @@ -180,7 +180,7 @@ void addDefaultHandlersFactory(HTTPRequestHandlerFactoryMain & factory, IServer addCommonDefaultHandlersFactory(factory, server); auto query_handler = std::make_shared>(server, "query"); - query_handler->allowPostAndGetParamsRequest(); + query_handler->allowPostAndGetParamsAndOptionsRequest(); factory.addHandler(query_handler); /// We check that prometheus handler will be served on current (default) port. diff --git a/src/Server/HTTPHandlerFactory.h b/src/Server/HTTPHandlerFactory.h index 6297f988eaa..5497d585d43 100644 --- a/src/Server/HTTPHandlerFactory.h +++ b/src/Server/HTTPHandlerFactory.h @@ -104,11 +104,13 @@ public: } /// Handle POST or GET with params - void allowPostAndGetParamsRequest() + void allowPostAndGetParamsAndOptionsRequest() { addFilter([](const auto & request) { - return request.getURI().find('?') != std::string::npos + return (request.getURI().find('?') != std::string::npos + && request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) + || request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS || request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST; }); }