Seastar
High performance C++ framework for concurrent servers
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
client.hh
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * 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/*
19 * Copyright (C) 2022 Scylladb, Ltd.
20 */
21
22#pragma once
23
24#ifndef SEASTAR_MODULE
25#include <boost/intrusive/list.hpp>
26#endif
27#include <seastar/net/api.hh>
28#include <seastar/http/connection_factory.hh>
29#include <seastar/http/reply.hh>
30#include <seastar/core/condition-variable.hh>
31#include <seastar/core/iostream.hh>
32#include <seastar/util/modules.hh>
33
34namespace bi = boost::intrusive;
35
36namespace seastar {
37
38SEASTAR_MODULE_EXPORT_BEGIN
39
40namespace tls { class certificate_credentials; }
41
42namespace http {
43
44namespace experimental { class client; }
45struct request;
46struct reply;
47
48namespace internal {
49
52public:
55 client_ref(client_ref&& o) noexcept : _c(std::exchange(o._c, nullptr)) {}
56 client_ref(const client_ref&) = delete;
57};
58
59}
60
61namespace experimental {
62
69class connection : public enable_shared_from_this<connection> {
70 friend class client;
71 using hook_t = bi::list_member_hook<bi::link_mode<bi::auto_unlink>>;
72 using reply_ptr = std::unique_ptr<reply>;
73
75 input_stream<char> _read_buf;
76 output_stream<char> _write_buf;
77 hook_t _hook;
78 future<> _closed;
80 // Client sends HTTP-1.1 version and assumes the server is 1.1-compatible
81 // too and thus the connection will be persistent by default. If the server
82 // responds with older version, this flag will be dropped (see recv_reply())
83 bool _persistent = true;
84
85public:
93
110
120
128
129private:
130 future<reply_ptr> do_make_request(request& rq);
131 void setup_request(request& rq);
132 future<> send_request_head(const request& rq);
133 future<reply_ptr> maybe_wait_for_continue(const request& req);
134 future<> write_body(const request& rq);
135 future<reply_ptr> recv_reply();
136
137 void shutdown() noexcept;
138};
139
151class client {
152public:
155
156private:
157 friend class http::internal::client_ref;
158 using connections_list_t = bi::list<connection, bi::member_hook<connection, typename connection::hook_t, &connection::_hook>, bi::constant_time_size<false>>;
159 static constexpr unsigned default_max_connections = 100;
160
161 std::unique_ptr<connection_factory> _new_connections;
162 unsigned _nr_connections = 0;
163 unsigned _max_connections;
164 unsigned long _total_new_connections = 0;
165 const retry_requests _retry;
166 condition_variable _wait_con;
167 connections_list_t _pool;
168
170
171 future<connection_ptr> get_connection(abort_source* as);
172 future<connection_ptr> make_connection(abort_source* as);
173 future<> put_connection(connection_ptr con);
174 future<> shrink_connections();
175
176 template <std::invocable<connection&> Fn>
177 auto with_connection(Fn&& fn, abort_source*);
178
179 template <typename Fn>
180 requires std::invocable<Fn, connection&>
181 auto with_new_connection(Fn&& fn, abort_source*);
182
183 future<> do_make_request(connection& con, request& req, reply_handler& handle, abort_source*, std::optional<reply::status_type> expected);
184
185public:
195 explicit client(socket_address addr);
196
209
248 explicit client(std::unique_ptr<connection_factory> f, unsigned max_connections = default_max_connections, retry_requests retry = retry_requests::no);
249
267 future<> make_request(request&& req, reply_handler&& handle, std::optional<reply::status_type>&& expected = std::nullopt, abort_source* as = nullptr);
268
276 future<> make_request(request& req, reply_handler& handle, std::optional<reply::status_type> expected = std::nullopt, abort_source* as = nullptr);
277
287
294
299 unsigned connections_nr() const noexcept {
300 return _nr_connections;
301 }
302
307 unsigned idle_connections_nr() const noexcept {
308 return _pool.size();
309 }
310
318 unsigned long total_new_connections_nr() const noexcept {
319 return _total_new_connections;
320 }
321};
322
323} // experimental namespace
324
325} // http namespace
326
327SEASTAR_MODULE_EXPORT_END
328} // seastar namespace
Definition: abort_source.hh:59
Type-safe boolean.
Definition: bool_class.hh:58
Conditional variable.
Definition: condition-variable.hh:73
Definition: api.hh:183
Definition: shared_ptr.hh:493
A representation of a possibly not-yet-computed value.
Definition: future.hh:1197
Class client wraps communications using HTTP protocol.
Definition: client.hh:151
client(std::unique_ptr< connection_factory > f, unsigned max_connections=default_max_connections, retry_requests retry=retry_requests::no)
Construct a client with connection factory.
unsigned idle_connections_nr() const noexcept
Returns the number of idle connections.
Definition: client.hh:307
unsigned long total_new_connections_nr() const noexcept
Returns the total number of connection factory invocations made so far.
Definition: client.hh:318
unsigned connections_nr() const noexcept
Returns the total number of connections.
Definition: client.hh:299
future make_request(request &&req, reply_handler &&handle, std::optional< reply::status_type > &&expected=std::nullopt, abort_source *as=nullptr)
Send the request and handle the response.
future close()
Closes the client.
future set_maximum_connections(unsigned nr)
Updates the maximum number of connections a client may have.
client(socket_address addr, shared_ptr< tls::certificate_credentials > creds, sstring host={})
Construct a secure client.
future make_request(request &req, reply_handler &handle, std::optional< reply::status_type > expected=std::nullopt, abort_source *as=nullptr)
Send the request and handle the response (abortable), same as make_request()
client(socket_address addr)
Construct a simple client.
Class connection represents an HTTP connection over a given transport.
Definition: client.hh:69
input_stream< char > in(reply &rep)
Get a reference on the connection input stream.
future close()
Closes the connection.
connection(connected_socket &&fd, internal::client_ref cr)
Create an http connection.
future< reply > make_request(request rq)
Send the request and wait for response.
Definition: client.hh:50
Definition: shared_ptr.hh:507
Definition: socket_defs.hh:47
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: noncopyable_function.hh:37
Definition: reply.hh:61
Definition: request.hh:52