2525
2626#include " types.h"
2727#include " utils/params_class.h"
28+ #include " web_server/utility.hpp"
2829
2930using namespace std ;
3031using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
@@ -37,7 +38,11 @@ extern ApiHandlerMap api_handlers; // defined in handlers.cpp
3738
3839static const auto TAG = u8" API服务" ;
3940
40- static bool authorize (const decltype (HttpServer::Request::header) &headers, const json &query_args,
41+ /* *
42+ * Do authorization (check access token),
43+ * should be called on incomming connection request (http server and websocket server)
44+ */
45+ static bool authorize (const SimpleWeb::CaseInsensitiveMultimap &headers, const json &query_args,
4146 const function<void (SimpleWeb::StatusCode)> on_failed = nullptr) {
4247 if (config.access_token .empty ()) {
4348 return true ;
@@ -90,7 +95,9 @@ void ApiServer::init() {
9095}
9196
9297void ApiServer::init_http () {
98+ // recreate http server instance
9399 http_server_ = make_shared<HttpServer>();
100+
94101 http_server_->default_resource [" GET" ]
95102 = http_server_->default_resource [" POST" ]
96103 = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
@@ -160,7 +167,7 @@ void ApiServer::init_http() {
160167 Log::d (TAG, u8" API 处理函数 " + handler_kv.first + u8" 开始处理请求" );
161168 ApiResult result;
162169 Params params (json_params);
163- handler_kv.second (params, result);
170+ handler_kv.second (params, result); // call the real handler
164171
165172 decltype (request->header ) headers{
166173 {" Content-Type" , " application/json; charset=UTF-8" }
@@ -173,6 +180,7 @@ void ApiServer::init_http() {
173180 };
174181 }
175182
183+ // data files handler
176184 const auto regex = " ^/(data/(?:bface|image|record|show)/.+)$" ;
177185 http_server_->resource [regex][" GET" ] = [](shared_ptr<HttpServer::Response> response,
178186 shared_ptr<HttpServer::Request> request) {
@@ -220,8 +228,13 @@ void ApiServer::init_http() {
220228 };
221229}
222230
223- template <typename Ws>
224- static void api_on_message (shared_ptr<typename Ws::Connection> connection, shared_ptr<typename Ws::Message> message) {
231+ /* *
232+ * \brief Common "on_message" callback for websocket server's api endpoint and reverse websocket api client.
233+ * \tparam WsT WsServer (websocket server /api/ endpoint) or WsClient (reverse websocket api client)
234+ */
235+ template <typename WsT>
236+ static void ws_api_on_message (shared_ptr<typename WsT::Connection> connection,
237+ shared_ptr<typename WsT::Message> message) {
225238 auto ws_message_str = message->string ();
226239 Log::d (TAG, u8" 收到 API 请求(WebSocket):" + ws_message_str);
227240
@@ -230,7 +243,7 @@ static void api_on_message(shared_ptr<typename Ws::Connection> connection, share
230243 auto send_result = [&]() {
231244 auto resp_body = result.json ().dump ();
232245 Log::d (TAG, u8" 响应数据已准备完毕:" + resp_body);
233- auto send_stream = make_shared<typename Ws ::SendStream>();
246+ auto send_stream = make_shared<typename WsT ::SendStream>();
234247 *send_stream << resp_body;
235248 connection->send (send_stream);
236249 Log::d (TAG, u8" 响应内容已发送" );
@@ -291,12 +304,18 @@ void ApiServer::init_ws() {
291304
292305 auto &api_endpoint = ws_server_->endpoint [" ^/api/?$" ];
293306 api_endpoint.on_open = on_open_callback;
294- api_endpoint.on_message = api_on_message <WsServer>;
307+ api_endpoint.on_message = ws_api_on_message <WsServer>;
295308
296309 auto &event_endpoint = ws_server_->endpoint [" ^/event/?$" ];
297310 event_endpoint.on_open = on_open_callback;
298311}
299312
313+ /* *
314+ * \brief Set some common headers like "User-Agent" and "Authorization"
315+ * for reverse websocket client (both api and event).
316+ * \tparam WsClientT WsClient or WssClient (WebSocket SSL)
317+ * \param client reference of the client instance
318+ */
300319template <typename WsClientT>
301320static void set_ws_reverse_client_headers (WsClientT &client) {
302321 client.config .header .emplace (" User-Agent" , CQAPP_USER_AGENT);
@@ -305,15 +324,22 @@ static void set_ws_reverse_client_headers(WsClientT &client) {
305324 }
306325}
307326
327+ /* *
328+ * \brief Create a reverse websocket api client instance.
329+ * \tparam WsClientT WsClient or WssClient (WebSocket SSL)
330+ * \param server_port_path destination to connect
331+ * \return the newly created client instance (as shared_ptr)
332+ */
308333template <typename WsClientT>
309- static shared_ptr<WsClientT> init_ws_reverse_api_client (const string &api_url ) {
310- auto client = make_shared<WsClientT>(api_url );
334+ static shared_ptr<WsClientT> init_ws_reverse_api_client (const string &server_port_path ) {
335+ auto client = make_shared<WsClientT>(server_port_path );
311336 set_ws_reverse_client_headers<WsClientT>(*client);
312- client->on_message = api_on_message <WsClientT>;
337+ client->on_message = ws_api_on_message <WsClientT>;
313338 return client;
314339}
315340
316341void ApiServer::init_ws_reverse () {
342+ // for api client, we create the instance at initialization stage
317343 try {
318344 if (boost::algorithm::starts_with (config.ws_reverse_api_url , " ws://" )) {
319345 ws_reverse_api_client_.ws = init_ws_reverse_api_client<WsClient>(
@@ -325,9 +351,11 @@ void ApiServer::init_ws_reverse() {
325351 ws_reverse_api_client_is_wss_ = true ;
326352 }
327353 } catch (...) {
354+ // in case "init_ws_reverse_api_client()" failed due to invalid "server_port_path"
328355 ws_reverse_api_client_is_wss_ = nullopt ;
329356 }
330357
358+ // for event client, we just calculate the "server_port_path"
331359 if (boost::algorithm::starts_with (config.ws_reverse_event_url , " ws://" )) {
332360 ws_reverse_event_server_port_path_ = config.ws_reverse_event_url .substr (strlen (" ws://" ));
333361 ws_reverse_event_client_is_wss_ = false ;
@@ -394,7 +422,7 @@ void ApiServer::start() {
394422 + ws_server_->config .address + " :" + to_string (ws_server_->config .port ));
395423 }
396424
397- if (config.use_ws_reverse /* use ws reverse */
425+ if (config.use_ws_reverse /* use reverse websocket */
398426 && ws_reverse_api_client_is_wss_.has_value () /* successfully initialized */ ) {
399427 ws_reverse_api_client_started_ = true ;
400428 ws_reverse_api_thread_ = thread ([&]() {
@@ -448,19 +476,19 @@ template <typename WsClientT>
448476static bool push_ws_reverse_event (const string &server_port_path, const json &payload) {
449477 auto succeeded = false ;
450478 try {
451- WsClientT client (server_port_path);
479+ WsClientT client (server_port_path); // this may fail due to invalid "server_port_path"
452480 set_ws_reverse_client_headers<WsClientT>(client);
453481 client.on_open = [&](shared_ptr<typename WsClientT::Connection> connection) {
454482 const auto send_stream = make_shared<typename WsClientT::SendStream>();
455483 *send_stream << payload.dump ();
456484 connection->send (send_stream);
457- connection->send_close (1000 );
485+ connection->send_close (1000 ); // close connection after sending the event
458486 succeeded = true ;
459487 };
460488 client.start ();
461489 } catch (...) {
462- // maybe "server_port_path" not valid,
463- // maybe connection failed,
490+ // maybe "server_port_path" is not valid
491+ // maybe connection is failed
464492 // maybe the end of world came
465493 }
466494 return succeeded;
@@ -478,10 +506,10 @@ void ApiServer::push_event(const json &payload) const {
478506 count++;
479507 }
480508 }
481- Log::d (TAG, u8" 已成功向 " + to_string (count) + u8" 个客户端推送事件 " );
509+ Log::d (TAG, u8" 已成功向 " + to_string (count) + u8" 个 WebSocket 客户端推送事件 " );
482510 }
483511
484- if (config.use_ws_reverse /* use ws reverse */
512+ if (config.use_ws_reverse /* use reverse websocket */
485513 && ws_reverse_event_client_is_wss_.has_value () /* successfully initialized */ ) {
486514 Log::d (TAG, u8" 开始通过 WebSocket 反向客户端上报事件" );
487515 bool succeeded;
0 commit comments