• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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