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/request.hpp> 12 : #include <boost/http_proto/request_view.hpp> 13 : #include "detail/copied_strings.hpp" 14 : #include <utility> 15 : 16 : namespace boost { 17 : namespace http_proto { 18 : 19 26 : request:: 20 26 : request() noexcept 21 : : fields_view_base( 22 26 : &this->fields_base::h_) 23 : , message_base( 24 26 : detail::kind::request) 25 : { 26 26 : } 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 2 : request:: 60 : request( 61 2 : request_view const& other) 62 : : fields_view_base( 63 2 : &this->fields_base::h_) 64 2 : , message_base(*other.ph_) 65 : { 66 2 : } 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 10 : request:: 83 : set_expect_100_continue(bool b) 84 : { 85 10 : if(h_.md.expect.count == 0) 86 : { 87 3 : BOOST_ASSERT( 88 : ! h_.md.expect.ec.failed()); 89 3 : BOOST_ASSERT( 90 : ! h_.md.expect.is_100_continue); 91 3 : if( b ) 92 : { 93 2 : append( 94 : field::expect, 95 2 : "100-continue"); 96 2 : return; 97 : } 98 1 : return; 99 : } 100 : 101 7 : if(h_.md.expect.count == 1) 102 : { 103 3 : if(b) 104 : { 105 2 : if(! h_.md.expect.ec.failed()) 106 : { 107 1 : BOOST_ASSERT( 108 : h_.md.expect.is_100_continue); 109 1 : return; 110 : } 111 1 : BOOST_ASSERT( 112 : ! h_.md.expect.is_100_continue); 113 1 : auto it = find(field::expect); 114 1 : BOOST_ASSERT(it != end()); 115 1 : set(it, "100-continue"); 116 1 : 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 4 : BOOST_ASSERT(h_.md.expect.ec.failed()); 126 : 127 4 : auto nc = (b ? 1 : 0); 128 4 : auto ne = h_.md.expect.count - nc; 129 4 : if( b ) 130 3 : set(find(field::expect), "100-continue"); 131 : 132 4 : raw_erase_n(field::expect, ne); 133 4 : h_.md.expect.count = nc; 134 4 : h_.md.expect.ec = {}; 135 4 : h_.md.expect.is_100_continue = b; 136 : } 137 : 138 : //------------------------------------------------ 139 : 140 : void 141 11 : request:: 142 : set_impl( 143 : http_proto::method m, 144 : core::string_view ms, 145 : core::string_view t, 146 : http_proto::version v) 147 : { 148 : detail::copied_strings cs( 149 22 : this->buffer()); 150 11 : ms = cs.maybe_copy(ms); 151 11 : t = cs.maybe_copy(t); 152 : 153 : auto const vs = 154 11 : to_string(v); 155 : auto const n = 156 11 : ms.size() + 1 + 157 11 : t.size() + 1 + 158 11 : vs.size() + 2; 159 11 : auto dest = set_prefix_impl(n); 160 10 : std::memcpy( 161 : dest, 162 10 : ms.data(), 163 : ms.size()); 164 10 : dest += ms.size(); 165 10 : *dest++ = ' '; 166 10 : std::memcpy( 167 : dest, 168 10 : t.data(), 169 : t.size()); 170 10 : dest += t.size(); 171 10 : *dest++ = ' '; 172 10 : std::memcpy( 173 : dest, 174 10 : vs.data(), 175 : vs.size()); 176 10 : dest += vs.size(); 177 10 : *dest++ = '\r'; 178 10 : *dest++ = '\n'; 179 : 180 10 : h_.version = v; 181 10 : h_.req.method = m; 182 10 : h_.req.method_len = 183 10 : static_cast<offset_type>(ms.size()); 184 10 : h_.req.target_len = 185 10 : static_cast<offset_type>(t.size()); 186 : 187 10 : h_.on_start_line(); 188 10 : } 189 : 190 : } // http_proto 191 : } // boost