2017-07-20 08:01:46 -07:00
|
|
|
[/
|
|
|
|
|
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
|
|
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
[section:http Using HTTP]
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
[block '''
|
|
|
|
|
<informaltable frame="all"><tgroup cols="1"><colspec colname="a"/><tbody><row><entry valign="top"><simplelist>
|
2016-10-09 06:34:35 -04:00
|
|
|
<member><link linkend="beast.http.message">Messages</link></member>
|
2016-09-25 11:19:51 -04:00
|
|
|
<member><link linkend="beast.http.headers">Headers</link></member>
|
|
|
|
|
<member><link linkend="beast.http.body">Body</link></member>
|
|
|
|
|
<member><link linkend="beast.http.algorithms">Algorithms</link></member>
|
|
|
|
|
<member><link linkend="beast.http.sockets">Sockets</link></member>
|
|
|
|
|
</simplelist></entry></row></tbody></tgroup></informaltable>
|
|
|
|
|
''']
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
Beast.HTTP offers programmers simple and performant models of HTTP messages and
|
|
|
|
|
their associated operations including synchronous and asynchronous reading and
|
|
|
|
|
writing of messages in the HTTP/1 wire format using Boost.Asio.
|
2016-05-01 12:33:35 -04:00
|
|
|
|
|
|
|
|
A HTTP message (referred to hereafter as "message") contains request or
|
|
|
|
|
response specific attributes, a series of zero or more name/value pairs
|
|
|
|
|
(collectively termed "headers"), and a series of octets called the message
|
|
|
|
|
body which may be zero in length. The HTTP protocol defines the client and
|
|
|
|
|
server roles: clients send messages called requests and servers send back
|
2016-09-25 11:19:51 -04:00
|
|
|
messages called responses.
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
|
|
|
[note
|
2016-09-25 11:19:51 -04:00
|
|
|
The following documentation assumes familiarity with both Boost.Asio
|
|
|
|
|
and the HTTP protocol specification described in __rfc7230__. Sample code
|
|
|
|
|
and identifiers mentioned in this section are written as if the following
|
|
|
|
|
declarations are in effect:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
#include <beast/http.hpp>
|
|
|
|
|
using namespace beast;
|
2016-09-25 11:19:51 -04:00
|
|
|
using namespace beast::http;
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-09 06:34:35 -04:00
|
|
|
[section:message Messages]
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-10-09 06:34:35 -04:00
|
|
|
The __message__ class template models HTTP/1 and HTTP/2 requests and responses.
|
|
|
|
|
These class templates are complete: they contain all the information needed
|
|
|
|
|
by the algorithms. Objects of this type are first class: They may be returned
|
|
|
|
|
from functions, moved, copied, passed as arguments, and stored in containers.
|
|
|
|
|
Request and response messages are distinct types; functions may be overloaded
|
|
|
|
|
on just one or the other if desired. Because this class template supports
|
|
|
|
|
HTTP/1 and HTTP/2, it is sometimes referred to as the universal message model.
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-10-09 06:34:35 -04:00
|
|
|
There are three important template parameters in the message class:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
2016-10-09 06:34:35 -04:00
|
|
|
template<
|
|
|
|
|
bool isRequest,
|
|
|
|
|
class Body,
|
|
|
|
|
class Headers
|
|
|
|
|
>
|
2016-09-25 11:19:51 -04:00
|
|
|
class message;
|
|
|
|
|
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
* [*`isRequest`]: Controls whether or not the message is a request or response.
|
|
|
|
|
Depending on the value, different data members will be present in the resulting
|
|
|
|
|
type.
|
|
|
|
|
|
|
|
|
|
* [*`Body`]: determines both the kind of container used to represent the
|
|
|
|
|
message body and the algorithms used to parse and serialize it.
|
|
|
|
|
|
|
|
|
|
* [*`Headers`]: determines the container used to represent the HTTP headers.
|
|
|
|
|
|
|
|
|
|
For notational convenience, the following template type aliases are provided:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
2016-10-09 06:34:35 -04:00
|
|
|
template<
|
|
|
|
|
class Body,
|
|
|
|
|
class Headers = basic_headers<std::allocator<char>>>
|
2016-09-25 11:19:51 -04:00
|
|
|
using request = message<true, Body, Headers>;
|
|
|
|
|
|
2016-10-09 06:34:35 -04:00
|
|
|
template<
|
|
|
|
|
class Body,
|
|
|
|
|
class Headers = basic_headers<std::allocator<char>>>
|
2016-09-25 11:19:51 -04:00
|
|
|
using response = message<false, Body, Headers>;
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
2016-10-09 06:34:35 -04:00
|
|
|
The message class template has different data members depending on whether
|
|
|
|
|
it represents a request or response. These simplified declarations
|
|
|
|
|
notionally illustrate the members of HTTP/1 messages:
|
2016-09-25 11:19:51 -04:00
|
|
|
|
|
|
|
|
```
|
|
|
|
|
template<class Body, class Headers>
|
2016-10-09 06:34:35 -04:00
|
|
|
struct request
|
2016-09-25 11:19:51 -04:00
|
|
|
{
|
2016-10-09 06:34:35 -04:00
|
|
|
int version; // 10 for HTTP/1.0, 11 for HTTP/1.1
|
2016-09-25 11:19:51 -04:00
|
|
|
std::string method;
|
|
|
|
|
std::string url;
|
|
|
|
|
Headers headers;
|
|
|
|
|
typename Body::value_type body;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class Body, class Headers>
|
2016-10-09 06:34:35 -04:00
|
|
|
struct response
|
2016-09-25 11:19:51 -04:00
|
|
|
{
|
2016-10-09 06:34:35 -04:00
|
|
|
int version; // 10 for HTTP/1.0, 11 for HTTP/1.1
|
2016-09-25 11:19:51 -04:00
|
|
|
int status;
|
|
|
|
|
std::string reason;
|
|
|
|
|
Headers headers;
|
|
|
|
|
typename Body::value_type body;
|
|
|
|
|
};
|
|
|
|
|
```
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
These statements set fields in request and response message objects:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
2016-10-09 06:34:35 -04:00
|
|
|
request<string_body> req;
|
|
|
|
|
req.version = 11; // HTTP/1.1
|
2016-08-26 09:00:28 -04:00
|
|
|
req.method = "GET";
|
2017-07-20 08:01:46 -07:00
|
|
|
req.url = "/index.html";
|
2016-09-25 11:19:51 -04:00
|
|
|
req.headers.insert("User-Agent", "Beast.HTTP");
|
2017-07-20 08:01:46 -07:00
|
|
|
req.body = "";
|
|
|
|
|
|
2016-10-09 06:34:35 -04:00
|
|
|
response<string_body> res;
|
2016-10-19 16:54:50 -04:00
|
|
|
res.version = 10; // HTTP/1.0
|
2016-09-25 11:19:51 -04:00
|
|
|
res.status = 404;
|
|
|
|
|
res.reason = "Not Found";
|
|
|
|
|
res.headers.insert("Server", "Beast.HTTP");
|
|
|
|
|
res.body = "The requested resource was not found.";
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
[endsect]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[section:headers Headers]
|
|
|
|
|
|
|
|
|
|
The [*`Headers`] type represents a container that can set or retrieve the
|
|
|
|
|
headers in a message. Beast provides the
|
|
|
|
|
[link beast.ref.http__basic_headers `basic_headers`] class which serves
|
|
|
|
|
the needs for most users. It supports modification and inspection of values.
|
|
|
|
|
The field names are not case-sensitive.
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
These statements change the values of the headers in the message passed:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
template<class Body>
|
2016-10-09 06:34:35 -04:00
|
|
|
void set_fields(request<Body>& req)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
if(! req.exists("User-Agent"))
|
|
|
|
|
req.insert("User-Agent", "myWebClient");
|
|
|
|
|
|
|
|
|
|
if(req.exists("Accept-Charset"))
|
|
|
|
|
req.erase("Accept-Charset");
|
|
|
|
|
|
|
|
|
|
req.replace("Accept", "text/plain");
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
[heading Advanced]
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
This illustration shows more detail about the
|
|
|
|
|
[link beast.ref.http__message [*`message`]] class template (boilerplate
|
|
|
|
|
present in the actual declaration has been removed for clarity):
|
|
|
|
|
|
|
|
|
|
[$images/message.png [width 580px] [height 225px]]
|
|
|
|
|
|
|
|
|
|
User defined [*`Headers`] types are possible. To support serialization, the
|
|
|
|
|
type must meet the requirements of __FieldSequence__. To support parsing using
|
|
|
|
|
the provided parser, the type must provide the `insert` member function.
|
|
|
|
|
|
|
|
|
|
[endsect]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[section:body Body]
|
|
|
|
|
|
|
|
|
|
The message [*`Body`] template parameter controls both the type of the data
|
|
|
|
|
member of the resulting message object, and the algorithms used during parsing
|
|
|
|
|
and serialization. Beast provides three very common [*`Body`] types:
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
|
|
|
* [link beast.ref.http__empty_body [*`empty_body`:]] An empty message body.
|
|
|
|
|
Used in GET requests where there is no message body. Example:
|
|
|
|
|
```
|
2016-10-09 06:34:35 -04:00
|
|
|
request<empty_body> req;
|
2016-08-26 09:00:28 -04:00
|
|
|
req.version = 11;
|
|
|
|
|
req.method = "GET";
|
|
|
|
|
req.url = "/index.html";
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
* [link beast.ref.http__string_body [*`string_body`:]] A body with a
|
|
|
|
|
`value_type` as `std::string`. Useful for quickly putting together a request
|
|
|
|
|
or response with simple text in the message body (such as an error message).
|
|
|
|
|
Has the same insertion complexity of `std::string`. This is the type of body
|
|
|
|
|
used in the examples:
|
|
|
|
|
```
|
2016-10-09 06:34:35 -04:00
|
|
|
response<string_body> res;
|
2016-09-25 11:19:51 -04:00
|
|
|
static_assert(std::is_same<decltype(res.body), std::string>::value);
|
|
|
|
|
res.body = "Here is the data you requested";
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
2016-05-28 09:23:54 -04:00
|
|
|
* [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a
|
|
|
|
|
`value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage
|
|
|
|
|
object which uses multiple octet arrays of varying lengths to represent data.
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2016-09-25 11:19:51 -04:00
|
|
|
[heading Advanced]
|
|
|
|
|
|
|
|
|
|
User-defined types are possible for the message body, where the type meets the
|
|
|
|
|
[link beast.ref.Body [*`Body`]] requirements. This simplified class declaration
|
|
|
|
|
shows the customization points available to user-defined body types:
|
|
|
|
|
|
|
|
|
|
[$images/body.png [width 510px] [height 210px]]
|
|
|
|
|
|
|
|
|
|
* [*`value_type`]: Determines the type of the
|
|
|
|
|
[link beast.ref.http__message.body `message::body`] member. If this
|
|
|
|
|
type defines default construction, move, copy, or swap, then message objects
|
|
|
|
|
declared with this [*`Body`] will have those operations defined.
|
|
|
|
|
|
|
|
|
|
* [*`reader`]: An optional nested type meeting the requirements of
|
|
|
|
|
[link beast.ref.Reader [*`Reader`]]. If present, this defines the algorithm
|
|
|
|
|
used for parsing bodies of this type.
|
|
|
|
|
|
|
|
|
|
* [*`writer`]: An optional nested type meeting the requirements of
|
|
|
|
|
[link beast.ref.Writer [*`Writer`]]. If present, this defines the algorithm
|
|
|
|
|
used for serializing bodies of this type.
|
|
|
|
|
|
|
|
|
|
The examples included with this library provide a Body implementation that
|
|
|
|
|
serializing message bodies that come from a file.
|
|
|
|
|
|
|
|
|
|
[endsect]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[section:algorithms Algorithms]
|
|
|
|
|
|
|
|
|
|
In addition to the universal message model, Beast provides synchronous
|
|
|
|
|
algorithms which operate on HTTP/1 messages:
|
|
|
|
|
|
|
|
|
|
* [link beast.ref.http__read [*read]]: Parse a message from a stream
|
|
|
|
|
|
|
|
|
|
* [link beast.ref.http__write [*write]]: Serialize a message into its wire format on a stream
|
|
|
|
|
|
|
|
|
|
Asynchronous versions of these algorithms are also available:
|
|
|
|
|
|
|
|
|
|
* [link beast.ref.http__async_read [*async_read]]: Parse a message from a stream
|
|
|
|
|
|
|
|
|
|
* [link beast.ref.http__async_write [*async_write]]: Serialize a message into its wire format on a stream
|
|
|
|
|
|
|
|
|
|
[endsect]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[section:sockets Using Sockets]
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
|
|
|
The library provides simple free functions modeled after Boost.Asio to
|
|
|
|
|
send and receive messages on TCP/IP sockets, SSL streams, or any object
|
|
|
|
|
which meets the Boost.Asio type requirements (SyncReadStream, SyncWriteStream,
|
|
|
|
|
AsyncReadStream, and AsyncWriteStream depending on the types of operations
|
2016-09-25 11:19:51 -04:00
|
|
|
performed). To send messages synchronously, use one of the
|
|
|
|
|
[link beast.ref.http__write `write`] functions:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
void send_request(boost::asio::ip::tcp::socket& sock)
|
|
|
|
|
{
|
2016-09-25 11:19:51 -04:00
|
|
|
request<empty_body> req;
|
2016-08-26 09:00:28 -04:00
|
|
|
req.version = 11;
|
|
|
|
|
req.method = "GET";
|
|
|
|
|
req.url = "/index.html";
|
2017-07-20 08:01:46 -07:00
|
|
|
...
|
2016-09-25 11:19:51 -04:00
|
|
|
write(sock, req); // Throws exception on error
|
2017-07-20 08:01:46 -07:00
|
|
|
...
|
|
|
|
|
// Alternatively
|
|
|
|
|
boost::system::error:code ec;
|
2016-09-25 11:19:51 -04:00
|
|
|
write(sock, req, ec);
|
2017-07-20 08:01:46 -07:00
|
|
|
if(ec)
|
|
|
|
|
std::cerr << "error writing http message: " << ec.message();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
An asynchronous interface is available:
|
|
|
|
|
```
|
|
|
|
|
void handle_write(boost::system::error_code);
|
|
|
|
|
...
|
2016-10-09 06:34:35 -04:00
|
|
|
request<empty_body> req;
|
2017-07-20 08:01:46 -07:00
|
|
|
...
|
2016-09-25 11:19:51 -04:00
|
|
|
async_write(sock, req, std::bind(&handle_write, std::placeholders::_1));
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When the implementation reads messages from a socket, it can read bytes lying
|
|
|
|
|
after the end of the message if they are present (the alternative is to read
|
|
|
|
|
a single byte at a time which is unsuitable for performance reasons). To
|
|
|
|
|
store and re-use these extra bytes on subsequent messages, the read interface
|
2016-09-25 11:19:51 -04:00
|
|
|
requires an additional parameter: a [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]
|
2017-07-20 08:01:46 -07:00
|
|
|
object. This example reads a message from the socket, with the extra bytes
|
|
|
|
|
stored in the streambuf parameter for use in a subsequent call to read:
|
|
|
|
|
```
|
|
|
|
|
boost::asio::streambuf sb;
|
|
|
|
|
...
|
2016-10-09 06:34:35 -04:00
|
|
|
response<string_body> res;
|
2016-09-25 11:19:51 -04:00
|
|
|
read(sock, sb, res); // Throws exception on error
|
2017-07-20 08:01:46 -07:00
|
|
|
...
|
|
|
|
|
// Alternatively
|
|
|
|
|
boost::system::error:code ec;
|
2016-09-25 11:19:51 -04:00
|
|
|
read(sock, sb, res, ec);
|
2017-07-20 08:01:46 -07:00
|
|
|
if(ec)
|
|
|
|
|
std::cerr << "error reading http message: " << ec.message();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
As with the write function, an asynchronous interface is available. The
|
|
|
|
|
stream buffer parameter must remain valid until the completion handler is
|
|
|
|
|
called:
|
|
|
|
|
```
|
|
|
|
|
void handle_read(boost::system::error_code);
|
|
|
|
|
...
|
|
|
|
|
boost::asio::streambuf sb;
|
2016-10-09 06:34:35 -04:00
|
|
|
response<string_body> res;
|
2017-07-20 08:01:46 -07:00
|
|
|
...
|
2016-09-25 11:19:51 -04:00
|
|
|
async_read(sock, res, std::bind(&handle_read, std::placeholders::_1));
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
An alternative to using a `boost::asio::streambuf` is to use a
|
2016-09-25 11:19:51 -04:00
|
|
|
__streambuf__, which meets the requirements of __DynamicBuffer__ and
|
|
|
|
|
is optimized for performance:
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
void handle_read(boost::system::error_code);
|
|
|
|
|
...
|
|
|
|
|
beast::streambuf sb;
|
2016-10-09 06:34:35 -04:00
|
|
|
response<string_body> res;
|
2016-09-25 11:19:51 -04:00
|
|
|
read(sock, sb, res);
|
2017-07-20 08:01:46 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `read` implementation can use any object meeting the requirements of
|
2016-09-25 11:19:51 -04:00
|
|
|
__DynamicBuffer__, allowing callers to define custom
|
2017-07-20 08:01:46 -07:00
|
|
|
memory management strategies used by the implementation.
|
|
|
|
|
|
|
|
|
|
[endsect]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[endsect]
|