/Users/deen/code/yugabyte-db/src/yb/server/webserver.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
33 | | // you may not use this file except in compliance with the License. |
34 | | // You may obtain a copy of the License at |
35 | | // |
36 | | // http://www.apache.org/licenses/LICENSE-2.0 |
37 | | // |
38 | | // Unless required by applicable law or agreed to in writing, software |
39 | | // distributed under the License is distributed on an "AS IS" BASIS, |
40 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
41 | | // See the License for the specific language governing permissions and |
42 | | // limitations under the License. |
43 | | #ifndef YB_SERVER_WEBSERVER_H |
44 | | #define YB_SERVER_WEBSERVER_H |
45 | | |
46 | | #include <map> |
47 | | #include <shared_mutex> |
48 | | #include <string> |
49 | | #include <vector> |
50 | | |
51 | | #include "yb/server/webserver_options.h" |
52 | | |
53 | | #include "yb/util/status_fwd.h" |
54 | | #include "yb/util/net/net_fwd.h" |
55 | | #include "yb/util/web_callback_registry.h" |
56 | | |
57 | | struct sq_connection; |
58 | | struct sq_request_info; |
59 | | struct sq_context; |
60 | | |
61 | | namespace yb { |
62 | | |
63 | | // Wrapper class for the Squeasel web server library. Clients may register callback |
64 | | // methods which produce output for a given URL path |
65 | | class Webserver : public WebCallbackRegistry { |
66 | | public: |
67 | | // Using this constructor, the webserver will bind to all available |
68 | | // interfaces. The server_name is used for display purposes. |
69 | | explicit Webserver(const WebserverOptions& opts, const std::string& server_name); |
70 | | |
71 | | ~Webserver(); |
72 | | |
73 | | // Starts a webserver on the port passed to the constructor. The webserver runs in a |
74 | | // separate thread, so this call is non-blocking. |
75 | | CHECKED_STATUS Start(); |
76 | | |
77 | | // Stops the webserver synchronously. |
78 | | void Stop(); |
79 | | |
80 | | // Return the addresses that this server has successfully |
81 | | // bound to. Requires that the server has been Start()ed. |
82 | | CHECKED_STATUS GetBoundAddresses(std::vector<Endpoint>* addrs) const; |
83 | | |
84 | | // Return the single HostPort that this server was asked to bind on |
85 | | CHECKED_STATUS GetInputHostPort(HostPort* hp) const; |
86 | | |
87 | | virtual void RegisterPathHandler(const std::string& path, const std::string& alias, |
88 | | const PathHandlerCallback& callback, |
89 | | bool is_styled = true, |
90 | | bool is_on_nav_bar = true, |
91 | | const std::string icon = "") override; |
92 | | |
93 | | // Change the footer HTML to be displayed at the bottom of all styled web pages. |
94 | | void set_footer_html(const std::string& html); |
95 | | |
96 | | // True if serving all traffic over SSL, false otherwise |
97 | | bool IsSecure() const; |
98 | | |
99 | | private: |
100 | | // Container class for a list of path handler callbacks for a single URL. |
101 | | class PathHandler { |
102 | | public: |
103 | | PathHandler(bool is_styled, bool is_on_nav_bar, std::string alias, const std::string icon) |
104 | | : is_styled_(is_styled), |
105 | | is_on_nav_bar_(is_on_nav_bar), |
106 | | alias_(std::move(alias)), |
107 | 1.00M | icon_(icon) {} |
108 | | |
109 | 1.02M | void AddCallback(const PathHandlerCallback& callback) { |
110 | 1.02M | callbacks_.push_back(callback); |
111 | 1.02M | } |
112 | | |
113 | 18.2k | bool is_styled() const { return is_styled_; } |
114 | 2.42k | bool is_on_nav_bar() const { return is_on_nav_bar_; } |
115 | 241 | const std::string& alias() const { return alias_; } |
116 | 241 | const std::string& icon() const { return icon_; } |
117 | 18.2k | const std::vector<PathHandlerCallback>& callbacks() const { return callbacks_; } |
118 | | |
119 | | private: |
120 | | // If true, the page appears is rendered styled. |
121 | | bool is_styled_; |
122 | | |
123 | | // If true, the page appears in the navigation bar. |
124 | | bool is_on_nav_bar_; |
125 | | |
126 | | // Alias used when displaying this link on the nav bar. |
127 | | std::string alias_; |
128 | | |
129 | | // Icon used when displaying this link on the nav bar. |
130 | | std::string icon_; |
131 | | |
132 | | // List of callbacks to render output for this page, called in order. |
133 | | std::vector<PathHandlerCallback> callbacks_; |
134 | | }; |
135 | | |
136 | | bool static_pages_available() const; |
137 | | |
138 | | // Build the string to pass to mongoose specifying where to bind. |
139 | | CHECKED_STATUS BuildListenSpec(std::string* spec) const; |
140 | | |
141 | | // Renders a common Bootstrap-styled header |
142 | | void BootstrapPageHeader(std::stringstream* output); |
143 | | |
144 | | // Renders a common Bootstrap-styled footer. Must be used in conjunction with |
145 | | // BootstrapPageHeader. |
146 | | void BootstrapPageFooter(std::stringstream* output); |
147 | | |
148 | | static void EnterWorkerThreadCallbackStatic(); |
149 | | static void LeaveWorkerThreadCallbackStatic(); |
150 | | |
151 | | // Dispatch point for all incoming requests. |
152 | | // Static so that it can act as a function pointer, and then call the next method |
153 | | static int BeginRequestCallbackStatic(struct sq_connection* connection); |
154 | | int BeginRequestCallback(struct sq_connection* connection, |
155 | | struct sq_request_info* request_info); |
156 | | |
157 | | int RunPathHandler(const PathHandler& handler, |
158 | | struct sq_connection* connection, |
159 | | struct sq_request_info* request_info); |
160 | | |
161 | | // Callback to funnel mongoose logs through glog. |
162 | | static int LogMessageCallbackStatic(const struct sq_connection* connection, |
163 | | const char* message); |
164 | | |
165 | | // Registered to handle "/", and prints a list of available URIs |
166 | | void RootHandler(const WebRequest& args, Webserver::WebResponse* resp); |
167 | | |
168 | | // Builds a map of argument name to argument value from a typical URL argument |
169 | | // string (that is, "key1=value1&key2=value2.."). If no value is given for a |
170 | | // key, it is entered into the map as (key, ""). |
171 | | void BuildArgumentMap(const std::string& args, ArgumentMap* output); |
172 | | |
173 | | const WebserverOptions opts_; |
174 | | |
175 | | // Lock guarding the path_handlers_ map and footer_html. |
176 | | std::shared_timed_mutex lock_; |
177 | | |
178 | | // Map of path to a PathHandler containing a list of handlers for that |
179 | | // path. More than one handler may register itself with a path so that many |
180 | | // components may contribute to a single page. |
181 | | typedef std::map<std::string, PathHandler*> PathHandlerMap; |
182 | | PathHandlerMap path_handlers_; |
183 | | |
184 | | // Snippet of HTML which will be displayed in the footer of all pages |
185 | | // rendered by this server. Protected by 'lock_'. |
186 | | std::string footer_html_; |
187 | | |
188 | | // The address of the interface on which to run this webserver. |
189 | | std::string http_address_; |
190 | | |
191 | | // Handle to Mongoose context; owned and freed by Mongoose internally |
192 | | struct sq_context* context_; |
193 | | |
194 | | // Server name for display purposes |
195 | | std::string server_name_; |
196 | | |
197 | | // Mutex guarding against concurrenct calls to Stop(). |
198 | | std::mutex stop_mutex_; |
199 | | }; |
200 | | |
201 | | } // namespace yb |
202 | | |
203 | | #endif // YB_SERVER_WEBSERVER_H |