1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
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)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #include <boost/beast/http/basic_parser.hpp>
11
12 namespace boost {
13 namespace beast {
14 namespace http {
15
16 //[code_http_10_custom_parser
17
18 template<bool isRequest>
19 class custom_parser : public basic_parser<isRequest>
20 {
21 private:
22 /** Called after receiving the request-line.
23
24 This virtual function is invoked after receiving a request-line
25 when parsing HTTP requests.
26 It can only be called when `isRequest == true`.
27
28 @param method The verb enumeration. If the method string is not
29 one of the predefined strings, this value will be @ref verb::unknown.
30
31 @param method_str The unmodified string representing the verb.
32
33 @param target The request-target.
34
35 @param version The HTTP-version. This will be 10 for HTTP/1.0,
36 and 11 for HTTP/1.1.
37
38 @param ec An output parameter which the function may set to indicate
39 an error. The error will be clear before this function is invoked.
40 */
41 void
42 on_request_impl(
43 verb method, // The method verb, verb::unknown if no match
44 string_view method_str, // The method as a string
45 string_view target, // The request-target
46 int version, // The HTTP-version
47 error_code& ec) override; // The error returned to the caller, if any
48
49 /** Called after receiving the status-line.
50
51 This virtual function is invoked after receiving a status-line
52 when parsing HTTP responses.
53 It can only be called when `isRequest == false`.
54
55 @param code The numeric status code.
56
57 @param reason The reason-phrase. Note that this value is
58 now obsolete, and only provided for historical or diagnostic
59 purposes.
60
61 @param version The HTTP-version. This will be 10 for HTTP/1.0,
62 and 11 for HTTP/1.1.
63
64 @param ec An output parameter which the function may set to indicate
65 an error. The error will be clear before this function is invoked.
66 */
67 void
68 on_response_impl(
69 int code, // The status-code
70 string_view reason, // The obsolete reason-phrase
71 int version, // The HTTP-version
72 error_code& ec) override; // The error returned to the caller, if any
73
74 /** Called once for each complete field in the HTTP header.
75
76 This virtual function is invoked for each field that is received
77 while parsing an HTTP message.
78
79 @param name The known field enum value. If the name of the field
80 is not recognized, this value will be @ref field::unknown.
81
82 @param name_string The exact name of the field as received from
83 the input, represented as a string.
84
85 @param value A string holding the value of the field.
86
87 @param ec An output parameter which the function may set to indicate
88 an error. The error will be clear before this function is invoked.
89 */
90 void
91 on_field_impl(
92 field f, // The known-field enumeration constant
93 string_view name, // The field name string.
94 string_view value, // The field value
95 error_code& ec) override; // The error returned to the caller, if any
96
97 /** Called once after the complete HTTP header is received.
98
99 This virtual function is invoked once, after the complete HTTP
100 header is received while parsing a message.
101
102 @param ec An output parameter which the function may set to indicate
103 an error. The error will be clear before this function is invoked.
104 */
105 void
106 on_header_impl(
107 error_code& ec) override; // The error returned to the caller, if any
108
109 /** Called once before the body is processed.
110
111 This virtual function is invoked once, before the content body is
112 processed (but after the complete header is received).
113
114 @param content_length A value representing the content length in
115 bytes if the length is known (this can include a zero length).
116 Otherwise, the value will be `boost::none`.
117
118 @param ec An output parameter which the function may set to indicate
119 an error. The error will be clear before this function is invoked.
120 */
121 void
122 on_body_init_impl(
123 boost::optional<
124 std::uint64_t> const&
125 content_length, // Content length if known, else `boost::none`
126 error_code& ec) override; // The error returned to the caller, if any
127
128 /** Called each time additional data is received representing the content body.
129
130 This virtual function is invoked for each piece of the body which is
131 received while parsing of a message. This function is only used when
132 no chunked transfer encoding is present.
133
134 @param body A string holding the additional body contents. This may
135 contain nulls or unprintable characters.
136
137 @param ec An output parameter which the function may set to indicate
138 an error. The error will be clear before this function is invoked.
139
140 @see on_chunk_body_impl
141 */
142 std::size_t
143 on_body_impl(
144 string_view s, // A portion of the body
145 error_code& ec) override; // The error returned to the caller, if any
146
147 /** Called each time a new chunk header of a chunk encoded body is received.
148
149 This function is invoked each time a new chunk header is received.
150 The function is only used when the chunked transfer encoding is present.
151
152 @param size The size of this chunk, in bytes.
153
154 @param extensions A string containing the entire chunk extensions.
155 This may be empty, indicating no extensions are present.
156
157 @param ec An output parameter which the function may set to indicate
158 an error. The error will be clear before this function is invoked.
159 */
160 void
161 on_chunk_header_impl(
162 std::uint64_t size, // The size of the upcoming chunk,
163 // or zero for the last chunk
164 string_view extension, // The chunk extensions (may be empty)
165 error_code& ec) override; // The error returned to the caller, if any
166
167 /** Called each time additional data is received representing part of a body chunk.
168
169 This virtual function is invoked for each piece of the body which is
170 received while parsing of a message. This function is only used when
171 no chunked transfer encoding is present.
172
173 @param remain The number of bytes remaining in this chunk. This includes
174 the contents of passed `body`. If this value is zero, then this represents
175 the final chunk.
176
177 @param body A string holding the additional body contents. This may
178 contain nulls or unprintable characters.
179
180 @param ec An output parameter which the function may set to indicate
181 an error. The error will be clear before this function is invoked.
182
183 @return This function should return the number of bytes actually consumed
184 from the `body` value. Any bytes that are not consumed on this call
185 will be presented in a subsequent call.
186
187 @see on_body_impl
188 */
189 std::size_t
190 on_chunk_body_impl(
191 std::uint64_t remain, // The number of bytes remaining in the chunk,
192 // including what is being passed here.
193 // or zero for the last chunk
194 string_view body, // The next piece of the chunk body
195 error_code& ec) override; // The error returned to the caller, if any
196
197 /** Called once when the complete message is received.
198
199 This virtual function is invoked once, after successfully parsing
200 a complete HTTP message.
201
202 @param ec An output parameter which the function may set to indicate
203 an error. The error will be clear before this function is invoked.
204 */
205 void
206 on_finish_impl(
207 error_code& ec) override; // The error returned to the caller, if any
208
209 public:
210 custom_parser() = default;
211 };
212
213 //]
214
215 // Definitions are not part of the docs but necessary to link
216
217 template<bool isRequest>
218 void custom_parser<isRequest>::
on_request_impl(verb method,string_view method_str,string_view path,int version,error_code & ec)219 on_request_impl(verb method, string_view method_str,
220 string_view path, int version, error_code& ec)
221 {
222 boost::ignore_unused(method, method_str, path, version);
223 ec = {};
224 }
225
226 template<bool isRequest>
227 void custom_parser<isRequest>::
on_response_impl(int status,string_view reason,int version,error_code & ec)228 on_response_impl(
229 int status,
230 string_view reason,
231 int version,
232 error_code& ec)
233 {
234 boost::ignore_unused(status, reason, version);
235 ec = {};
236 }
237
238 template<bool isRequest>
239 void custom_parser<isRequest>::
on_field_impl(field f,string_view name,string_view value,error_code & ec)240 on_field_impl(
241 field f,
242 string_view name,
243 string_view value,
244 error_code& ec)
245 {
246 boost::ignore_unused(f, name, value);
247 ec = {};
248 }
249
250 template<bool isRequest>
251 void custom_parser<isRequest>::
on_header_impl(error_code & ec)252 on_header_impl(error_code& ec)
253 {
254 ec = {};
255 }
256
257 template<bool isRequest>
258 void custom_parser<isRequest>::
on_body_init_impl(boost::optional<std::uint64_t> const & content_length,error_code & ec)259 on_body_init_impl(
260 boost::optional<std::uint64_t> const& content_length,
261 error_code& ec)
262 {
263 boost::ignore_unused(content_length);
264 ec = {};
265 }
266
267 template<bool isRequest>
268 std::size_t custom_parser<isRequest>::
on_body_impl(string_view body,error_code & ec)269 on_body_impl(string_view body, error_code& ec)
270 {
271 boost::ignore_unused(body);
272 ec = {};
273 return body.size();
274 }
275
276 template<bool isRequest>
277 void custom_parser<isRequest>::
on_chunk_header_impl(std::uint64_t size,string_view extension,error_code & ec)278 on_chunk_header_impl(
279 std::uint64_t size,
280 string_view extension,
281 error_code& ec)
282 {
283 boost::ignore_unused(size, extension);
284 ec = {};
285 }
286
287 template<bool isRequest>
288 std::size_t custom_parser<isRequest>::
on_chunk_body_impl(std::uint64_t remain,string_view body,error_code & ec)289 on_chunk_body_impl(
290 std::uint64_t remain,
291 string_view body,
292 error_code& ec)
293 {
294 boost::ignore_unused(remain);
295 ec = {};
296 return body.size();
297 }
298
299 template<bool isRequest>
300 void custom_parser<isRequest>::
on_finish_impl(error_code & ec)301 on_finish_impl(error_code& ec)
302 {
303 ec = {};
304 }
305
306 template class custom_parser<true>;
307 template class custom_parser<false>;
308
309 } // http
310 } // beast
311 } // boost
312