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/config.hpp> 14 : #include <boost/http_proto/error.hpp> 15 : #include <boost/http_proto/field.hpp> 16 : #include <boost/http_proto/metadata.hpp> 17 : #include <boost/http_proto/method.hpp> 18 : #include <boost/http_proto/status.hpp> 19 : #include <boost/http_proto/version.hpp> 20 : #include <boost/core/detail/string_view.hpp> 21 : #include <boost/assert.hpp> 22 : #include <cstdint> 23 : #include <type_traits> 24 : 25 : namespace boost { 26 : namespace http_proto { 27 : 28 : class fields_base; 29 : struct header_limits; 30 : 31 : namespace detail { 32 : 33 : enum kind : unsigned char 34 : { 35 : fields = 0, 36 : request, 37 : response, 38 : }; 39 : 40 : struct empty 41 : { 42 : kind param; 43 : }; 44 : 45 : struct header 46 : { 47 : // this field lookup table is 48 : // stored at the end of the 49 : // allocated buffer, in 50 : // reverse order. 51 : struct entry 52 : { 53 : offset_type np; // name pos 54 : offset_type nn; // name size 55 : offset_type vp; // value pos 56 : offset_type vn; // value size 57 : field id; 58 : 59 : entry operator+( 60 : std::size_t dv) const noexcept; 61 : entry operator-( 62 : std::size_t dv) const noexcept; 63 : }; 64 : 65 : struct table 66 : { 67 : explicit 68 5149 : table( 69 : void* end) noexcept 70 5149 : : p_(reinterpret_cast< 71 5149 : entry*>(end)) 72 : { 73 5149 : } 74 : 75 : entry& 76 5176 : operator[]( 77 : std::size_t i) const noexcept 78 : { 79 5176 : return p_[-1 * ( 80 5176 : static_cast< 81 5176 : long>(i) + 1)]; 82 : } 83 : 84 : private: 85 : entry* p_; 86 : }; 87 : 88 : struct fld_t 89 : { 90 : }; 91 : 92 : struct req_t 93 : { 94 : offset_type method_len; 95 : offset_type target_len; 96 : http_proto::method method; 97 : }; 98 : 99 : struct res_t 100 : { 101 : unsigned short status_int; 102 : http_proto::status status; 103 : }; 104 : 105 : //-------------------------------------------- 106 : 107 : detail::kind kind; 108 : char const* cbuf = nullptr; 109 : char* buf = nullptr; 110 : std::size_t cap = 0; 111 : 112 : offset_type size = 0; 113 : offset_type count = 0; 114 : offset_type prefix = 0; 115 : 116 : http_proto::version version = 117 : http_proto::version::http_1_1; 118 : metadata md; 119 : 120 : union 121 : { 122 : fld_t fld; 123 : req_t req; 124 : res_t res; 125 : }; 126 : 127 : private: 128 : struct fields_tag {}; 129 : struct request_tag {}; 130 : struct response_tag {}; 131 : 132 : constexpr header(fields_tag) noexcept; 133 : constexpr header(request_tag) noexcept; 134 : constexpr header(response_tag) noexcept; 135 : 136 : public: 137 : // in fields_base.hpp 138 : static header& get(fields_base& f) noexcept; 139 : 140 : BOOST_HTTP_PROTO_DECL static header const* 141 : get_default(detail::kind k) noexcept; 142 : 143 : // called from parser 144 : explicit header(empty) noexcept; 145 : 146 : BOOST_HTTP_PROTO_DECL header(detail::kind) noexcept; 147 : BOOST_HTTP_PROTO_DECL void swap(header&) noexcept; 148 : BOOST_HTTP_PROTO_DECL bool keep_alive() const noexcept; 149 : 150 : static std::size_t bytes_needed( 151 : std::size_t size, std::size_t count) noexcept; 152 : static std::size_t table_space( 153 : std::size_t count) noexcept; 154 : std::size_t table_space() const noexcept; 155 : 156 : table tab() const noexcept; 157 : entry* tab_() const noexcept; 158 : bool is_default() const noexcept; 159 : std::size_t find(field) const noexcept; 160 : std::size_t find(core::string_view) const noexcept; 161 : void copy_table(void*, std::size_t) const noexcept; 162 : void copy_table(void*) const noexcept; 163 : void assign_to(header&) const noexcept; 164 : 165 : // metadata 166 : 167 : std::size_t maybe_count(field) const noexcept; 168 : bool is_special(field) const noexcept; 169 : void on_start_line(); 170 : void on_insert(field, core::string_view); 171 : void on_erase(field); 172 : void on_insert_connection(core::string_view); 173 : void on_insert_content_length(core::string_view); 174 : void on_insert_expect(core::string_view); 175 : void on_insert_transfer_encoding(); 176 : void on_insert_upgrade(core::string_view); 177 : void on_erase_connection(); 178 : void on_erase_content_length(); 179 : void on_erase_expect(); 180 : void on_erase_transfer_encoding(); 181 : void on_erase_upgrade(); 182 : void on_erase_all(field); 183 : void update_payload() noexcept; 184 : 185 : // parsing 186 : 187 : static std::size_t count_crlf( 188 : core::string_view s) noexcept; 189 : BOOST_HTTP_PROTO_DECL void parse( 190 : std::size_t, header_limits const&, 191 : system::error_code&) noexcept; 192 : }; 193 : 194 : } // detail 195 : } // http_proto 196 : } // boost 197 : 198 : #endif