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