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

10  

11  
#ifndef BOOST_HTTP_RESPONSE_PARSER_HPP
11  
#ifndef BOOST_HTTP_RESPONSE_PARSER_HPP
12  
#define BOOST_HTTP_RESPONSE_PARSER_HPP
12  
#define BOOST_HTTP_RESPONSE_PARSER_HPP
13  

13  

14  
#include <boost/http/detail/config.hpp>
14  
#include <boost/http/detail/config.hpp>
15  
#include <boost/http/error.hpp>
15  
#include <boost/http/error.hpp>
16  
#include <boost/http/parser.hpp>
16  
#include <boost/http/parser.hpp>
17  
#include <boost/http/static_response.hpp>
17  
#include <boost/http/static_response.hpp>
18  
#include <boost/http/status.hpp>
18  
#include <boost/http/status.hpp>
19  

19  

20  
#include <memory>
20  
#include <memory>
21  

21  

22  
namespace boost {
22  
namespace boost {
23  
namespace http {
23  
namespace http {
24  

24  

25  
/// @copydoc parser
25  
/// @copydoc parser
26  
/// @brief A parser for HTTP/1 responses.
26  
/// @brief A parser for HTTP/1 responses.
27  
/// @see @ref request_parser.
27  
/// @see @ref request_parser.
28  
class response_parser
28  
class response_parser
29  
    : public parser
29  
    : public parser
30  
{
30  
{
31  
public:
31  
public:
32  
    /** Destructor.
32  
    /** Destructor.
33  

33  

34  
        Any views or buffers obtained from this
34  
        Any views or buffers obtained from this
35  
        parser become invalid.
35  
        parser become invalid.
36  
    */
36  
    */
37  
    ~response_parser() = default;
37  
    ~response_parser() = default;
38  

38  

39  
    /** Default constructor.
39  
    /** Default constructor.
40  

40  

41  
        Constructs a parser with no allocated state.
41  
        Constructs a parser with no allocated state.
42  
        The parser must be assigned from a valid
42  
        The parser must be assigned from a valid
43  
        parser before use.
43  
        parser before use.
44  

44  

45  
        @par Postconditions
45  
        @par Postconditions
46  
        The parser has no allocated state.
46  
        The parser has no allocated state.
47  
    */
47  
    */
48  
    response_parser() = default;
48  
    response_parser() = default;
49  

49  

50  
    /** Constructor.
50  
    /** Constructor.
51  

51  

52  
        Constructs a parser with the provided configuration.
52  
        Constructs a parser with the provided configuration.
53  

53  

54  
        The parser will allocate the required space on
54  
        The parser will allocate the required space on
55  
        startup based on the config parameters, and will
55  
        startup based on the config parameters, and will
56  
        not perform any further allocations.
56  
        not perform any further allocations.
57  

57  

58  
        @par Example
58  
        @par Example
59  
        @code
59  
        @code
60  
        auto cfg = make_parser_config(parser_config{false});
60  
        auto cfg = make_parser_config(parser_config{false});
61  
        response_parser pr(cfg);
61  
        response_parser pr(cfg);
62  
        @endcode
62  
        @endcode
63  

63  

64  
        @par Complexity
64  
        @par Complexity
65  
        Constant.
65  
        Constant.
66  

66  

67  
        @par Exception Safety
67  
        @par Exception Safety
68  
        Calls to allocate may throw.
68  
        Calls to allocate may throw.
69  

69  

70  
        @param cfg Shared pointer to parser configuration.
70  
        @param cfg Shared pointer to parser configuration.
71  

71  

72  
        @see @ref make_parser_config, @ref parser_config.
72  
        @see @ref make_parser_config, @ref parser_config.
73  
    */
73  
    */
74  
    BOOST_HTTP_DECL
74  
    BOOST_HTTP_DECL
75  
    explicit
75  
    explicit
76  
    response_parser(
76  
    response_parser(
77  
        std::shared_ptr<parser_config_impl const> cfg);
77  
        std::shared_ptr<parser_config_impl const> cfg);
78  

78  

79  
    /** Constructor.
79  
    /** Constructor.
80  

80  

81  
        The states of `other` are transferred
81  
        The states of `other` are transferred
82  
        to the newly constructed object,
82  
        to the newly constructed object,
83  
        including the allocated buffer.
83  
        including the allocated buffer.
84  
        After construction, the only valid
84  
        After construction, the only valid
85  
        operations on the moved-from object
85  
        operations on the moved-from object
86  
        are destruction and assignment.
86  
        are destruction and assignment.
87  

87  

88  
        Buffer sequences previously obtained
88  
        Buffer sequences previously obtained
89  
        using @ref prepare or @ref pull_body
89  
        using @ref prepare or @ref pull_body
90  
        remain valid.
90  
        remain valid.
91  

91  

92  
        @par Complexity
92  
        @par Complexity
93  
        Constant.
93  
        Constant.
94  

94  

95  
        @param other The parser to move from.
95  
        @param other The parser to move from.
96  
    */
96  
    */
97  
    response_parser(
97  
    response_parser(
98  
        response_parser&& other) noexcept = default;
98  
        response_parser&& other) noexcept = default;
99  

99  

100  
    /** Assignment.
100  
    /** Assignment.
101  
        The states of `other` are transferred
101  
        The states of `other` are transferred
102  
        to this object, including the allocated
102  
        to this object, including the allocated
103  
        buffer.
103  
        buffer.
104  
        After assignment, the only valid
104  
        After assignment, the only valid
105  
        operations on the moved-from object
105  
        operations on the moved-from object
106  
        are destruction and assignment.
106  
        are destruction and assignment.
107  
        Buffer sequences previously obtained
107  
        Buffer sequences previously obtained
108  
        using @ref prepare or @ref pull_body
108  
        using @ref prepare or @ref pull_body
109  
        remain valid.
109  
        remain valid.
110  
        @par Complexity
110  
        @par Complexity
111  
        Constant.
111  
        Constant.
112  
        @param other The parser to move from.
112  
        @param other The parser to move from.
113  
    */
113  
    */
114  
    response_parser&
114  
    response_parser&
115  
    operator=(response_parser&& other) noexcept
115  
    operator=(response_parser&& other) noexcept
116  
    {
116  
    {
117  
        assign(std::move(other));
117  
        assign(std::move(other));
118  
        return *this;
118  
        return *this;
119  
    }
119  
    }
120  

120  

121  
    /** Prepare for the next message on the stream.
121  
    /** Prepare for the next message on the stream.
122  

122  

123  
        This informs the parser not to read a
123  
        This informs the parser not to read a
124  
        payload for the next message, regardless
124  
        payload for the next message, regardless
125  
        of the presence or absence of certain
125  
        of the presence or absence of certain
126  
        fields such as Content-Length or a chunked
126  
        fields such as Content-Length or a chunked
127  
        Transfer-Encoding. Depending on the request,
127  
        Transfer-Encoding. Depending on the request,
128  
        some responses do not carry a body. For
128  
        some responses do not carry a body. For
129  
        example, a 200 response to a CONNECT
129  
        example, a 200 response to a CONNECT
130  
        request from a tunneling proxy, or a
130  
        request from a tunneling proxy, or a
131  
        response to a HEAD request. In these
131  
        response to a HEAD request. In these
132  
        cases, callers may use this function
132  
        cases, callers may use this function
133  
        inform the parser that no body is
133  
        inform the parser that no body is
134  
        expected. The parser will consider the
134  
        expected. The parser will consider the
135  
        message complete after the header has
135  
        message complete after the header has
136  
        been received.
136  
        been received.
137  

137  

138  
        @par Preconditions
138  
        @par Preconditions
139  
        No previous call to @ref start for the new message.
139  
        No previous call to @ref start for the new message.
140  

140  

141  
        @see
141  
        @see
142  
            https://datatracker.ietf.org/doc/html/rfc7230#section-3.3
142  
            https://datatracker.ietf.org/doc/html/rfc7230#section-3.3
143  
    */
143  
    */
144  
    void
144  
    void
145  
    start_head_response()
145  
    start_head_response()
146  
    {
146  
    {
147  
        start_impl(true);
147  
        start_impl(true);
148  
    }
148  
    }
149  

149  

150  
    /** Return a reference to the parsed response headers.
150  
    /** Return a reference to the parsed response headers.
151  

151  

152  
        The returned reference remains valid until:
152  
        The returned reference remains valid until:
153  
        @li @ref start or @ref start_head_response is called
153  
        @li @ref start or @ref start_head_response is called
154  
        @li @ref reset is called
154  
        @li @ref reset is called
155  
        @li The parser instance is destroyed
155  
        @li The parser instance is destroyed
156  

156  

157  
        @par Preconditions
157  
        @par Preconditions
158  
        @code
158  
        @code
159  
        this->got_header() == true
159  
        this->got_header() == true
160  
        @endcode
160  
        @endcode
161  

161  

162  
        @par Exception Safety
162  
        @par Exception Safety
163  
        Strong guarantee.
163  
        Strong guarantee.
164  

164  

165  
        @see
165  
        @see
166  
            @ref got_header.
166  
            @ref got_header.
167  
    */
167  
    */
168  
    BOOST_HTTP_DECL
168  
    BOOST_HTTP_DECL
169  
    static_response const&
169  
    static_response const&
170  
    get() const;
170  
    get() const;
171  
};
171  
};
172  

172  

173  
} // http
173  
} // http
174  
} // boost
174  
} // boost
175  

175  

176  
#endif
176  
#endif