LCOV - code coverage report
Current view: top level - http_proto - parser.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 6 7 85.7 %
Date: 2023-01-26 23:44:13 Functions: 4 5 80.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/http_proto
       8             : //
       9             : 
      10             : #ifndef BOOST_HTTP_PROTO_BASIC_PARSER_HPP
      11             : #define BOOST_HTTP_PROTO_BASIC_PARSER_HPP
      12             : 
      13             : #include <boost/http_proto/detail/config.hpp>
      14             : #include <boost/http_proto/buffer.hpp>
      15             : #include <boost/http_proto/error.hpp>
      16             : #include <boost/http_proto/sink.hpp>
      17             : #include <boost/http_proto/string_view.hpp>
      18             : #include <boost/http_proto/detail/circular_buffer.hpp>
      19             : #include <boost/http_proto/detail/flat_buffer.hpp>
      20             : #include <boost/http_proto/detail/header.hpp>
      21             : #include <boost/http_proto/detail/workspace.hpp>
      22             : #include <boost/url/grammar/error.hpp>
      23             : #include <boost/optional.hpp>
      24             : #include <cstddef>
      25             : #include <cstdint>
      26             : #include <memory>
      27             : #include <utility>
      28             : 
      29             : namespace boost {
      30             : namespace http_proto {
      31             : 
      32             : #ifndef BOOST_HTTP_PROTO_DOCS
      33             : enum class version : char;
      34             : class request_parser;
      35             : class response_parser;
      36             : struct brotli_decoder_t;
      37             : struct brotli_encoder_t;
      38             : struct deflate_decoder_t;
      39             : struct deflate_encoder_t;
      40             : struct gzip_decoder_t;
      41             : struct gzip_encoder_t;
      42             : namespace detail {
      43             : struct codec;
      44             : }
      45             : #endif
      46             : 
      47             : /** A parser for HTTP/1 messages.
      48             : 
      49             :     The parser is strict. Any malformed
      50             :     inputs according to the documented
      51             :     HTTP ABNFs is treated as an
      52             :     unrecoverable error.
      53             : */
      54             : class BOOST_SYMBOL_VISIBLE
      55           0 :     parser
      56             : {
      57             : public:
      58             :     /** Parser configuration settings
      59             : 
      60             :         @see
      61             :             @li <a href="https://stackoverflow.com/questions/686217/maximum-on-http-header-values"
      62             :                 >Maximum on HTTP header values (Stackoverflow)</a>
      63             :     */
      64             :     struct config_base
      65             :     {
      66             :         /** Largest allowed size for the headers.
      67             : 
      68             :             This determines an upper bound on the
      69             :             allowed size of the start-line plus
      70             :             all of the individual fields in the
      71             :             headers. This counts all delimiters
      72             :             including trailing CRLFs.
      73             :         */
      74             :         std::size_t headers_limit = 16 * 1024;
      75             : 
      76             :         /** Largest allowed size for the start-line.
      77             : 
      78             :             This determines an upper bound on the
      79             :             allowed size for the request-line of
      80             :             an HTTP request or the status-line of
      81             :             an HTTP response.
      82             :         */
      83             :         std::size_t start_line_limit = 4096;
      84             : 
      85             :         /** Largest size for one field.
      86             : 
      87             :             This determines an upper bound on the
      88             :             allowed size for any single header
      89             :             in an HTTP message. This counts
      90             :             the field name, field value, and
      91             :             delimiters including a trailing CRLF.
      92             :         */
      93             :         std::size_t field_size_limit = 4096;
      94             : 
      95             :         /** Largest allowed number of fields.
      96             : 
      97             :             This determines an upper bound on the
      98             :             largest number of individual header
      99             :             fields that may appear in an HTTP
     100             :             message.
     101             :         */
     102             :         std::size_t fields_limit = 100;
     103             : 
     104             :         /** Largest allowed size for a content body.
     105             : 
     106             :             The size of the body is measured
     107             :             after removing any transfer encodings,
     108             :             including a chunked encoding.
     109             :         */
     110             :         std::uint64_t body_limit = 64 * 1024;
     111             :     };
     112             : 
     113             :     using buffers = mutable_buffers_pair;
     114             : 
     115             : private:
     116             :     BOOST_HTTP_PROTO_DECL parser(
     117             :         detail::kind, config_base const&);
     118             :     BOOST_HTTP_PROTO_DECL void construct(
     119             :         std::size_t extra_buffer_size);
     120             : public:
     121             : 
     122             :     //--------------------------------------------
     123             :     //
     124             :     // Special Members
     125             :     //
     126             :     //--------------------------------------------
     127             : 
     128             :     /** Destructor
     129             :     */
     130             :     BOOST_HTTP_PROTO_DECL
     131             :     ~parser();
     132             : 
     133             :     /** Constructor
     134             :     */
     135             :     BOOST_HTTP_PROTO_DECL
     136             :     parser(parser&&) noexcept;
     137             : 
     138             :     //--------------------------------------------
     139             :     //
     140             :     // Observers
     141             :     //
     142             :     //--------------------------------------------
     143             : 
     144             : #if 0
     145             :     /** Return true if any input was committed.
     146             :     */
     147             :     bool
     148             :     got_some() const noexcept
     149             :     {
     150             :         return st_ != state::need_start;
     151             :     }
     152             : #endif
     153             : 
     154             :     /** Return true if the complete header was parsed.
     155             :     */
     156             :     bool
     157             :     got_header() const noexcept
     158             :     {
     159             :         return st_ > state::headers;
     160             :     }
     161             : 
     162             :     /** Returns `true` if a complete message has been parsed.
     163             : 
     164             :         Calling @ref reset prepares the parser
     165             :         to process the next message in the stream.
     166             : 
     167             :     */
     168             :     bool
     169             :     is_complete() const noexcept
     170             :     {
     171             :         return st_ == state::complete;
     172             :     }
     173             : 
     174             :     BOOST_HTTP_PROTO_DECL
     175             :     string_view
     176             :     body() const noexcept;
     177             : 
     178             :     //--------------------------------------------
     179             :     //
     180             :     // Modifiers
     181             :     //
     182             :     //--------------------------------------------
     183             : 
     184             :     /** Prepare for a new stream.
     185             :     */
     186             :     BOOST_HTTP_PROTO_DECL
     187             :     void
     188             :     reset() noexcept;
     189             : 
     190             : private:
     191             :     // New message on the current stream
     192             :     BOOST_HTTP_PROTO_DECL void
     193             :         start_impl(bool head_response);
     194             : public:
     195             : 
     196             :     /** Return the input buffer
     197             :     */
     198             :     BOOST_HTTP_PROTO_DECL
     199             :     buffers
     200             :     prepare();
     201             : 
     202             :     /** Commit bytes to the input buffer
     203             :     */
     204             :     BOOST_HTTP_PROTO_DECL
     205             :     void
     206             :     commit(
     207             :         std::size_t n);
     208             : 
     209             :     /** Indicate there will be no more input
     210             :     */
     211             :     BOOST_HTTP_PROTO_DECL
     212             :     void
     213             :     commit_eof();
     214             : 
     215             :     /** Parse pending input data
     216             :     */
     217             :     BOOST_HTTP_PROTO_DECL
     218             :     void
     219             :     parse(
     220             :         error_code& ec);
     221             : 
     222             :     //--------------------------------------------
     223             : 
     224             :     /** Return any leftover data
     225             : 
     226             :         This is used to forward unconsumed data
     227             :         that could lie past the last message.
     228             :         For example on a CONNECT request there
     229             :         could be additional protocol-dependent
     230             :         data that we want to retrieve.
     231             :     */
     232             :     BOOST_HTTP_PROTO_DECL
     233             :     string_view
     234             :     release_buffered_data() noexcept;
     235             : 
     236             : private:
     237         744 :     void apply_params() noexcept
     238             :     {
     239         744 :     }
     240             : 
     241             :     void apply_param(...) = delete;
     242             : 
     243             :     template<class P0, class... Pn>
     244             :     void
     245           4 :     apply_params(P0&& p0, Pn&&... pn)
     246             :     {
     247             :         // If you get an error here it means
     248             :         // you passed an unknown parameter type.
     249           4 :         apply_param(std::forward<P0>(p0));
     250             : 
     251           4 :         apply_params(std::forward<Pn>(pn)...);
     252           4 :     }
     253             : 
     254             :     BOOST_HTTP_PROTO_DECL void apply_param(config_base const&) noexcept;
     255             : 
     256             :     // in detail/impl/brotli_codec.ipp
     257             :     BOOST_HTTP_PROTO_EXT_DECL void apply_param(brotli_decoder_t const&);
     258             : 
     259             :     // in detail/impl/zlib_codec.ipp
     260             :     BOOST_HTTP_PROTO_ZLIB_DECL void apply_param(deflate_decoder_t const&);
     261             :     BOOST_HTTP_PROTO_ZLIB_DECL void apply_param(gzip_decoder_t const&);
     262             : 
     263             :     detail::header const* safe_get_header() const;
     264             :     void parse_body(error_code&);
     265             :     void parse_chunk(error_code&);
     266             : 
     267             :     friend class request_parser;
     268             :     friend class response_parser;
     269             : 
     270             :     enum
     271             :     {
     272             :         br_codec = 0,
     273             :         deflate_codec = 1,
     274             :         gzip_codec = 2
     275             :     };
     276             : 
     277             :     enum class state
     278             :     {
     279             :         // order matters
     280             :         need_start,
     281             :         headers,        // header fields
     282             :         headers_done,   // delivered headers
     283             :         body,           // reading payload
     284             :         complete,       // done
     285             :     };
     286             : 
     287             :     config_base cfg_;
     288             :     detail::header h_;
     289             :     detail::workspace ws_;
     290             :     detail::header::config cfg_impl_;
     291             : 
     292             :     std::unique_ptr<
     293             :         detail::codec> dec_[3];
     294             :     detail::flat_buffer h_buf_;
     295             :     detail::circular_buffer b_buf_;
     296             :     detail::circular_buffer c_buf_;
     297             :     detail::codec* cod_;
     298             : 
     299             :     state st_;
     300             :     bool got_eof_;
     301             :     bool head_response_;
     302             : };
     303             : 
     304             : } // http_proto
     305             : } // boost
     306             : 
     307             : #include <boost/http_proto/impl/parser.hpp>
     308             : 
     309             : #endif

Generated by: LCOV version 1.15