Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2025 Mohammad Nejati
4 : //
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)
7 : //
8 : // Official repository: https://github.com/cppalliance/http_proto
9 : //
10 :
11 : #ifndef BOOST_HTTP_PROTO_RESPONSE_PARSER_HPP
12 : #define BOOST_HTTP_PROTO_RESPONSE_PARSER_HPP
13 :
14 : #include <boost/http_proto/detail/config.hpp>
15 : #include <boost/http_proto/error.hpp>
16 : #include <boost/http_proto/parser.hpp>
17 : #include <boost/http_proto/static_response.hpp>
18 : #include <boost/http_proto/status.hpp>
19 :
20 : namespace boost {
21 : namespace http_proto {
22 :
23 : /// @copydoc parser
24 : /// @brief A parser for HTTP/1 responses.
25 : /// @see @ref request_parser.
26 : class response_parser
27 : : public parser
28 : {
29 : public:
30 : /** Configuration settings for response_parser.
31 :
32 : @see
33 : @ref install_parser_service,
34 : @ref response_parser.
35 : */
36 : struct config : config_base
37 : {
38 : /** Constructor.
39 : */
40 15 : config() noexcept
41 15 : {
42 15 : body_limit = 1024 * 1024;
43 15 : }
44 : };
45 :
46 : /** Destructor.
47 :
48 : Any views or buffers obtained from this
49 : parser become invalid.
50 : */
51 37 : ~response_parser() = default;
52 :
53 : /** Constructor.
54 :
55 : Default-constructed parsers do not reference any
56 : implementation and therefore must be assigned to before using.
57 : */
58 5 : response_parser() = default;
59 :
60 : /** Constructor.
61 :
62 : The states of `other` are transferred
63 : to the newly constructed object,
64 : including the allocated buffer.
65 : After construction, the only valid
66 : operations on the moved-from object
67 : are destruction and assignemt.
68 :
69 : Buffer sequences previously obtained
70 : using @ref prepare or @ref pull_body
71 : remain valid.
72 :
73 : @par Complexity
74 : Constant.
75 :
76 : @param other The parser to move from.
77 : */
78 1 : response_parser(
79 : response_parser&& other) noexcept = default;
80 :
81 : /** Assignment.
82 : The states of `other` are transferred
83 : to this object, including the allocated
84 : buffer.
85 : After assignment, the only valid
86 : operations on the moved-from object
87 : are destruction and assignment.
88 : Buffer sequences previously obtained
89 : using @ref prepare or @ref pull_body
90 : remain valid.
91 : @par Complexity
92 : Constant.
93 : @param other The parser to move from.
94 : */
95 : response_parser&
96 2 : operator=(response_parser&& other) noexcept
97 : {
98 2 : assign(std::move(other));
99 2 : return *this;
100 : }
101 :
102 : /** Constructor.
103 :
104 : Constructs a parser that uses the @ref
105 : config parameters installed on the
106 : provided `ctx`.
107 :
108 : The parser will attempt to allocate
109 : the required space on startup, with the
110 : amount depending on the @ref config
111 : parameters, and will not perform any
112 : further allocations, except for Brotli
113 : decoder instances, if enabled.
114 :
115 : Depending on which compression algorithms
116 : are enabled in the @ref config, the parser
117 : will attempt to access the corresponding
118 : decoder services on the same `ctx`.
119 :
120 : @par Example
121 : @code
122 : response_parser sr(ctx);
123 : @endcode
124 :
125 : @par Complexity
126 : Constant.
127 :
128 : @par Exception Safety
129 : Calls to allocate may throw.
130 :
131 : @param ctx Context from which the
132 : response_parser will access registered
133 : services. The caller is responsible for
134 : ensuring that the provided ctx remains
135 : valid for the lifetime of the response_parser.
136 :
137 : @see
138 : @ref install_parser_service,
139 : @ref config.
140 : */
141 : BOOST_HTTP_PROTO_DECL
142 : explicit
143 : response_parser(capy::polystore& ctx);
144 :
145 : /** Prepare for the next message on the stream.
146 :
147 : This informs the parser not to read a
148 : payload for the next message, regardless
149 : of the presence or absence of certain
150 : fields such as Content-Length or a chunked
151 : Transfer-Encoding. Depending on the request,
152 : some responses do not carry a body. For
153 : example, a 200 response to a CONNECT
154 : request from a tunneling proxy, or a
155 : response to a HEAD request. In these
156 : cases, callers may use this function
157 : inform the parser that no body is
158 : expected. The parser will consider the
159 : message complete after the header has
160 : been received.
161 :
162 : @par Preconditions
163 : No previous call to @ref start for the new message.
164 :
165 : @see
166 : https://datatracker.ietf.org/doc/html/rfc7230#section-3.3
167 : */
168 : void
169 : start_head_response()
170 : {
171 : start_impl(true);
172 : }
173 :
174 : /** Return a reference to the parsed response headers.
175 :
176 : The returned reference remains valid until:
177 : @li @ref start or @ref start_head_response is called
178 : @li @ref reset is called
179 : @li The parser instance is destroyed
180 :
181 : @par Preconditions
182 : @code
183 : this->got_header() == true
184 : @endcode
185 :
186 : @par Exception Safety
187 : Strong guarantee.
188 :
189 : @see
190 : @ref got_header.
191 : */
192 : BOOST_HTTP_PROTO_DECL
193 : static_response const&
194 : get() const;
195 : };
196 :
197 : } // http_proto
198 : } // boost
199 :
200 : #endif
|