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_RESPONSE_HPP
10  
#ifndef BOOST_HTTP_STATIC_RESPONSE_HPP
11  
#define BOOST_HTTP_STATIC_RESPONSE_HPP
11  
#define BOOST_HTTP_STATIC_RESPONSE_HPP
12  

12  

13  
#include <boost/http/response_base.hpp>
13  
#include <boost/http/response_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 responses.
18  
/** A modifiable static container for HTTP responses.
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 response always
24  
    invariant: changes to the response 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_response res(buf, sizeof(buf));
30  
    static_response res(buf, sizeof(buf));
31  

31  

32  
    res.set_start_line(status::not_found);
32  
    res.set_start_line(status::not_found);
33  
    res.set(field::server, "Boost.HTTP");
33  
    res.set(field::server, "Boost.HTTP");
34  
    res.set(field::content_type, "text/plain");
34  
    res.set(field::content_type, "text/plain");
35  
    res.set_content_length(80);
35  
    res.set_content_length(80);
36  

36  

37  
    assert(res.buffer() ==
37  
    assert(res.buffer() ==
38  
        "HTTP/1.1 404 Not Found\r\n"
38  
        "HTTP/1.1 404 Not Found\r\n"
39  
        "Server: Boost.HTTP\r\n"
39  
        "Server: Boost.HTTP\r\n"
40  
        "Content-Type: text/plain\r\n"
40  
        "Content-Type: text/plain\r\n"
41  
        "Content-Length: 80\r\n"
41  
        "Content-Length: 80\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() == Capacity 
47  
    this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() == Capacity 
48  
    @endcode
48  
    @endcode
49  

49  

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

51  

52  
    @see
52  
    @see
53  
        @ref response,
53  
        @ref response,
54  
        @ref response_base.
54  
        @ref response_base.
55  
*/
55  
*/
56  
class static_response
56  
class static_response
57  
    : public response_base
57  
    : public response_base
58  
{
58  
{
59  
public:
59  
public:
60  
    //--------------------------------------------
60  
    //--------------------------------------------
61  
    //
61  
    //
62  
    // Special Members
62  
    // Special Members
63  
    //
63  
    //
64  
    //--------------------------------------------
64  
    //--------------------------------------------
65  

65  

66  
    /** Constructor.
66  
    /** Constructor.
67  

67  

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

71  

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

75  

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

81  

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

91  

92  
    /** Constructor (deleted)
92  
    /** Constructor (deleted)
93  
    */
93  
    */
94  
    static_response(
94  
    static_response(
95  
        static_response const&) = delete;
95  
        static_response const&) = delete;
96  

96  

97  
    /** Constructor.
97  
    /** Constructor.
98  

98  

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

107  

108  
        @par Complexity
108  
        @par Complexity
109  
        Constant.
109  
        Constant.
110  

110  

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

122  

123  
    /** Assignment.
123  
    /** Assignment.
124  

124  

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

128  

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

133  

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

136  

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

140  

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

143  

144  
        @param r The response to copy.
144  
        @param r The response to copy.
145  

145  

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

155  

156  
    /** Assignment.
156  
    /** Assignment.
157  

157  

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

161  

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

166  

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

169  

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

173  

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

176  

177  
        @param r The response to copy.
177  
        @param r The response to copy.
178  

178  

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

189  

190  
} // http
190  
} // http
191  
} // boost
191  
} // boost
192  

192  

193  
#endif
193  
#endif