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/request.hpp> 11 : #include <boost/http_proto/request_view.hpp> 12 : #include "detail/copied_strings.hpp" 13 : #include "detail/number_string.hpp" 14 : #include <utility> 15 : 16 : namespace boost { 17 : namespace http_proto { 18 : 19 17 : request:: 20 17 : request() noexcept 21 : : fields_view_base( 22 17 : &this->fields_base::h_) 23 : , message_base( 24 17 : detail::kind::request) 25 : { 26 17 : } 27 : 28 191 : request:: 29 : request( 30 191 : core::string_view s) 31 : : fields_view_base( 32 191 : &this->fields_base::h_) 33 : , message_base( 34 191 : detail::kind::request, s) 35 : { 36 : 37 191 : } 38 : 39 22 : request:: 40 : request( 41 22 : request&& other) noexcept 42 : : fields_view_base( 43 22 : &this->fields_base::h_) 44 : , message_base( 45 22 : detail::kind::request) 46 : { 47 22 : swap(other); 48 22 : } 49 : 50 2 : request:: 51 : request( 52 2 : request const& other) 53 : : fields_view_base( 54 2 : &this->fields_base::h_) 55 2 : , message_base(*other.ph_) 56 : { 57 2 : } 58 : 59 0 : request:: 60 : request( 61 0 : request_view const& other) 62 : : fields_view_base( 63 0 : &this->fields_base::h_) 64 0 : , message_base(*other.ph_) 65 : { 66 0 : } 67 : 68 : request& 69 20 : request:: 70 : operator=( 71 : request&& other) noexcept 72 : { 73 : request temp( 74 20 : std::move(other)); 75 20 : temp.swap(*this); 76 20 : return *this; 77 : } 78 : 79 : //------------------------------------------------ 80 : 81 : void 82 2 : request:: 83 : set_expect_100_continue(bool b) 84 : { 85 2 : if(h_.md.expect.count == 0) 86 : { 87 1 : BOOST_ASSERT( 88 : ! h_.md.expect.ec.failed()); 89 1 : BOOST_ASSERT( 90 : ! h_.md.expect.is_100_continue); 91 1 : if( b ) 92 : { 93 1 : append( 94 : field::expect, 95 1 : "100-continue"); 96 1 : return; 97 : } 98 0 : return; 99 : } 100 : 101 1 : if(h_.md.expect.count == 1) 102 : { 103 1 : if(b) 104 : { 105 0 : if(! h_.md.expect.ec.failed()) 106 : { 107 0 : BOOST_ASSERT( 108 : h_.md.expect.is_100_continue); 109 0 : return; 110 : } 111 0 : BOOST_ASSERT( 112 : ! h_.md.expect.is_100_continue); 113 0 : auto it = find(field::expect); 114 0 : BOOST_ASSERT(it != end()); 115 0 : erase(it); 116 0 : return; 117 : } 118 : 119 1 : auto it = find(field::expect); 120 1 : BOOST_ASSERT(it != end()); 121 1 : erase(it); 122 1 : return; 123 : } 124 : 125 0 : if(b) 126 : { 127 0 : if(! h_.md.expect.ec.failed()) 128 : { 129 : // remove all but one 130 0 : raw_erase_n( 131 : field::expect, 132 0 : h_.md.expect.count - 1); 133 0 : return; 134 : } 135 : 136 0 : erase(field::expect); 137 0 : append( 138 : field::expect, 139 0 : "100-continue"); 140 0 : return; 141 : } 142 : 143 0 : erase(field::expect); 144 : } 145 : 146 : //------------------------------------------------ 147 : 148 : void 149 10 : request:: 150 : set_impl( 151 : http_proto::method m, 152 : core::string_view ms, 153 : core::string_view t, 154 : http_proto::version v) 155 : { 156 : detail::copied_strings cs( 157 20 : this->buffer()); 158 10 : ms = cs.maybe_copy(ms); 159 10 : t = cs.maybe_copy(t); 160 : 161 : auto const vs = 162 10 : to_string(v); 163 : auto const n = 164 10 : ms.size() + 1 + 165 10 : t.size() + 1 + 166 10 : vs.size() + 2; 167 10 : auto dest = set_prefix_impl(n); 168 9 : std::memcpy( 169 : dest, 170 9 : ms.data(), 171 : ms.size()); 172 9 : dest += ms.size(); 173 9 : *dest++ = ' '; 174 9 : std::memcpy( 175 : dest, 176 9 : t.data(), 177 : t.size()); 178 9 : dest += t.size(); 179 9 : *dest++ = ' '; 180 9 : std::memcpy( 181 : dest, 182 9 : vs.data(), 183 : vs.size()); 184 9 : dest += vs.size(); 185 9 : *dest++ = '\r'; 186 9 : *dest++ = '\n'; 187 : 188 9 : h_.version = v; 189 9 : h_.req.method = m; 190 9 : h_.req.method_len = 191 9 : static_cast<offset_type>(ms.size()); 192 9 : h_.req.target_len = 193 9 : static_cast<offset_type>(t.size()); 194 : 195 9 : h_.on_start_line(); 196 9 : } 197 : 198 : } // http_proto 199 : } // boost