Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
ConnectionHandler.hpp
1#pragma once
2
3#include "util/StopHelper.hpp"
4#include "util/StringHash.hpp"
5#include "util/Taggable.hpp"
6#include "util/log/Logger.hpp"
7#include "util/prometheus/Gauge.hpp"
8#include "util/prometheus/Label.hpp"
9#include "util/prometheus/Prometheus.hpp"
10#include "web/ProxyIpResolver.hpp"
11#include "web/SubscriptionContextInterface.hpp"
12#include "web/ng/Connection.hpp"
13#include "web/ng/Error.hpp"
14#include "web/ng/MessageHandler.hpp"
15#include "web/ng/ProcessingPolicy.hpp"
16#include "web/ng/Request.hpp"
17#include "web/ng/Response.hpp"
18
19#include <boost/asio/spawn.hpp>
20#include <boost/signals2/signal.hpp>
21#include <boost/signals2/variadic_signal.hpp>
22
23#include <atomic>
24#include <chrono>
25#include <cstddef>
26#include <functional>
27#include <memory>
28#include <optional>
29#include <string>
30#include <unordered_map>
31
32namespace web::ng::impl {
33
34class ConnectionHandler {
35public:
36 using OnDisconnectHook = std::function<void(Connection const&)>;
37 using OnIpChangeHook = std::function<void(std::string const&, std::string const&)>;
38 using TargetToHandlerMap =
39 std::unordered_map<std::string, MessageHandler, util::StringHash, std::equal_to<>>;
40
41private:
42 util::Logger log_{"WebServer"};
43 util::Logger perfLog_{"Performance"};
44
45 ProcessingPolicy processingPolicy_;
46 std::optional<size_t> maxParallelRequests_;
47
48 std::reference_wrapper<util::TagDecoratorFactory> tagFactory_;
49
50 ProxyIpResolver proxyIpResolver_;
51
52 OnDisconnectHook onDisconnectHook_;
53 OnIpChangeHook onIpChangeHook_;
54
55 TargetToHandlerMap getHandlers_;
56 TargetToHandlerMap postHandlers_;
57 std::optional<MessageHandler> wsHandler_;
58
59 boost::signals2::signal<void()> onStop_;
60 std::unique_ptr<std::atomic_bool> stopping_ = std::make_unique<std::atomic_bool>(false);
61
62 std::reference_wrapper<util::prometheus::GaugeInt> connectionsCounter_ =
64 "connections_total_number",
65 util::prometheus::Labels{{{"status", "connected"}}}
66 );
67
68 util::StopHelper stopHelper_;
69
70public:
71 ConnectionHandler(
72 ProcessingPolicy processingPolicy,
73 std::optional<size_t> maxParallelRequests,
74 util::TagDecoratorFactory& tagFactory,
75 ProxyIpResolver proxyIpResolver,
76 OnDisconnectHook onDisconnectHook,
77 OnIpChangeHook onIpChangeHook
78 );
79
80 ConnectionHandler(ConnectionHandler&&) = delete;
81
82 static constexpr std::chrono::milliseconds kCloseConnectionTimeout{500};
83
84 void
85 onGet(std::string const& target, MessageHandler handler);
86
87 void
88 onPost(std::string const& target, MessageHandler handler);
89
90 void
91 onWs(MessageHandler handler);
92
93 void
94 processConnection(ConnectionPtr connection, boost::asio::yield_context yield);
95
96 static void
97 stopConnection(Connection& connection, boost::asio::yield_context yield);
98
99 void
100 stop(boost::asio::yield_context yield);
101
102 [[nodiscard]] bool
103 isStopping() const;
104
105private:
113 [[nodiscard]] bool
114 handleError(Error const& error, Connection const& connection) const;
115
123 bool
124 sequentRequestResponseLoop(
125 Connection& connection,
126 SubscriptionContextPtr& subscriptionContext,
127 boost::asio::yield_context yield
128 );
129
130 bool
131 parallelRequestResponseLoop(
132 Connection& connection,
133 SubscriptionContextPtr& subscriptionContext,
134 boost::asio::yield_context yield
135 );
136
137 std::optional<bool>
138 processRequest(
139 Connection& connection,
140 SubscriptionContextPtr& subscriptionContext,
141 Request const& request,
142 boost::asio::yield_context yield
143 );
144
146 handleRequest(
147 ConnectionMetadata& connectionMetadata,
148 SubscriptionContextPtr& subscriptionContext,
149 Request const& request,
150 boost::asio::yield_context yield
151 );
152
153 void
154 resolveClientIp(Connection& connection, Request const& request) const;
155};
156
157} // namespace web::ng::impl
static util::prometheus::GaugeInt & gaugeInt(std::string name, util::prometheus::Labels labels, std::optional< std::string > description=std::nullopt)
Get an integer based gauge metric. It will be created if it doesn't exist.
Definition Prometheus.cpp:231
A simple thread-safe logger for the channel specified in the constructor.
Definition Logger.hpp:78
Helper class to stop a class asynchronously.
Definition StopHelper.hpp:15
A factory for TagDecorator instantiation.
Definition Taggable.hpp:165
Class representing a collection of Prometheus labels.
Definition Label.hpp:41
Resolves the client's IP address, considering proxy servers.
Definition ProxyIpResolver.hpp:25
An interface for a connection metadata class.
Definition Connection.hpp:25
A class representing a connection to a client.
Definition Connection.hpp:114
Represents an HTTP or WebSocket request.
Definition Request.hpp:18
Represents an HTTP or Websocket response.
Definition Response.hpp:21
std::shared_ptr< SubscriptionContextInterface > SubscriptionContextPtr
An alias for shared pointer to a SubscriptionContextInterface.
Definition SubscriptionContextInterface.hpp:64