1  
//
1  
//
2  
// Copyright (c) 2025 Mohammad Nejati
2  
// Copyright (c) 2025 Mohammad Nejati
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/http
7  
// Official repository: https://github.com/cppalliance/http
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_HTTP_STATIC_REQUEST_HPP
10  
#ifndef BOOST_HTTP_STATIC_REQUEST_HPP
11  
#define BOOST_HTTP_STATIC_REQUEST_HPP
11  
#define BOOST_HTTP_STATIC_REQUEST_HPP
12  

12  

13  
#include <boost/http/request_base.hpp>
13  
#include <boost/http/request_base.hpp>
14  

14  

15  
namespace boost {
15  
namespace boost {
16  
namespace http {
16  
namespace http {
17  

17  

18  
/** A modifiable static container for HTTP requests.
18  
/** A modifiable static container for HTTP requests.
19  

19  

20  
    This container uses an external memory
20  
    This container uses an external memory
21  
    storage with fixed capacity.
21  
    storage with fixed capacity.
22  
    The contents may be inspected and modified,
22  
    The contents may be inspected and modified,
23  
    and the implementation maintains a useful
23  
    and the implementation maintains a useful
24  
    invariant: changes to the request always
24  
    invariant: changes to the request always
25  
    leave it in a valid state.
25  
    leave it in a valid state.
26  

26  

27  
    @par Example
27  
    @par Example
28  
    @code
28  
    @code
29  
    char buf[1024];
29  
    char buf[1024];
30  
    static_request req(buf, sizeof(buf));
30  
    static_request req(buf, sizeof(buf));
31  

31  

32  
    req.set_start_line(method::get, "/");
32  
    req.set_start_line(method::get, "/");
33  
    req.set(field::host, "example.com");
33  
    req.set(field::host, "example.com");
34  
    req.set(field::accept_encoding, "gzip, deflate, br");
34  
    req.set(field::accept_encoding, "gzip, deflate, br");
35  
    req.set(field::cache_control, "no-cache");
35  
    req.set(field::cache_control, "no-cache");
36  

36  

37  
    assert(req.buffer() ==
37  
    assert(req.buffer() ==
38  
        "GET / HTTP/1.1\r\n"
38  
        "GET / HTTP/1.1\r\n"
39  
        "Host: example.com\r\n"
39  
        "Host: example.com\r\n"
40  
        "Accept-Encoding: gzip, deflate, br\r\n"
40  
        "Accept-Encoding: gzip, deflate, br\r\n"
41  
        "Cache-Control: no-cache\r\n"
41  
        "Cache-Control: no-cache\r\n"
42  
        "\r\n");
42  
        "\r\n");
43  
    @endcode
43  
    @endcode
44  

44  

45  
    @par Invariants
45  
    @par Invariants
46  
    @code
46  
    @code
47  
    this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() ==
47  
    this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() ==
48  
   Capacity
48  
   Capacity
49  
    @endcode
49  
    @endcode
50  

50  

51  
    @tparam Capacity The maximum capacity in bytes.
51  
    @tparam Capacity The maximum capacity in bytes.
52  

52  

53  
    @see
53  
    @see
54  
        @ref request,
54  
        @ref request,
55  
        @ref request_base.
55  
        @ref request_base.
56  
*/
56  
*/
57  
class static_request
57  
class static_request
58  
    : public request_base
58  
    : public request_base
59  
{
59  
{
60  
public:
60  
public:
61  
    //--------------------------------------------
61  
    //--------------------------------------------
62  
    //
62  
    //
63  
    // Special Members
63  
    // Special Members
64  
    //
64  
    //
65  
    //--------------------------------------------
65  
    //--------------------------------------------
66  

66  

67  
    /** Constructor.
67  
    /** Constructor.
68  

68  

69  
        Constructs a request object that uses an
69  
        Constructs a request object that uses an
70  
        external memory storage and does not perform
70  
        external memory storage and does not perform
71  
        any allocations during its lifetime.
71  
        any allocations during its lifetime.
72  

72  

73  
        The caller is responsible for ensuring that the
73  
        The caller is responsible for ensuring that the
74  
        lifetime of the storage extends until the
74  
        lifetime of the storage extends until the
75  
        request object is destroyed.
75  
        request object is destroyed.
76  

76  

77  
        @par Postcondition
77  
        @par Postcondition
78  
        @code
78  
        @code
79  
        this->capacity_in_bytes() == cap
79  
        this->capacity_in_bytes() == cap
80  
        this->max_capacity_in_bytes() == cap
80  
        this->max_capacity_in_bytes() == cap
81  
        @endcode
81  
        @endcode
82  

82  

83  
        @param storage The storage to use.
83  
        @param storage The storage to use.
84  
        @param cap The capacity of the storage.
84  
        @param cap The capacity of the storage.
85  
    */
85  
    */
86  
    static_request(
86  
    static_request(
87  
        void* storage,
87  
        void* storage,
88  
        std::size_t cap)
88  
        std::size_t cap)
89  
        : request_base(storage, cap)
89  
        : request_base(storage, cap)
90  
    {
90  
    {
91  
    }
91  
    }
92  

92  

93  
    /** Constructor (deleted)
93  
    /** Constructor (deleted)
94  
    */
94  
    */
95  
    static_request(
95  
    static_request(
96  
        static_request const&) = delete;
96  
        static_request const&) = delete;
97  

97  

98  
    /** Constructor.
98  
    /** Constructor.
99  

99  

100  
        The contents of `r` are transferred
100  
        The contents of `r` are transferred
101  
        to the newly constructed object,
101  
        to the newly constructed object,
102  
        which includes the underlying
102  
        which includes the underlying
103  
        character buffer.
103  
        character buffer.
104  
        After construction, the moved-from
104  
        After construction, the moved-from
105  
        object has a valid but unspecified
105  
        object has a valid but unspecified
106  
        state where the only safe operation
106  
        state where the only safe operation
107  
        is destruction.
107  
        is destruction.
108  

108  

109  
        @par Complexity
109  
        @par Complexity
110  
        Constant.
110  
        Constant.
111  

111  

112  
        @param r The request to move from.
112  
        @param r The request to move from.
113  
    */
113  
    */
114  
    static_request(
114  
    static_request(
115  
        static_request&& r) noexcept
115  
        static_request&& r) noexcept
116  
        : request_base()
116  
        : request_base()
117  
    {
117  
    {
118  
        h_.swap(r.h_);
118  
        h_.swap(r.h_);
119  
        external_storage_ = true;
119  
        external_storage_ = true;
120  
        max_cap_ = r.max_cap_;
120  
        max_cap_ = r.max_cap_;
121  
        r.max_cap_ = 0;
121  
        r.max_cap_ = 0;
122  
    }
122  
    }
123  

123  

124  
    /** Assignment.
124  
    /** Assignment.
125  

125  

126  
        The contents of `r` are copied and
126  
        The contents of `r` are copied and
127  
        the previous contents of `this` are
127  
        the previous contents of `this` are
128  
        discarded.
128  
        discarded.
129  

129  

130  
        @par Postconditions
130  
        @par Postconditions
131  
        @code
131  
        @code
132  
        this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
132  
        this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
133  
        @endcode
133  
        @endcode
134  

134  

135  
        @par Complexity
135  
        @par Complexity
136  
        Linear in `r.size()`.
136  
        Linear in `r.size()`.
137  

137  

138  
        @par Exception Safety
138  
        @par Exception Safety
139  
        Strong guarantee.
139  
        Strong guarantee.
140  
        Exception thrown if max capacity exceeded.
140  
        Exception thrown if max capacity exceeded.
141  

141  

142  
        @throw std::length_error
142  
        @throw std::length_error
143  
        Max capacity would be exceeded.
143  
        Max capacity would be exceeded.
144  

144  

145  
        @param r The request to copy.
145  
        @param r The request to copy.
146  

146  

147  
        @return A reference to this object.
147  
        @return A reference to this object.
148  
    */
148  
    */
149  
    static_request&
149  
    static_request&
150  
    operator=(
150  
    operator=(
151  
        static_request const& r)
151  
        static_request const& r)
152  
    {
152  
    {
153  
        copy_impl(r.h_);
153  
        copy_impl(r.h_);
154  
        return *this;
154  
        return *this;
155  
    }
155  
    }
156  

156  

157  
    /** Assignment.
157  
    /** Assignment.
158  

158  

159  
        The contents of `r` are copied and
159  
        The contents of `r` are copied and
160  
        the previous contents of `this` are
160  
        the previous contents of `this` are
161  
        discarded.
161  
        discarded.
162  

162  

163  
        @par Postconditions
163  
        @par Postconditions
164  
        @code
164  
        @code
165  
        this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
165  
        this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
166  
        @endcode
166  
        @endcode
167  

167  

168  
        @par Complexity
168  
        @par Complexity
169  
        Linear in `r.size()`.
169  
        Linear in `r.size()`.
170  

170  

171  
        @par Exception Safety
171  
        @par Exception Safety
172  
        Strong guarantee.
172  
        Strong guarantee.
173  
        Exception thrown if max capacity exceeded.
173  
        Exception thrown if max capacity exceeded.
174  

174  

175  
        @throw std::length_error
175  
        @throw std::length_error
176  
        Max capacity would be exceeded.
176  
        Max capacity would be exceeded.
177  

177  

178  
        @param r The request to copy.
178  
        @param r The request to copy.
179  

179  

180  
        @return A reference to this object.
180  
        @return A reference to this object.
181  
    */
181  
    */
182  
    static_request&
182  
    static_request&
183  
    operator=(
183  
    operator=(
184  
        request_base const& r)
184  
        request_base const& r)
185  
    {
185  
    {
186  
        copy_impl(r.h_);
186  
        copy_impl(r.h_);
187  
        return *this;
187  
        return *this;
188  
    }
188  
    }
189  
};
189  
};
190  

190  

191  
} // http
191  
} // http
192  
} // boost
192  
} // boost
193  

193  

194  
#endif
194  
#endif