Line data Source code
1 : //
2 : // Copyright (c) 2019 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_REQUEST_VIEW_HPP
11 : #define BOOST_HTTP_PROTO_REQUEST_VIEW_HPP
12 :
13 : #include <boost/http_proto/detail/config.hpp>
14 : #include <boost/http_proto/message_view_base.hpp>
15 : #include <boost/core/detail/string_view.hpp>
16 :
17 : namespace boost {
18 : namespace http_proto {
19 :
20 : /** A view to a valid HTTP request.
21 :
22 : Objects of this type represent a view to
23 : a HTTP request container. That is, it acts
24 : like a `core::string_view` in terms of
25 : ownership. The caller is responsible for
26 : ensuring that the lifetime of the underlying
27 : buffer extends until it is no
28 : longer referenced.
29 :
30 : @see
31 : @ref request,
32 : @ref static_request,
33 : @ref request_parser,
34 : */
35 : class request_view
36 : : public message_view_base
37 : {
38 : friend class request_base;
39 : friend class request_parser;
40 :
41 : explicit
42 319 : request_view(
43 : detail::header const* ph) noexcept
44 319 : : fields_view_base(ph)
45 : {
46 319 : BOOST_ASSERT(ph_->kind ==
47 : detail::kind::request);
48 319 : }
49 :
50 : public:
51 : //--------------------------------------------
52 : //
53 : // Special Members
54 : //
55 : //--------------------------------------------
56 :
57 : /** Constructor.
58 :
59 : A default-constructed request views refer
60 : to a valid HTTP `GET` request with no
61 : headers, which always remains valid.
62 :
63 : @par Example
64 : @code
65 : request_view reqv;
66 : @endcode
67 :
68 : @par Postconditions
69 : @code
70 : this->buffer() == "GET / HTTP/1.1\r\n\r\n"
71 : @endcode
72 :
73 : @par Complexity
74 : Constant.
75 : */
76 4 : request_view() noexcept
77 4 : : fields_view_base(
78 : detail::header::get_default(
79 4 : detail::kind::request))
80 : {
81 4 : }
82 :
83 : /** Constructor.
84 :
85 : After construction, both request views
86 : reference the same underlying buffer.
87 : Ownership is not transferred.
88 :
89 : @par Postconditions
90 : @code
91 : this->buffer().data() == other.buffer().data()
92 : @endcode
93 :
94 : @par Complexity
95 : Constant.
96 :
97 : @param other The other view.
98 : */
99 1 : request_view(
100 : request_view const& other) noexcept = default;
101 :
102 : /** Assignment.
103 :
104 : After assignment, both request views
105 : reference the same underlying buffer.
106 : Ownership is not transferred.
107 :
108 : @par Postconditions
109 : @code
110 : this->buffer().data() == other.buffer().data()
111 : @endcode
112 :
113 : @par Complexity
114 : Constant.
115 :
116 : @return A reference to this object.
117 :
118 : @param other The other view.
119 : */
120 : request_view&
121 1 : operator=(
122 : request_view const& other) noexcept = default;
123 :
124 : /** Destructor
125 :
126 : Any reference, iterators, or other views
127 : which reference the same underlying
128 : buffer remain valid.
129 : */
130 : ~request_view() = default;
131 :
132 : //--------------------------------------------
133 : //
134 : // Observers
135 : //
136 : //--------------------------------------------
137 :
138 : /** Return the method as an integral constant
139 :
140 : If the method returned is equal to
141 : @ref method::unknown, the method may
142 : be obtained as a string instead, by
143 : calling @ref method_text.
144 : */
145 : http_proto::method
146 55 : method() const noexcept
147 : {
148 55 : return ph_->req.method;
149 : };
150 :
151 : /** Return the method as a string
152 : */
153 : core::string_view
154 55 : method_text() const noexcept
155 : {
156 110 : return core::string_view(
157 55 : ph_->cbuf,
158 55 : ph_->req.method_len);
159 : }
160 :
161 : /** Return the request-target string.
162 : */
163 : core::string_view
164 55 : target() const noexcept
165 : {
166 110 : return core::string_view(
167 55 : ph_->cbuf +
168 55 : ph_->req.method_len + 1,
169 55 : ph_->req.target_len);
170 : }
171 :
172 : //--------------------------------------------
173 :
174 : /** Swap.
175 :
176 : Exchanges the view with that of `other`.
177 : All iterators and references remain valid.
178 :
179 : If `this == &other`, this function call has no effect.
180 :
181 : @par Example
182 : @code
183 : request r1(method::get, "/");
184 : request r2(method::delete_, "/item/42");
185 : request_view v1 = r1;
186 : request_view v2 = r2;
187 : v1.swap(v2);
188 : assert(v1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
189 : assert(v2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
190 : @endcode
191 :
192 : @par Complexity
193 : Constant.
194 :
195 : @param other The object to swap with.
196 : */
197 : void
198 : swap(request_view& other) noexcept
199 : {
200 : auto ph = ph_;
201 : ph_ = other.ph_;
202 : ph_ = ph;
203 : }
204 :
205 : /** Swap.
206 :
207 : Exchanges the view of `v0` with
208 : another `v1`. All iterators and
209 : references remain valid.
210 :
211 : If `&v0 == &v1`, this function call has no effect.
212 :
213 : @par Example
214 : @code
215 : request r1(method::get, "/");
216 : request r2(method::delete_, "/item/42");
217 : request_view v1 = r1;
218 : request_view v2 = r2;
219 : std::swap(v1, v2);
220 : assert(v1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
221 : assert(v2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
222 : @endcode
223 :
224 : @par Effects
225 : @code
226 : v0.swap(v1);
227 : @endcode
228 :
229 : @par Complexity
230 : Constant.
231 :
232 : @param v0 The first object to swap.
233 : @param v1 The second object to swap.
234 :
235 : @see
236 : @ref request_view::swap.
237 : */
238 : friend
239 : void
240 : swap(
241 : request_view& v0,
242 : request_view& v1) noexcept
243 : {
244 : v0.swap(v1);
245 : }
246 : };
247 :
248 : } // http_proto
249 : } // boost
250 :
251 : #endif
|