LCOV - code coverage report
Current view: top level - boost/http_proto/detail - header.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 11 11 100.0 %
Date: 2024-04-15 15:38:04 Functions: 3 3 100.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_DETAIL_HEADER_HPP
      11             : #define BOOST_HTTP_PROTO_DETAIL_HEADER_HPP
      12             : 
      13             : #include <boost/http_proto/detail/align_up.hpp>
      14             : #include <boost/http_proto/detail/config.hpp>
      15             : #include <boost/http_proto/error.hpp>
      16             : #include <boost/http_proto/field.hpp>
      17             : #include <boost/http_proto/metadata.hpp>
      18             : #include <boost/http_proto/method.hpp>
      19             : #include <boost/http_proto/status.hpp>
      20             : #include <boost/http_proto/version.hpp>
      21             : #include <boost/core/detail/string_view.hpp>
      22             : #include <boost/assert.hpp>
      23             : #include <cstdint>
      24             : #include <type_traits>
      25             : 
      26             : namespace boost {
      27             : namespace http_proto {
      28             : 
      29             : class fields_base;
      30             : struct header_limits;
      31             : 
      32             : namespace detail {
      33             : 
      34             : enum kind : unsigned char
      35             : {
      36             :     fields = 0,
      37             :     request,
      38             :     response,
      39             : };
      40             : 
      41             : struct empty
      42             : {
      43             :     kind param;
      44             : };
      45             : 
      46             : struct header
      47             : {
      48             :     // this field lookup table is
      49             :     // stored at the end of the
      50             :     // allocated buffer, in
      51             :     // reverse order.
      52             :     struct entry
      53             :     {
      54             :         offset_type np;   // name pos
      55             :         offset_type nn;   // name size
      56             :         offset_type vp;   // value pos
      57             :         offset_type vn;   // value size
      58             :         field id;
      59             : 
      60             :         entry operator+(
      61             :             std::size_t dv) const noexcept;
      62             :         entry operator-(
      63             :             std::size_t dv) const noexcept;
      64             :     };
      65             : 
      66             :     // HTTP-message = start-line CRLF *( field-line CRLF ) CRLF
      67             :     // start-line   = request-line / status-line
      68             :     // status-line  = HTTP-version SP status-code SP [ reason-phrase ]
      69             :     // status-code  = 3DIGIT
      70             :     // HTTP-name    = %x48.54.54.50 ; HTTP
      71             :     // HTTP-version = HTTP-name "/" DIGIT "." DIGIT
      72             :     //
      73             :     //     => "HTTP/1.1 111 \r\n" + trailing "\r\n"
      74             :     static
      75             :     constexpr
      76             :     std::size_t const min_status_line = 17;
      77             : 
      78             :     // "X:\r\n"
      79             :     static
      80             :     constexpr
      81             :     std::size_t const min_field_line = 4;
      82             : 
      83             :     static
      84             :     constexpr
      85             :     std::size_t const max_field_lines =
      86             :         (max_offset - min_status_line) / min_field_line;
      87             : 
      88             :     /** Returns the largest permissible capacity in bytes
      89             :     */
      90             :     static
      91             :     constexpr
      92             :     std::size_t
      93        3339 :     max_capacity_in_bytes() noexcept
      94             :     {
      95             :         // the entire serialized contents of the header
      96             :         // must fit entirely in max_offset
      97        3339 :         return align_up(
      98             :             (max_offset + (max_field_lines * sizeof(entry))),
      99        3339 :             alignof(entry));
     100             :     }
     101             : 
     102             :     struct table
     103             :     {
     104             :         explicit
     105        5215 :         table(
     106             :             void* end) noexcept
     107        5215 :             : p_(reinterpret_cast<
     108        5215 :                 entry*>(end))
     109             :         {
     110        5215 :         }
     111             : 
     112             :         entry&
     113        5245 :         operator[](
     114             :             std::size_t i) const noexcept
     115             :         {
     116        5245 :             return p_[-1 * (
     117        5245 :                 static_cast<
     118        5245 :                     long>(i) + 1)];
     119             :         }
     120             : 
     121             :     private:
     122             :         entry* p_;
     123             :     };
     124             : 
     125             :     struct fld_t
     126             :     {
     127             :     };
     128             : 
     129             :     struct req_t
     130             :     {
     131             :         offset_type method_len;
     132             :         offset_type target_len;
     133             :         http_proto::method method;
     134             :     };
     135             : 
     136             :     struct res_t
     137             :     {
     138             :         unsigned short status_int;
     139             :         http_proto::status status;
     140             :     };
     141             : 
     142             :     //--------------------------------------------
     143             : 
     144             :     detail::kind kind;
     145             :     char const* cbuf = nullptr;
     146             :     char* buf = nullptr;
     147             :     std::size_t cap = 0;
     148             :     std::size_t max_cap = max_capacity_in_bytes();
     149             : 
     150             :     offset_type size = 0;
     151             :     offset_type count = 0;
     152             :     offset_type prefix = 0;
     153             : 
     154             :     http_proto::version version =
     155             :         http_proto::version::http_1_1;
     156             :     metadata md;
     157             : 
     158             :     union
     159             :     {
     160             :         fld_t fld;
     161             :         req_t req;
     162             :         res_t res;
     163             :     };
     164             : 
     165             : private:
     166             :     struct fields_tag {};
     167             :     struct request_tag {};
     168             :     struct response_tag {};
     169             : 
     170             :     constexpr header(fields_tag) noexcept;
     171             :     constexpr header(request_tag) noexcept;
     172             :     constexpr header(response_tag) noexcept;
     173             : 
     174             : public:
     175             :     // in fields_base.hpp
     176             :     static header& get(fields_base& f) noexcept;
     177             : 
     178             :     BOOST_HTTP_PROTO_DECL static header const*
     179             :         get_default(detail::kind k) noexcept;
     180             : 
     181             :     // called from parser
     182             :     explicit header(empty) noexcept;
     183             : 
     184             :     BOOST_HTTP_PROTO_DECL header(detail::kind) noexcept;
     185             :     BOOST_HTTP_PROTO_DECL void swap(header&) noexcept;
     186             :     BOOST_HTTP_PROTO_DECL bool keep_alive() const noexcept;
     187             : 
     188             :     static std::size_t bytes_needed(
     189             :         std::size_t size, std::size_t count) noexcept;
     190             :     static std::size_t table_space(
     191             :         std::size_t count) noexcept;
     192             :     std::size_t table_space() const noexcept;
     193             : 
     194             :     table tab() const noexcept;
     195             :     entry* tab_() const noexcept;
     196             :     bool is_default() const noexcept;
     197             :     std::size_t find(field) const noexcept;
     198             :     std::size_t find(core::string_view) const noexcept;
     199             :     void copy_table(void*, std::size_t) const noexcept;
     200             :     void copy_table(void*) const noexcept;
     201             :     void assign_to(header&) const noexcept;
     202             : 
     203             :     // metadata
     204             : 
     205             :     std::size_t maybe_count(field) const noexcept;
     206             :     bool is_special(field) const noexcept;
     207             :     void on_start_line();
     208             :     void on_insert(field, core::string_view);
     209             :     void on_erase(field);
     210             :     void on_insert_connection(core::string_view);
     211             :     void on_insert_content_length(core::string_view);
     212             :     void on_insert_expect(core::string_view);
     213             :     void on_insert_transfer_encoding();
     214             :     void on_insert_upgrade(core::string_view);
     215             :     void on_erase_connection();
     216             :     void on_erase_content_length();
     217             :     void on_erase_expect();
     218             :     void on_erase_transfer_encoding();
     219             :     void on_erase_upgrade();
     220             :     void on_erase_all(field);
     221             :     void update_payload() noexcept;
     222             : 
     223             :     // parsing
     224             : 
     225             :     static std::size_t count_crlf(
     226             :         core::string_view s) noexcept;
     227             :     BOOST_HTTP_PROTO_DECL void parse(
     228             :         std::size_t, header_limits const&,
     229             :             system::error_code&) noexcept;
     230             : };
     231             : 
     232             : } // detail
     233             : } // http_proto
     234             : } // boost
     235             : 
     236             : #endif

Generated by: LCOV version 1.15