]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/http/reply.hh
import quincy beta 17.1.0
[ceph.git] / ceph / src / seastar / include / seastar / http / reply.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 // This file was modified from boost http example
23 //
24 // reply.hpp
25 // ~~~~~~~~~
26 //
27 // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
28 //
29 // Distributed under the Boost Software License, Version 1.0. (See accompanying
30 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
31 //
32 #pragma once
33
34 #include <seastar/core/sstring.hh>
35 #include <unordered_map>
36 #include <seastar/http/mime_types.hh>
37 #include <seastar/core/iostream.hh>
38 #include <seastar/util/noncopyable_function.hh>
39
40 namespace seastar {
41
42 namespace httpd {
43
44 class connection;
45 class routes;
46
47 /**
48 * A reply to be sent to a client.
49 */
50 struct reply {
51 /**
52 * The status of the reply.
53 */
54 enum class status_type {
55 continue_ = 100, //!< continue
56 switching_protocols = 101, //!< switching_protocols
57 ok = 200, //!< ok
58 created = 201, //!< created
59 accepted = 202, //!< accepted
60 nonauthoritative_information = 203, //!< nonauthoritative_information
61 no_content = 204, //!< no_content
62 reset_content = 205, //!< reset_content
63 multiple_choices = 300, //!< multiple_choices
64 moved_permanently = 301, //!< moved_permanently
65 moved_temporarily = 302, //!< moved_temporarily
66 see_other = 303, //!< see_other
67 not_modified = 304, //!< not_modified
68 use_proxy = 305, //!< use_proxy
69 temporary_redirect = 307, //!< temporary_redirect
70 bad_request = 400, //!< bad_request
71 unauthorized = 401, //!< unauthorized
72 payment_required = 402, //!< payment_required
73 forbidden = 403, //!< forbidden
74 not_found = 404, //!< not_found
75 method_not_allowed = 405, //!< method_not_allowed
76 not_acceptable = 406, //!< not_acceptable
77 request_timeout = 408, //!< request_timeout
78 conflict = 409, //!< conflict
79 gone = 410, //!< gone
80 length_required = 411, //!< length_required
81 payload_too_large = 413, //!< payload_too_large
82 uri_too_long = 414, //!< uri_too_long
83 unsupported_media_type = 415, //!< unsupported_media_type
84 expectation_failed = 417, //!< expectation_failed
85 unprocessable_entity = 422, //!< unprocessable_entity
86 upgrade_required = 426, //!< upgrade_required
87 too_many_requests = 429, //!< too_many_requests
88 internal_server_error = 500, //!< internal_server_error
89 not_implemented = 501, //!< not_implemented
90 bad_gateway = 502, //!< bad_gateway
91 service_unavailable = 503, //!< service_unavailable
92 gateway_timeout = 504, //!< gateway_timeout
93 http_version_not_supported = 505, //!< http_version_not_supported
94 insufficient_storage = 507 //!< insufficient_storage
95 } _status;
96
97 /**
98 * The headers to be included in the reply.
99 */
100 std::unordered_map<sstring, sstring> _headers;
101
102 sstring _version;
103 /**
104 * The content to be sent in the reply.
105 */
106 sstring _content;
107
108 sstring _response_line;
109 reply()
110 : _status(status_type::ok) {
111 }
112
113 reply& add_header(const sstring& h, const sstring& value) {
114 _headers[h] = value;
115 return *this;
116 }
117
118 reply& set_version(const sstring& version) {
119 _version = version;
120 return *this;
121 }
122
123 reply& set_status(status_type status, const sstring& content = "") {
124 _status = status;
125 if (content != "") {
126 _content = content;
127 }
128 return *this;
129 }
130
131 /**
132 * Set the content type mime type.
133 * Used when the mime type is known.
134 * For most cases, use the set_content_type
135 */
136 reply& set_mime_type(const sstring& mime) {
137 _headers["Content-Type"] = mime;
138 return *this;
139 }
140
141 /**
142 * Set the content type mime type according to the file extension
143 * that would have been used if it was a file: e.g. html, txt, json etc'
144 */
145 reply& set_content_type(const sstring& content_type = "html") {
146 set_mime_type(httpd::mime_types::extension_to_type(content_type));
147 return *this;
148 }
149
150 reply& done(const sstring& content_type) {
151 return set_content_type(content_type).done();
152 }
153 /**
154 * Done should be called before using the reply.
155 * It would set the response line
156 */
157 reply& done() {
158 _response_line = response_line();
159 return *this;
160 }
161 sstring response_line();
162
163 /*!
164 * \brief use an output stream to write the message body
165 *
166 * When a handler needs to use an output stream it should call this method
167 * with a function.
168 *
169 * \param content_type - is used to choose the content type of the body. Use the file extension
170 * you would have used for such a content, (i.e. "txt", "html", "json", etc')
171 * \param body_writer - a function that accept an output stream and use that stream to write the body.
172 * The function should take ownership of the stream while using it and must close the stream when it
173 * is done.
174 *
175 * Message would use chunked transfer encoding in the reply.
176 *
177 */
178
179 void write_body(const sstring& content_type, noncopyable_function<future<>(output_stream<char>&&)>&& body_writer);
180
181 /*!
182 * \brief Write a string as the reply
183 *
184 * \param content_type - is used to choose the content type of the body. Use the file extension
185 * you would have used for such a content, (i.e. "txt", "html", "json", etc')
186 * \param content - the message content.
187 * This would set the the content and content type of the message along
188 * with any additional information that is needed to send the message.
189 */
190 void write_body(const sstring& content_type, const sstring& content);
191
192 private:
193 future<> write_reply_to_connection(connection& con);
194 future<> write_reply_headers(connection& connection);
195
196 noncopyable_function<future<>(output_stream<char>&&)> _body_writer;
197 friend class routes;
198 friend class connection;
199 };
200
201 } // namespace httpd
202
203 }