| Home | Libraries | People | FAQ | More

### Parser Stream Operations

Non-trivial algorithms need to do more than receive entire messages at once, such as:

- Receive the header first and body later.
- Receive a large body using a fixed-size buffer.
- Receive a message incrementally: bounded work in each I/O cycle.
- Defer the commitment to a Body type until after reading the header.

These types of operations require callers to manage the lifetime of associated state, by constructing a class derived from `basic_parser`. Beast comes with the derived instance `parser` which creates complete `message` objects using the `basic_fields` Fields container.

Table 1.23. Parser

Name | Description
--- | ---
`parser` |
    /// An HTTP/1 parser for producing a message.
    template<
        bool isRequest,                         // `true` to parse an HTTP request
        class Body,                             // The Body type for the resulting message
        class Allocator = std::allocator<char>> // The type of allocator for the header
    class parser
        : public basic_parser<...>;
`request_parser` |
    /// An HTTP/1 parser for producing a request message.
    template<class Body, class Allocator = std::allocator<char>>
    using request_parser = parser<true, Body, Allocator>;
`response_parser` |
    /// An HTTP/1 parser for producing a response message.
    template<class Body, class Allocator = std::allocator<char>>
    using response_parser = parser<false, Body, Allocator>;

| Note
The `basic_parser` and classes derived from it handle octet streams serialized in the HTTP/1 format described in rfc7230.

The stream operations which work on parsers are:

Table 1.24. Parser Stream Operations

Name | Description
--- | ---
read | Read everything into a parser from a SyncReadStream.
async_read | Read everything into a parser asynchronously from an AsyncReadStream.
read_header | Read only the header octets into a parser from a SyncReadStream.
async_read_header | Read only the header octets into a parser asynchronously from an AsyncReadStream.
read_some | Read some octets into a parser from a SyncReadStream.
async_read_some | Read some octets into a parser asynchronously from an AsyncReadStream.

As with message stream operations, parser stream operations require a persisted DynamicBuffer for holding unused octets from the stream. The basic parser implementation is optimized for the case where this dynamic buffer stores its input sequence in a single contiguous memory buffer. It is advised to use an instance of `flat_buffer`, `flat_static_buffer`, or `flat_static_buffer_base` for this purpose, although a user defined instance of DynamicBuffer which produces input sequences of length one is also suitable.

The parser contains a message constructed internally. Arguments passed to the parser's constructor are forwarded into the message container. The caller can access the message inside the parser by calling `parser::get`. If the `Fields` and `Body` types are MoveConstructible, the caller can take ownership of the message by calling `parser::release`. In this example we read an HTTP response with a string body using a parser, then print the response:

    template<class SyncReadStream>
    void
    print_response(SyncReadStream& stream)
    {
        static_assert(is_sync_read_stream<SyncReadStream>::value,
            "SyncReadStream type requirements not met");

        // Declare a parser for an HTTP response
        response_parser<string_body> parser;

        // Read the entire message
        read(stream, parser);

        // Now print the message
        std::cout << parser.get() << std::endl;
    }