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 : 14 : #include <cstring> 15 : #include <utility> 16 : 17 : #include "detail/header_impl.hpp" 18 : 19 : namespace boost { 20 : namespace http_proto { 21 : 22 26 : request:: 23 26 : request() noexcept 24 : : fields_view_base( 25 26 : &this->fields_base::h_) 26 : , message_base( 27 26 : detail::kind::request) 28 : { 29 26 : } 30 : 31 196 : request:: 32 : request( 33 196 : core::string_view s) 34 : : fields_view_base( 35 196 : &this->fields_base::h_) 36 : , message_base( 37 196 : detail::kind::request, s) 38 : { 39 : 40 196 : } 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 2 : request:: 63 : request( 64 2 : request_view const& other) 65 : : fields_view_base( 66 2 : &this->fields_base::h_) 67 2 : , message_base(*other.ph_) 68 : { 69 2 : } 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 10 : request:: 86 : set_expect_100_continue(bool b) 87 : { 88 10 : if(h_.md.expect.count == 0) 89 : { 90 3 : BOOST_ASSERT( 91 : ! h_.md.expect.ec.failed()); 92 3 : BOOST_ASSERT( 93 : ! h_.md.expect.is_100_continue); 94 3 : if( b ) 95 : { 96 2 : append( 97 : field::expect, 98 2 : "100-continue"); 99 2 : return; 100 : } 101 1 : return; 102 : } 103 : 104 7 : if(h_.md.expect.count == 1) 105 : { 106 3 : if(b) 107 : { 108 2 : if(! h_.md.expect.ec.failed()) 109 : { 110 1 : BOOST_ASSERT( 111 : h_.md.expect.is_100_continue); 112 1 : return; 113 : } 114 1 : BOOST_ASSERT( 115 : ! h_.md.expect.is_100_continue); 116 1 : auto it = find(field::expect); 117 1 : BOOST_ASSERT(it != end()); 118 1 : set(it, "100-continue"); 119 1 : return; 120 : } 121 : 122 1 : auto it = find(field::expect); 123 1 : BOOST_ASSERT(it != end()); 124 1 : erase(it); 125 1 : return; 126 : } 127 : 128 4 : BOOST_ASSERT(h_.md.expect.ec.failed()); 129 : 130 4 : auto nc = (b ? 1 : 0); 131 4 : auto ne = h_.md.expect.count - nc; 132 4 : if( b ) 133 3 : set(find(field::expect), "100-continue"); 134 : 135 4 : raw_erase_n(field::expect, ne); 136 4 : h_.md.expect.count = nc; 137 4 : h_.md.expect.ec = {}; 138 4 : h_.md.expect.is_100_continue = b; 139 : } 140 : 141 : //------------------------------------------------ 142 : 143 : void 144 16 : request:: 145 : set_impl( 146 : http_proto::method m, 147 : core::string_view ms, 148 : core::string_view t, 149 : http_proto::version v) 150 : { 151 : auto const vs = 152 16 : to_string(v); 153 : auto const n = 154 : // method SP 155 16 : ms.size() + 1 + 156 : // request-target SP 157 16 : t.size() + 1 + 158 : // HTTP-version CRLF 159 16 : vs.size() + 2; 160 : 161 31 : detail::prefix_op op(*this, n); 162 15 : auto dest = op.prefix_.data(); 163 15 : std::memmove( 164 : dest, 165 15 : ms.data(), 166 : ms.size()); 167 15 : dest += ms.size(); 168 15 : *dest++ = ' '; 169 15 : std::memmove( 170 : dest, 171 15 : t.data(), 172 : t.size()); 173 15 : dest += t.size(); 174 15 : *dest++ = ' '; 175 15 : std::memcpy( 176 : dest, 177 15 : vs.data(), 178 : vs.size()); 179 15 : dest += vs.size(); 180 15 : *dest++ = '\r'; 181 15 : *dest++ = '\n'; 182 : 183 15 : h_.version = v; 184 15 : h_.req.method = m; 185 15 : h_.req.method_len = 186 15 : static_cast<offset_type>(ms.size()); 187 15 : h_.req.target_len = 188 15 : static_cast<offset_type>(t.size()); 189 : 190 15 : h_.on_start_line(); 191 15 : } 192 : 193 : } // http_proto 194 : } // boost