aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Server/WebUIRequestHandler.cpp
blob: 131badbe83ace3852a781972b56071543139e23a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "WebUIRequestHandler.h"
#include "IServer.h"

#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Util/LayeredConfiguration.h>

#include <IO/HTTPCommon.h>

#include <re2/re2.h>

#include <incbin.h>

#include "clickhouse_config.h"

/// Embedded HTML pages
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");


namespace DB
{

WebUIRequestHandler::WebUIRequestHandler(IServer & server_)
    : server(server_)
{
}


void WebUIRequestHandler::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);

    if (request.getURI().starts_with("/play"))
    {
        response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
        *response.send() << std::string_view(reinterpret_cast<const char *>(gresource_play_htmlData), gresource_play_htmlSize);
    }
    else if (request.getURI().starts_with("/dashboard"))
    {
        response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);

        std::string html(reinterpret_cast<const char *>(gresource_dashboard_htmlData), gresource_dashboard_htmlSize);

        /// 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");

        *response.send() << html;
    }
    else if (request.getURI() == "/js/uplot.js")
    {
        response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
        *response.send() << std::string_view(reinterpret_cast<const char *>(gresource_uplot_jsData), gresource_uplot_jsSize);
    }
    else
    {
        response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_NOT_FOUND);
        *response.send() << "Not found.\n";
    }
}

}