Seastar
High performance C++ framework for concurrent servers
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
request.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//
23// request.hpp
24// ~~~~~~~~~~~
25//
26// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
27//
28// Distributed under the Boost Software License, Version 1.0. (See accompanying
29// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
30//
31#pragma once
32
33#include <seastar/core/iostream.hh>
34#include <seastar/core/sstring.hh>
35#include <strings.h>
36#include <seastar/http/common.hh>
37#include <seastar/http/mime_types.hh>
38#include <seastar/net/socket_defs.hh>
39#include <seastar/core/iostream.hh>
40#include <seastar/util/string_utils.hh>
41#include <seastar/util/iostream.hh>
42
43namespace seastar {
44
45namespace http {
46
47namespace experimental { class connection; }
48
52struct request {
53 enum class ctclass
54 : char {
55 other, multipart, app_x_www_urlencoded,
56 };
57
58 socket_address _client_address;
59 socket_address _server_address;
60 sstring _method;
61 sstring _url;
62 sstring _version;
63 ctclass content_type_class;
64 size_t content_length = 0;
65 mutable size_t _bytes_written = 0;
66 std::unordered_map<sstring, sstring, seastar::internal::case_insensitive_hash, seastar::internal::case_insensitive_cmp> _headers;
67 std::unordered_map<sstring, sstring> query_parameters;
69 sstring content; // server-side deprecated: use content_stream instead
70 /*
71 * The handler should read the contents of this stream till reaching eof (i.e., the end of this request's content). Failing to do so
72 * will force the server to close this connection, and the client will not be able to reuse this connection for the next request.
73 * The stream should not be closed by the handler, the server will close it for the handler.
74 * */
75 input_stream<char>* content_stream;
76 std::unordered_map<sstring, sstring> trailing_headers;
77 std::unordered_map<sstring, sstring> chunk_extensions;
78 sstring protocol_name = "http";
79 noncopyable_function<future<>(output_stream<char>&&)> body_writer; // for client
80
86 return _client_address;
87 }
88
94 return _server_address;
95 }
96
102 sstring get_header(const sstring& name) const {
103 auto res = _headers.find(name);
104 if (res == _headers.end()) {
105 return "";
106 }
107 return res->second;
108 }
109
115 sstring get_query_param(const sstring& key) const {
116 auto res = query_parameters.find(key);
117 if (res == query_parameters.end()) {
118 return "";
119 }
120 return res->second;
121 }
122
129 sstring get_path_param(const sstring& key) const {
130 return param.get_decoded_param(key);
131 }
132
136 sstring get_protocol_name() const {
137 return protocol_name;
138 }
139
144 sstring get_url() const {
145 return get_protocol_name() + "://" + get_header("Host") + _url;
146 }
147
148 bool is_multi_part() const {
149 return content_type_class == ctclass::multipart;
150 }
151
152 bool is_form_post() const {
153 return content_type_class == ctclass::app_x_www_urlencoded;
154 }
155
156 bool should_keep_alive() const {
157 if (_version == "0.9") {
158 return false;
159 }
160
161 // TODO: handle HTTP/2.0 when it releases
162
163 auto it = _headers.find("Connection");
164 if (_version == "1.0") {
165 return it != _headers.end()
166 && seastar::internal::case_insensitive_cmp()(it->second, "keep-alive");
167 } else { // HTTP/1.1
168 return it == _headers.end() || !seastar::internal::case_insensitive_cmp()(it->second, "close");
169 }
170 }
171
179
184 sstring format_url() const;
185
191 void set_mime_type(const sstring& mime) {
192 _headers["Content-Type"] = mime;
193 }
194
199 void set_content_type(const sstring& content_type = "html") {
200 set_mime_type(http::mime_types::extension_to_type(content_type));
201 }
202
214 void write_body(const sstring& content_type, sstring content);
215
233 void write_body(const sstring& content_type, noncopyable_function<future<>(output_stream<char>&&)>&& body_writer);
234
241 template <typename W>
242 requires std::is_invocable_r_v<future<>, W, output_stream<char>&>
243 void write_body(const sstring& content_type, W&& body_writer) {
244 write_body(content_type, [body_writer = std::move(body_writer)] (output_stream<char>&& out) mutable -> future<> {
245 return util::write_to_stream_and_close(std::move(out), std::move(body_writer));
246 });
247 }
248
271 void write_body(const sstring& content_type, size_t len, noncopyable_function<future<>(output_stream<char>&&)>&& body_writer);
272
279 template <typename W>
280 requires std::is_invocable_r_v<future<>, W, output_stream<char>&>
281 void write_body(const sstring& content_type, size_t len, W&& body_writer) {
282 write_body(content_type, len, [body_writer = std::move(body_writer)] (output_stream<char>&& out) mutable -> future<> {
283 return util::write_to_stream_and_close(std::move(out), std::move(body_writer));
284 });
285 }
286
295
304 static request make(sstring method, sstring host, sstring path);
305
314 static request make(httpd::operation_type type, sstring host, sstring path);
315
316private:
317 void add_query_param(std::string_view param);
318 sstring request_line() const;
319 future<> write_request_headers(output_stream<char>& out) const;
320 friend class experimental::connection;
321};
322
323} // namespace httpd
324
325namespace httpd {
326using request [[deprecated("Use http::request instead")]] = http::request;
327}
328
329}
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
Class connection represents an HTTP connection over a given transport.
Definition: client.hh:68
Definition: common.hh:48
Definition: socket_defs.hh:47
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: noncopyable_function.hh:37
Definition: request.hh:52
sstring format_url() const
sstring get_path_param(const sstring &key) const
Definition: request.hh:129
sstring get_header(const sstring &name) const
Definition: request.hh:102
void write_body(const sstring &content_type, size_t len, noncopyable_function< future<>(output_stream< char > &&)> &&body_writer)
Use an output stream to write the message body.
void set_mime_type(const sstring &mime)
Definition: request.hh:191
void write_body(const sstring &content_type, W &&body_writer)
use and output stream to write the message body
Definition: request.hh:243
void write_body(const sstring &content_type, size_t len, W &&body_writer)
use and output stream to write the message body
Definition: request.hh:281
const socket_address & get_client_address() const
Definition: request.hh:85
void set_content_type(const sstring &content_type="html")
Definition: request.hh:199
void write_body(const sstring &content_type, sstring content)
Write a string as the body.
static request make(sstring method, sstring host, sstring path)
Make simple request.
void set_expects_continue()
Make request send Expect header.
static request make(httpd::operation_type type, sstring host, sstring path)
Make simple request.
void write_body(const sstring &content_type, noncopyable_function< future<>(output_stream< char > &&)> &&body_writer)
Use an output stream to write the message body.
sstring get_url() const
Definition: request.hh:144
const socket_address & get_server_address() const
Definition: request.hh:93
sstring get_query_param(const sstring &key) const
Definition: request.hh:115
sstring get_protocol_name() const
Definition: request.hh:136