diff --git a/outputfile b/outputfile new file mode 100644 index 00000000000..27c7df52583 --- /dev/null +++ b/outputfile @@ -0,0 +1,15 @@ +There is no handle /files + +Use / or /ping for health checks. +Or /replicas_status for more sophisticated health checks. + +Send queries from your program with POST method or GET /?query=... + +Use clickhouse-client: + +For interactive data analysis: + clickhouse-client + +For batch query processing: + clickhouse-client --query='SELECT 1' > result + clickhouse-client < query > result diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index fb5717ba33f..5fa56418d87 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -2488,6 +2488,23 @@ void Server::createServers( { const char * port_name; + /// File System + port_name = "file_system.port"; + createServer(config, listen_host, port_name, listen_try, start_servers, servers, [&](UInt16 port) -> ProtocolServerAdapter + { + Poco::Net::ServerSocket socket; + auto address = socketBindListen(config, socket, listen_host, port); + socket.setReceiveTimeout(settings.http_receive_timeout); + socket.setSendTimeout(settings.http_send_timeout); + + return ProtocolServerAdapter( + listen_host, + port_name, + "http://" + address.toString(), + std::make_unique( + httpContext(), createHandlerFactory(*this, config, async_metrics, "FilesHTTPHandler-factory"), server_pool, socket, http_params)); + }); + if (server_type.shouldStart(ServerType::Type::HTTP)) { /// HTTP diff --git a/programs/server/config.xml b/programs/server/config.xml index ee649f6d3ae..76acbb8d5a6 100644 --- a/programs/server/config.xml +++ b/programs/server/config.xml @@ -141,6 +141,15 @@ --> 8123 + + + 8124 + /etc/clickhouse-server/export + + + + + diff --git a/src/Server/CertificateReloader.h b/src/Server/CertificateReloader.h index 6523c3d981a..a6d68c9c816 100644 --- a/src/Server/CertificateReloader.h +++ b/src/Server/CertificateReloader.h @@ -49,7 +49,7 @@ public: /// Handle configuration reload void tryLoad(const Poco::Util::AbstractConfiguration & config); - /// Reload certificates + /// Callback for Let's Enrypt integration void reloadCertificates(); /// A callback for OpenSSL diff --git a/src/Server/FileRequestHandler.cpp b/src/Server/FileRequestHandler.cpp new file mode 100644 index 00000000000..42a08107c96 --- /dev/null +++ b/src/Server/FileRequestHandler.cpp @@ -0,0 +1,40 @@ +#include "FileRequestHandler.h" +#include "IServer.h" + +#include +#include +#include + +#include +#include + +#include + + +namespace DB +{ + +FileRequestHandler::FileRequestHandler(IServer & server_, const std::string & base_directory_path_) + : server(server_), base_directory_path(base_directory_path_) +{ +} + + +void FileRequestHandler::handleRequest(HTTPServerRequest & request, HTTPServerResponse & response) +{ + auto keep_alive_timeout = server.config().getUInt("keep_alive_timeout", 10); + + response.setContentType("text/html; charset=UTF-8"); + + if (request.getVersion() == HTTPServerRequest::HTTP_1_1) + response.setChunkedTransferEncoding(true); + + setResponseDefaultHeaders(response, keep_alive_timeout); + + + response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK); + *response.send() << getResource(base_directory_path + request.getURI()); + +} + +} diff --git a/src/Server/FileRequestHandler.h b/src/Server/FileRequestHandler.h new file mode 100644 index 00000000000..e7a6b5801d0 --- /dev/null +++ b/src/Server/FileRequestHandler.h @@ -0,0 +1,23 @@ +#pragma once + +#include + + +namespace DB +{ + +class IServer; + +/// Response with file to user. +class FileRequestHandler : public HTTPRequestHandler +{ +private: + IServer & server; + const std::string & base_directory_path; + +public: + FileRequestHandler(IServer & server_, const std::string & base_directory_path_); + void handleRequest(HTTPServerRequest & request, HTTPServerResponse & response) override; +}; + +} diff --git a/src/Server/HTTPHandlerFactory.cpp b/src/Server/HTTPHandlerFactory.cpp index fc31ad2874e..339691c7b65 100644 --- a/src/Server/HTTPHandlerFactory.cpp +++ b/src/Server/HTTPHandlerFactory.cpp @@ -10,6 +10,7 @@ #include "HTTPHandler.h" #include "StaticRequestHandler.h" #include "ReplicasStatusHandler.h" +#include "FileRequestHandler.h" #include "InterserverIOHTTPHandler.h" #include "WebUIRequestHandler.h" @@ -66,6 +67,11 @@ static void addDefaultHandlersFactory( IServer & server, const Poco::Util::AbstractConfiguration & config, AsynchronousMetrics & async_metrics); +static void addFileSystemHandlerFactory( + HTTPRequestHandlerFactoryMain & factory, + IServer & server, + const Poco::Util::AbstractConfiguration & config +); static auto createPingHandlerFactory(IServer & server) { @@ -192,6 +198,13 @@ static inline HTTPRequestHandlerFactoryPtr createInterserverHTTPHandlerFactory(I return factory; } +static inline HTTPRequestHandlerFactoryPtr createFileSystemHTTPHandlerFactory(IServer & server, const Poco::Util::AbstractConfiguration & config, const std::string & name) +{ + auto factory = std::make_shared(name); + addFileSystemHandlerFactory(*factory, server, config); + + return factory; +} HTTPRequestHandlerFactoryPtr createHandlerFactory(IServer & server, const Poco::Util::AbstractConfiguration & config, AsynchronousMetrics & async_metrics, const std::string & name) { @@ -255,6 +268,14 @@ void addCommonDefaultHandlersFactory(HTTPRequestHandlerFactoryMain & factory, IS factory.addHandler(js_handler); } +void addFileSystemHandlerFactory(HTTPRequestHandlerFactoryMain & factory, IServer & server, const Poco::Util::AbstractConfiguration & config) +{ + auto files_handler = std::make_shared>(server, config.getString("file_system.base_directory", "/")); + files_handler->attachNonStrictPath("/"); + files_handler->allowGetAndHeadRequest(); + factory.addHandler(files_handler); +} + void addDefaultHandlersFactory( HTTPRequestHandlerFactoryMain & factory, IServer & server,