1//
2// Copyright (c) 2016-2019 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#ifndef BOOST_BEAST_HTTP_BASIC_PARSER_HPP
11#define BOOST_BEAST_HTTP_BASIC_PARSER_HPP
12
13#include <boost/beast/core/detail/config.hpp>
14#include <boost/beast/core/error.hpp>
15#include <boost/beast/core/string.hpp>
16#include <boost/beast/http/field.hpp>
17#include <boost/beast/http/verb.hpp>
18#include <boost/beast/http/detail/basic_parser.hpp>
19#include <boost/asio/buffer.hpp>
20#include <boost/optional.hpp>
21#include <boost/assert.hpp>
22#include <cstdint>
23#include <limits>
24#include <memory>
25#include <type_traits>
26#include <utility>
27
28namespace boost {
29namespace beast {
30namespace http {
31
32/** A parser for decoding HTTP/1 wire format messages.
33
34 This parser is designed to efficiently parse messages in the
35 HTTP/1 wire format. It allocates no memory when input is
36 presented as a single contiguous buffer, and uses minimal
37 state. It will handle chunked encoding and it understands
38 the semantics of the Connection, Content-Length, and Upgrade
39 fields.
40 The parser is optimized for the case where the input buffer
41 sequence consists of a single contiguous buffer. The
42 @ref beast::basic_flat_buffer class is provided, which guarantees
43 that the input sequence of the stream buffer will be represented
44 by exactly one contiguous buffer. To ensure the optimum performance
45 of the parser, use @ref beast::basic_flat_buffer with HTTP algorithms
46 such as @ref read, @ref read_some, @ref async_read, and @ref async_read_some.
47 Alternatively, the caller may use custom techniques to ensure that
48 the structured portion of the HTTP message (header or chunk header)
49 is contained in a linear buffer.
50
51 The interface to the parser uses virtual member functions.
52 To use this class, derive your type from @ref basic_parser. When
53 bytes are presented, the implementation will make a series of zero
54 or more calls to virtual functions, which the derived class must
55 implement.
56
57 Every virtual function must be provided by the derived class,
58 or else a compilation error will be generated. The implementation
59 will make sure that `ec` is clear before each virtual function
60 is invoked. If a virtual function sets an error, it is propagated
61 out of the parser to the caller.
62
63 @tparam isRequest A `bool` indicating whether the parser will be
64 presented with request or response message.
65
66 @note If the parser encounters a field value with obs-fold
67 longer than 4 kilobytes in length, an error is generated.
68*/
69template<bool isRequest>
70class basic_parser
71 : private detail::basic_parser_base
72{
73 boost::optional<std::uint64_t>
74 body_limit_ =
75 boost::optional<std::uint64_t>(
76 default_body_limit(is_request{})); // max payload body
77 std::uint64_t len_ = 0; // size of chunk or body
78 std::uint64_t len0_ = 0; // content length if known
79 std::unique_ptr<char[]> buf_; // temp storage
80 std::size_t buf_len_ = 0; // size of buf_
81 std::size_t skip_ = 0; // resume search here
82 std::uint32_t header_limit_ = 8192; // max header size
83 unsigned short status_ = 0; // response status
84 state state_ = state::nothing_yet; // initial state
85 unsigned f_ = 0; // flags
86
87 // limit on the size of the stack flat buffer
88 static std::size_t constexpr max_stack_buffer = 8192;
89
90 // Message will be complete after reading header
91 static unsigned constexpr flagSkipBody = 1<< 0;
92
93 // Consume input buffers across semantic boundaries
94 static unsigned constexpr flagEager = 1<< 1;
95
96 // The parser has read at least one byte
97 static unsigned constexpr flagGotSome = 1<< 2;
98
99 // Message semantics indicate a body is expected.
100 // cleared if flagSkipBody set
101 //
102 static unsigned constexpr flagHasBody = 1<< 3;
103
104 static unsigned constexpr flagHTTP11 = 1<< 4;
105 static unsigned constexpr flagNeedEOF = 1<< 5;
106 static unsigned constexpr flagExpectCRLF = 1<< 6;
107 static unsigned constexpr flagConnectionClose = 1<< 7;
108 static unsigned constexpr flagConnectionUpgrade = 1<< 8;
109 static unsigned constexpr flagConnectionKeepAlive = 1<< 9;
110 static unsigned constexpr flagContentLength = 1<< 10;
111 static unsigned constexpr flagChunked = 1<< 11;
112 static unsigned constexpr flagUpgrade = 1<< 12;
113 static unsigned constexpr flagFinalChunk = 1<< 13;
114
115 static constexpr
116 std::uint64_t
117 default_body_limit(std::true_type)
118 {
119 // limit for requests
120 return 1 * 1024 * 1024; // 1MB
121 }
122
123 static constexpr
124 std::uint64_t
125 default_body_limit(std::false_type)
126 {
127 // limit for responses
128 return 8 * 1024 * 1024; // 8MB
129 }
130
131 template<bool OtherIsRequest>
132 friend class basic_parser;
133
134#ifndef BOOST_BEAST_DOXYGEN
135 friend class basic_parser_test;
136#endif
137
138protected:
139 /// Default constructor
140 basic_parser() = default;
141
142 /** Move constructor
143
144 @note
145
146 After the move, the only valid operation on the
147 moved-from object is destruction.
148 */
149 basic_parser(basic_parser &&) = default;
150
151 /// Move assignment
152 basic_parser& operator=(basic_parser &&) = default;
153
154public:
155 /// `true` if this parser parses requests, `false` for responses.
156 using is_request =
157 std::integral_constant<bool, isRequest>;
158
159 /// Destructor
160 virtual ~basic_parser() = default;
161
162 /// Copy constructor
163 basic_parser(basic_parser const&) = delete;
164
165 /// Copy assignment
166 basic_parser& operator=(basic_parser const&) = delete;
167
168 /// Returns `true` if the parser has received at least one byte of input.
169 bool
170 got_some() const
171 {
172 return state_ != state::nothing_yet;
173 }
174
175 /** Returns `true` if the message is complete.
176
177 The message is complete after the full header is prduced
178 and one of the following is true:
179
180 @li The skip body option was set.
181
182 @li The semantics of the message indicate there is no body.
183
184 @li The semantics of the message indicate a body is expected,
185 and the entire body was parsed.
186 */
187 bool
188 is_done() const
189 {
190 return state_ == state::complete;
191 }
192
193 /** Returns `true` if a the parser has produced the full header.
194 */
195 bool
196 is_header_done() const
197 {
198 return state_ > state::fields;
199 }
200
201 /** Returns `true` if the message is an upgrade message.
202
203 @note The return value is undefined unless
204 @ref is_header_done would return `true`.
205 */
206 bool
207 upgrade() const
208 {
209 return (f_ & flagConnectionUpgrade) != 0;
210 }
211
212 /** Returns `true` if the last value for Transfer-Encoding is "chunked".
213
214 @note The return value is undefined unless
215 @ref is_header_done would return `true`.
216 */
217 bool
218 chunked() const
219 {
220 return (f_ & flagChunked) != 0;
221 }
222
223 /** Returns `true` if the message has keep-alive connection semantics.
224
225 This function always returns `false` if @ref need_eof would return
226 `false`.
227
228 @note The return value is undefined unless
229 @ref is_header_done would return `true`.
230 */
231 bool
232 keep_alive() const;
233
234 /** Returns the optional value of Content-Length if known.
235
236 @note The return value is undefined unless
237 @ref is_header_done would return `true`.
238 */
239 boost::optional<std::uint64_t>
240 content_length() const;
241
242 /** Returns the remaining content length if known
243
244 If the message header specifies a Content-Length,
245 the return value will be the number of bytes remaining
246 in the payload body have not yet been parsed.
247
248 @note The return value is undefined unless
249 @ref is_header_done would return `true`.
250 */
251 boost::optional<std::uint64_t>
252 content_length_remaining() const;
253
254 /** Returns `true` if the message semantics require an end of file.
255
256 Depending on the contents of the header, the parser may
257 require and end of file notification to know where the end
258 of the body lies. If this function returns `true` it will be
259 necessary to call @ref put_eof when there will never be additional
260 data from the input.
261 */
262 bool
263 need_eof() const
264 {
265 return (f_ & flagNeedEOF) != 0;
266 }
267
268 /** Set the limit on the payload body.
269
270 This function sets the maximum allowed size of the payload body,
271 before any encodings except chunked have been removed. Depending
272 on the message semantics, one of these cases will apply:
273
274 @li The Content-Length is specified and exceeds the limit. In
275 this case the result @ref error::body_limit is returned
276 immediately after the header is parsed.
277
278 @li The Content-Length is unspecified and the chunked encoding
279 is not specified as the last encoding. In this case the end of
280 message is determined by the end of file indicator on the
281 associated stream or input source. If a sufficient number of
282 body payload octets are presented to the parser to exceed the
283 configured limit, the parse fails with the result
284 @ref error::body_limit
285
286 @li The Transfer-Encoding specifies the chunked encoding as the
287 last encoding. In this case, when the number of payload body
288 octets produced by removing the chunked encoding exceeds
289 the configured limit, the parse fails with the result
290 @ref error::body_limit.
291
292 Setting the limit after any body octets have been parsed
293 results in undefined behavior.
294
295 The default limit is 1MB for requests and 8MB for responses.
296
297 @param v An optional integral value representing the body limit.
298 If this is equal to `boost::none`, then the body limit is disabled.
299 */
300 void
301 body_limit(boost::optional<std::uint64_t> v)
302 {
303 body_limit_ = v;
304 }
305
306 /** Set a limit on the total size of the header.
307
308 This function sets the maximum allowed size of the header
309 including all field name, value, and delimiter characters
310 and also including the CRLF sequences in the serialized
311 input. If the end of the header is not found within the
312 limit of the header size, the error @ref error::header_limit
313 is returned by @ref put.
314
315 Setting the limit after any header octets have been parsed
316 results in undefined behavior.
317 */
318 void
319 header_limit(std::uint32_t v)
320 {
321 header_limit_ = v;
322 }
323
324 /// Returns `true` if the eager parse option is set.
325 bool
326 eager() const
327 {
328 return (f_ & flagEager) != 0;
329 }
330
331 /** Set the eager parse option.
332
333 Normally the parser returns after successfully parsing a structured
334 element (header, chunk header, or chunk body) even if there are octets
335 remaining in the input. This is necessary when attempting to parse the
336 header first, or when the caller wants to inspect information which may
337 be invalidated by subsequent parsing, such as a chunk extension. The
338 `eager` option controls whether the parser keeps going after parsing
339 structured element if there are octets remaining in the buffer and no
340 error occurs. This option is automatically set or cleared during certain
341 stream operations to improve performance with no change in functionality.
342
343 The default setting is `false`.
344
345 @param v `true` to set the eager parse option or `false` to disable it.
346 */
347 void
348 eager(bool v)
349 {
350 if(v)
351 f_ |= flagEager;
352 else
353 f_ &= ~flagEager;
354 }
355
356 /// Returns `true` if the skip parse option is set.
357 bool
358 skip() const
359 {
360 return (f_ & flagSkipBody) != 0;
361 }
362
363 /** Set the skip parse option.
364
365 This option controls whether or not the parser expects to see an HTTP
366 body, regardless of the presence or absence of certain fields such as
367 Content-Length or a chunked Transfer-Encoding. Depending on the request,
368 some responses do not carry a body. For example, a 200 response to a
369 CONNECT request from a tunneling proxy, or a response to a HEAD request.
370 In these cases, callers may use this function inform the parser that
371 no body is expected. The parser will consider the message complete
372 after the header has been received.
373
374 @param v `true` to set the skip body option or `false` to disable it.
375
376 @note This function must called before any bytes are processed.
377 */
378 void
379 skip(bool v);
380
381 /** Write a buffer sequence to the parser.
382
383 This function attempts to incrementally parse the HTTP
384 message data stored in the caller provided buffers. Upon
385 success, a positive return value indicates that the parser
386 made forward progress, consuming that number of
387 bytes.
388
389 In some cases there may be an insufficient number of octets
390 in the input buffer in order to make forward progress. This
391 is indicated by the code @ref error::need_more. When
392 this happens, the caller should place additional bytes into
393 the buffer sequence and call @ref put again.
394
395 The error code @ref error::need_more is special. When this
396 error is returned, a subsequent call to @ref put may succeed
397 if the buffers have been updated. Otherwise, upon error
398 the parser may not be restarted.
399
400 @param buffers An object meeting the requirements of
401 <em>ConstBufferSequence</em> that represents the next chunk of
402 message data. If the length of this buffer sequence is
403 one, the implementation will not allocate additional memory.
404 The class @ref beast::basic_flat_buffer is provided as one way to
405 meet this requirement
406
407 @param ec Set to the error, if any occurred.
408
409 @return The number of octets consumed in the buffer
410 sequence. The caller should remove these octets even if the
411 error is set.
412 */
413 template<class ConstBufferSequence>
414 std::size_t
415 put(ConstBufferSequence const& buffers, error_code& ec);
416
417#if ! BOOST_BEAST_DOXYGEN
418 std::size_t
419 put(net::const_buffer buffer,
420 error_code& ec);
421#endif
422
423 /** Inform the parser that the end of stream was reached.
424
425 In certain cases, HTTP needs to know where the end of
426 the stream is. For example, sometimes servers send
427 responses without Content-Length and expect the client
428 to consume input (for the body) until EOF. Callbacks
429 and errors will still be processed as usual.
430
431 This is typically called when a read from the
432 underlying stream object sets the error code to
433 `net::error::eof`.
434
435 @note Only valid after parsing a complete header.
436
437 @param ec Set to the error, if any occurred.
438 */
439 void
440 put_eof(error_code& ec);
441
442protected:
443 /** Called after receiving the request-line.
444
445 This virtual function is invoked after receiving a request-line
446 when parsing HTTP requests.
447 It can only be called when `isRequest == true`.
448
449 @param method The verb enumeration. If the method string is not
450 one of the predefined strings, this value will be @ref verb::unknown.
451
452 @param method_str The unmodified string representing the verb.
453
454 @param target The request-target.
455
456 @param version The HTTP-version. This will be 10 for HTTP/1.0,
457 and 11 for HTTP/1.1.
458
459 @param ec An output parameter which the function may set to indicate
460 an error. The error will be clear before this function is invoked.
461 */
462 virtual
463 void
464 on_request_impl(
465 verb method,
466 string_view method_str,
467 string_view target,
468 int version,
469 error_code& ec) = 0;
470
471 /** Called after receiving the status-line.
472
473 This virtual function is invoked after receiving a status-line
474 when parsing HTTP responses.
475 It can only be called when `isRequest == false`.
476
477 @param code The numeric status code.
478
479 @param reason The reason-phrase. Note that this value is
480 now obsolete, and only provided for historical or diagnostic
481 purposes.
482
483 @param version The HTTP-version. This will be 10 for HTTP/1.0,
484 and 11 for HTTP/1.1.
485
486 @param ec An output parameter which the function may set to indicate
487 an error. The error will be clear before this function is invoked.
488 */
489 virtual
490 void
491 on_response_impl(
492 int code,
493 string_view reason,
494 int version,
495 error_code& ec) = 0;
496
497 /** Called once for each complete field in the HTTP header.
498
499 This virtual function is invoked for each field that is received
500 while parsing an HTTP message.
501
502 @param name The known field enum value. If the name of the field
503 is not recognized, this value will be @ref field::unknown.
504
505 @param name_string The exact name of the field as received from
506 the input, represented as a string.
507
508 @param value A string holding the value of the field.
509
510 @param ec An output parameter which the function may set to indicate
511 an error. The error will be clear before this function is invoked.
512 */
513 virtual
514 void
515 on_field_impl(
516 field name,
517 string_view name_string,
518 string_view value,
519 error_code& ec) = 0;
520
521 /** Called once after the complete HTTP header is received.
522
523 This virtual function is invoked once, after the complete HTTP
524 header is received while parsing a message.
525
526 @param ec An output parameter which the function may set to indicate
527 an error. The error will be clear before this function is invoked.
528 */
529 virtual
530 void
531 on_header_impl(error_code& ec) = 0;
532
533 /** Called once before the body is processed.
534
535 This virtual function is invoked once, before the content body is
536 processed (but after the complete header is received).
537
538 @param content_length A value representing the content length in
539 bytes if the length is known (this can include a zero length).
540 Otherwise, the value will be `boost::none`.
541
542 @param ec An output parameter which the function may set to indicate
543 an error. The error will be clear before this function is invoked.
544 */
545 virtual
546 void
547 on_body_init_impl(
548 boost::optional<std::uint64_t> const& content_length,
549 error_code& ec) = 0;
550
551 /** Called each time additional data is received representing the content body.
552
553 This virtual function is invoked for each piece of the body which is
554 received while parsing of a message. This function is only used when
555 no chunked transfer encoding is present.
556
557 @param body A string holding the additional body contents. This may
558 contain nulls or unprintable characters.
559
560 @param ec An output parameter which the function may set to indicate
561 an error. The error will be clear before this function is invoked.
562
563 @see on_chunk_body_impl
564 */
565 virtual
566 std::size_t
567 on_body_impl(
568 string_view body,
569 error_code& ec) = 0;
570
571 /** Called each time a new chunk header of a chunk encoded body is received.
572
573 This function is invoked each time a new chunk header is received.
574 The function is only used when the chunked transfer encoding is present.
575
576 @param size The size of this chunk, in bytes.
577
578 @param extensions A string containing the entire chunk extensions.
579 This may be empty, indicating no extensions are present.
580
581 @param ec An output parameter which the function may set to indicate
582 an error. The error will be clear before this function is invoked.
583 */
584 virtual
585 void
586 on_chunk_header_impl(
587 std::uint64_t size,
588 string_view extensions,
589 error_code& ec) = 0;
590
591 /** Called each time additional data is received representing part of a body chunk.
592
593 This virtual function is invoked for each piece of the body which is
594 received while parsing of a message. This function is only used when
595 no chunked transfer encoding is present.
596
597 @param remain The number of bytes remaining in this chunk. This includes
598 the contents of passed `body`. If this value is zero, then this represents
599 the final chunk.
600
601 @param body A string holding the additional body contents. This may
602 contain nulls or unprintable characters.
603
604 @param ec An output parameter which the function may set to indicate
605 an error. The error will be clear before this function is invoked.
606
607 @return This function should return the number of bytes actually consumed
608 from the `body` value. Any bytes that are not consumed on this call
609 will be presented in a subsequent call.
610
611 @see on_body_impl
612 */
613 virtual
614 std::size_t
615 on_chunk_body_impl(
616 std::uint64_t remain,
617 string_view body,
618 error_code& ec) = 0;
619
620 /** Called once when the complete message is received.
621
622 This virtual function is invoked once, after successfully parsing
623 a complete HTTP message.
624
625 @param ec An output parameter which the function may set to indicate
626 an error. The error will be clear before this function is invoked.
627 */
628 virtual
629 void
630 on_finish_impl(error_code& ec) = 0;
631
632private:
633
634 boost::optional<std::uint64_t>
635 content_length_unchecked() const;
636
637 template<class ConstBufferSequence>
638 std::size_t
639 put_from_stack(
640 std::size_t size,
641 ConstBufferSequence const& buffers,
642 error_code& ec);
643
644 void
645 maybe_need_more(
646 char const* p, std::size_t n,
647 error_code& ec);
648
649 void
650 parse_start_line(
651 char const*& p, char const* last,
652 error_code& ec, std::true_type);
653
654 void
655 parse_start_line(
656 char const*& p, char const* last,
657 error_code& ec, std::false_type);
658
659 void
660 parse_fields(
661 char const*& p, char const* last,
662 error_code& ec);
663
664 void
665 finish_header(
666 error_code& ec, std::true_type);
667
668 void
669 finish_header(
670 error_code& ec, std::false_type);
671
672 void
673 parse_body(char const*& p,
674 std::size_t n, error_code& ec);
675
676 void
677 parse_body_to_eof(char const*& p,
678 std::size_t n, error_code& ec);
679
680 void
681 parse_chunk_header(char const*& p,
682 std::size_t n, error_code& ec);
683
684 void
685 parse_chunk_body(char const*& p,
686 std::size_t n, error_code& ec);
687
688 void
689 do_field(field f,
690 string_view value, error_code& ec);
691};
692
693} // http
694} // beast
695} // boost
696
697#include <boost/beast/http/impl/basic_parser.hpp>
698#ifdef BOOST_BEAST_HEADER_ONLY
699#include <boost/beast/http/impl/basic_parser.ipp>
700#endif
701
702#endif
703

source code of boost/libs/beast/include/boost/beast/http/basic_parser.hpp