]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/opentelemetry-cpp/ext/include/opentelemetry/ext/http/server/file_http_server.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / ext / include / opentelemetry / ext / http / server / file_http_server.h
CommitLineData
1e59de90
TL
1// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include <fstream>
7#include <iostream>
8#include <string>
9#include <unordered_map>
10#include <vector>
11
12#include "opentelemetry/ext/http/server/http_server.h"
13
14namespace HTTP_SERVER_NS
15{
16
17class FileHttpServer : public HTTP_SERVER_NS::HttpServer
18{
19protected:
20 /**
21 * Construct the server by initializing the endpoint for serving static files,
22 * which show up on the web if the user is on the given host:port. Static
23 * files can be seen relative to the folder where the executable was ran.
24 */
25 FileHttpServer(const std::string &host = "127.0.0.1", int port = 3333) : HttpServer()
26 {
27 std::ostringstream os;
28 os << host << ":" << port;
29 setServerName(os.str());
30 addListeningPort(port);
31 };
32
33 /**
34 * Set the HTTP server to serve static files from the root of host:port.
35 * Derived HTTP servers should initialize the file endpoint AFTER they
36 * initialize their own, otherwise everything will be served like a file
37 * @param server should be an instance of this object
38 */
39 void InitializeFileEndpoint(FileHttpServer &server) { server[root_endpt_] = ServeFile; }
40
41private:
42 /**
43 * Return whether a file is found whose location is searched for relative to
44 * where the executable was triggered. If the file is valid, fill result with
45 * the file data/information required to display it on a webpage
46 * @param name of the file to look for,
47 * @param resulting file information, necessary for displaying them on a
48 * webpage
49 * @returns whether a file was found and result filled with display
50 * information
51 */
52 bool FileGetSuccess(const std::string &filename, std::vector<char> &result)
53 {
54#ifdef _WIN32
55 std::replace(filename.begin(), filename.end(), '/', '\\');
56#endif
57 std::streampos size;
58 std::ifstream file(filename, std::ios::in | std::ios::binary | std::ios::ate);
59 if (file.is_open())
60 {
61 size = file.tellg();
62 if (size)
63 {
64 result.resize(size);
65 file.seekg(0, std::ios::beg);
66 file.read(result.data(), size);
67 }
68 file.close();
69 return true;
70 }
71 return false;
72 };
73
74 /**
75 * Returns the extension of a file
76 * @param name of the file
77 * @returns file extension type under HTTP protocol
78 */
79 std::string GetMimeContentType(const std::string &filename)
80 {
81 std::string file_ext = filename.substr(filename.find_last_of(".") + 1);
82 auto file_type = mime_types_.find(file_ext);
83 return (file_type != mime_types_.end()) ? file_type->second : HTTP_SERVER_NS::CONTENT_TYPE_TEXT;
84 };
85
86 /**
87 * Returns the standardized name of a file by removing backslashes, and
88 * assuming index.html is the wanted file if a directory is given
89 * @param name of the file
90 */
91 std::string GetFileName(std::string name)
92 {
93 if (name.back() == '/')
94 {
95 auto temp = name.substr(0, name.size() - 1);
96 name = temp;
97 }
98 // If filename appears to be a directory, serve the hypothetical index.html
99 // file there
100 if (name.find(".") == std::string::npos)
101 name += "/index.html";
102
103 return name;
104 }
105
106 /**
107 * Sets the response object with the correct file data based on the requested
108 * file address, or return 404 error if a file isn't found
109 * @param req is the HTTP request, which we use to figure out the response to
110 * send
111 * @param resp is the HTTP response we want to send to the frontend, including
112 * file data
113 */
114 HTTP_SERVER_NS::HttpRequestCallback ServeFile{
115 [&](HTTP_SERVER_NS::HttpRequest const &req, HTTP_SERVER_NS::HttpResponse &resp) {
116 LOG_INFO("File: %s\n", req.uri.c_str());
117 auto f = GetFileName(req.uri);
118 auto filename = f.c_str() + 1;
119
120 std::vector<char> content;
121 if (FileGetSuccess(filename, content))
122 {
123 resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = GetMimeContentType(filename);
124 resp.body = std::string(content.data(), content.size());
125 resp.code = 200;
126 resp.message = HTTP_SERVER_NS::HttpServer::getDefaultResponseMessage(resp.code);
127 return resp.code;
128 }
129 // Two additional 'special' return codes possible here:
130 // 0 - proceed to next handler
131 // -1 - immediately terminate and close connection
132 resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = HTTP_SERVER_NS::CONTENT_TYPE_TEXT;
133 resp.code = 404;
134 resp.message = HTTP_SERVER_NS::HttpServer::getDefaultResponseMessage(resp.code);
135 resp.body = resp.message;
136 return 404;
137 }};
138
139 // Maps file extensions to their HTTP-compatible mime file type
140 const std::unordered_map<std::string, std::string> mime_types_ = {
141 {"css", "text/css"}, {"png", "image/png"}, {"js", "text/javascript"},
142 {"htm", "text/html"}, {"html", "text/html"}, {"json", "application/json"},
143 {"txt", "text/plain"}, {"jpg", "image/jpeg"}, {"jpeg", "image/jpeg"},
144 };
145 const std::string root_endpt_ = "/";
146};
147
148} // namespace HTTP_SERVER_NS