LCOV - code coverage report
Current view: top level - boost/http_proto/response.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 40 40
Test Date: 2025-10-12 23:51:56 Functions: 100.0 % 12 12

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2024 Christian Mazakas
       4              : // Copyright (c) 2025 Mohammad Nejati
       5              : //
       6              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       7              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       8              : //
       9              : // Official repository: https://github.com/cppalliance/http_proto
      10              : //
      11              : 
      12              : #ifndef BOOST_HTTP_PROTO_RESPONSE_HPP
      13              : #define BOOST_HTTP_PROTO_RESPONSE_HPP
      14              : 
      15              : #include <boost/http_proto/response_base.hpp>
      16              : 
      17              : namespace boost {
      18              : namespace http_proto {
      19              : 
      20              : /** A modifiable container for HTTP responses.
      21              : 
      22              :     This container owns a response, represented by
      23              :     a buffer which is managed by performing
      24              :     dynamic memory allocations as needed. The
      25              :     contents may be inspected and modified, and
      26              :     the implementation maintains a useful
      27              :     invariant: changes to the response always
      28              :     leave it in a valid state.
      29              : 
      30              :     @par Example
      31              :     @code
      32              :     response res(status::not_found);
      33              : 
      34              :     res.set(field::server, "Boost.HttpProto");
      35              :     res.set(field::content_type, "text/plain");
      36              :     res.set_content_length(80);
      37              : 
      38              :     assert(res.buffer() ==
      39              :         "HTTP/1.1 404 Not Found\r\n"
      40              :         "Server: Boost.HttpProto\r\n"
      41              :         "Content-Type: text/plain\r\n"
      42              :         "Content-Length: 80\r\n"
      43              :         "\r\n");
      44              :     @endcode
      45              : 
      46              :     @see
      47              :         @ref static_response,
      48              :         @ref response_base.
      49              : */
      50              : class response
      51              :     : public response_base
      52              : {
      53              : public:
      54              :     //--------------------------------------------
      55              :     //
      56              :     // Special Members
      57              :     //
      58              :     //--------------------------------------------
      59              : 
      60              :     /** Constructor.
      61              : 
      62              :         A default-constructed response contains
      63              :         a valid HTTP 200 OK response with no headers.
      64              : 
      65              :         @par Example
      66              :         @code
      67              :         response res;
      68              :         @endcode
      69              : 
      70              :         @par Postconditions
      71              :         @code
      72              :         this->buffer() == "HTTP/1.1 200 OK\r\n\r\n"
      73              :         @endcode
      74              : 
      75              :         @par Complexity
      76              :         Constant.
      77              :     */
      78           99 :     response() noexcept = default;
      79              : 
      80              :     /** Constructor.
      81              : 
      82              :         Constructs a response from the string `s`,
      83              :         which must contain valid HTTP response
      84              :         or else an exception is thrown.
      85              :         The new response retains ownership by
      86              :         making a copy of the passed string.
      87              : 
      88              :         @par Example
      89              :         @code
      90              :         response res(
      91              :             "HTTP/1.1 404 Not Found\r\n"
      92              :             "Server: Boost.HttpProto\r\n"
      93              :             "Content-Type: text/plain\r\n"
      94              :             "\r\n");
      95              :         @endcode
      96              : 
      97              :         @par Postconditions
      98              :         @code
      99              :         this->buffer.data() != s.data()
     100              :         @endcode
     101              : 
     102              :         @par Complexity
     103              :         Linear in `s.size()`.
     104              : 
     105              :         @par Exception Safety
     106              :         Calls to allocate may throw.
     107              :         Exception thrown on invalid input.
     108              : 
     109              :         @throw system_error
     110              :         The input does not contain a valid response.
     111              : 
     112              :         @param s The string to parse.
     113              :     */
     114              :     explicit
     115          100 :     response(
     116              :         core::string_view s)
     117          100 :         : response_base(s)
     118              :     {
     119           99 :     }
     120              : 
     121              :     /** Constructor.
     122              : 
     123              :         Allocates `cap` bytes initially, with an
     124              :         upper limit of `max_cap`. Growing beyond
     125              :         `max_cap` will throw an exception.
     126              : 
     127              :         Useful when an estimated initial size is
     128              :         known, but further growth up to a maximum
     129              :         is allowed.
     130              : 
     131              :         When `max_cap == cap`, the container
     132              :         guarantees to never allocate.
     133              : 
     134              :         @par Preconditions
     135              :         @code
     136              :         max_cap >= cap
     137              :         @endcode
     138              : 
     139              :         @par Exception Safety
     140              :         Calls to allocate may throw.
     141              : 
     142              :         @param cap Initial capacity in bytes (may be `0`).
     143              : 
     144              :         @param max_cap Maximum allowed capacity in bytes.
     145              :     */
     146              :     explicit
     147           10 :     response(
     148              :         std::size_t cap,
     149              :         std::size_t max_cap = std::size_t(-1))
     150           10 :         : response()
     151              :     {
     152           10 :         reserve_bytes(cap);
     153           10 :         set_max_capacity_in_bytes(max_cap);
     154           10 :     }
     155              : 
     156              :     /** Constructor.
     157              : 
     158              :         The start-line of the response will
     159              :         contain the standard text for the
     160              :         supplied status code and HTTP version.
     161              : 
     162              :         @par Example
     163              :         @code
     164              :         response res(status::not_found, version::http_1_0);
     165              :         @endcode
     166              : 
     167              :         @par Complexity
     168              :         Linear in `obsolete_reason(s).size()`.
     169              : 
     170              :         @par Exception Safety
     171              :         Calls to allocate may throw.
     172              : 
     173              :         @param sc The status code.
     174              : 
     175              :         @param v The HTTP version.
     176              :     */
     177           11 :     response(
     178              :         http_proto::status sc,
     179              :         http_proto::version v)
     180           11 :         : response()
     181              :     {
     182           11 :         set_start_line(sc, v);
     183           11 :     }
     184              : 
     185              :     /** Constructor.
     186              : 
     187              :         The start-line of the response will
     188              :         contain the standard text for the
     189              :         supplied status code with the HTTP version
     190              :         defaulted to `HTTP/1.1`.
     191              : 
     192              :         @par Example
     193              :         @code
     194              :         response res(status::not_found);
     195              :         @endcode
     196              : 
     197              :         @par Complexity
     198              :         Linear in `obsolete_reason(s).size()`.
     199              : 
     200              :         @par Exception Safety
     201              :         Calls to allocate may throw.
     202              : 
     203              :         @param sc The status code.
     204              :     */
     205              :     explicit
     206            2 :     response(
     207              :         http_proto::status sc)
     208            2 :         : response(
     209            2 :             sc, http_proto::version::http_1_1)
     210              :     {
     211            2 :     }
     212              : 
     213              :     /** Constructor.
     214              : 
     215              :         The contents of `r` are transferred
     216              :         to the newly constructed object,
     217              :         which includes the underlying
     218              :         character buffer.
     219              :         After construction, the moved-from
     220              :         object is as if default-constructed.
     221              : 
     222              :         @par Postconditions
     223              :         @code
     224              :         r.buffer() == "HTTP/1.1 200 OK\r\n\r\n"
     225              :         @endcode
     226              : 
     227              :         @par Complexity
     228              :         Constant.
     229              : 
     230              :         @param r The response to move from.
     231              :     */
     232            3 :     response(response&& r) noexcept
     233            3 :         : response()
     234              :     {
     235            3 :         swap(r);
     236            3 :     }
     237              : 
     238              :     /** Constructor.
     239              : 
     240              :         The newly constructed object contains
     241              :         a copy of `r`.
     242              : 
     243              :         @par Postconditions
     244              :         @code
     245              :         this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
     246              :         @endcode
     247              : 
     248              :         @par Complexity
     249              :         Linear in `r.size()`.
     250              : 
     251              :         @par Exception Safety
     252              :         Calls to allocate may throw.
     253              : 
     254              :         @param r The response to copy.
     255              :     */
     256            3 :     response(response const&) = default;
     257              : 
     258              :     /** Constructor.
     259              : 
     260              :         The newly constructed object contains
     261              :         a copy of `r`.
     262              : 
     263              :         @par Postconditions
     264              :         @code
     265              :         this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
     266              :         @endcode
     267              : 
     268              :         @par Complexity
     269              :         Linear in `r.size()`.
     270              : 
     271              :         @par Exception Safety
     272              :         Calls to allocate may throw.
     273              : 
     274              :         @param r The response to copy.
     275              :     */
     276            4 :     response(response_base const& r)
     277            4 :         : response_base(r)
     278              :     {
     279            4 :     }
     280              : 
     281              :     /** Assignment
     282              : 
     283              :         The contents of `r` are transferred to
     284              :         `this`, including the underlying
     285              :         character buffer. The previous contents
     286              :         of `this` are destroyed.
     287              :         After assignment, the moved-from
     288              :         object is as if default-constructed.
     289              : 
     290              :         @par Postconditions
     291              :         @code
     292              :         r.buffer() == "HTTP/1.1 200 OK\r\n\r\n"
     293              :         @endcode
     294              : 
     295              :         @par Complexity
     296              :         Constant.
     297              : 
     298              :         @param r The response to assign from.
     299              : 
     300              :         @return A reference to this object.
     301              :     */
     302              :     response&
     303            1 :     operator=(
     304              :         response&& r) noexcept
     305              :     {
     306            1 :         response temp(std::move(r));
     307            1 :         temp.swap(*this);
     308            2 :         return *this;
     309            1 :     }
     310              : 
     311              :     /** Assignment.
     312              : 
     313              :         The contents of `r` are copied and
     314              :         the previous contents of `this` are
     315              :         discarded.
     316              : 
     317              :         @par Postconditions
     318              :         @code
     319              :         this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
     320              :         @endcode
     321              : 
     322              :         @par Complexity
     323              :         Linear in `r.size()`.
     324              : 
     325              :         @par Exception Safety
     326              :         Strong guarantee.
     327              :         Calls to allocate may throw.
     328              :         Exception thrown if max capacity exceeded.
     329              : 
     330              :         @throw std::length_error
     331              :         Max capacity would be exceeded.
     332              : 
     333              :         @param r The response to copy.
     334              : 
     335              :         @return A reference to this object.
     336              :     */
     337              :     response&
     338            1 :     operator=(
     339              :         response const& r)
     340              :     {
     341            1 :         copy_impl(r.h_);
     342            1 :         return *this;
     343              :     }
     344              : 
     345              :     /** Assignment.
     346              : 
     347              :         The contents of `r` are copied and
     348              :         the previous contents of `this` are
     349              :         discarded.
     350              : 
     351              :         @par Postconditions
     352              :         @code
     353              :         this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
     354              :         @endcode
     355              : 
     356              :         @par Complexity
     357              :         Linear in `r.size()`.
     358              : 
     359              :         @par Exception Safety
     360              :         Strong guarantee.
     361              :         Calls to allocate may throw.
     362              :         Exception thrown if max capacity exceeded.
     363              : 
     364              :         @throw std::length_error
     365              :         Max capacity would be exceeded.
     366              : 
     367              :         @param r The response to copy.
     368              : 
     369              :         @return A reference to this object.
     370              :     */
     371              :     response&
     372            1 :     operator=(
     373              :         response_base const& r)
     374              :     {
     375            1 :         copy_impl(r.h_);
     376            1 :         return *this;
     377              :     }
     378              : 
     379              :     //--------------------------------------------
     380              : 
     381              :     /** Swap.
     382              : 
     383              :         Exchanges the contents of this response
     384              :         with another response. All views,
     385              :         iterators and references remain valid.
     386              : 
     387              :         If `this == &other`, this function call has no effect.
     388              : 
     389              :         @par Example
     390              :         @code
     391              :         response r1(status::ok);
     392              :         response r2(status::bad_request);
     393              :         r1.swap(r2);
     394              :         assert(r1.buffer() == "HTTP/1.1 400 Bad Request\r\n\r\n" );
     395              :         assert(r2.buffer() == "HTTP/1.1 200 OK\r\n\r\n" );
     396              :         @endcode
     397              : 
     398              :         @par Complexity
     399              :         Constant
     400              : 
     401              :         @param other The object to swap with
     402              :     */
     403              :     void
     404            4 :     swap(response& other) noexcept
     405              :     {
     406            4 :         h_.swap(other.h_);
     407            4 :         std::swap(max_cap_, other.max_cap_);
     408            4 :     }
     409              : 
     410              :     /** Swap.
     411              : 
     412              :         Exchanges the contents of `v0` with
     413              :         another `v1`. All views, iterators and
     414              :         references remain valid.
     415              : 
     416              :         If `&v0 == &v1`, this function call has no effect.
     417              : 
     418              :         @par Example
     419              :         @code
     420              :         response r1(status::ok);
     421              :         response r2(status::bad_request);
     422              :         std::swap(r1, r2);
     423              :         assert(r1.buffer() == "HTTP/1.1 400 Bad Request\r\n\r\n" );
     424              :         assert(r2.buffer() == "HTTP/1.1 200 OK\r\n\r\n" );
     425              :         @endcode
     426              : 
     427              :         @par Effects
     428              :         @code
     429              :         v0.swap(v1);
     430              :         @endcode
     431              : 
     432              :         @par Complexity
     433              :         Constant.
     434              : 
     435              :         @param v0 The first object to swap.
     436              :         @param v1 The second object to swap.
     437              : 
     438              :         @see
     439              :             @ref response::swap.
     440              :     */
     441              :     friend
     442              :     void
     443              :     swap(
     444              :         response& v0,
     445              :         response& v1) noexcept
     446              :     {
     447              :         v0.swap(v1);
     448              :     }
     449              : };
     450              : 
     451              : } // http_proto
     452              : } // boost
     453              : 
     454              : #endif
        

Generated by: LCOV version 2.1