Line data Source code
1 : // 2 : // Copyright (c) 2021 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/CPPAlliance/http_proto 8 : // 9 : 10 : #ifndef BOOST_HTTP_PROTO_RFC_IMPL_TRANSFER_ENCODING_RULE_IPP 11 : #define BOOST_HTTP_PROTO_RFC_IMPL_TRANSFER_ENCODING_RULE_IPP 12 : 13 : #include <boost/http_proto/rfc/transfer_encoding_rule.hpp> 14 : #include <boost/http_proto/rfc/token_rule.hpp> 15 : #include <boost/http_proto/rfc/detail/rules.hpp> 16 : #include <boost/url/grammar/ci_string.hpp> 17 : #include <boost/url/grammar/parse.hpp> 18 : 19 : namespace boost { 20 : namespace http_proto { 21 : 22 : //------------------------------------------------ 23 : 24 : namespace detail { 25 : 26 : /* 27 : tparams = *tparam 28 : tparam = OWS ";" OWS token BWS "=" BWS ( token / quoted-string ) 29 : */ 30 : 31 : struct tparam_rule_t 32 : { 33 : using value_type = 34 : transfer_coding::param; 35 : 36 : auto 37 49 : parse( 38 : char const*& it, 39 : char const* end) const noexcept -> 40 : result<value_type> 41 : { 42 49 : value_type t; 43 49 : auto it0 = it; 44 : // OWS 45 49 : it = grammar::find_if_not( 46 : it, end, ws); 47 : // ";" 48 49 : if(it == end) 49 : { 50 15 : it = it0; 51 15 : BOOST_HTTP_PROTO_RETURN_EC( 52 : grammar::error::need_more); 53 : } 54 34 : if(*it != ';') 55 : { 56 20 : it = it0; 57 20 : BOOST_HTTP_PROTO_RETURN_EC( 58 : grammar::error::mismatch); 59 : } 60 14 : ++it; 61 : // OWS 62 14 : it = grammar::find_if_not( 63 : it, end, ws); 64 : // token 65 : { 66 : auto rv = grammar::parse( 67 14 : it, end, token_rule); 68 14 : if(! rv) 69 0 : return rv.error(); 70 14 : t.key = *rv; 71 : } 72 : // BWS 73 14 : it = grammar::find_if_not( 74 : it, end, ws); 75 : // "=" 76 14 : if(it == end) 77 : { 78 0 : it = it0; 79 0 : BOOST_HTTP_PROTO_RETURN_EC( 80 : grammar::error::need_more); 81 : } 82 14 : if(*it != '=') 83 : { 84 0 : it = it0; 85 0 : BOOST_HTTP_PROTO_RETURN_EC( 86 : grammar::error::syntax); 87 : } 88 14 : ++it; 89 : // BWS 90 14 : it = grammar::find_if_not( 91 : it, end, ws); 92 : // quoted-token 93 : { 94 : auto rv = grammar::parse( 95 14 : it, end, quoted_token_rule); 96 14 : if(! rv) 97 0 : return rv.error(); 98 14 : t.value = *rv; 99 : } 100 14 : return t; 101 : } 102 : }; 103 : 104 : constexpr tparam_rule_t tparam_rule{}; 105 : 106 : } // detail 107 : 108 : //------------------------------------------------ 109 : 110 : auto 111 179 : transfer_coding_rule_t:: 112 : parse( 113 : char const*& it, 114 : char const* end) const noexcept -> 115 : result<value_type> 116 : { 117 358 : value_type t; 118 : { 119 : // token 120 : auto rv = grammar::parse( 121 179 : it, end, token_rule); 122 179 : if(! rv) 123 8 : return rv.error(); 124 171 : t.str = *rv; 125 : 126 : // These can't have tparams 127 171 : if(grammar::ci_is_equal( 128 : t.str, "chunked")) 129 : { 130 69 : t.id = transfer_coding::chunked; 131 69 : return t; 132 : } 133 102 : if(grammar::ci_is_equal( 134 : t.str, "compress")) 135 : { 136 34 : t.id = transfer_coding::compress; 137 34 : return t; 138 : } 139 68 : if(grammar::ci_is_equal( 140 : t.str, "deflate")) 141 : { 142 7 : t.id = transfer_coding::deflate; 143 7 : return t; 144 : } 145 61 : if(grammar::ci_is_equal( 146 : t.str, "gzip")) 147 : { 148 26 : t.id = transfer_coding::gzip; 149 26 : return t; 150 : } 151 : } 152 : // *( OWS ";" OWS token BWS "=" BWS ( token / quoted-string ) 153 : { 154 : auto rv = grammar::parse(it, end, 155 35 : grammar::range_rule( 156 35 : detail::tparam_rule)); 157 35 : if(! rv) 158 0 : return rv.error(); 159 35 : t.params = std::move(*rv); 160 : } 161 35 : return t; 162 : } 163 : 164 : } // http_proto 165 : } // boost 166 : 167 : #endif