68 const std::shared_ptr<log::Logger>& logger = {});
70 virtual ~DhtProxyServer();
72 DhtProxyServer(
const DhtProxyServer& other) =
delete;
73 DhtProxyServer(DhtProxyServer&& other) =
delete;
74 DhtProxyServer& operator=(
const DhtProxyServer& other) =
delete;
75 DhtProxyServer& operator=(DhtProxyServer&& other) =
delete;
77 asio::io_context& io_context()
const;
81 using clock = std::chrono::steady_clock;
82 using time_point = clock::time_point;
85 using sys_clock = std::chrono::system_clock;
86 using sys_time_point = sys_clock::time_point;
90 uint64_t highPriorityCount {0};
91 uint64_t normalPriorityCount {0};
93 void increment(
bool highPriority)
98 normalPriorityCount++;
101 Json::Value toJson()
const
104 val[
"highPriorityCount"] =
static_cast<Json::UInt64
>(highPriorityCount);
105 val[
"normalPriorityCount"] =
static_cast<Json::UInt64
>(normalPriorityCount);
109 std::string toString()
const
111 return fmt::format(
"{} high priority, {} normal priority", highPriorityCount, normalPriorityCount);
141 std::string toString()
const;
149 std::shared_ptr<ServerStats> stats()
const {
return stats_; }
151 std::shared_ptr<ServerStats> updateStats(std::shared_ptr<NodeInfo> info)
const;
153 std::shared_ptr<DhtRunner> getNode()
const {
return dht_; }
156 class ConnectionListener;
157 struct RestRouterTraitsTls;
158 struct RestRouterTraits;
160 template<
typename HttpResponse>
161 static HttpResponse initHttpResponse(HttpResponse response);
162 static restinio::request_handling_status_t serverError(restinio::request_t& request);
164 template<
typename ServerSettings>
165 void addServerSettings(ServerSettings& serverSettings,
const unsigned int max_pipelined_requests = 16);
167 std::unique_ptr<RestRouter> createRestRouter();
169 void onConnectionClosed(restinio::connection_id_t);
178 RequestStatus getNodeInfo(restinio::request_handle_t request, restinio::router::route_params_t params)
const;
186 RequestStatus getStats(restinio::request_handle_t request, restinio::router::route_params_t params);
198 RequestStatus get(restinio::request_handle_t request, restinio::router::route_params_t params);
210 RequestStatus listen(restinio::request_handle_t request, restinio::router::route_params_t params);
221 RequestStatus put(restinio::request_handle_t request, restinio::router::route_params_t params);
223 void handleCancelPermamentPut(
const asio::error_code& ec,
const InfoHash& key, Value::Id vid);
225#ifdef OPENDHT_PROXY_SERVER_IDENTITY
235 RequestStatus putSigned(restinio::request_handle_t request, restinio::router::route_params_t params)
const;
246 RequestStatus putEncrypted(restinio::request_handle_t request, restinio::router::route_params_t params);
260 RequestStatus getFiltered(restinio::request_handle_t request, restinio::router::route_params_t params);
269 RequestStatus options(restinio::request_handle_t request, restinio::router::route_params_t params);
271 struct PushSessionContext
274 std::string sessionId;
275 PushSessionContext(
const std::string&
id)
280#ifdef OPENDHT_PUSH_NOTIFICATIONS
281 PushType getTypeFromString(
const std::string& type);
282 std::string getDefaultTopic(PushType type);
284 RequestStatus pingPush(restinio::request_handle_t request, restinio::router::route_params_t );
294 RequestStatus subscribe(restinio::request_handle_t request, restinio::router::route_params_t params);
303 RequestStatus unsubscribe(restinio::request_handle_t request, restinio::router::route_params_t params);
310 void sendPushNotification(
311 const std::string& key, Json::Value&& json, PushType type,
bool highPriority,
const std::string& topic);
321 void handleNotifyPushListenExpire(
const asio::error_code& ec,
322 const std::string pushToken,
323 std::function<Json::Value()> json,
325 const std::string& topic);
334 void handleCancelPushListen(
const asio::error_code& ec,
335 const std::string pushToken,
337 const std::string clientId);
352 bool handlePushListen(
const InfoHash& infoHash,
353 const std::string& pushToken,
355 const std::string& clientId,
356 const std::shared_ptr<DhtProxyServer::PushSessionContext>& sessionCtx,
357 const std::string& topic,
358 const std::vector<std::shared_ptr<Value>>& values,
363 void handlePrintStats(
const asio::error_code& ec);
366 template<
typename Os>
367 void saveState(Os& stream);
369 template<
typename Is>
370 void loadState(Is& is,
size_t size);
372 std::shared_ptr<asio::io_context> ioContext_;
373 std::shared_ptr<DhtRunner> dht_;
374 Json::StreamWriterBuilder jsonBuilder_;
375 Json::CharReaderBuilder jsonReaderBuilder_;
376 std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
378 std::string persistPath_;
381 std::thread serverThread_;
382 std::unique_ptr<restinio::http_server_t<RestRouterTraitsTls>> httpsServer_;
383 std::unique_ptr<restinio::http_server_t<RestRouterTraits>> httpServer_;
386 std::pair<std::string, std::string> pushHostPort_;
388 mutable std::mutex requestLock_;
389 std::map<
unsigned int , std::shared_ptr<http::Request>> requests_;
391 std::shared_ptr<log::Logger> logger_;
393 std::shared_ptr<ServerStats> stats_;
394 std::shared_ptr<NodeInfo> nodeInfo_ {};
395 std::unique_ptr<asio::steady_timer> printStatsTimer_;
396 const time_point serverStartTime_;
397 mutable std::mutex pushStatsMutex_;
398 PushStats androidPush_;
400 PushStats unifiedPush_;
403 std::mutex lockListener_;
405 std::map<restinio::connection_id_t, http::ListenerSession> listeners_;
407 std::shared_ptr<ConnectionListener> connListener_;
410 sys_time_point expiration;
411 std::string pushToken;
412 std::string clientId;
413 std::shared_ptr<PushSessionContext> sessionCtx;
414 std::unique_ptr<asio::system_timer> expireTimer;
415 std::unique_ptr<asio::system_timer> expireNotifyTimer;
420 template<
typename Packer>
421 void msgpack_pack(Packer& p)
const
423 p.pack_map(2 + (sessionCtx ? 1 : 0) + (clientId.empty() ? 0 : 1) + (type == PushType::None ? 0 : 2)
424 + (topic.empty() ? 0 : 1));
428 p.pack(sys_clock::to_time_t(expiration));
429 if (not clientId.empty()) {
434 std::lock_guard l(sessionCtx->lock);
436 p.pack(sessionCtx->sessionId);
438 if (type != PushType::None) {
444 if (not topic.empty()) {
450 void msgpack_unpack(
const msgpack::object& o);
454 std::map<dht::Value::Id, PermanentPut> puts;
455 MSGPACK_DEFINE_ARRAY(puts)
457 std::mutex lockSearchPuts_;
458 std::map<InfoHash, SearchPuts> puts_;
460 mutable std::atomic<size_t> requestNum_ {0};
461 mutable std::atomic<time_point> lastStatsReset_ {time_point::min()};
463 std::string pushServer_;
464 std::string bundleId_;
466#ifdef OPENDHT_PUSH_NOTIFICATIONS
469 sys_time_point expiration;
470 std::string clientId;
471 std::shared_ptr<PushSessionContext> sessionCtx;
472 std::future<size_t> internalToken;
473 std::unique_ptr<asio::system_timer> expireTimer;
474 std::unique_ptr<asio::system_timer> expireNotifyTimer;
478 template<
typename Packer>
479 void msgpack_pack(Packer& p)
const
481 p.pack_map(3 + (sessionCtx ? 1 : 0) + (topic.empty() ? 0 : 1));
485 p.pack(sys_clock::to_time_t(expiration));
487 std::lock_guard l(sessionCtx->lock);
489 p.pack(sessionCtx->sessionId);
493 if (!topic.empty()) {
499 void msgpack_unpack(
const msgpack::object& o);
503 std::map<InfoHash, std::vector<Listener>> listeners;
504 MSGPACK_DEFINE_ARRAY(listeners)
506 std::map<std::string, PushListener> pushListeners_;