Line data Source code
1 : // 2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com) 3 : // Copyright (c) 2024 Christian Mazakas 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 : // 8 : // Official repository: https://github.com/cppalliance/http_proto 9 : // 10 : 11 : #include <boost/http_proto/message_base.hpp> 12 : #include <boost/http_proto/rfc/list_rule.hpp> 13 : #include <boost/http_proto/rfc/token_rule.hpp> 14 : #include <boost/http_proto/detail/except.hpp> 15 : #include "detail/number_string.hpp" 16 : #include <boost/url/grammar/parse.hpp> 17 : #include <boost/url/grammar/ci_string.hpp> 18 : 19 : namespace boost { 20 : namespace http_proto { 21 : 22 : void 23 0 : message_base:: 24 : set_payload_size( 25 : std::uint64_t n) 26 : { 27 : //if(! is_head_response()) 28 : if(true) 29 : { 30 : // comes first for exception safety 31 0 : set_content_length(n); 32 : 33 0 : set_chunked(false); 34 : } 35 : else 36 : { 37 : // VFALCO ? 38 : } 39 0 : } 40 : 41 : void 42 0 : message_base:: 43 : set_content_length( 44 : std::uint64_t n) 45 : { 46 0 : set(field::content_length, 47 0 : detail::number_string(n)); 48 0 : } 49 : 50 : void 51 0 : message_base:: 52 : set_chunked(bool value) 53 : { 54 0 : if(value) 55 : { 56 : // set chunked 57 0 : if(! h_.md.transfer_encoding.is_chunked ) 58 : { 59 0 : append( 60 : field::transfer_encoding, 61 0 : "chunked"); 62 0 : return; 63 : } 64 : } 65 : else 66 : { 67 : // clear chunked 68 : // VFALCO ? 69 : } 70 : } 71 : 72 : void 73 12 : message_base:: 74 : set_keep_alive(bool value) 75 : { 76 12 : if(ph_->md.connection.ec.failed()) 77 : { 78 : // throw? return false? 79 5 : return; 80 : } 81 : 82 12 : if(ph_->md.connection.count == 0) 83 : { 84 : // no Connection field 85 5 : switch(ph_->version) 86 : { 87 3 : default: 88 : case version::http_1_1: 89 3 : if(! value) 90 2 : set(field::connection, "close"); 91 3 : break; 92 : 93 2 : case version::http_1_0: 94 2 : if(value) 95 1 : set(field::connection, "keep-alive"); 96 2 : break; 97 : } 98 5 : return; 99 : } 100 : 101 : // VFALCO TODO iterate in reverse order, 102 : // and cache the last iterator to use 103 : // for appending 104 : 105 : // one or more Connection fields 106 7 : auto it = begin(); 107 : auto const erase_token = 108 14 : [&](core::string_view token) 109 : { 110 14 : while(it != end()) 111 : { 112 8 : if(it->id != field::connection) 113 : { 114 0 : ++it; 115 4 : continue; 116 : } 117 : auto rv = grammar::parse( 118 8 : it->value, 119 16 : list_rule(token_rule, 1)); 120 8 : BOOST_ASSERT(! rv.has_error()); 121 8 : BOOST_ASSERT(! rv->empty()); 122 8 : auto itv = rv->begin(); 123 8 : if(urls::grammar::ci_is_equal( 124 8 : *itv, token)) 125 : { 126 4 : if(rv->size() == 1) 127 : { 128 : // only one token 129 3 : it = erase(it); 130 : } 131 : else 132 : { 133 : // first token matches 134 1 : ++itv; 135 1 : set(it, 136 1 : it->value.substr( 137 1 : (*itv).data() - 138 3 : it->value.data())); 139 1 : ++it; 140 : } 141 4 : continue; 142 : } 143 : // search remaining tokens 144 8 : std::string s = *itv++; 145 7 : while(itv != rv->end()) 146 : { 147 3 : if(! urls::grammar::ci_is_equal( 148 3 : *itv, token)) 149 1 : s += ", " + std::string(*itv); 150 3 : ++itv; 151 : } 152 4 : set(it, s); 153 4 : ++it; 154 : } 155 6 : }; 156 7 : if(value) 157 : { 158 6 : if(ph_->md.connection.close) 159 5 : erase_token("close"); 160 : } 161 : else 162 : { 163 1 : if(ph_->md.connection.keep_alive) 164 1 : erase_token("keep-alive"); 165 : } 166 7 : switch(ph_->version) 167 : { 168 5 : default: 169 : case version::http_1_1: 170 5 : if(! value) 171 : { 172 : // add one "close" token if needed 173 0 : if(! ph_->md.connection.close) 174 0 : append(field::connection, "close"); 175 : } 176 5 : break; 177 : 178 2 : case version::http_1_0: 179 2 : if(value) 180 : { 181 : // add one "keep-alive" token if needed 182 1 : if(! ph_->md.connection.keep_alive) 183 0 : append(field::connection, "keep-alive"); 184 : } 185 2 : break; 186 : } 187 : } 188 : 189 : } // http_proto 190 : } // boost