• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Decorator</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_websocket.html" title="WebSocket">
9<link rel="prev" href="handshaking.html" title="Handshaking">
10<link rel="next" href="messages.html" title="Messages">
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="handshaking.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_websocket.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="messages.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_websocket.decorator"></a><a class="link" href="decorator.html" title="Decorator">Decorator</a>
28</h3></div></div></div>
29<p>
30        For programs which need to modify either the outgoing WebSocket HTTP Upgrade
31        request, the outgoing WebSocket HTTP Upgrade response, or both, the stream
32        supports an optional property called a <span class="emphasis"><em>decorator</em></span>. This
33        is a function pointer or callable object which is invoked before the implementation
34        sends an HTTP message. The decorator receives a modifiable reference to the
35        message, allowing for modifications. The interface to this system uses:
36      </p>
37<div class="table">
38<a name="beast.using_websocket.decorator.websocket_decorator_interface"></a><p class="title"><b>Table 1.32. WebSocket Decorator Interface</b></p>
39<div class="table-contents"><table class="table" summary="WebSocket Decorator Interface">
40<colgroup>
41<col>
42<col>
43</colgroup>
44<thead><tr>
45<th>
46                <p>
47                  Name
48                </p>
49              </th>
50<th>
51                <p>
52                  Description
53                </p>
54              </th>
55</tr></thead>
56<tbody>
57<tr>
58<td>
59                <p>
60                  <a class="link" href="../ref/boost__beast__websocket__request_type.html" title="websocket::request_type"><code class="computeroutput"><span class="identifier">request_type</span></code></a>
61                </p>
62              </td>
63<td>
64                <p>
65                  This is the type of the object passed to the decorator to represent
66                  HTTP Upgrade requests.
67                </p>
68              </td>
69</tr>
70<tr>
71<td>
72                <p>
73                  <a class="link" href="../ref/boost__beast__websocket__response_type.html" title="websocket::response_type"><code class="computeroutput"><span class="identifier">response_type</span></code></a>
74                </p>
75              </td>
76<td>
77                <p>
78                  This is the type of the object passed to the decorator to represent
79                  HTTP Upgrade response.
80                </p>
81              </td>
82</tr>
83<tr>
84<td>
85                <p>
86                  <a class="link" href="../ref/boost__beast__websocket__stream_base__decorator.html" title="websocket::stream_base::decorator"><code class="computeroutput"><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span></code></a>
87                </p>
88              </td>
89<td>
90                <p>
91                  Objects of this type are used to hold a decorator to be set on
92                  the stream using <code class="computeroutput"><span class="identifier">set_option</span></code>.
93                </p>
94              </td>
95</tr>
96<tr>
97<td>
98                <p>
99                  <a class="link" href="../ref/boost__beast__websocket__stream/set_option.html" title="websocket::stream::set_option"><code class="computeroutput"><span class="identifier">stream</span><span class="special">::</span><span class="identifier">set_option</span></code></a>
100                </p>
101              </td>
102<td>
103                <p>
104                  This function is used to set a <code class="computeroutput"><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span></code>
105                  on the stream.
106                </p>
107              </td>
108</tr>
109</tbody>
110</table></div>
111</div>
112<br class="table-break"><p>
113        This declares a normal function which decorates outgoing HTTP requests:
114      </p>
115<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">set_user_agent</span><span class="special">(</span><span class="identifier">request_type</span><span class="special">&amp;</span> <span class="identifier">req</span><span class="special">)</span>
116<span class="special">{</span>
117    <span class="comment">// Set the User-Agent on the request</span>
118    <span class="identifier">req</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">user_agent</span><span class="special">,</span> <span class="string">"My User Agent"</span><span class="special">);</span>
119<span class="special">}</span>
120</pre>
121<p>
122        When using a decorator, it must be set on the stream before any handshaking
123        takes place. This sets the decorator on the stream, to be used for all subsequent
124        calls to accept or handshake:
125      </p>
126<pre class="programlisting"><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp_stream</span><span class="special">&gt;</span> <span class="identifier">ws</span><span class="special">(</span><span class="identifier">ioc</span><span class="special">);</span>
127
128<span class="comment">// The function `set_user_agent` will be invoked with</span>
129<span class="comment">// every upgrade request before it is sent by the stream.</span>
130
131<span class="identifier">ws</span><span class="special">.</span><span class="identifier">set_option</span><span class="special">(</span><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span><span class="special">(&amp;</span><span class="identifier">set_user_agent</span><span class="special">));</span>
132</pre>
133<p>
134        Alternatively, a function object may be used. Small function objects will
135        not incur a memory allocation. The follow code declares and sets a function
136        object as a decorator:
137      </p>
138<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">set_server</span>
139<span class="special">{</span>
140    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">response_type</span><span class="special">&amp;</span> <span class="identifier">res</span><span class="special">)</span>
141    <span class="special">{</span>
142        <span class="comment">// Set the Server field on the response</span>
143        <span class="identifier">res</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">user_agent</span><span class="special">,</span> <span class="string">"My Server"</span><span class="special">);</span>
144    <span class="special">}</span>
145<span class="special">};</span>
146
147<span class="identifier">ws</span><span class="special">.</span><span class="identifier">set_option</span><span class="special">(</span><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span><span class="special">(</span><span class="identifier">set_server</span><span class="special">{}));</span>
148</pre>
149<p>
150        A lambda may be used in place of a named function object:
151      </p>
152<pre class="programlisting"><span class="identifier">ws</span><span class="special">.</span><span class="identifier">set_option</span><span class="special">(</span><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span><span class="special">(</span>
153    <span class="special">[](</span><span class="identifier">response_type</span><span class="special">&amp;</span> <span class="identifier">res</span><span class="special">)</span>
154    <span class="special">{</span>
155        <span class="comment">// Set the Server field on the response</span>
156        <span class="identifier">res</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">user_agent</span><span class="special">,</span> <span class="string">"My Server"</span><span class="special">);</span>
157    <span class="special">}));</span>
158</pre>
159<p>
160        It also possible for a single decorator to handle both requests and responses,
161        if it is overloaded for both types either as a generic lambda (C++14 and
162        later) or as a class as shown here:
163      </p>
164<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">set_message_fields</span>
165<span class="special">{</span>
166    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">request_type</span><span class="special">&amp;</span> <span class="identifier">req</span><span class="special">)</span>
167    <span class="special">{</span>
168        <span class="comment">// Set the User-Agent on the request</span>
169        <span class="identifier">req</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">user_agent</span><span class="special">,</span> <span class="string">"My User Agent"</span><span class="special">);</span>
170    <span class="special">}</span>
171
172    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">response_type</span><span class="special">&amp;</span> <span class="identifier">res</span><span class="special">)</span>
173    <span class="special">{</span>
174        <span class="comment">// Set the Server field on the response</span>
175        <span class="identifier">res</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">user_agent</span><span class="special">,</span> <span class="string">"My Server"</span><span class="special">);</span>
176    <span class="special">}</span>
177<span class="special">};</span>
178
179<span class="identifier">ws</span><span class="special">.</span><span class="identifier">set_option</span><span class="special">(</span><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span><span class="special">(</span><span class="identifier">set_message_fields</span><span class="special">{}));</span>
180</pre>
181<p>
182        The implementation takes ownership by decay-copy of the invocable object
183        used as the decorator. Move-only types are possible:
184      </p>
185<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">set_auth</span>
186<span class="special">{</span>
187    <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">key</span><span class="special">;</span>
188
189    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">request_type</span><span class="special">&amp;</span> <span class="identifier">req</span><span class="special">)</span>
190    <span class="special">{</span>
191        <span class="comment">// Set the authorization field</span>
192        <span class="identifier">req</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">authorization</span><span class="special">,</span> <span class="special">*</span><span class="identifier">key</span><span class="special">);</span>
193    <span class="special">}</span>
194<span class="special">};</span>
195
196<span class="comment">// The stream takes ownership of the decorator object</span>
197<span class="identifier">ws</span><span class="special">.</span><span class="identifier">set_option</span><span class="special">(</span><span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span><span class="special">(</span>
198    <span class="identifier">set_auth</span><span class="special">{</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_unique</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;(</span><span class="string">"Basic QWxhZGRpbjpPcGVuU2VzYW1l"</span><span class="special">)}));</span>
199</pre>
200<div class="important"><table border="0" summary="Important">
201<tr>
202<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
203<th align="left">Important</th>
204</tr>
205<tr><td align="left" valign="top"><p>
206          Undefined behavior results if the decorator modifies the fields specific
207          to perform the WebSocket Upgrade, such as the Upgrade or Connection fields.
208        </p></td></tr>
209</table></div>
210</div>
211<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
212<td align="left"></td>
213<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Vinnie
214      Falco<p>
215        Distributed under the Boost Software License, Version 1.0. (See accompanying
216        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>)
217      </p>
218</div></td>
219</tr></table>
220<hr>
221<div class="spirit-nav">
222<a accesskey="p" href="handshaking.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_websocket.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="messages.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
223</div>
224</body>
225</html>
226