• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Buffer-Oriented Parsing</title>
5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Beast">
8<link rel="up" href="../using_http.html" title="HTTP">
9<link rel="prev" href="buffer_oriented_serializing.html" title="Buffer-Oriented Serializing">
10<link rel="next" href="chunked_encoding.html" title="Chunked Encoding">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="buffer_oriented_serializing.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_http.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="chunked_encoding.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h3 class="title">
27<a name="beast.using_http.buffer_oriented_parsing"></a><a class="link" href="buffer_oriented_parsing.html" title="Buffer-Oriented Parsing">Buffer-Oriented
28      Parsing</a>
29</h3></div></div></div>
30<p>
31        A subclass of <a class="link" href="../ref/boost__beast__http__basic_parser.html" title="http::basic_parser"><code class="computeroutput"><span class="identifier">basic_parser</span></code></a> can be invoked directly,
32        without using the provided stream operations. This could be useful for implementing
33        algorithms on objects whose interface does not conform to <a class="link" href="../concepts/streams.html" title="Streams"><span class="emphasis"><em>Stream</em></span></a>.
34        For example, a <a href="http://zeromq.org/" target="_top"><span class="bold"><strong>ZeroMQ</strong></span>
35        socket</a>. The basic parser interface is interactive; the caller invokes
36        the function <a class="link" href="../ref/boost__beast__http__basic_parser/put.html" title="http::basic_parser::put"><code class="computeroutput"><span class="identifier">basic_parser</span><span class="special">::</span><span class="identifier">put</span></code></a> repeatedly with buffers until
37        an error occurs or the parsing is done. The function <a class="link" href="../ref/boost__beast__http__basic_parser/put_eof.html" title="http::basic_parser::put_eof"><code class="computeroutput"><span class="identifier">basic_parser</span><span class="special">::</span><span class="identifier">put_eof</span></code></a> Is used when the caller
38        knows that there will never be more data (for example, if the underlying
39        connection is closed),
40      </p>
41<h5>
42<a name="beast.using_http.buffer_oriented_parsing.h0"></a>
43        <span class="phrase"><a name="beast.using_http.buffer_oriented_parsing.parser_options"></a></span><a class="link" href="buffer_oriented_parsing.html#beast.using_http.buffer_oriented_parsing.parser_options">Parser
44        Options</a>
45      </h5>
46<p>
47        The parser provides a few options which may be set before parsing begins:
48      </p>
49<div class="table">
50<a name="beast.using_http.buffer_oriented_parsing.parser_options0"></a><p class="title"><b>Table 1.24. Parser Options</b></p>
51<div class="table-contents"><table class="table" summary="Parser Options">
52<colgroup>
53<col>
54<col>
55<col>
56</colgroup>
57<thead><tr>
58<th>
59                <p>
60                  Name
61                </p>
62              </th>
63<th>
64                <p>
65                  Default
66                </p>
67              </th>
68<th>
69                <p>
70                  Description
71                </p>
72              </th>
73</tr></thead>
74<tbody>
75<tr>
76<td>
77                <p>
78                  <a class="link" href="../ref/boost__beast__http__basic_parser/eager/overload2.html" title="http::basic_parser::eager (2 of 2 overloads)"><code class="computeroutput"><span class="identifier">eager</span></code></a>
79                </p>
80              </td>
81<td>
82                <p>
83                  <code class="computeroutput"><span class="keyword">false</span></code>
84                </p>
85              </td>
86<td>
87                <p>
88                  Normally the parser returns after successfully parsing a structured
89                  element (header, chunk header, or chunk body) even if there are
90                  octets remaining in the input. This is necessary when attempting
91                  to parse the header first, or when the caller wants to inspect
92                  information which may be invalidated by subsequent parsing, such
93                  as a chunk extension. The <code class="computeroutput"><span class="identifier">eager</span></code>
94                  option controls whether the parser keeps going after parsing structured
95                  element if there are octets remaining in the buffer and no error
96                  occurs. This option is automatically set or cleared during certain
97                  stream operations to improve performance with no change in functionality.
98                </p>
99              </td>
100</tr>
101<tr>
102<td>
103                <p>
104                  <a class="link" href="../ref/boost__beast__http__basic_parser/skip/overload2.html" title="http::basic_parser::skip (2 of 2 overloads)"><code class="computeroutput"><span class="identifier">skip</span></code></a>
105                </p>
106              </td>
107<td>
108                <p>
109                  <code class="computeroutput"><span class="keyword">false</span></code>
110                </p>
111              </td>
112<td>
113                <p>
114                  This option controls whether or not the parser expects to see an
115                  HTTP body, regardless of the presence or absence of certain fields
116                  such as Content-Length or a chunked Transfer-Encoding. Depending
117                  on the request, some responses do not carry a body. For example,
118                  a 200 response to a <a href="https://tools.ietf.org/html/rfc7231#section-4.3.6" target="_top">CONNECT</a>
119                  request from a tunneling proxy, or a response to a <a href="https://tools.ietf.org/html/rfc7231#section-4.3.2" target="_top">HEAD</a>
120                  request. In these cases, callers may use this function inform the
121                  parser that no body is expected. The parser will consider the message
122                  complete after the header has been received.
123                </p>
124              </td>
125</tr>
126<tr>
127<td>
128                <p>
129                  <a class="link" href="../ref/boost__beast__http__basic_parser/body_limit.html" title="http::basic_parser::body_limit"><code class="computeroutput"><span class="identifier">body_limit</span></code></a>
130                </p>
131              </td>
132<td>
133                <p>
134                  1MB/8MB
135                </p>
136              </td>
137<td>
138                <p>
139                  This function sets the maximum allowed size of the content body.
140                  When a body larger than the specified size is detected, an error
141                  is generated and parsing terminates. This setting helps protect
142                  servers from resource exhaustion attacks. The default limit when
143                  parsing requests is 1MB, and for parsing responses 8MB.
144                </p>
145              </td>
146</tr>
147<tr>
148<td>
149                <p>
150                  <a class="link" href="../ref/boost__beast__http__basic_parser/header_limit.html" title="http::basic_parser::header_limit"><code class="computeroutput"><span class="identifier">header_limit</span></code></a>
151                </p>
152              </td>
153<td>
154                <p>
155                  8KB
156                </p>
157              </td>
158<td>
159                <p>
160                  This function sets the maximum allowed size of the header including
161                  all field name, value, and delimiter characters and also including
162                  the CRLF sequences in the serialized input.
163                </p>
164              </td>
165</tr>
166</tbody>
167</table></div>
168</div>
169<br class="table-break"><div class="section">
170<div class="titlepage"><div><div><h4 class="title">
171<a name="beast.using_http.buffer_oriented_parsing.read_from_std_istream"></a><a class="link" href="buffer_oriented_parsing.html#beast.using_http.buffer_oriented_parsing.read_from_std_istream" title="Read From std::istream ��">Read
172        From std::istream ��</a>
173</h4></div></div></div>
174<p>
175          The standard library provides the type <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code>
176          for performing high level read operations on character streams. The variable
177          <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span></code> is based on this input stream. This
178          example uses the buffer oriented interface of <a class="link" href="../ref/boost__beast__http__basic_parser.html" title="http::basic_parser"><code class="computeroutput"><span class="identifier">basic_parser</span></code></a> to build a stream
179          operation which parses an HTTP message from a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code>:
180        </p>
181<pre class="programlisting"><span class="comment">/** Read a message from a `std::istream`.
182
183    This function attempts to parse a complete HTTP/1 message from the stream.
184
185    @param is The `std::istream` to read from.
186
187    @param buffer The buffer to use.
188
189    @param msg The message to store the result.
190
191    @param ec Set to the error, if any occurred.
192*/</span>
193<span class="keyword">template</span><span class="special">&lt;</span>
194    <span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">,</span>
195    <span class="keyword">bool</span> <span class="identifier">isRequest</span><span class="special">,</span>
196    <span class="keyword">class</span> <span class="identifier">Body</span><span class="special">&gt;</span>
197<span class="keyword">void</span>
198<span class="identifier">read_istream</span><span class="special">(</span>
199    <span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is</span><span class="special">,</span>
200    <span class="identifier">basic_flat_buffer</span><span class="special">&lt;</span><span class="identifier">Allocator</span><span class="special">&gt;&amp;</span> <span class="identifier">buffer</span><span class="special">,</span>
201    <span class="identifier">message</span><span class="special">&lt;</span><span class="identifier">isRequest</span><span class="special">,</span> <span class="identifier">Body</span><span class="special">,</span> <span class="identifier">fields</span><span class="special">&gt;&amp;</span> <span class="identifier">msg</span><span class="special">,</span>
202    <span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">)</span>
203<span class="special">{</span>
204    <span class="comment">// Create the message parser</span>
205    <span class="comment">//</span>
206    <span class="comment">// Arguments passed to the parser's constructor are</span>
207    <span class="comment">// forwarded to the message constructor. Here, we use</span>
208    <span class="comment">// a move construction in case the caller has constructed</span>
209    <span class="comment">// their message in a non-default way.</span>
210    <span class="comment">//</span>
211    <span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">isRequest</span><span class="special">,</span> <span class="identifier">Body</span><span class="special">&gt;</span> <span class="identifier">p</span><span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)};</span>
212
213    <span class="keyword">do</span>
214    <span class="special">{</span>
215        <span class="comment">// Extract whatever characters are presently available in the istream</span>
216        <span class="keyword">if</span><span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">rdbuf</span><span class="special">()-&gt;</span><span class="identifier">in_avail</span><span class="special">()</span> <span class="special">&gt;</span> <span class="number">0</span><span class="special">)</span>
217        <span class="special">{</span>
218            <span class="comment">// Get a mutable buffer sequence for writing</span>
219            <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">prepare</span><span class="special">(</span>
220                <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">rdbuf</span><span class="special">()-&gt;</span><span class="identifier">in_avail</span><span class="special">()));</span>
221
222            <span class="comment">// Now get everything we can from the istream</span>
223            <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">commit</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">readsome</span><span class="special">(</span>
224                <span class="keyword">reinterpret_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">b</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">size</span><span class="special">())));</span>
225        <span class="special">}</span>
226        <span class="keyword">else</span> <span class="keyword">if</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
227        <span class="special">{</span>
228            <span class="comment">// Our buffer is empty and we need more characters, </span>
229            <span class="comment">// see if we've reached the end of file on the istream</span>
230            <span class="keyword">if</span><span class="special">(!</span> <span class="identifier">is</span><span class="special">.</span><span class="identifier">eof</span><span class="special">())</span>
231            <span class="special">{</span>
232                <span class="comment">// Get a mutable buffer sequence for writing</span>
233                <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">prepare</span><span class="special">(</span><span class="number">1024</span><span class="special">);</span>
234
235                <span class="comment">// Try to get more from the istream. This might block.</span>
236                <span class="identifier">is</span><span class="special">.</span><span class="identifier">read</span><span class="special">(</span><span class="keyword">reinterpret_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">b</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
237
238                <span class="comment">// If an error occurs on the istream then return it to the caller.</span>
239                <span class="keyword">if</span><span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">fail</span><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="special">!</span> <span class="identifier">is</span><span class="special">.</span><span class="identifier">eof</span><span class="special">())</span>
240                <span class="special">{</span>
241                    <span class="comment">// We'll just re-use io_error since std::istream has no error_code interface.</span>
242                    <span class="identifier">ec</span> <span class="special">=</span> <span class="identifier">make_error_code</span><span class="special">(</span><span class="identifier">errc</span><span class="special">::</span><span class="identifier">io_error</span><span class="special">);</span>
243                    <span class="keyword">return</span><span class="special">;</span>
244                <span class="special">}</span>
245
246                <span class="comment">// Commit the characters we got to the buffer.</span>
247                <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">commit</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">gcount</span><span class="special">()));</span>
248            <span class="special">}</span>
249            <span class="keyword">else</span>
250            <span class="special">{</span>
251                <span class="comment">// Inform the parser that we've reached the end of the istream.</span>
252                <span class="identifier">p</span><span class="special">.</span><span class="identifier">put_eof</span><span class="special">(</span><span class="identifier">ec</span><span class="special">);</span>
253                <span class="keyword">if</span><span class="special">(</span><span class="identifier">ec</span><span class="special">)</span>
254                    <span class="keyword">return</span><span class="special">;</span>
255                <span class="keyword">break</span><span class="special">;</span>
256            <span class="special">}</span>
257        <span class="special">}</span>
258
259        <span class="comment">// Write the data to the parser</span>
260        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">bytes_used</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">put</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">ec</span><span class="special">);</span>
261
262        <span class="comment">// This error means that the parser needs additional octets.</span>
263        <span class="keyword">if</span><span class="special">(</span><span class="identifier">ec</span> <span class="special">==</span> <span class="identifier">error</span><span class="special">::</span><span class="identifier">need_more</span><span class="special">)</span>
264            <span class="identifier">ec</span> <span class="special">=</span> <span class="special">{};</span>
265        <span class="keyword">if</span><span class="special">(</span><span class="identifier">ec</span><span class="special">)</span>
266            <span class="keyword">return</span><span class="special">;</span>
267
268        <span class="comment">// Consume the buffer octets that were actually parsed.</span>
269        <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">consume</span><span class="special">(</span><span class="identifier">bytes_used</span><span class="special">);</span>
270    <span class="special">}</span>
271    <span class="keyword">while</span><span class="special">(!</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">is_done</span><span class="special">());</span>
272
273    <span class="comment">// Transfer ownership of the message container in the parser to the caller.</span>
274    <span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">release</span><span class="special">();</span>
275<span class="special">}</span>
276</pre>
277<div class="tip"><table border="0" summary="Tip">
278<tr>
279<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
280<th align="left">Tip</th>
281</tr>
282<tr><td align="left" valign="top"><p>
283            Parsing from a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code> could be implemented using
284            an alternate strategy: adapt the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code>
285            interface to a <a href="../../../../../../doc/html/boost_asio/reference/SyncReadStream.html" target="_top"><span class="emphasis"><em>SyncReadStream</em></span></a>,
286            enabling use with the library's existing stream algorithms. This is left
287            as an exercise for the reader.
288          </p></td></tr>
289</table></div>
290</div>
291</div>
292<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
293<td align="left"></td>
294<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Vinnie
295      Falco<p>
296        Distributed under the Boost Software License, Version 1.0. (See accompanying
297        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
298      </p>
299</div></td>
300</tr></table>
301<hr>
302<div class="spirit-nav">
303<a accesskey="p" href="buffer_oriented_serializing.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_http.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="chunked_encoding.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
304</div>
305</body>
306</html>
307