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 % 58 58
Test Date: 2025-12-18 06:34:36 Functions: 100.0 % 17 17

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2025 Mohammad Nejati
       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_REQUEST_HPP
      12              : #define BOOST_HTTP_PROTO_REQUEST_HPP
      13              : 
      14              : #include <boost/http_proto/detail/config.hpp>
      15              : #include <boost/http_proto/message_base.hpp>
      16              : 
      17              : namespace boost {
      18              : namespace http_proto {
      19              : 
      20              : /** A container for HTTP requests.
      21              : 
      22              :     This container owns a request, 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 request always leave
      28              :     it in a valid state.
      29              : 
      30              :     @par Example
      31              :     @code
      32              :     request req(method::get, "/");
      33              : 
      34              :     req.set(field::host, "example.com");
      35              :     req.set(field::accept_encoding, "gzip, deflate, br");
      36              :     req.set(field::cache_control, "no-cache");
      37              : 
      38              :     assert(req.buffer() ==
      39              :     "GET / HTTP/1.1\r\n"
      40              :     "Host: example.com\r\n"
      41              :     "Accept-Encoding: gzip, deflate, br\r\n"
      42              :     "Cache-Control: no-cache\r\n"
      43              :     "\r\n");
      44              :     @endcode
      45              : 
      46              :     @see
      47              :         @ref request_parser,
      48              :         @ref response.
      49              : */
      50              : class request
      51              :     : public message_base
      52              : {
      53              :     friend class request_parser;
      54              : 
      55          315 :     request(
      56              :         view_tag_t,
      57              :         detail::header const& h) noexcept
      58          315 :         : message_base(view_tag, h)
      59              :     {
      60          315 :     }
      61              : 
      62              : public:
      63              :     //--------------------------------------------
      64              :     //
      65              :     // Special Members
      66              :     //
      67              :     //--------------------------------------------
      68              : 
      69              :     /** Constructor.
      70              : 
      71              :         A default-constructed request contains
      72              :         a valid HTTP `GET` request with no headers.
      73              : 
      74              :         @par Example
      75              :         @code
      76              :         request req;
      77              :         @endcode
      78              : 
      79              :         @par Postconditions
      80              :         @code
      81              :         this->buffer() == "GET / HTTP/1.1\r\n\r\n"
      82              :         @endcode
      83              : 
      84              :         @par Complexity
      85              :         Constant.
      86              :     */
      87           28 :     request() noexcept
      88           28 :         : message_base(detail::kind::request)
      89              :     {
      90           28 :     }
      91              : 
      92              :     /** Constructor.
      93              : 
      94              :         Constructs a request from the string `s`,
      95              :         which must contain valid HTTP request
      96              :         or else an exception is thrown.
      97              :         The new request retains ownership by
      98              :         making a copy of the passed string.
      99              : 
     100              :         @par Example
     101              :         @code
     102              :         request req(
     103              :             "GET / HTTP/1.1\r\n"
     104              :             "Accept-Encoding: gzip, deflate, br\r\n"
     105              :             "Cache-Control: no-cache\r\n"
     106              :             "\r\n");
     107              :         @endcode
     108              : 
     109              :         @par Postconditions
     110              :         @code
     111              :         this->buffer.data() != s.data()
     112              :         @endcode
     113              : 
     114              :         @par Complexity
     115              :         Linear in `s.size()`.
     116              : 
     117              :         @par Exception Safety
     118              :         Calls to allocate may throw.
     119              :         Exception thrown on invalid input.
     120              : 
     121              :         @throw system_error
     122              :         The input does not contain a valid request.
     123              : 
     124              :         @param s The string to parse.
     125              :     */
     126              :     explicit
     127          208 :     request(
     128              :         core::string_view s)
     129          208 :         : message_base(detail::kind::request, s)
     130              :     {
     131          207 :     }
     132              : 
     133              :     /** Constructor.
     134              : 
     135              :         The start-line of the request will
     136              :         contain the standard text for the
     137              :         supplied method, target and HTTP version.
     138              : 
     139              :         @par Example
     140              :         @code
     141              :         request req(method::get, "/index.html", version::http_1_0);
     142              :         @endcode
     143              : 
     144              :         @par Complexity
     145              :         Linear in `to_string(m).size() + t.size()`.
     146              : 
     147              :         @par Exception Safety
     148              :         Calls to allocate may throw.
     149              : 
     150              :         @param m The method to set.
     151              : 
     152              :         @param t The string representing a target.
     153              : 
     154              :         @param v The version to set.
     155              :     */
     156              :     request(
     157              :         http_proto::method m,
     158              :         core::string_view t,
     159              :         http_proto::version v) noexcept
     160              :         : message_base(detail::kind::request)
     161              :     {
     162              :         set_start_line(m, t, v);
     163              :     }
     164              : 
     165              :     /** Constructor.
     166              : 
     167              :         The start-line of the request will
     168              :         contain the standard text for the
     169              :         supplied method and target with the HTTP
     170              :         version defaulted to `HTTP/1.1`.
     171              : 
     172              :         @par Example
     173              :         @code
     174              :         request req(method::get, "/index.html");
     175              :         @endcode
     176              : 
     177              :         @par Complexity
     178              :         Linear in `to_string(s).size()`.
     179              : 
     180              :         @par Exception Safety
     181              :         Calls to allocate may throw.
     182              : 
     183              :         @param m The method to set.
     184              : 
     185              :         @param t The string representing a target.
     186              :     */
     187              :     request(
     188              :         http_proto::method m,
     189              :         core::string_view t)
     190              :         : request(
     191              :             m, t, http_proto::version::http_1_1)
     192              :     {
     193              :     }
     194              : 
     195              :     /** Constructor.
     196              : 
     197              :         Allocates `cap` bytes initially, with an
     198              :         upper limit of `max_cap`. Growing beyond
     199              :         `max_cap` will throw an exception.
     200              : 
     201              :         Useful when an estimated initial size is
     202              :         known, but further growth up to a maximum
     203              :         is allowed.
     204              : 
     205              :         When `cap == max_cap`, the container
     206              :         guarantees to never allocate.
     207              : 
     208              :         @par Preconditions
     209              :         @code
     210              :         max_cap >= cap
     211              :         @endcode
     212              : 
     213              :         @par Exception Safety
     214              :         Calls to allocate may throw.
     215              : 
     216              :         @param cap Initial capacity in bytes (may be `0`).
     217              : 
     218              :         @param max_cap Maximum allowed capacity in bytes.
     219              :     */
     220           10 :     request(
     221              :         std::size_t cap,
     222              :         std::size_t max_cap = std::size_t(-1))
     223           10 :         : message_base(detail::kind::request)
     224              :     {
     225           10 :         reserve_bytes(cap);
     226           10 :         set_max_capacity_in_bytes(max_cap);
     227           10 :     }
     228              : 
     229              :     /** Constructor.
     230              : 
     231              :         The contents of `r` are transferred
     232              :         to the newly constructed object,
     233              :         which includes the underlying
     234              :         character buffer.
     235              :         After construction, the moved-from
     236              :         object is as if default-constructed.
     237              : 
     238              :         @par Postconditions
     239              :         @code
     240              :         r.buffer() == "GET / HTTP/1.1\r\n\r\n"
     241              :         @endcode
     242              : 
     243              :         @par Complexity
     244              :         Constant.
     245              : 
     246              :         @param r The request to move from.
     247              :     */
     248           25 :     request(
     249              :         request&& other) noexcept
     250           25 :         : message_base(detail::kind::request)
     251              :     {
     252           25 :         swap(other);
     253           25 :     }
     254              : 
     255              :     /** Constructor.
     256              : 
     257              :         The newly constructed object contains
     258              :         a copy of `r`.
     259              : 
     260              :         @par Postconditions
     261              :         @code
     262              :         this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
     263              :         @endcode
     264              : 
     265              :         @par Complexity
     266              :         Linear in `r.size()`.
     267              : 
     268              :         @par Exception Safety
     269              :         Calls to allocate may throw.
     270              : 
     271              :         @param r The request to copy.
     272              :     */
     273            4 :     request(
     274              :         request const& r) = default;
     275              : 
     276              :     /** Assignment
     277              : 
     278              :         The contents of `r` are transferred to
     279              :         `this`, including the underlying
     280              :         character buffer. The previous contents
     281              :         of `this` are destroyed.
     282              :         After assignment, the moved-from
     283              :         object is as if default-constructed.
     284              : 
     285              :         @par Postconditions
     286              :         @code
     287              :         r.buffer() == "GET / HTTP/1.1\r\n\r\n"
     288              :         @endcode
     289              : 
     290              :         @par Complexity
     291              :         Constant.
     292              : 
     293              :         @param r The request to assign from.
     294              : 
     295              :         @return A reference to this object.
     296              :     */
     297              :     request&
     298           23 :     operator=(request&& r) noexcept
     299              :     {
     300           23 :         request temp(std::move(r));
     301           23 :         temp.swap(*this);
     302           46 :         return *this;
     303           23 :     }
     304              : 
     305              :     /** Assignment.
     306              : 
     307              :         The contents of `r` are copied and
     308              :         the previous contents of `this` are
     309              :         discarded.
     310              : 
     311              :         @par Postconditions
     312              :         @code
     313              :         this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
     314              :         @endcode
     315              : 
     316              :         @par Complexity
     317              :         Linear in `r.size()`.
     318              : 
     319              :         @par Exception Safety
     320              :         Strong guarantee.
     321              :         Calls to allocate may throw.
     322              :         Exception thrown if max capacity exceeded.
     323              : 
     324              :         @throw std::length_error
     325              :         Max capacity would be exceeded.
     326              : 
     327              :         @param r The request to copy.
     328              : 
     329              :         @return A reference to this object.
     330              :     */
     331              :     request&
     332            3 :     operator=(
     333              :         request const& r)
     334              :     {
     335            3 :         copy_impl(r.h_);
     336            3 :         return *this;
     337              :     }
     338              : 
     339              :     //--------------------------------------------
     340              : 
     341              :     /** Swap.
     342              : 
     343              :         Exchanges the contents of this request
     344              :         with another request. All views,
     345              :         iterators and references remain valid.
     346              : 
     347              :         If `this == &other`, this function call has no effect.
     348              : 
     349              :         @par Example
     350              :         @code
     351              :         request r1(method::get, "/");
     352              :         request r2(method::delete_, "/item/42");
     353              :         r1.swap(r2);
     354              :         assert(r1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
     355              :         assert(r2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
     356              :         @endcode
     357              : 
     358              :         @par Complexity
     359              :         Constant
     360              : 
     361              :         @param other The object to swap with
     362              :     */
     363              :     void
     364           48 :     swap(request& other) noexcept
     365              :     {
     366           48 :         h_.swap(other.h_);
     367           48 :         std::swap(max_cap_, other.max_cap_);
     368           48 :         std::swap(view_, other.view_);
     369           48 :     }
     370              : 
     371              :     /** Swap.
     372              : 
     373              :         Exchanges the contents of `v0` with
     374              :         another `v1`. All views, iterators and
     375              :         references remain valid.
     376              : 
     377              :         If `&v0 == &v1`, this function call has no effect.
     378              : 
     379              :         @par Example
     380              :         @code
     381              :         request r1(method::get, "/");
     382              :         request r2(method::delete_, "/item/42");
     383              :         std::swap(r1, r2);
     384              :         assert(r1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
     385              :         assert(r2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
     386              :         @endcode
     387              : 
     388              :         @par Effects
     389              :         @code
     390              :         v0.swap(v1);
     391              :         @endcode
     392              : 
     393              :         @par Complexity
     394              :         Constant.
     395              : 
     396              :         @param v0 The first object to swap.
     397              :         @param v1 The second object to swap.
     398              : 
     399              :         @see
     400              :             @ref request::swap
     401              :     */
     402              :     friend
     403              :     void
     404              :     swap(
     405              :         request& v0,
     406              :         request& v1) noexcept
     407              :     {
     408              :         v0.swap(v1);
     409              :     }
     410              : 
     411              :     //--------------------------------------------
     412              :     //
     413              :     // Observers
     414              :     //
     415              :     //--------------------------------------------
     416              : 
     417              :     /** Return the method as a name constant.
     418              : 
     419              :         If the method returned is equal to
     420              :         @ref method::unknown, the method may
     421              :         be obtained as a string instead, by
     422              :         calling @ref method_text.
     423              :     */
     424              :     http_proto::method
     425           76 :     method() const noexcept
     426              :     {
     427           76 :         return h_.req.method;
     428              :     }
     429              : 
     430              :     /** Return the method as a string.
     431              :     */
     432              :     core::string_view
     433           83 :     method_text() const noexcept
     434              :     {
     435          166 :         return core::string_view(
     436           83 :             h_.cbuf,
     437           83 :             h_.req.method_len);
     438              :     }
     439              : 
     440              :     /** Return the request-target string.
     441              :     */
     442              :     core::string_view
     443           73 :     target() const noexcept
     444              :     {
     445          146 :         return core::string_view(
     446           73 :             h_.cbuf +
     447           73 :                 h_.req.method_len + 1,
     448           73 :             h_.req.target_len);
     449              :     }
     450              : 
     451              :     //--------------------------------------------
     452              :     //
     453              :     // Modifiers
     454              :     //
     455              :     //--------------------------------------------
     456              : 
     457              :     /** Set the method of the request to the enum.
     458              : 
     459              :         @par Exception Safety
     460              :         Strong guarantee.
     461              :         Calls to allocate may throw.
     462              :         Exception thrown if max capacity exceeded.
     463              : 
     464              :         @throw std::length_error
     465              :         Max capacity would be exceeded.
     466              : 
     467              :         @param m The method to set.
     468              :     */
     469              :     void
     470            2 :     set_method(
     471              :         http_proto::method m)
     472              :     {
     473            2 :         set_start_line_impl(
     474              :             m,
     475              :             to_string(m),
     476              :             target(),
     477              :             version());
     478            2 :     }
     479              : 
     480              :     /** Set the method of the request to the string.
     481              : 
     482              :         @par Exception Safety
     483              :         Strong guarantee.
     484              :         Calls to allocate may throw.
     485              :         Exception thrown on invalid input.
     486              :         Exception thrown if max capacity exceeded.
     487              : 
     488              :         @throw system_error
     489              :         Input is invalid.
     490              : 
     491              :         @throw std::length_error
     492              :         Max capacity would be exceeded.
     493              : 
     494              :         @param s A string view representing the
     495              :         method to set.
     496              :     */
     497              :     void
     498            5 :     set_method(
     499              :         core::string_view s)
     500              :     {
     501            5 :         set_start_line_impl(
     502              :             string_to_method(s),
     503              :             s,
     504              :             target(),
     505              :             version());
     506            5 :     }
     507              : 
     508              :     /** Set the target string of the request.
     509              : 
     510              :         This function sets the request-target.
     511              :         The caller is responsible for ensuring
     512              :         that the string passed is syntactically
     513              :         valid.
     514              : 
     515              :         @par Exception Safety
     516              :         Strong guarantee.
     517              :         Calls to allocate may throw.
     518              :         Exception thrown on invalid input.
     519              :         Exception thrown if max capacity exceeded.
     520              : 
     521              :         @throw system_error
     522              :         Input is invalid.
     523              : 
     524              :         @throw std::length_error
     525              :         Max capacity would be exceeded.
     526              : 
     527              :         @param s A string view representing the
     528              :         target to set.
     529              :     */
     530              :     void
     531            5 :     set_target(
     532              :         core::string_view s)
     533              :     {
     534            5 :         set_start_line_impl(
     535              :             h_.req.method,
     536              :             method_text(),
     537              :             s,
     538              :             version());
     539            5 :     }
     540              : 
     541              :     /** Set the HTTP version of the request.
     542              : 
     543              :         @par Exception Safety
     544              :         Strong guarantee.
     545              :         Calls to allocate may throw.
     546              :         Exception thrown if max capacity exceeded.
     547              : 
     548              :         @throw std::length_error
     549              :         Max capacity would be exceeded.
     550              : 
     551              :         @param v The version to set.
     552              :     */
     553              :     void
     554            2 :     set_version(
     555              :         http_proto::version v)
     556              :     {
     557            2 :         set_start_line_impl(
     558              :             h_.req.method,
     559              :             method_text(),
     560              :             target(),
     561              :             v);
     562            2 :     }
     563              : 
     564              :     /** Set the method, target, and version of the request.
     565              : 
     566              :         This is more efficient than setting the
     567              :         properties individually.
     568              : 
     569              :         @par Exception Safety
     570              :         Strong guarantee.
     571              :         Calls to allocate may throw.
     572              :         Exception thrown on invalid input.
     573              :         Exception thrown if max capacity exceeded.
     574              : 
     575              :         @throw system_error
     576              :         Input is invalid.
     577              : 
     578              :         @throw std::length_error
     579              :         Max capacity would be exceeded.
     580              : 
     581              :         @param m The method to set.
     582              : 
     583              :         @param t A string view representing the
     584              :         target to set.
     585              : 
     586              :         @param v The version to set.
     587              :     */
     588              :     void
     589            2 :     set_start_line(
     590              :         http_proto::method m,
     591              :         core::string_view t,
     592              :         http_proto::version v =
     593              :             http_proto::version::http_1_1)
     594              :     {
     595            2 :         set_start_line_impl(m, to_string(m), t, v);
     596            1 :     }
     597              : 
     598              :     /** Set the method, target, and version of the request.
     599              : 
     600              :         This is more efficient than setting the
     601              :         properties individually.
     602              : 
     603              :         @par Exception Safety
     604              :         Strong guarantee.
     605              :         Calls to allocate may throw.
     606              :         Exception thrown on invalid input.
     607              :         Exception thrown if max capacity exceeded.
     608              : 
     609              :         @throw system_error
     610              :         Input is invalid.
     611              : 
     612              :         @throw std::length_error
     613              :         Max capacity would be exceeded.
     614              : 
     615              :         @param m A string view representing the
     616              :         method to set.
     617              : 
     618              :         @param t A string view representing the
     619              :         target to set.
     620              : 
     621              :         @param v The version to set.
     622              :     */
     623              :     void
     624              :     set_start_line(
     625              :         core::string_view m,
     626              :         core::string_view t,
     627              :         http_proto::version v =
     628              :             http_proto::version::http_1_1)
     629              :     {
     630              :         set_start_line_impl(string_to_method(m), m, t, v);
     631              :     }
     632              : 
     633              :     /** Set the `Expect: 100-continue` header.
     634              : 
     635              :         @par Exception Safety
     636              :         Strong guarantee.
     637              :         Calls to allocate may throw.
     638              :         Exception thrown if max capacity exceeded.
     639              : 
     640              :         @throw std::length_error
     641              :         Max capacity would be exceeded.
     642              : 
     643              :         @param b If `true` sets `Expect: 100-continue`
     644              :         header otherwise erase it.
     645              :     */
     646              :     BOOST_HTTP_PROTO_DECL
     647              :     void
     648              :     set_expect_100_continue(bool b);
     649              : 
     650              : private:
     651              :     BOOST_HTTP_PROTO_DECL
     652              :     void
     653              :     set_start_line_impl(
     654              :         http_proto::method m,
     655              :         core::string_view ms,
     656              :         core::string_view t,
     657              :         http_proto::version v);
     658              : };
     659              : 
     660              : } // http_proto
     661              : } // boost
     662              : 
     663              : #endif
        

Generated by: LCOV version 2.1