forked from boostorg/beast
fix #397 method enum class is added to represent all known request methods. Functions are provided to convert from strings to and from the method enumeration. The fields container is modified to also work with the enum.
174 lines
5.6 KiB
Plaintext
174 lines
5.6 KiB
Plaintext
[/
|
|
Copyright (c) 2013-2017 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)
|
|
]
|
|
|
|
[section:message Message Containers]
|
|
|
|
Beast provides a single class template __message__ which models
|
|
HTTP/1 and
|
|
[@https://tools.ietf.org/html/rfc7540 HTTP/2]
|
|
messages:
|
|
```
|
|
/// An HTTP message
|
|
template<
|
|
bool isRequest, // `true` for requests, `false` for responses
|
|
class Body, // Controls the container and algorithms used for the body
|
|
class Fields = fields> // The type of container to store the fields
|
|
class message;
|
|
```
|
|
|
|
The container offers value semantics including move and copy if supported
|
|
by `Body` and `Fields`. User defined template function parameters can
|
|
accept any message, or can use partial specialization to accept just
|
|
requests or responses. The default __fields__ is a provided associative
|
|
container using the standard allocator and supporting modification and
|
|
inspection of fields. As per __rfc7230__, a non-case-sensitive comparison
|
|
is used for field names. User defined types for fields are possible. This
|
|
is discussed in
|
|
[link beast.adv_http.fields Advanced Fields].
|
|
The `Body` type determines the type of the container used to represent the
|
|
body as well as the algorithms for transferring buffers to and from the
|
|
the container. The library comes with a collection of common body types,
|
|
described in
|
|
[link beast.http.message.body Body Types].
|
|
As with fields, user defined body types are possible. This is described in
|
|
[link beast.adv_http.body Advanced Body].
|
|
|
|
|
|
|
|
Sometimes it is desired to only work with a header. Beast provides a single
|
|
class template __header__ to model HTTP/1 and HTTP/2 headers:
|
|
```
|
|
/// An HTTP header
|
|
template<
|
|
bool isRequest, // `true` for requests, `false` for responses
|
|
class Fields = fields> // The type of container to store the fields
|
|
class header;
|
|
```
|
|
|
|
Requests and responses share the version, fields, and body but have
|
|
a few members unique to the type. This is implemented by declaring the
|
|
header classes as partial specializations of `isRequest`. Furthermore,
|
|
__message__ is derived from __header__; a message may be passed as an
|
|
argument to a function taking a suitably typed header as a parameter.
|
|
This diagram shows the inheritance relationship between header and message,
|
|
along with the fields from the different partial specializations for each
|
|
possible value of `isRequest`:
|
|
|
|
[$images/message.png [width 711px] [height 424px]]
|
|
|
|
For notational convenience, the template type aliases
|
|
[link beast.ref.http__request `request`] and
|
|
[link beast.ref.http__response `response`]
|
|
are provided, which also supply commonly chosen __fields__ type as a default:
|
|
```
|
|
/// A typical HTTP request
|
|
template<class Body, class Fields = fields>
|
|
using request = message<true, Body, Fields>;
|
|
|
|
/// A typical HTTP response
|
|
template<class Body, class Fields = fields>
|
|
using response = message<false, Body, Fields>;
|
|
```
|
|
|
|
[heading:body Body Types]
|
|
|
|
Beast defines the __Body__ concept, which determines both the type of
|
|
the `message::body` member (as seen in the diagram above) and may also
|
|
include algorithms for transferring buffers in and out. These algorithms
|
|
are used during parsing and serialization. These body types are available
|
|
within the library, and users may define their own body types which meet
|
|
the __Body__ requirements:
|
|
|
|
[table
|
|
[[Name][Description]]
|
|
[[
|
|
[link beast.ref.http__buffer_body `buffer_body`]
|
|
][
|
|
A body with `value_type` holding a __ConstBufferSequence__ holding
|
|
caller provided buffers which must be updated during incremental
|
|
serialization. Messages with this body type only support serialization.
|
|
]]
|
|
[[
|
|
[link beast.ref.http__dynamic_body `dynamic_body`]
|
|
|
|
[link beast.ref.http__basic_dynamic_body `basic_dynamic_body`]
|
|
][
|
|
A body whose `value_type` is a __DynamicBuffer__. It inherits
|
|
the insertion complexity of the underlying choice of dynamic buffer.
|
|
Messages with this body type may be serialized and parsed.
|
|
]]
|
|
[[
|
|
[link beast.ref.http__empty_body `empty_body`]
|
|
][
|
|
A special body with an empty `value_type` indicating that the
|
|
message has no body. Messages with this body may be serialized
|
|
and parsed; however, body octets received while parsing a message
|
|
with this body will generate a unique error.
|
|
]]
|
|
[[
|
|
[link beast.ref.http__string_body `string_body`]
|
|
][
|
|
A body whose `value_type` is `std::string`. Insertion complexity
|
|
is amortized constant time, while capacity grows geometrically.
|
|
Messages with this body type may be serialized and parsed. This
|
|
is the type of body used in the examples.
|
|
]]
|
|
]
|
|
|
|
[heading Usage]
|
|
|
|
The code examples below show how to create and fill in request and response
|
|
objects:
|
|
|
|
[table Create Request
|
|
[[Statements] [Serialized Result]]
|
|
[[
|
|
```
|
|
request<string_body> req;
|
|
req.version = 11; // HTTP/1.1
|
|
req.method(verb::get);
|
|
req.target("/index.htm");
|
|
req.fields.insert("Accept", "text/html");
|
|
req.fields.insert("Connection", "keep-alive");
|
|
req.fields.insert("User-Agent", "Beast");
|
|
```
|
|
][
|
|
```
|
|
GET /index.htm HTTP/1.1\r\n
|
|
Accept: text/html\r\n
|
|
Connection: keep-alive\r\n
|
|
User-Agent: Beast\r\n
|
|
\r\n
|
|
```
|
|
]]
|
|
]
|
|
|
|
[table Create Response
|
|
[[Statements] [Serialized Result]]
|
|
[[
|
|
```
|
|
response<string_body> res;
|
|
res.version = 11; // HTTP/1.1
|
|
res.status = 200;
|
|
res.reason("OK");
|
|
res.body = "Hello, world!";
|
|
res.fields.insert("Server", "Beast");
|
|
res.fields.insert("Content-Length", res.body.size());
|
|
```
|
|
][
|
|
```
|
|
200 OK HTTP/1.1\r\n
|
|
Server: Beast\r\n
|
|
Content-Length: 13\r\n
|
|
\r\n
|
|
Hello, world!
|
|
```
|
|
]]
|
|
]
|
|
|
|
[endsect]
|