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 198 : request::
32 : request(
33 198 : core::string_view s)
34 : : fields_view_base(
35 198 : &this->fields_base::h_)
36 : , message_base(
37 198 : detail::kind::request, s)
38 : {
39 197 : }
40 :
41 4 : request::
42 : request(
43 4 : std::size_t initial_size)
44 : : fields_view_base(
45 4 : &this->fields_base::h_)
46 : , message_base(
47 4 : detail::kind::request, initial_size, initial_size)
48 : {
49 4 : }
50 :
51 5 : request::
52 : request(
53 : std::size_t initial_size,
54 5 : std::size_t max_capacity)
55 : : fields_view_base(
56 5 : &this->fields_base::h_)
57 : , message_base(
58 5 : detail::kind::request, initial_size, max_capacity)
59 : {
60 5 : }
61 :
62 23 : request::
63 : request(
64 23 : request&& other) noexcept
65 : : fields_view_base(
66 23 : &this->fields_base::h_)
67 : , message_base(
68 23 : detail::kind::request)
69 : {
70 23 : swap(other);
71 23 : }
72 :
73 2 : request::
74 : request(
75 2 : request const& other)
76 : : fields_view_base(
77 2 : &this->fields_base::h_)
78 2 : , message_base(*other.ph_)
79 : {
80 2 : }
81 :
82 2 : request::
83 : request(
84 2 : request_view const& other)
85 : : fields_view_base(
86 2 : &this->fields_base::h_)
87 2 : , message_base(*other.ph_)
88 : {
89 2 : }
90 :
91 : request&
92 21 : request::
93 : operator=(
94 : request&& other) noexcept
95 : {
96 : request temp(
97 21 : std::move(other));
98 21 : temp.swap(*this);
99 21 : return *this;
100 : }
101 :
102 : //------------------------------------------------
103 :
104 : void
105 10 : request::
106 : set_expect_100_continue(bool b)
107 : {
108 10 : if(h_.md.expect.count == 0)
109 : {
110 3 : BOOST_ASSERT(
111 : ! h_.md.expect.ec.failed());
112 3 : BOOST_ASSERT(
113 : ! h_.md.expect.is_100_continue);
114 3 : if( b )
115 : {
116 2 : append(
117 : field::expect,
118 2 : "100-continue");
119 2 : return;
120 : }
121 1 : return;
122 : }
123 :
124 7 : if(h_.md.expect.count == 1)
125 : {
126 3 : if(b)
127 : {
128 2 : if(! h_.md.expect.ec.failed())
129 : {
130 1 : BOOST_ASSERT(
131 : h_.md.expect.is_100_continue);
132 1 : return;
133 : }
134 1 : BOOST_ASSERT(
135 : ! h_.md.expect.is_100_continue);
136 1 : auto it = find(field::expect);
137 1 : BOOST_ASSERT(it != end());
138 1 : set(it, "100-continue");
139 1 : return;
140 : }
141 :
142 1 : auto it = find(field::expect);
143 1 : BOOST_ASSERT(it != end());
144 1 : erase(it);
145 1 : return;
146 : }
147 :
148 4 : BOOST_ASSERT(h_.md.expect.ec.failed());
149 :
150 4 : auto nc = (b ? 1 : 0);
151 4 : auto ne = h_.md.expect.count - nc;
152 4 : if( b )
153 3 : set(find(field::expect), "100-continue");
154 :
155 4 : raw_erase_n(field::expect, ne);
156 4 : h_.md.expect.count = nc;
157 4 : h_.md.expect.ec = {};
158 4 : h_.md.expect.is_100_continue = b;
159 : }
160 :
161 : //------------------------------------------------
162 :
163 : void
164 16 : request::
165 : set_impl(
166 : http_proto::method m,
167 : core::string_view ms,
168 : core::string_view t,
169 : http_proto::version v)
170 : {
171 : auto const vs =
172 16 : to_string(v);
173 : auto const n =
174 : // method SP
175 16 : ms.size() + 1 +
176 : // request-target SP
177 16 : t.size() + 1 +
178 : // HTTP-version CRLF
179 16 : vs.size() + 2;
180 :
181 31 : detail::prefix_op op(*this, n);
182 15 : auto dest = op.prefix_.data();
183 15 : std::memmove(
184 : dest,
185 15 : ms.data(),
186 : ms.size());
187 15 : dest += ms.size();
188 15 : *dest++ = ' ';
189 15 : std::memmove(
190 : dest,
191 15 : t.data(),
192 : t.size());
193 15 : dest += t.size();
194 15 : *dest++ = ' ';
195 15 : std::memcpy(
196 : dest,
197 15 : vs.data(),
198 : vs.size());
199 15 : dest += vs.size();
200 15 : *dest++ = '\r';
201 15 : *dest++ = '\n';
202 :
203 15 : h_.version = v;
204 15 : h_.req.method = m;
205 15 : h_.req.method_len =
206 15 : static_cast<offset_type>(ms.size());
207 15 : h_.req.target_len =
208 15 : static_cast<offset_type>(t.size());
209 :
210 15 : h_.on_start_line();
211 15 : }
212 :
213 : } // http_proto
214 : } // boost
|