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