2020-10-20 00:28:33 +00:00
|
|
|
#include "WebUIRequestHandler.h"
|
|
|
|
#include "IServer.h"
|
2023-10-28 05:15:49 +00:00
|
|
|
#include <Server/HTTP/WriteBufferFromHTTPServerResponse.h>
|
2020-10-20 00:28:33 +00:00
|
|
|
|
|
|
|
#include <Poco/Net/HTTPServerResponse.h>
|
|
|
|
#include <Poco/Util/LayeredConfiguration.h>
|
|
|
|
|
2023-12-05 12:34:37 +00:00
|
|
|
#include <Interpreters/Context.h>
|
2020-10-20 00:28:33 +00:00
|
|
|
#include <IO/HTTPCommon.h>
|
|
|
|
|
2023-09-14 16:12:29 +00:00
|
|
|
#ifdef __clang__
|
|
|
|
# pragma clang diagnostic push
|
|
|
|
# pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
|
|
|
#endif
|
2022-08-22 19:55:41 +00:00
|
|
|
#include <re2/re2.h>
|
2023-09-14 16:12:29 +00:00
|
|
|
#ifdef __clang__
|
|
|
|
# pragma clang diagnostic pop
|
|
|
|
#endif
|
2022-08-22 19:55:41 +00:00
|
|
|
|
2023-07-23 02:56:47 +00:00
|
|
|
#include <incbin.h>
|
|
|
|
|
2023-07-23 22:03:40 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2023-07-23 02:56:47 +00:00
|
|
|
/// Embedded HTML pages
|
2023-07-23 22:03:40 +00:00
|
|
|
INCBIN(resource_play_html, SOURCE_DIR "/programs/server/play.html");
|
|
|
|
INCBIN(resource_dashboard_html, SOURCE_DIR "/programs/server/dashboard.html");
|
|
|
|
INCBIN(resource_uplot_js, SOURCE_DIR "/programs/server/js/uplot.js");
|
2023-12-24 11:14:45 +00:00
|
|
|
INCBIN(resource_binary_html, SOURCE_DIR "/programs/server/binary.html");
|
2023-07-23 02:56:47 +00:00
|
|
|
|
2020-10-20 00:28:33 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2022-08-21 10:11:25 +00:00
|
|
|
WebUIRequestHandler::WebUIRequestHandler(IServer & server_)
|
|
|
|
: server(server_)
|
2020-10-20 00:28:33 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-12-15 19:17:42 +00:00
|
|
|
void WebUIRequestHandler::handleRequest(HTTPServerRequest & request, HTTPServerResponse & response, const ProfileEvents::Event & /*write_event*/)
|
2020-10-20 00:28:33 +00:00
|
|
|
{
|
2023-12-05 12:34:37 +00:00
|
|
|
auto keep_alive_timeout = server.context()->getServerSettings().keep_alive_timeout.totalSeconds();
|
2020-10-20 00:28:33 +00:00
|
|
|
|
|
|
|
response.setContentType("text/html; charset=UTF-8");
|
|
|
|
|
2021-02-19 12:51:26 +00:00
|
|
|
if (request.getVersion() == HTTPServerRequest::HTTP_1_1)
|
2020-10-20 00:28:33 +00:00
|
|
|
response.setChunkedTransferEncoding(true);
|
|
|
|
|
|
|
|
setResponseDefaultHeaders(response, keep_alive_timeout);
|
2022-08-21 10:11:25 +00:00
|
|
|
|
|
|
|
if (request.getURI().starts_with("/play"))
|
|
|
|
{
|
|
|
|
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
|
2023-10-28 05:15:49 +00:00
|
|
|
WriteBufferFromHTTPServerResponse(response, request.getMethod() == HTTPRequest::HTTP_HEAD, keep_alive_timeout).write(reinterpret_cast<const char *>(gresource_play_htmlData), gresource_play_htmlSize);
|
2022-08-21 10:11:25 +00:00
|
|
|
}
|
|
|
|
else if (request.getURI().starts_with("/dashboard"))
|
|
|
|
{
|
|
|
|
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
|
|
|
|
|
2023-07-23 02:56:47 +00:00
|
|
|
std::string html(reinterpret_cast<const char *>(gresource_dashboard_htmlData), gresource_dashboard_htmlSize);
|
2022-08-21 10:11:25 +00:00
|
|
|
|
|
|
|
/// Replace a link to external JavaScript file to embedded file.
|
|
|
|
/// This allows to open the HTML without running a server and to host it on server.
|
|
|
|
/// Note: we can embed the JavaScript file inline to the HTML,
|
|
|
|
/// but we don't do it to keep the "view-source" perfectly readable.
|
|
|
|
|
|
|
|
static re2::RE2 uplot_url = R"(https://[^\s"'`]+u[Pp]lot[^\s"'`]*\.js)";
|
|
|
|
RE2::Replace(&html, uplot_url, "/js/uplot.js");
|
|
|
|
|
2023-10-28 05:15:49 +00:00
|
|
|
WriteBufferFromHTTPServerResponse(response, request.getMethod() == HTTPRequest::HTTP_HEAD, keep_alive_timeout).write(html);
|
2022-08-21 10:11:25 +00:00
|
|
|
}
|
2023-12-24 11:14:45 +00:00
|
|
|
else if (request.getURI().starts_with("/binary"))
|
|
|
|
{
|
|
|
|
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
|
|
|
|
*response.send() << std::string_view(reinterpret_cast<const char *>(gresource_binary_htmlData), gresource_binary_htmlSize);
|
|
|
|
}
|
2022-08-21 10:11:25 +00:00
|
|
|
else if (request.getURI() == "/js/uplot.js")
|
|
|
|
{
|
|
|
|
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
|
2023-10-28 05:15:49 +00:00
|
|
|
WriteBufferFromHTTPServerResponse(response, request.getMethod() == HTTPRequest::HTTP_HEAD, keep_alive_timeout).write(reinterpret_cast<const char *>(gresource_uplot_jsData), gresource_uplot_jsSize);
|
2022-08-21 10:11:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_NOT_FOUND);
|
2023-10-27 02:38:36 +00:00
|
|
|
response.send()->writeln("Not found.");
|
2022-08-21 10:11:25 +00:00
|
|
|
}
|
2020-10-20 00:28:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|