2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_HTTP_ICY_STREAM_HPP
11 #define BOOST_BEAST_HTTP_ICY_STREAM_HPP
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>
24 /** Stream wrapper to process Shoutcast HTTP responses
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
32 For asynchronous operations, the application must ensure
33 that they are are all performed within the same implicit
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.
43 To use the @ref icy_stream template with an @ref tcp_stream
46 http::icy_stream<tcp_stream> is(ioc);
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.
55 @note A stream object must not be moved or destroyed while there
56 are pending asynchronous operations associated with it.
59 <em>AsyncStream</em>, <em>SyncStream</em>
61 template<class NextLayer>
75 return {"HTTP/1.1", 8};
79 /// The type of the next layer.
80 using next_layer_type =
81 typename std::remove_reference<NextLayer>::type;
83 /// The type of the executor associated with the object.
84 using executor_type = typename next_layer_type::executor_type;
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;
93 The treatment of pending operations will be the same as that
96 ~icy_stream() = default;
100 Arguments, if any, are forwarded to the next layer's constructor.
102 template<class... Args>
104 icy_stream(Args&&... args);
106 //--------------------------------------------------------------------------
108 /** Get the executor associated with the object.
110 This function may be used to obtain the executor object that the
111 stream uses to dispatch handlers for asynchronous operations.
113 @return A copy of the executor that stream will use to dispatch handlers.
116 get_executor() noexcept
118 return stream_.get_executor();
121 /** Get a reference to the next layer
123 This function returns a reference to the next layer
124 in a stack of stream layers.
126 @return A reference to the next layer in the stack of
135 /** Get a reference to the next layer
137 This function returns a reference to the next layer in a
138 stack of stream layers.
140 @return A reference to the next layer in the stack of
143 next_layer_type const&
149 //--------------------------------------------------------------------------
151 /** Read some data from the stream.
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
157 @param buffers The buffers into which the data will be read.
159 @returns The number of bytes read.
161 @throws system_error Thrown on failure.
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
168 template<class MutableBufferSequence>
170 read_some(MutableBufferSequence const& buffers);
172 /** Read some data from the stream.
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
178 @param buffers The buffers into which the data will be read.
180 @param ec Set to indicate what error occurred, if any.
182 @returns The number of bytes read.
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
189 template<class MutableBufferSequence>
192 MutableBufferSequence const& buffers,
195 /** Start an asynchronous read.
197 This function is used to asynchronously read one or more bytes of data from
198 the stream. The function call always returns immediately.
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.
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
211 const boost::system::error_code& error, // Result of operation.
212 std::size_t bytes_transferred // Number of bytes read.
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`.
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
226 class MutableBufferSequence,
227 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
228 net::default_completion_token_t<executor_type>
230 BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
232 MutableBufferSequence const& buffers,
233 ReadHandler&& handler =
234 net::default_completion_token_t<executor_type>{});
236 /** Write some data to the stream.
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.
242 @param buffers The data to be written.
244 @returns The number of bytes written.
246 @throws system_error Thrown on failure.
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.
252 template<class ConstBufferSequence>
254 write_some(ConstBufferSequence const& buffers);
256 /** Write some data to the stream.
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.
262 @param buffers The data to be written.
264 @param ec Set to indicate what error occurred, if any.
266 @returns The number of bytes written.
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.
272 template<class ConstBufferSequence>
275 ConstBufferSequence const& buffers,
278 /** Start an asynchronous write.
280 This function is used to asynchronously write one or more bytes of data to
281 the stream. The function call always returns immediately.
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.
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
294 error_code const& error, // Result of operation.
295 std::size_t bytes_transferred // Number of bytes written.
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`.
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.
308 class ConstBufferSequence,
309 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
310 net::default_completion_token_t<executor_type>
312 BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
314 ConstBufferSequence const& buffers,
315 WriteHandler&& handler =
316 net::default_completion_token_t<executor_type>{});
323 #include <boost/beast/_experimental/http/impl/icy_stream.hpp>