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 183 : request:: 29 : request( 30 183 : core::string_view s) 31 : : fields_view_base( 32 183 : &this->fields_base::h_) 33 : , message_base( 34 183 : detail::kind::request, s) 35 : { 36 : 37 183 : } 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 1 : return append( 93 : field::expect, 94 1 : "100-continue"); 95 0 : return; 96 : } 97 : 98 1 : if(h_.md.expect.count == 1) 99 : { 100 1 : if(b) 101 : { 102 0 : if(! h_.md.expect.ec.failed()) 103 : { 104 0 : BOOST_ASSERT( 105 : h_.md.expect.is_100_continue); 106 0 : return; 107 : } 108 0 : BOOST_ASSERT( 109 : ! h_.md.expect.is_100_continue); 110 0 : auto it = find(field::expect); 111 0 : BOOST_ASSERT(it != end()); 112 0 : erase(it); 113 0 : return; 114 : } 115 : 116 1 : auto it = find(field::expect); 117 1 : BOOST_ASSERT(it != end()); 118 1 : erase(it); 119 1 : return; 120 : } 121 : 122 0 : if(b) 123 : { 124 0 : if(! h_.md.expect.ec.failed()) 125 : { 126 : // remove all but one 127 0 : raw_erase_n( 128 : field::expect, 129 0 : h_.md.expect.count - 1); 130 0 : return; 131 : } 132 : 133 0 : erase(field::expect); 134 0 : return append( 135 : field::expect, 136 0 : "100-continue"); 137 : } 138 : 139 0 : erase(field::expect); 140 : } 141 : 142 : //------------------------------------------------ 143 : 144 : void 145 10 : request:: 146 : set_impl( 147 : http_proto::method m, 148 : core::string_view ms, 149 : core::string_view t, 150 : http_proto::version v) 151 : { 152 : detail::copied_strings cs( 153 20 : this->buffer()); 154 10 : ms = cs.maybe_copy(ms); 155 10 : t = cs.maybe_copy(t); 156 : 157 : auto const vs = 158 10 : to_string(v); 159 : auto const n = 160 10 : ms.size() + 1 + 161 10 : t.size() + 1 + 162 10 : vs.size() + 2; 163 10 : auto dest = set_prefix_impl(n); 164 9 : std::memcpy( 165 : dest, 166 9 : ms.data(), 167 : ms.size()); 168 9 : dest += ms.size(); 169 9 : *dest++ = ' '; 170 9 : std::memcpy( 171 : dest, 172 9 : t.data(), 173 : t.size()); 174 9 : dest += t.size(); 175 9 : *dest++ = ' '; 176 9 : std::memcpy( 177 : dest, 178 9 : vs.data(), 179 : vs.size()); 180 9 : dest += vs.size(); 181 9 : *dest++ = '\r'; 182 9 : *dest++ = '\n'; 183 : 184 9 : h_.version = v; 185 9 : h_.req.method = m; 186 9 : h_.req.method_len = 187 9 : static_cast<offset_type>(ms.size()); 188 9 : h_.req.target_len = 189 9 : static_cast<offset_type>(t.size()); 190 : 191 9 : h_.on_start_line(); 192 9 : } 193 : 194 : } // http_proto 195 : } // boost