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">&</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"><</span><span class="identifier">tcp_stream</span><span class="special">></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">(&</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">&</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">&</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">&</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">&</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">></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">&</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>(</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