]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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> | |
11fdf7f2 TL |
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 { | |
f67539c2 | 55 | continue_ = 100, //!< continue |
20effc67 | 56 | switching_protocols = 101, //!< switching_protocols |
11fdf7f2 TL |
57 | ok = 200, //!< ok |
58 | created = 201, //!< created | |
59 | accepted = 202, //!< accepted | |
20effc67 | 60 | nonauthoritative_information = 203, //!< nonauthoritative_information |
11fdf7f2 | 61 | no_content = 204, //!< no_content |
20effc67 | 62 | reset_content = 205, //!< reset_content |
11fdf7f2 TL |
63 | multiple_choices = 300, //!< multiple_choices |
64 | moved_permanently = 301, //!< moved_permanently | |
65 | moved_temporarily = 302, //!< moved_temporarily | |
20effc67 | 66 | see_other = 303, //!< see_other |
11fdf7f2 | 67 | not_modified = 304, //!< not_modified |
20effc67 TL |
68 | use_proxy = 305, //!< use_proxy |
69 | temporary_redirect = 307, //!< temporary_redirect | |
11fdf7f2 TL |
70 | bad_request = 400, //!< bad_request |
71 | unauthorized = 401, //!< unauthorized | |
20effc67 | 72 | payment_required = 402, //!< payment_required |
11fdf7f2 TL |
73 | forbidden = 403, //!< forbidden |
74 | not_found = 404, //!< not_found | |
20effc67 TL |
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 | |
9f95a23c TL |
80 | length_required = 411, //!< length_required |
81 | payload_too_large = 413, //!< payload_too_large | |
20effc67 TL |
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 | |
11fdf7f2 TL |
88 | internal_server_error = 500, //!< internal_server_error |
89 | not_implemented = 501, //!< not_implemented | |
90 | bad_gateway = 502, //!< bad_gateway | |
20effc67 TL |
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 | |
11fdf7f2 TL |
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 | } |