1  
//
1  
//
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2024 Christian Mazakas
3  
// Copyright (c) 2024 Christian Mazakas
4  
// Copyright (c) 2025 Mohammad Nejati
4  
// Copyright (c) 2025 Mohammad Nejati
5  
//
5  
//
6  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
7  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8  
//
8  
//
9  
// Official repository: https://github.com/cppalliance/http
9  
// Official repository: https://github.com/cppalliance/http
10  
//
10  
//
11  

11  

12  
#ifndef BOOST_HTTP_RESPONSE_BASE_HPP
12  
#ifndef BOOST_HTTP_RESPONSE_BASE_HPP
13  
#define BOOST_HTTP_RESPONSE_BASE_HPP
13  
#define BOOST_HTTP_RESPONSE_BASE_HPP
14  

14  

15  
#include <boost/http/detail/config.hpp>
15  
#include <boost/http/detail/config.hpp>
16  
#include <boost/http/message_base.hpp>
16  
#include <boost/http/message_base.hpp>
17  
#include <boost/http/status.hpp>
17  
#include <boost/http/status.hpp>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace http {
20  
namespace http {
21  

21  

22  
/** Mixin for modifing HTTP responses.
22  
/** Mixin for modifing HTTP responses.
23  

23  

24  
    @see
24  
    @see
25  
        @ref message_base,
25  
        @ref message_base,
26  
        @ref response,
26  
        @ref response,
27  
        @ref static_response.
27  
        @ref static_response.
28  
*/
28  
*/
29  
class response_base
29  
class response_base
30  
    : public message_base
30  
    : public message_base
31  
{
31  
{
32  
    friend class response;
32  
    friend class response;
33  
    friend class static_response;
33  
    friend class static_response;
34  

34  

35  
    response_base() noexcept
35  
    response_base() noexcept
36  
        : message_base(detail::kind::response)
36  
        : message_base(detail::kind::response)
37  
    {
37  
    {
38  
    }
38  
    }
39  

39  

40  
    explicit
40  
    explicit
41  
    response_base(core::string_view s)
41  
    response_base(core::string_view s)
42  
        : message_base(detail::kind::response, s)
42  
        : message_base(detail::kind::response, s)
43  
    {
43  
    {
44  
    }
44  
    }
45  

45  

46  
    response_base(
46  
    response_base(
47  
        void* storage,
47  
        void* storage,
48  
        std::size_t cap) noexcept
48  
        std::size_t cap) noexcept
49  
        : message_base(
49  
        : message_base(
50  
            detail::kind::response, storage, cap)
50  
            detail::kind::response, storage, cap)
51  
    {
51  
    {
52  
    }
52  
    }
53  

53  

54  
public:
54  
public:
55  
    //--------------------------------------------
55  
    //--------------------------------------------
56  
    //
56  
    //
57  
    // Observers
57  
    // Observers
58  
    //
58  
    //
59  
    //--------------------------------------------
59  
    //--------------------------------------------
60  

60  

61  
    /** Return the reason string.
61  
    /** Return the reason string.
62  

62  

63  
        This field is obsolete in HTTP/1
63  
        This field is obsolete in HTTP/1
64  
        and should only be used for display
64  
        and should only be used for display
65  
        purposes.
65  
        purposes.
66  
    */
66  
    */
67  
    core::string_view
67  
    core::string_view
68  
    reason() const noexcept
68  
    reason() const noexcept
69  
    {
69  
    {
70  
        return core::string_view(
70  
        return core::string_view(
71  
            h_.cbuf + 13,
71  
            h_.cbuf + 13,
72  
            h_.prefix - 15);
72  
            h_.prefix - 15);
73  
    }
73  
    }
74  

74  

75  
    /** Return the status code.
75  
    /** Return the status code.
76  
    */
76  
    */
77  
    http::status
77  
    http::status
78  
    status() const noexcept
78  
    status() const noexcept
79  
    {
79  
    {
80  
        return h_.res.status;
80  
        return h_.res.status;
81  
    }
81  
    }
82  

82  

83  
    /** Return the status code as an integral.
83  
    /** Return the status code as an integral.
84  
    */
84  
    */
85  
    unsigned short
85  
    unsigned short
86  
    status_int() const noexcept
86  
    status_int() const noexcept
87  
    {
87  
    {
88  
        return h_.res.status_int;
88  
        return h_.res.status_int;
89  
    }
89  
    }
90  

90  

91  
    //--------------------------------------------
91  
    //--------------------------------------------
92  
    //
92  
    //
93  
    // Modifiers
93  
    // Modifiers
94  
    //
94  
    //
95  
    //--------------------------------------------
95  
    //--------------------------------------------
96  

96  

97  
    /** Set the status code and version of the response.
97  
    /** Set the status code and version of the response.
98  

98  

99  
        The reason-phrase will be set to the
99  
        The reason-phrase will be set to the
100  
        standard text for the specified status
100  
        standard text for the specified status
101  
        code.
101  
        code.
102  

102  

103  
        This is more efficient than setting the
103  
        This is more efficient than setting the
104  
        properties individually.
104  
        properties individually.
105  

105  

106  
        @par Exception Safety
106  
        @par Exception Safety
107  
        Strong guarantee.
107  
        Strong guarantee.
108  
        Calls to allocate may throw.
108  
        Calls to allocate may throw.
109  
        Exception thrown if max capacity exceeded.
109  
        Exception thrown if max capacity exceeded.
110  

110  

111  
        @throw std::length_error
111  
        @throw std::length_error
112  
        Max capacity would be exceeded.
112  
        Max capacity would be exceeded.
113  
        @throw std::invalid_argument
113  
        @throw std::invalid_argument
114  
        `sc == status::unknown`
114  
        `sc == status::unknown`
115  

115  

116  
        @param sc The status code to set. This
116  
        @param sc The status code to set. This
117  
        must not be @ref status::unknown.
117  
        must not be @ref status::unknown.
118  

118  

119  
        @param v The version to set.
119  
        @param v The version to set.
120  
    */
120  
    */
121  
    void
121  
    void
122  
    set_start_line(
122  
    set_start_line(
123  
        http::status sc,
123  
        http::status sc,
124  
        http::version v =
124  
        http::version v =
125  
            http::version::http_1_1)
125  
            http::version::http_1_1)
126  
    {
126  
    {
127  
        set_start_line_impl(sc,
127  
        set_start_line_impl(sc,
128  
            static_cast<unsigned short>(sc),
128  
            static_cast<unsigned short>(sc),
129  
                to_string(sc), v);
129  
                to_string(sc), v);
130  
    }
130  
    }
131  

131  

132  
    /** Set the HTTP version of the response
132  
    /** Set the HTTP version of the response
133  

133  

134  
        @par Exception Safety
134  
        @par Exception Safety
135  
        Strong guarantee.
135  
        Strong guarantee.
136  
        Calls to allocate may throw.
136  
        Calls to allocate may throw.
137  
        Exception thrown if maximum capacity exceeded.
137  
        Exception thrown if maximum capacity exceeded.
138  

138  

139  
        @throw std::length_error
139  
        @throw std::length_error
140  
        Maximum capacity would be exceeded.
140  
        Maximum capacity would be exceeded.
141  

141  

142  
        @param v The version to set.
142  
        @param v The version to set.
143  
    */
143  
    */
144  
    BOOST_HTTP_DECL
144  
    BOOST_HTTP_DECL
145  
    void
145  
    void
146  
    set_version(
146  
    set_version(
147  
        http::version v);
147  
        http::version v);
148  

148  

149  
    /** Set the status code of the response.
149  
    /** Set the status code of the response.
150  

150  

151  
        The reason-phrase will be set to the
151  
        The reason-phrase will be set to the
152  
        standard text for the specified status
152  
        standard text for the specified status
153  
        code. The version will remain unchanged.
153  
        code. The version will remain unchanged.
154  

154  

155  
        @par Exception Safety
155  
        @par Exception Safety
156  
        Strong guarantee.
156  
        Strong guarantee.
157  
        Calls to allocate may throw.
157  
        Calls to allocate may throw.
158  
        Exception thrown if maximum capacity exceeded.
158  
        Exception thrown if maximum capacity exceeded.
159  

159  

160  
        @throw std::length_error
160  
        @throw std::length_error
161  
        Maximum capacity would be exceeded.
161  
        Maximum capacity would be exceeded.
162  
        @throw std::invalid_argument
162  
        @throw std::invalid_argument
163  
        `sc == status::unknown`
163  
        `sc == status::unknown`
164  

164  

165  
        @param sc The status code to set. This
165  
        @param sc The status code to set. This
166  
        must not be @ref status::unknown.
166  
        must not be @ref status::unknown.
167  
    */
167  
    */
168  
    void
168  
    void
169  
    set_status(
169  
    set_status(
170  
        http::status sc)
170  
        http::status sc)
171  
    {
171  
    {
172  
        if(sc == http::status::unknown)
172  
        if(sc == http::status::unknown)
173  
            detail::throw_invalid_argument();
173  
            detail::throw_invalid_argument();
174  
        set_start_line_impl(sc,
174  
        set_start_line_impl(sc,
175  
            static_cast<unsigned short>(sc),
175  
            static_cast<unsigned short>(sc),
176  
            to_string(sc),
176  
            to_string(sc),
177  
            version());
177  
            version());
178  
    }
178  
    }
179  

179  

180  
    /** Set the status code and version of the response.
180  
    /** Set the status code and version of the response.
181  

181  

182  
        The reason-phrase will be set to the
182  
        The reason-phrase will be set to the
183  
        standard text for the specified status
183  
        standard text for the specified status
184  
        code.
184  
        code.
185  

185  

186  
        This is more efficient than setting the
186  
        This is more efficient than setting the
187  
        properties individually.
187  
        properties individually.
188  

188  

189  
        @par Exception Safety
189  
        @par Exception Safety
190  
        Strong guarantee.
190  
        Strong guarantee.
191  
        Calls to allocate may throw.
191  
        Calls to allocate may throw.
192  
        Exception thrown on invalid input.
192  
        Exception thrown on invalid input.
193  
        Exception thrown if max capacity exceeded.
193  
        Exception thrown if max capacity exceeded.
194  

194  

195  
        @throw system_error
195  
        @throw system_error
196  
        Input is invalid.
196  
        Input is invalid.
197  

197  

198  
        @throw std::length_error
198  
        @throw std::length_error
199  
        Max capacity would be exceeded.
199  
        Max capacity would be exceeded.
200  

200  

201  
        @param si An integral representing the
201  
        @param si An integral representing the
202  
        status code to set.
202  
        status code to set.
203  

203  

204  
        @param reason A string view representing the
204  
        @param reason A string view representing the
205  
        reason string to set.
205  
        reason string to set.
206  

206  

207  
        @param v The version to set.
207  
        @param v The version to set.
208  
    */
208  
    */
209  
    void
209  
    void
210  
    set_start_line(
210  
    set_start_line(
211  
        unsigned short si,
211  
        unsigned short si,
212  
        core::string_view reason,
212  
        core::string_view reason,
213  
        http::version v =
213  
        http::version v =
214  
            http::version::http_1_1)
214  
            http::version::http_1_1)
215  
    {
215  
    {
216  
        set_start_line_impl(
216  
        set_start_line_impl(
217  
            int_to_status(si),
217  
            int_to_status(si),
218  
            si,
218  
            si,
219  
            reason,
219  
            reason,
220  
            v);
220  
            v);
221  
    }
221  
    }
222  

222  

223  
private:
223  
private:
224  
    BOOST_HTTP_DECL
224  
    BOOST_HTTP_DECL
225  
    void
225  
    void
226  
    set_start_line_impl(
226  
    set_start_line_impl(
227  
        http::status sc,
227  
        http::status sc,
228  
        unsigned short si,
228  
        unsigned short si,
229  
        core::string_view reason,
229  
        core::string_view reason,
230  
        http::version v);
230  
        http::version v);
231  
};
231  
};
232  

232  

233  
} // http
233  
} // http
234  
} // boost
234  
} // boost
235  

235  

236  
#endif
236  
#endif