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

Generated by: LCOV version 2.1