LCOV - code coverage report
Current view: top level - include/boost/http - request.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 40 40
Test Date: 2026-06-13 19:44:58 Functions: 100.0 % 12 12

           TLA  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
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_HTTP_REQUEST_HPP
      11                 : #define BOOST_HTTP_REQUEST_HPP
      12                 : 
      13                 : #include <boost/http/request_base.hpp>
      14                 : 
      15                 : namespace boost {
      16                 : namespace http {
      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 HIT         202 :     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             212 :     request(
     114                 :         core::string_view s)
     115             212 :         : request_base(s)
     116                 :     {
     117             211 :     }
     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              26 :     request(
     143                 :         http::method m,
     144                 :         core::string_view t,
     145                 :         http::version v) noexcept
     146              26 :         : request()
     147                 :     {
     148              26 :         set_start_line(m, t, v);
     149              26 :     }
     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 `to_string(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              26 :     request(
     174                 :         http::method m,
     175                 :         core::string_view t)
     176              26 :         : request(
     177              26 :             m, t, http::version::http_1_1)
     178                 :     {
     179              26 :     }
     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               2 :     operator=(
     377                 :         request_base const& r)
     378                 :     {
     379               2 :         copy_impl(r.h_);
     380               2 :         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
     456                 : } // boost
     457                 : 
     458                 : #endif
        

Generated by: LCOV version 2.3