Line data Source code
1 : // 2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com) 3 : // Copyright (c) 2024 Christian Mazakas 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 : // 8 : // Official repository: https://github.com/cppalliance/http_proto 9 : // 10 : 11 : #ifndef BOOST_HTTP_PROTO_RESPONSE_HPP 12 : #define BOOST_HTTP_PROTO_RESPONSE_HPP 13 : 14 : #include <boost/http_proto/detail/config.hpp> 15 : #include <boost/http_proto/message_base.hpp> 16 : #include <boost/http_proto/response_view.hpp> 17 : #include <boost/http_proto/status.hpp> 18 : 19 : namespace boost { 20 : namespace http_proto { 21 : 22 : /** Container for HTTP responses 23 : */ 24 : class BOOST_SYMBOL_VISIBLE 25 : response 26 : : public message_base 27 : { 28 : public: 29 : /** Constructor 30 : */ 31 : BOOST_HTTP_PROTO_DECL 32 : response() noexcept; 33 : 34 : /** Constructor 35 : */ 36 : BOOST_HTTP_PROTO_DECL 37 : explicit 38 : response( 39 : core::string_view s); 40 : 41 : /** Constructor 42 : 43 : Construct a response container which allocates 44 : `storage_size` bytes for storing the header. 45 : Attempting to grow the container beyond 46 : this amount will result in an exception. 47 : The storage is also used internally to store 48 : instances of an implementation-defined type. 49 : The requested number of bytes will be aligned 50 : accordingly (currently the alignment requirement is 4). 51 : 52 : <br/> 53 : 54 : This constructor is useful when an upper-bound size 55 : of the response is known ahead of time and we want 56 : to prevent reallocations. 57 : 58 : <br/> 59 : 60 : Passing an initial storage size of `0` does not 61 : throw and the maximum capacity is set to an 62 : implementation-defined limit observable via 63 : @ref max_capacity_in_bytes(). 64 : 65 : @param storage_size The initial and final size of 66 : the storage. 67 : 68 : @code 69 : boost::http_proto::response 70 : make_response(std::string_view server) 71 : { 72 : std::size_t size = 4096; 73 : // res.buffer() is now stable 74 : boost::http_proto::response res(size); 75 : BOOST_ASSERT( 76 : res.max_capacity_in_bytes(), 4096); 77 : 78 : // uses spare capacity so that reallocations 79 : // are avoided 80 : res.append( 81 : boost::http_proto::field::server, server); 82 : res.append( 83 : boost::http_proto::field::connection, "close"); 84 : return res; 85 : } 86 : @endcode 87 : */ 88 : BOOST_HTTP_PROTO_DECL 89 : explicit 90 : response( 91 : std::size_t storage_size); 92 : 93 : /** Constructor 94 : 95 : Construct a response container which allocates 96 : `storage_size` bytes for storing the header, with an 97 : upper limit of `max_storage_size`. Attempting to 98 : grow the container beyond its maximum will result in 99 : an exception. The storage is also used internally to 100 : store instances of an implementation-defined type. 101 : Both values will be aligned accordingly (currently 102 : the alignment requirement is 4). 103 : 104 : <br/> 105 : 106 : This constructor is useful when there's a best-fit 107 : guess for an initial header size but we still wish 108 : to permit reallocating and growing the container to 109 : some upper limit. 110 : 111 : <br/> 112 : 113 : Passing an initial size of `0` does not throw. 114 : 115 : @param storage_size The initial size of the storage. 116 : 117 : @param max_storage_size The maximum size of the 118 : allocated storage. Any operation that attempts to 119 : grow the container beyond this value throws 120 : `std::length_error`. 121 : 122 : @throws std::length_error Thrown if `size > max_size` 123 : 124 : @code 125 : boost::http_proto::response 126 : make_response(std::string_view host) 127 : { 128 : std::size_t size = 4096; 129 : boost::http_proto::response res(size, 2 * size); 130 : BOOST_ASSERT( 131 : res.max_capacity_in_bytes(), 2 * 4096); 132 : 133 : // uses spare capacity so that reallocations 134 : // are avoided 135 : res.append( 136 : boost::http_proto::field::host, host); 137 : res.append( 138 : boost::http_proto::field::connection, "close"); 139 : return res; 140 : } 141 : @endcode 142 : */ 143 : BOOST_HTTP_PROTO_DECL 144 : response( 145 : std::size_t storage_size, 146 : std::size_t max_storage_size); 147 : 148 : /** Constructor 149 : 150 : The moved-from object will be 151 : left in the default-constructed 152 : state. 153 : */ 154 : BOOST_HTTP_PROTO_DECL 155 : response(response&& other) noexcept; 156 : 157 : /** Constructor 158 : */ 159 : BOOST_HTTP_PROTO_DECL 160 : response(response const& other); 161 : 162 : /** Constructor 163 : */ 164 : BOOST_HTTP_PROTO_DECL 165 : response( 166 : response_view const& other); 167 : 168 : /** Assignment 169 : */ 170 : BOOST_HTTP_PROTO_DECL 171 : response& 172 : operator=( 173 : response&& other) noexcept; 174 : 175 : /** Assignment 176 : */ 177 : response& 178 3 : operator=( 179 : response const& other) 180 : { 181 3 : copy_impl(*other.ph_); 182 3 : return *this; 183 : } 184 : 185 : /** Assignment 186 : */ 187 : response& 188 1 : operator=( 189 : response_view const& other) 190 : { 191 1 : copy_impl(*other.ph_); 192 1 : return *this; 193 : } 194 : 195 : /** Constructor 196 : */ 197 : BOOST_HTTP_PROTO_DECL 198 : response( 199 : http_proto::status sc, 200 : http_proto::version v); 201 : 202 : /** Constructor 203 : * 204 : * The start-line of the response will contain the standard 205 : * text for the supplied status code and the HTTP version 206 : * will be defaulted to 1.1. 207 : */ 208 : BOOST_HTTP_PROTO_DECL 209 : explicit 210 : response( 211 : http_proto::status sc); 212 : 213 : /** Return a read-only view to the response 214 : */ 215 5 : operator 216 : response_view() const noexcept 217 : { 218 5 : return response_view(ph_); 219 : } 220 : 221 : //-------------------------------------------- 222 : // 223 : // Observers 224 : // 225 : //-------------------------------------------- 226 : 227 : /** Return the reason string 228 : 229 : This field is obsolete in HTTP/1 230 : and should only be used for display 231 : purposes. 232 : */ 233 : core::string_view 234 28 : reason() const noexcept 235 : { 236 56 : return core::string_view( 237 28 : ph_->cbuf + 13, 238 28 : ph_->prefix - 15); 239 : } 240 : 241 : /** Return the status code 242 : */ 243 : http_proto::status 244 28 : status() const noexcept 245 : { 246 28 : return ph_->res.status; 247 : } 248 : 249 : /** Return the status code 250 : */ 251 : unsigned short 252 28 : status_int() const noexcept 253 : { 254 28 : return ph_->res.status_int; 255 : } 256 : 257 : /** Return the HTTP version 258 : */ 259 : http_proto::version 260 28 : version() const noexcept 261 : { 262 28 : return ph_->version; 263 : } 264 : 265 : //-------------------------------------------- 266 : // 267 : // Modifiers 268 : // 269 : //-------------------------------------------- 270 : 271 : /** Set the version, status code of the response 272 : 273 : The reason phrase will be set to the 274 : standard text for the specified status 275 : code. 276 : 277 : @par sc The status code. This must not be 278 : @ref http_proto::status::unknown. 279 : 280 : @par v The HTTP-version. 281 : */ 282 : void 283 13 : set_start_line( 284 : http_proto::status sc, 285 : http_proto::version v = 286 : http_proto::version::http_1_1) 287 : { 288 13 : set_impl( 289 : sc, 290 : static_cast< 291 : unsigned short>(sc), 292 : obsolete_reason(sc), 293 : v); 294 13 : } 295 : 296 : void 297 6 : set_start_line( 298 : unsigned short si, 299 : core::string_view reason, 300 : http_proto::version v) 301 : { 302 6 : set_impl( 303 : int_to_status(si), 304 : si, 305 : reason, 306 : v); 307 6 : } 308 : 309 : /** Swap this with another instance 310 : */ 311 : void 312 6 : swap(response& other) noexcept 313 : { 314 6 : h_.swap(other.h_); 315 6 : } 316 : 317 : /** Swap two instances 318 : */ 319 : // hidden friend 320 : friend 321 : void 322 : swap( 323 : response& t0, 324 : response& t1) noexcept 325 : { 326 : t0.swap(t1); 327 : } 328 : 329 : private: 330 : BOOST_HTTP_PROTO_DECL 331 : void 332 : set_impl( 333 : http_proto::status sc, 334 : unsigned short si, 335 : core::string_view reason, 336 : http_proto::version v); 337 : }; 338 : 339 : } // http_proto 340 : } // boost 341 : 342 : #endif