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