]> git.proxmox.com Git - ceph.git/blame - ceph/src/Beast/doc/http.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / doc / http.qbk
CommitLineData
7c673cae
FG
1[/
2 Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6]
7
8[/
9ideas:
10 - complete send request walkthrough (client)
11 - complete receive response walkthrough (client)
12 - complete receive request walkthrough (server)
13 - complete send response walkthrough (server)
14
15 - Introduce concepts from simple to complex
16 - Smooth progression of new ideas building on the previous ideas
17
18 - do we show a simplified message with collapsed fields?
19 - do we introduce `header` or `message` first?
20
21
22contents:
23 Message (and header, fields)
24 Create request
25 Create response
26 Algorithms
27 Write
28 Read
29 Examples
30 Send Request
31 Receive Response
32 Receive Request
33 Send Response
34 Advanced
35 Responding to HEAD
36 Expect: 100-continue
37 Body (user defined)
38
39
40section beast.http.examples Examples
41
42note
43 In the example code which follows, `socket` refers to an object of type
44 `boost::asio::ip::tcp::socket` which is currently connected to a remote peer.
45]
46
47
48
49[section:http Using HTTP]
50
51[block '''
52<informaltable frame="all"><tgroup cols="1"><colspec colname="a"/><tbody><row><entry valign="top"><simplelist>
53 <member><link linkend="beast.http.message">Message</link></member>
54 <member><link linkend="beast.http.fields">Fields</link></member>
55 <member><link linkend="beast.http.body">Body</link></member>
56 <member><link linkend="beast.http.algorithms">Algorithms</link></member>
57</simplelist></entry></row></tbody></tgroup></informaltable>
58''']
59
60Beast offers programmers simple and performant models of HTTP messages and
61their associated operations including synchronous and asynchronous reading and
62writing of messages and headers in the HTTP/1 wire format using Boost.Asio.
63
64[note
65 The following documentation assumes familiarity with both Boost.Asio
66 and the HTTP protocol specification described in __rfc7230__. Sample code
67 and identifiers mentioned in this section are written as if the following
68 declarations are in effect:
69 ```
70 #include <beast/core.hpp>
71 #include <beast/http.hpp>
72 using namespace beast;
73 using namespace beast::http;
74 ```
75]
76
77
78
79
80
81[section:message Message]
82
83The HTTP protocol defines the client and server roles: clients send messages
84called requests and servers send back messages called responses. A HTTP message
85(referred to hereafter as "message") contains request or response specific
86attributes (contained in the "Start Line"), a series of zero or more name/value
87pairs (collectively termed "Fields"), and an optional series of octets called
88the message body which may be zero in length. The start line for a HTTP request
89includes a string called the method, a string called the URL, and a version
90number indicating HTTP/1.0 or HTTP/1.1. For a response, the start line contains
91an integer status code and a string called the reason phrase. Alternatively, a
92HTTP message can be viewed as two parts: a header, followed by a body.
93
94[note
95 The Reason-Phrase is obsolete as of rfc7230.
96]
97
98The __header__ class template models the header for HTTP/1 and HTTP/2 messages.
99This class template is a family of specializations, one for requests and one
100for responses, depending on the [*`isRequest`] template value.
101The [*`Fields`] template type determines the type of associative container
102used to store the field values. The provided __basic_fields__ class template
103and __fields__ type alias are typical choices for the [*`Fields`] type, but
104advanced applications may supply user defined types which meet the requirements.
105The __message__ class template models the header and optional body for HTTP/1
106and HTTP/2 requests and responses. It is derived from the __header__ class
107template with the same shared template parameters, and adds the `body` data
108member. The message class template requires an additional template argument
109type [*`Body`]. This type controls the container used to represent the body,
110if any, as well as the algorithms needed to serialize and parse bodies of
111that type.
112
113This illustration shows the declarations and members of the __header__ and
114__message__ class templates, as well as the inheritance relationship:
115
116[$images/message.png [width 650px] [height 390px]]
117
118For notational convenience, these template type aliases are provided which
119supply typical choices for the [*`Fields`] type:
120```
121using request_header = header<true, fields>;
122using response_header = header<false, fields>;
123
124template<class Body, class Fields = fields>
125using request = message<true, Body, Fields>;
126
127template<class Body, class Fields = fields>
128using response = message<false, Body, Fields>;
129```
130
131The code examples below show how to create and fill in a request and response
132object:
133
134[table Create Message
135[[HTTP Request] [HTTP Response]]
136[[
137 ```
138 request<string_body> req;
139 req.version = 11; // HTTP/1.1
140 req.method = "GET";
141 req.url = "/index.htm"
142 req.fields.insert("Accept", "text/html");
143 req.fields.insert("Connection", "keep-alive");
144 req.fields.insert("User-Agent", "Beast");
145 ```
146][
147 ```
148 response<string_body> res;
149 res.version = 11; // HTTP/1.1
150 res.status = 200;
151 res.reason = "OK";
152 res.fields.insert("Sever", "Beast");
153 res.fields.insert("Content-Length", 4);
154 res.body = "****";
155 ```
156]]]
157
158In the serialized format of a HTTP message, the header is represented as a
159series of text lines ending in CRLF (`"\r\n"`). The end of the header is
160indicated by a line containing only CRLF. Here are examples of serialized HTTP
161request and response objects. The objects created above will produce these
162results when serialized. Note that only the response has a body:
163
164[table Serialized HTTP Request and Response
165[[HTTP Request] [HTTP Response]]
166[[
167 ```
168 GET /index.htm HTTP/1.1\r\n
169 Accept: text/html\r\n
170 Connection: keep-alive\r\n
171 User-Agent: Beast\r\n
172 \r\n
173 ```
174][
175 ```
176 200 OK HTTP/1.1\r\n
177 Server: Beast\r\n
178 Content-Length: 4\r\n
179 \r\n
180 ****
181 ```
182]]]
183
184
185
186
187[endsect]
188
189
190
191
192[section:fields Fields]
193
194The [*`Fields`] type represents a container that can set or retrieve the
195fields in a message. Beast provides the
196[link beast.ref.http__basic_fields `basic_fields`] class which serves
197the needs for most users. It supports modification and inspection of values.
198The field names are not case-sensitive.
199
200These statements change the values of the headers in the message passed:
201```
202 template<class Body>
203 void set_fields(request<Body>& req)
204 {
205 if(! req.exists("User-Agent"))
206 req.insert("User-Agent", "myWebClient");
207
208 if(req.exists("Accept-Charset"))
209 req.erase("Accept-Charset");
210
211 req.replace("Accept", "text/plain");
212 }
213```
214
215User defined [*`Fields`] types are possible. To support serialization, the
216type must meet the requirements of __FieldSequence__. To support parsing using
217the provided parser, the type must provide the `insert` member function.
218
219[endsect]
220
221
222
223[section:body Body]
224
225The message [*`Body`] template parameter controls both the type of the data
226member of the resulting message object, and the algorithms used during parsing
227and serialization. Beast provides three very common [*`Body`] types:
228
229* [link beast.ref.http__string_body [*`string_body`:]] A body with a
230`value_type` as `std::string`. Useful for quickly putting together a request
231or response with simple text in the message body (such as an error message).
232Has the same insertion complexity of `std::string`. This is the type of body
233used in the examples:
234```
235 response<string_body> res;
236 static_assert(std::is_same<decltype(res.body), std::string>::value);
237 res.body = "Here is the data you requested";
238```
239
240* [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a
241`value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage
242object which uses multiple octet arrays of varying lengths to represent data.
243
244[heading Advanced]
245
246User-defined types are possible for the message body, where the type meets the
247[link beast.ref.Body [*`Body`]] requirements. This simplified class declaration
248shows the customization points available to user-defined body types:
249
250[$images/body.png [width 510px] [height 210px]]
251
252* [*`value_type`]: Determines the type of the
253 [link beast.ref.http__message.body `message::body`] member. If this
254 type defines default construction, move, copy, or swap, then message objects
255 declared with this [*`Body`] will have those operations defined.
256
257* [*`reader`]: An optional nested type meeting the requirements of
258 [link beast.ref.Reader [*`Reader`]]. If present, this defines the algorithm
259 used for parsing bodies of this type.
260
261* [*`writer`]: An optional nested type meeting the requirements of
262 [link beast.ref.Writer [*`Writer`]]. If present, this defines the algorithm
263 used for serializing bodies of this type.
264
265The examples included with this library provide a Body implementation that
266serializing message bodies that come from a file.
267
268[endsect]
269
270
271
272[section:algorithms Algorithms]
273
274Algorithms are provided to serialize and deserialize HTTP/1 messages on
275streams.
276
277* [link beast.ref.http__read [*read]]: Deserialize a HTTP/1 __header__ or __message__ from a stream.
278* [link beast.ref.http__write [*write]]: Serialize a HTTP/1 __header__ or __message__ to a stream.
279
280Asynchronous versions of these algorithms are also available:
281
282* [link beast.ref.http__async_read [*async_read]]: Deserialize a HTTP/1 __header__ or __message__ asynchronously from a stream.
283* [link beast.ref.http__async_write [*async_write]]: Serialize a HTTP/1 __header__ or __message__ asynchronously to a stream.
284
285[heading Using Sockets]
286
287The free function algorithms are modeled after Boost.Asio to send and receive
288messages on TCP/IP sockets, SSL streams, or any object which meets the
289Boost.Asio type requirements (__SyncReadStream__, __SyncWriteStream__,
290__AsyncReadStream__, and __AsyncWriteStream__ depending on the types of
291operations performed). To send messages synchronously, use one of the
292[link beast.ref.http__write `write`] functions:
293```
294 void send_request(boost::asio::ip::tcp::socket& sock)
295 {
296 request<string_body> req;
297 req.version = 11;
298 req.method = "GET";
299 req.url = "/index.html";
300 ...
301 write(sock, req); // Throws exception on error
302 ...
303 // Alternatively
304 boost::system::error:code ec;
305 write(sock, req, ec);
306 if(ec)
307 std::cerr << "error writing http message: " << ec.message();
308 }
309```
310
311An asynchronous interface is available:
312```
313 void handle_write(boost::system::error_code);
314 ...
315 request<string_body> req;
316 ...
317 async_write(sock, req, std::bind(&handle_write, std::placeholders::_1));
318```
319
320When the implementation reads messages from a socket, it can read bytes lying
321after the end of the message if they are present (the alternative is to read
322a single byte at a time which is unsuitable for performance reasons). To
323store and re-use these extra bytes on subsequent messages, the read interface
324requires an additional parameter: a [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]
325object. This example reads a message from the socket, with the extra bytes
326stored in the streambuf parameter for use in a subsequent call to read:
327```
328 boost::asio::streambuf sb;
329 ...
330 response<string_body> res;
331 read(sock, sb, res); // Throws exception on error
332 ...
333 // Alternatively
334 boost::system::error:code ec;
335 read(sock, sb, res, ec);
336 if(ec)
337 std::cerr << "error reading http message: " << ec.message();
338```
339
340As with the write function, an asynchronous interface is available. The
341stream buffer parameter must remain valid until the completion handler is
342called:
343```
344 void handle_read(boost::system::error_code);
345 ...
346 boost::asio::streambuf sb;
347 response<string_body> res;
348 ...
349 async_read(sock, res, std::bind(&handle_read, std::placeholders::_1));
350```
351
352An alternative to using a `boost::asio::streambuf` is to use a
353__streambuf__, which meets the requirements of __DynamicBuffer__ and
354is optimized for performance:
355```
356 void handle_read(boost::system::error_code);
357 ...
358 beast::streambuf sb;
359 response<string_body> res;
360 read(sock, sb, res);
361```
362
363The `read` implementation can use any object meeting the requirements of
364__DynamicBuffer__, allowing callers to define custom
365memory management strategies used by the implementation.
366
367[endsect]
368
369
370
371[endsect]