Boost logo

Boost :

Subject: [boost] [beast] Supporting ICY 200 OK
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2017-10-01 22:06:12

Bjorn brought up the point that there are some niche cases where
applications do not strictly follow the HTTP message syntax for
responses. Specifically, for Shoutcast(?) / Icecast mp3 servers the
status-line in the response looks something like this:

    ICY 200 OK\r\n

I have thought about ways to support this directly in Beast but I have
decided against it. "ICY 200" is not HTTP according to the RFC, and
trying to accommodate this use case places needless technical debt in
public interfaces.

However, I came up with a very simple technique to make this work with
Beast by writing just a tiny bit of extra code. The solution is to
implement a stream wrapper which meets the requirements of
SyncReadStream[1] and/or AsyncReadStream[2] and forwards the calls to
read to the "next layer" object, which will be the actual socket or

The implementation of the icy_stream wrapper can check to see if the
first 3 bytes received from the next layer match "ICY" and if so,
return a buffer to the caller which replaces those characters with
"HTTP/1.1" (or "HTTP/1.0"). With this wrapper, calls to
beast::http::read or beast::http::async_read can parse the custom
response as a regular HTTP message. The wrapper can embed state
information to inform the caller if the "ICY" string was not received.

The declaration for such a wrapper might look like this:

    template<class NextLayer>
    class icy_stream;

Usage for the wrapper:

    asio::ip::tcp::socket sock{ios};
    icy_stream<asio::ip::tcp::socket&> stream{sock};
    beast::http::response<beast::http::empty_body> res;
    beast::multi_buffer buffer;
    beast::http::read(stream, buffer, res);

This technique may of course be generalized to support any desired
similar but non-standard HTTP requests or responses in a fashion that
is completely transparent to Beast.


[1] <>

[2] <>

Boost list run by bdawes at, gregod at, cpdaniel at, john at