]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/_experimental/http/icy_stream.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / beast / _experimental / http / icy_stream.hpp
1 //
2 // Copyright (c) 2016-2019 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/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_HTTP_ICY_STREAM_HPP
11 #define BOOST_BEAST_HTTP_ICY_STREAM_HPP
12
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/core/error.hpp>
15 #include <boost/asio/async_result.hpp>
16 #include <boost/asio/buffer.hpp>
17 #include <boost/logic/tribool.hpp>
18 #include <type_traits>
19
20 namespace boost {
21 namespace beast {
22 namespace http {
23
24 /** Stream wrapper to process Shoutcast HTTP responses
25
26 This wrapper replaces the word "ICY" in the first
27 HTTP response received on the connection, with "HTTP/1.1".
28 This allows the Beast parser to be used with Shoutcast
29 servers, which send a non-standard HTTP message as the
30 response.
31
32 For asynchronous operations, the application must ensure
33 that they are are all performed within the same implicit
34 or explicit strand.
35
36 @par Thread Safety
37 @e Distinct @e objects: Safe.@n
38 @e Shared @e objects: Unsafe.
39 The application must also ensure that all asynchronous
40 operations are performed within the same implicit or explicit strand.
41
42 @par Example
43 To use the @ref icy_stream template with an @ref tcp_stream
44 you would write:
45 @code
46 http::icy_stream<tcp_stream> is(ioc);
47 @endcode
48
49 @tparam NextLayer The type representing the next layer, to which
50 data will be read and written during operations. For synchronous
51 operations, the type must support the <em>SyncStream</em> concept.
52 For asynchronous operations, the type must support the
53 <em>AsyncStream</em> concept.
54
55 @note A stream object must not be moved or destroyed while there
56 are pending asynchronous operations associated with it.
57
58 @par Concepts
59 <em>AsyncStream</em>, <em>SyncStream</em>
60 */
61 template<class NextLayer>
62 class icy_stream
63 {
64 NextLayer stream_;
65 char buf_[8];
66 unsigned char n_ = 0;
67 bool detect_ = true;
68
69 struct ops;
70
71 static
72 net::const_buffer
73 version()
74 {
75 return {"HTTP/1.1", 8};
76 }
77
78 public:
79 /// The type of the next layer.
80 using next_layer_type =
81 typename std::remove_reference<NextLayer>::type;
82
83 /// The type of the executor associated with the object.
84 using executor_type = typename next_layer_type::executor_type;
85
86 icy_stream(icy_stream&&) = default;
87 icy_stream(icy_stream const&) = default;
88 icy_stream& operator=(icy_stream&&) = default;
89 icy_stream& operator=(icy_stream const&) = default;
90
91 /** Destructor
92
93 The treatment of pending operations will be the same as that
94 of the next layer.
95 */
96 ~icy_stream() = default;
97
98 /** Constructor
99
100 Arguments, if any, are forwarded to the next layer's constructor.
101 */
102 template<class... Args>
103 explicit
104 icy_stream(Args&&... args);
105
106 //--------------------------------------------------------------------------
107
108 /** Get the executor associated with the object.
109
110 This function may be used to obtain the executor object that the
111 stream uses to dispatch handlers for asynchronous operations.
112
113 @return A copy of the executor that stream will use to dispatch handlers.
114 */
115 executor_type
116 get_executor() noexcept
117 {
118 return stream_.get_executor();
119 }
120
121 /** Get a reference to the next layer
122
123 This function returns a reference to the next layer
124 in a stack of stream layers.
125
126 @return A reference to the next layer in the stack of
127 stream layers.
128 */
129 next_layer_type&
130 next_layer()
131 {
132 return stream_;
133 }
134
135 /** Get a reference to the next layer
136
137 This function returns a reference to the next layer in a
138 stack of stream layers.
139
140 @return A reference to the next layer in the stack of
141 stream layers.
142 */
143 next_layer_type const&
144 next_layer() const
145 {
146 return stream_;
147 }
148
149 //--------------------------------------------------------------------------
150
151 /** Read some data from the stream.
152
153 This function is used to read data from the stream. The function call will
154 block until one or more bytes of data has been read successfully, or until
155 an error occurs.
156
157 @param buffers The buffers into which the data will be read.
158
159 @returns The number of bytes read.
160
161 @throws system_error Thrown on failure.
162
163 @note The `read_some` operation may not read all of the requested number of
164 bytes. Consider using the function `net::read` if you need to ensure
165 that the requested amount of data is read before the blocking operation
166 completes.
167 */
168 template<class MutableBufferSequence>
169 std::size_t
170 read_some(MutableBufferSequence const& buffers);
171
172 /** Read some data from the stream.
173
174 This function is used to read data from the stream. The function call will
175 block until one or more bytes of data has been read successfully, or until
176 an error occurs.
177
178 @param buffers The buffers into which the data will be read.
179
180 @param ec Set to indicate what error occurred, if any.
181
182 @returns The number of bytes read.
183
184 @note The `read_some` operation may not read all of the requested number of
185 bytes. Consider using the function `net::read` if you need to ensure
186 that the requested amount of data is read before the blocking operation
187 completes.
188 */
189 template<class MutableBufferSequence>
190 std::size_t
191 read_some(
192 MutableBufferSequence const& buffers,
193 error_code& ec);
194
195 /** Start an asynchronous read.
196
197 This function is used to asynchronously read one or more bytes of data from
198 the stream. The function call always returns immediately.
199
200 @param buffers The buffers into which the data will be read. Although the
201 buffers object may be copied as necessary, ownership of the underlying
202 buffers is retained by the caller, which must guarantee that they remain
203 valid until the handler is called.
204
205 @param handler The completion handler to invoke when the operation
206 completes. The implementation takes ownership of the handler by
207 performing a decay-copy. The equivalent function signature of
208 the handler must be:
209 @code
210 void handler(
211 const boost::system::error_code& error, // Result of operation.
212 std::size_t bytes_transferred // Number of bytes read.
213 );
214 @endcode
215 Regardless of whether the asynchronous operation completes
216 immediately or not, the handler will not be invoked from within
217 this function. Invocation of the handler will be performed in a
218 manner equivalent to using `net::post`.
219
220 @note The `async_read_some` operation may not read all of the requested number of
221 bytes. Consider using the function `net::async_read` if you need
222 to ensure that the requested amount of data is read before the asynchronous
223 operation completes.
224 */
225 template<
226 class MutableBufferSequence,
227 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
228 net::default_completion_token_t<executor_type>
229 >
230 BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
231 async_read_some(
232 MutableBufferSequence const& buffers,
233 ReadHandler&& handler =
234 net::default_completion_token_t<executor_type>{});
235
236 /** Write some data to the stream.
237
238 This function is used to write data on the stream. The function call will
239 block until one or more bytes of data has been written successfully, or
240 until an error occurs.
241
242 @param buffers The data to be written.
243
244 @returns The number of bytes written.
245
246 @throws system_error Thrown on failure.
247
248 @note The `write_some` operation may not transmit all of the data to the
249 peer. Consider using the function `net::write` if you need to
250 ensure that all data is written before the blocking operation completes.
251 */
252 template<class ConstBufferSequence>
253 std::size_t
254 write_some(ConstBufferSequence const& buffers);
255
256 /** Write some data to the stream.
257
258 This function is used to write data on the stream. The function call will
259 block until one or more bytes of data has been written successfully, or
260 until an error occurs.
261
262 @param buffers The data to be written.
263
264 @param ec Set to indicate what error occurred, if any.
265
266 @returns The number of bytes written.
267
268 @note The `write_some` operation may not transmit all of the data to the
269 peer. Consider using the function `net::write` if you need to
270 ensure that all data is written before the blocking operation completes.
271 */
272 template<class ConstBufferSequence>
273 std::size_t
274 write_some(
275 ConstBufferSequence const& buffers,
276 error_code& ec);
277
278 /** Start an asynchronous write.
279
280 This function is used to asynchronously write one or more bytes of data to
281 the stream. The function call always returns immediately.
282
283 @param buffers The data to be written to the stream. Although the buffers
284 object may be copied as necessary, ownership of the underlying buffers is
285 retained by the caller, which must guarantee that they remain valid until
286 the handler is called.
287
288 @param handler The completion handler to invoke when the operation
289 completes. The implementation takes ownership of the handler by
290 performing a decay-copy. The equivalent function signature of
291 the handler must be:
292 @code
293 void handler(
294 error_code const& error, // Result of operation.
295 std::size_t bytes_transferred // Number of bytes written.
296 );
297 @endcode
298 Regardless of whether the asynchronous operation completes
299 immediately or not, the handler will not be invoked from within
300 this function. Invocation of the handler will be performed in a
301 manner equivalent to using `net::post`.
302
303 @note The `async_write_some` operation may not transmit all of the data to
304 the peer. Consider using the function `net::async_write` if you need
305 to ensure that all data is written before the asynchronous operation completes.
306 */
307 template<
308 class ConstBufferSequence,
309 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
310 net::default_completion_token_t<executor_type>
311 >
312 BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
313 async_write_some(
314 ConstBufferSequence const& buffers,
315 WriteHandler&& handler =
316 net::default_completion_token_t<executor_type>{});
317 };
318
319 } // http
320 } // beast
321 } // boost
322
323 #include <boost/beast/_experimental/http/impl/icy_stream.hpp>
324
325 #endif