LCOV - code coverage report
Current view: top level - boost/http_proto - request.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 32 32
Test Date: 2025-12-09 20:49:48 Functions: 100.0 % 10 10

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

Generated by: LCOV version 2.1