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