mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Beast.WebSocket:
Beast.WebSocket provides developers with a robust WebSocket implementation built on Boost.Asio with a consistent asynchronous model using a modern C++ approach.
This commit is contained in:
215
doc/http.qbk
Normal file
215
doc/http.qbk
Normal file
@@ -0,0 +1,215 @@
|
||||
[/
|
||||
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)
|
||||
]
|
||||
|
||||
[section:http HTTP]
|
||||
|
||||
Beast.HTTP offers programmers simple and performant models of HTTP messages and
|
||||
their associated operations including synchronous and asynchronous reading and
|
||||
writing using Boost.Asio.
|
||||
|
||||
The HTTP protocol is described fully in
|
||||
[@https://tools.ietf.org/html/rfc2616 rfc2616]
|
||||
|
||||
|
||||
|
||||
[section:motivation Motivation]
|
||||
|
||||
The HTTP protocol is pervasive in network applications. As C++ is a logical
|
||||
choice for high performance network servers, there is great utility in solid
|
||||
building blocks for manipulating, sending, and receiving HTTP messages
|
||||
compliant with the Hypertext Transfer Protocol and the supplements that
|
||||
follow. Unfortunately reliable implementations or industry standards do not
|
||||
exist in C++.
|
||||
|
||||
Beast.HTTP is built on Boost.Asio and uses HTTP parser from NodeJS, which is
|
||||
extensively field tested and exceptionally robust. A proposal to add networking
|
||||
functionality to the C++ standard library, based on Boost.Asio, is under
|
||||
consideration by the standards committee. Since the final approved networking
|
||||
interface for the C++ standard library will likely closely resemble the current
|
||||
interface of Boost.Asio, it is logical for Beast.HTTP to use Boost.Asio as its
|
||||
network transport.
|
||||
|
||||
[note The documentation which follows assumes familiarity with
|
||||
both Boost.Asio and the HTTP protocol specification described in
|
||||
[@https://tools.ietf.org/html/rfc2616 rfc2616] ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:example Example]
|
||||
|
||||
All examples and identifiers mentioned in this document are written as
|
||||
if the following declarations are in effect:
|
||||
```
|
||||
#include <beast/http.h>
|
||||
using namespace beast::http;
|
||||
using namespace boost::asio;
|
||||
```
|
||||
|
||||
Create a HTTP request:
|
||||
```
|
||||
request<string_body> req({method_t::http_get, "/", 11});
|
||||
req.headers.insert("Host", "127.0.0.1:80");
|
||||
req.headers.insert("User-Agent", "Beast.HTTP");
|
||||
|
||||
```
|
||||
|
||||
To send a message it must first be prepared through a call to `prepare`. This
|
||||
customization point transforms the `message` into a `prepared_message`,
|
||||
filling in some standard HTTP behavior and allowing the Body associated with
|
||||
the message to perform preparatory steps. For example, a string body may set
|
||||
the Content-Length and Content-Type appropriately.
|
||||
```
|
||||
void send_request(ip::tcp::socket& sock,
|
||||
request<string_body>&& req)
|
||||
{
|
||||
// Send the request on the socket
|
||||
write(sock, prepare(req, connection(keep_alive));
|
||||
}
|
||||
```
|
||||
|
||||
Messages can be read from the network and parsed into a `parsed_message` object,
|
||||
which extends the `message` by adding parse-specific metadata such as the
|
||||
keep-alive which is context sensitive (depending on the HTTP version for
|
||||
example). When preparing a response for sending, `prepare` must be called with
|
||||
an additional parameter, the corresponding parsed request. The implementation
|
||||
inspects the contents of the request to set dependent fields of the response.
|
||||
This example reads a message, builds a response, and sends it.
|
||||
```
|
||||
void handle_connection(ip::tcp::socket& sock)
|
||||
{
|
||||
parsed_request<string_body> req;
|
||||
read(sock, req);
|
||||
response<string_body> resp;
|
||||
...
|
||||
write(sock, prepare(resp, req));
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:message Message model]
|
||||
|
||||
A HTTP message (referred to hereafter as "message") contains a request or
|
||||
response line, 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. Applications using HTTP often perform these operations
|
||||
on messages:
|
||||
|
||||
* [*Parse] a new message from a series of octets.
|
||||
|
||||
* [*Assemble] a new message from scratch or from an existing message.
|
||||
|
||||
* [*Serialize] a message into a series of octets.
|
||||
|
||||
* [*Read] a message from a stream. This can be thought of as a compound
|
||||
operation; a network read, followed by a [*parse].
|
||||
|
||||
* [*Write] a message to a stream. This can be thought of as a compound
|
||||
operation: a [*serialize] followed by a network write.
|
||||
|
||||
The spectrum of hardware and software platforms which perform these typical
|
||||
HTTP operations is vast, ranging from powerful servers in large datacenters
|
||||
to tiny resource-limited embedded devices. No single concrete implementation
|
||||
of a class intended to model messages can efficiently serve all needs.
|
||||
For example, an object that minimizes resources during parsing may not be
|
||||
able to edit and change headers dynamically. A message that represents the
|
||||
message body as a disk file may support sending but not parsing. Many efficient
|
||||
and correct models of messages exist, supporting some or all of the
|
||||
operations listed above.
|
||||
|
||||
To support a variety of implementation strategies, we introduce customization
|
||||
points for the header and body via class template arguments. This illustration
|
||||
shows the message class template (boilerplate present in the actual
|
||||
declaration has been removed for clarity):
|
||||
|
||||
[$images/message.png [width 580px] [height 225px]]
|
||||
|
||||
The default constructor, move special members, and copy special members are
|
||||
all defaulted. A message is movable, copyable, or default constructible based
|
||||
on the capabilities of its template arguments.
|
||||
|
||||
Messages modeled in this fashion are ['complete], containing all of the
|
||||
information required to perform the supported set of operations. They are
|
||||
['first-class types], returnable from functions and composable. HTTP
|
||||
requests and responses are distinct types, allowing functions to be
|
||||
overloaded on the type of message.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:body Body parameter]
|
||||
|
||||
The `Body` template argument in the `message` class must meet the
|
||||
[link beast.types.Body [*`Body`] requirements]. It provides customization
|
||||
of the data member in the message, the algorithm for parsing, and the
|
||||
algorithm for serialization:
|
||||
|
||||
[$images/body.png [width 510px] [height 210px]]
|
||||
|
||||
The following types, provided by the library, meet the `Body` requirements:
|
||||
|
||||
* [link beast.ref.http__empty_body [*`empty_body`:]] An empty message body.
|
||||
Used in GET requests where there is no message body.
|
||||
|
||||
* [link beast.ref.http__string_body [*`string_body`:]] A body with a
|
||||
`value_type` of `std::string`. Useful for quickly putting together a request
|
||||
or response with simple text in the message body (such as an error message).
|
||||
Subject to the performance limit of strings if large amounts of data are
|
||||
inserted.
|
||||
|
||||
* [link beast.ref.http__basic_streambuf_body [*`basic_streambuf_body`:]] A body with a
|
||||
`value_type` of `streambuf`. A streambuf is an efficient storage object which
|
||||
uses multiple octet arrays of varying lengths to represent data.
|
||||
|
||||
Instances of the optional nested types `writer` and `reader` perform
|
||||
serialization and deserialization of the message body. If either or
|
||||
both of these types are present, the message becomes serializable, parsable,
|
||||
or both. They model [link beast.types.Reader [*`Reader`]] and
|
||||
[link beast.types.Writer [*`Writer`]] respectively.
|
||||
|
||||
For specialized applications, users may implement their own types which
|
||||
meet the requirements. The examples included with this library provide a
|
||||
Body implementation used to serve files in a HTTP server.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:headers Headers container]
|
||||
|
||||
The `Headers` type represents the field/value pairs present in every HTTP
|
||||
message. These types implement the
|
||||
[link beast.types.FieldSequence [*`FieldSequence`]]
|
||||
concept. The value type of a field sequence is an object meeting the
|
||||
requirements of [link beast.types.Field [*`Field`]]. The implementation can
|
||||
serialize any instance of `Headers` that meets the field sequence requirements.
|
||||
This example shows a function which returns `true` if the specified field
|
||||
sequence has a connect field:
|
||||
```
|
||||
template<class FieldSequence>
|
||||
bool
|
||||
has_connect(FieldSequence const& fs)
|
||||
{
|
||||
return std::find_if(fs.begin(), fs.end(),
|
||||
[&](auto const& field)
|
||||
{
|
||||
return ci_equal(field.name(), "Connect");
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
Reference in New Issue
Block a user