Seastar
High performance C++ framework for concurrent servers
httpd.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 2015 Cloudius Systems
20 */
21
22#pragma once
23
24#ifndef SEASTAR_MODULE
25#include <limits>
26#include <cctype>
27#include <vector>
28#include <boost/intrusive/list.hpp>
29#endif
30#include <seastar/http/request_parser.hh>
31#include <seastar/http/request.hh>
32#include <seastar/core/seastar.hh>
33#include <seastar/core/sstring.hh>
34#include <seastar/core/app-template.hh>
35#include <seastar/core/circular_buffer.hh>
36#include <seastar/core/distributed.hh>
37#include <seastar/core/queue.hh>
38#include <seastar/core/gate.hh>
40#include <seastar/util/std-compat.hh>
41#include <seastar/util/modules.hh>
42#include <seastar/http/routes.hh>
43#include <seastar/net/tls.hh>
44#include <seastar/core/shared_ptr.hh>
45
46namespace seastar {
47
48namespace http {
49SEASTAR_MODULE_EXPORT
50struct reply;
51}
52
53namespace httpd {
54
55SEASTAR_MODULE_EXPORT
56class http_server;
57SEASTAR_MODULE_EXPORT
58class http_stats;
59
60using namespace std::chrono_literals;
61
62SEASTAR_MODULE_EXPORT_BEGIN
64 metrics::metric_groups _metric_groups;
65public:
66 http_stats(http_server& server, const sstring& name);
67};
68
69class connection : public boost::intrusive::list_base_hook<> {
70 http_server& _server;
72 input_stream<char> _read_buf;
73 output_stream<char> _write_buf;
74 socket_address _client_addr;
75 socket_address _server_addr;
76 static constexpr size_t limit = 4096;
78 http_request_parser _parser;
79 std::unique_ptr<http::request> _req;
80 std::unique_ptr<http::reply> _resp;
81 // null element marks eof
83 bool _done = false;
84 const bool _tls;
85public:
86 [[deprecated("use connection(http_server&, connected_socket&&, bool tls)")]]
87 connection(http_server& server, connected_socket&& fd, socket_address, bool tls)
88 : connection(server, std::move(fd), tls) {}
89 connection(http_server& server, connected_socket&& fd, bool tls)
90 : _server(server)
91 , _fd(std::move(fd))
92 , _read_buf(_fd.input())
93 , _write_buf(_fd.output())
94 , _client_addr(_fd.remote_address())
95 , _server_addr(_fd.local_address())
96 , _tls(tls) {
97 on_new_connection();
98 }
100 socket_address client_addr, socket_address server_addr, bool tls)
101 : _server(server)
102 , _fd(std::move(fd))
103 , _read_buf(_fd.input())
104 , _write_buf(_fd.output())
105 , _client_addr(std::move(client_addr))
106 , _server_addr(std::move(server_addr))
107 , _tls(tls) {
108 on_new_connection();
109 }
110 ~connection();
111 void on_new_connection();
112
113 future<> process();
114 void shutdown();
115 future<> read();
116 future<> read_one();
117 future<> respond();
118 future<> do_response_loop();
119
120 void set_headers(http::reply& resp);
121
122 future<> start_response();
123
124 future<bool> generate_reply(std::unique_ptr<http::request> req);
125 void generate_error_reply_and_close(std::unique_ptr<http::request> req, http::reply::status_type status, const sstring& msg);
126
127 future<> write_body();
128
129 output_stream<char>& out();
130};
131
133
135 std::vector<server_socket> _listeners;
136 http_stats _stats;
137 uint64_t _total_connections = 0;
138 uint64_t _current_connections = 0;
139 uint64_t _requests_served = 0;
140 uint64_t _read_errors = 0;
141 uint64_t _respond_errors = 0;
143 sstring _date = http_date();
144 timer<> _date_format_timer { [this] {_date = http_date();} };
145 size_t _content_length_limit = std::numeric_limits<size_t>::max();
146 bool _content_streaming = false;
147 gate _task_gate;
148public:
149 routes _routes;
152 explicit http_server(const sstring& name) : _stats(*this, name) {
153 _date_format_timer.arm_periodic(1s);
154 }
181 [[deprecated("use listen(socket_address addr, server_credentials_ptr credentials)")]]
183
184 size_t get_content_length_limit() const;
185
186 void set_content_length_limit(size_t limit);
187
188 bool get_content_streaming() const;
189
190 void set_content_streaming(bool b);
191
192 future<> listen(socket_address addr, server_credentials_ptr credentials);
193 future<> listen(socket_address addr, listen_options lo, server_credentials_ptr credentials);
194 future<> listen(socket_address addr, listen_options lo);
195 future<> listen(socket_address addr);
196 future<> stop();
197
198 future<> do_accepts(int which);
199 future<> do_accepts(int which, bool with_tls);
200
201 uint64_t total_connections() const;
202 uint64_t current_connections() const;
203 uint64_t requests_served() const;
204 uint64_t read_errors() const;
205 uint64_t reply_errors() const;
206 // Write the current date in the specific "preferred format" defined in
207 // RFC 7231, Section 7.1.1.1.
208 static sstring http_date();
209private:
210 future<> do_accept_one(int which, bool with_tls);
211 boost::intrusive::list<connection> _connections;
212 friend class seastar::httpd::connection;
213 friend class http_server_tester;
214};
215
217public:
218 static std::vector<server_socket>& listeners(http_server& server) {
219 return server._listeners;
220 }
221};
222
223/*
224 * A helper class to start, set and listen an http server
225 * typical use would be:
226 *
227 * auto server = new http_server_control();
228 * server->start().then([server] {
229 * server->set_routes(set_routes);
230 * }).then([server, port] {
231 * server->listen(port);
232 * }).then([port] {
233 * std::cout << "Seastar HTTP server listening on port " << port << " ...\n";
234 * });
235 */
237 std::unique_ptr<distributed<http_server>> _server_dist;
238private:
239 static sstring generate_server_name();
240public:
241 http_server_control() : _server_dist(new distributed<http_server>) {
242 }
243
244 future<> start(const sstring& name = generate_server_name());
245 future<> stop() noexcept;
246 future<> set_routes(std::function<void(routes& r)> fun);
247 future<> listen(socket_address addr);
251 distributed<http_server>& server();
252};
253SEASTAR_MODULE_EXPORT_END
254}
255
256}
Definition: api.hh:183
output_stream< char > output(size_t buffer_size=8192)
input_stream< char > input(connected_socket_input_stream_config csisc={})
socket_address local_address() const noexcept
Local address of the socket.
socket_address remote_address() const noexcept
Remote address of the socket.
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
Definition: gate.hh:61
Definition: httpd.hh:69
Definition: httpd.hh:236
Definition: httpd.hh:216
Definition: httpd.hh:134
void set_tls_credentials(server_credentials_ptr credentials)
set tls credentials for the server Setting the tls credentials will set the http-server to work in ht...
Definition: httpd.hh:63
Definition: routes.hh:81
holds the metric definition.
Definition: metrics_registration.hh:94
Definition: queue.hh:44
Definition: sharded.hh:177
Definition: socket_defs.hh:47
Definition: timer.hh:83
void arm_periodic(duration delta) noexcept
Definition: timer.hh:188
server_socket listen(socket_address sa)
holds the metric_groups definition needed by class that reports metrics
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: reply.hh:61
status_type
Definition: reply.hh:65
Definition: api.hh:392