87class OPENDHT_PUBLIC Connection :
public std::enable_shared_from_this<Connection>
90 Connection(asio::io_context& ctx,
const bool ssl =
true, std::shared_ptr<log::Logger> l = {});
91 Connection(asio::io_context& ctx, std::shared_ptr<dht::crypto::Certificate> server_ca,
92 const dht::crypto::Identity& identity, std::shared_ptr<log::Logger> l = {});
95 inline unsigned int id()
const {
return id_; };
98 void checkOcsp(
bool check =
true) { checkOcsp_ = check; }
100 void set_ssl_verification(
const std::string& hostname,
const asio::ssl::verify_mode verify_mode);
102 asio::streambuf& input();
103 std::istream& data() {
return istream_; }
105 std::string read_bytes(
size_t bytes = 0);
106 std::string read_until(
const char delim);
108 void async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, ConnectHandlerCb);
109 void async_handshake(HandlerCb cb);
110 void async_write(BytesHandlerCb cb);
111 void async_read_until(
const char* delim, BytesHandlerCb cb);
112 void async_read_until(
char delim, BytesHandlerCb cb);
113 void async_read(
size_t bytes, BytesHandlerCb cb);
114 void async_read_some(
size_t bytes, BytesHandlerCb cb);
116 void set_keepalive(uint32_t seconds);
118 const asio::ip::address& local_address()
const;
120 void timeout(
const std::chrono::seconds& timeout, HandlerCb cb = {});
127 T wrapCallback(T cb)
const {
128 return [t=shared_from_this(),cb=std::move(cb)](
auto ...params) {
133 mutable std::mutex mutex_;
136 static std::atomic_uint ids_;
138 asio::io_context& ctx_;
139 std::unique_ptr<socket_t> socket_;
140 std::shared_ptr<asio::ssl::context> ssl_ctx_;
141 std::unique_ptr<ssl_socket_t> ssl_socket_;
143 asio::ip::tcp::endpoint endpoint_;
145 asio::streambuf write_buf_;
146 asio::streambuf read_buf_;
147 std::istream istream_;
149 asio::ip::address local_address_;
151 std::unique_ptr<asio::steady_timer> timeout_timer_;
152 std::shared_ptr<log::Logger> logger_;
153 bool checkOcsp_ {
false};
159class OPENDHT_PUBLIC Resolver
162 using ResolverCb = std::function<void(
const asio::error_code& ec,
163 const std::vector<asio::ip::tcp::endpoint>& endpoints)>;
165 Resolver(asio::io_context& ctx,
const std::string& url, std::shared_ptr<log::Logger> logger = {});
166 Resolver(asio::io_context& ctx,
const std::string& host,
const std::string& service,
167 const bool ssl =
false, std::shared_ptr<log::Logger> logger = {});
170 Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints,
171 const bool ssl =
false, std::shared_ptr<log::Logger> logger = {});
172 Resolver(asio::io_context& ctx,
const std::string& url, std::vector<asio::ip::tcp::endpoint> endpoints,
173 std::shared_ptr<log::Logger> logger = {});
177 inline const Url& get_url()
const {
181 void add_callback(ResolverCb cb, sa_family_t family = AF_UNSPEC);
183 std::shared_ptr<log::Logger> getLogger()
const {
190 void resolve(
const std::string& host,
const std::string& service);
192 mutable std::mutex mutex_;
195 asio::error_code ec_;
196 asio::ip::tcp::resolver resolver_;
197 std::shared_ptr<bool> destroyed_;
198 std::vector<asio::ip::tcp::endpoint> endpoints_;
200 bool completed_ {
false};
201 std::queue<ResolverCb> cbs_;
203 std::shared_ptr<log::Logger> logger_;
217class OPENDHT_PUBLIC Request :
public std::enable_shared_from_this<Request>
227 using OnStatusCb = std::function<void(
unsigned status_code)>;
228 using OnDataCb = std::function<void(
const char* at,
size_t length)>;
229 using OnStateChangeCb = std::function<void(State state,
const Response& response)>;
230 using OnJsonCb = std::function<void(Json::Value value,
const Response& response)>;
231 using OnDoneCb = std::function<void(
const Response& response)>;
234 Request(asio::io_context& ctx,
const std::string& url,
const Json::Value& json, OnJsonCb jsoncb,
235 std::shared_ptr<log::Logger> logger = {});
236 Request(asio::io_context& ctx,
const std::string& url, OnJsonCb jsoncb,
237 std::shared_ptr<log::Logger> logger = {});
239 Request(asio::io_context& ctx,
const std::string& url, std::shared_ptr<log::Logger> logger = {});
240 Request(asio::io_context& ctx,
const std::string& host,
const std::string& service,
241 const bool ssl =
false, std::shared_ptr<log::Logger> logger = {});
242 Request(asio::io_context& ctx,
const std::string& url, OnDoneCb onDone, std::shared_ptr<log::Logger> logger = {});
245 Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, sa_family_t family = AF_UNSPEC);
246 Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver,
const std::string& target, sa_family_t family = AF_UNSPEC);
249 Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints,
250 const bool ssl =
false, std::shared_ptr<log::Logger> logger = {});
254 inline unsigned int id()
const {
return id_; };
255 void set_connection(std::shared_ptr<Connection> connection);
256 std::shared_ptr<Connection> get_connection()
const;
257 inline const Url& get_url()
const {
258 return resolver_->get_url();
261 void timeout(
const std::chrono::seconds& timeout, HandlerCb cb = {}) {
271 inline std::string& to_string() {
275 void set_certificate_authority(std::shared_ptr<dht::crypto::Certificate> certificate);
276 void set_identity(
const dht::crypto::Identity& identity);
277 void set_logger(std::shared_ptr<log::Logger> logger);
283 void set_method(restinio::http_method_id_t method);
284 void set_target(std::string target);
285 void set_header_field(restinio::http_field_t field, std::string value);
286 void set_connection_type(restinio::http_connection_header_t connection);
287 void set_body(std::string body);
288 void set_auth(
const std::string& username,
const std::string& password);
290 void add_on_status_callback(OnStatusCb cb);
291 void add_on_body_callback(OnDataCb cb);
292 void add_on_state_change_callback(OnStateChangeCb cb);
293 void add_on_done_callback(OnDoneCb cb);
304 void terminate(
const asio::error_code& ec);
307 using OnCompleteCb = std::function<void()>;
310 OnStatusCb on_status;
311 OnDataCb on_header_field;
312 OnDataCb on_header_value;
314 OnStateChangeCb on_state_change;
317 static std::string getRelativePath(
const Url& origin,
const std::string& path);
319 void notify_state_change(State state);
323 static std::string url_encode(std::string_view value);
325 void init_default_headers();
331 void connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb = {});
335 void handle_request(
const asio::error_code& ec);
336 void handle_response(
const asio::error_code& ec,
size_t bytes);
338 void onHeadersComplete();
339 void onBody(
const char* at,
size_t length);
342 mutable std::mutex mutex_;
344 std::shared_ptr<log::Logger> logger_;
346 restinio::http_request_header_t header_;
347 std::map<restinio::http_field_t, std::string> headers_;
348 restinio::http_connection_header_t connection_type_ {restinio::http_connection_header_t::close};
354 dht::crypto::Identity client_identity_;
355 std::shared_ptr<dht::crypto::Certificate> server_ca_;
356 std::string service_;
360 static std::atomic_uint ids_;
361 asio::io_context& ctx_;
362 sa_family_t family_ = AF_UNSPEC;
363 std::shared_ptr<Connection> conn_;
364 std::shared_ptr<Resolver> resolver_;
366 Response response_ {};
367 std::string request_;
368 std::atomic<bool> finishing_ {
false};
369 std::unique_ptr<llhttp_t> parser_;
370 std::unique_ptr<llhttp_settings_t> parser_s_;
373 std::shared_ptr<Request> next_;
374 std::weak_ptr<Request> prev_;
375 unsigned num_redirect {0};
376 bool follow_redirect {
true};
378 HandlerCb timeoutCb_ {};
379 std::chrono::seconds timeout_ {0};