]>
Commit | Line | Data |
---|---|---|
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 | #ifndef BEAST_WEBSOCKET_OPTION_HPP | |
9 | #define BEAST_WEBSOCKET_OPTION_HPP | |
10 | ||
11 | #include <beast/config.hpp> | |
12 | #include <beast/websocket/rfc6455.hpp> | |
13 | #include <beast/websocket/detail/decorator.hpp> | |
14 | #include <beast/core/detail/type_traits.hpp> | |
15 | #include <algorithm> | |
16 | #include <cstdint> | |
17 | #include <functional> | |
18 | #include <stdexcept> | |
19 | #include <type_traits> | |
20 | #include <utility> | |
21 | ||
22 | namespace beast { | |
23 | namespace websocket { | |
24 | ||
25 | /** Automatic fragmentation option. | |
26 | ||
27 | Determines if outgoing message payloads are broken up into | |
28 | multiple pieces. | |
29 | ||
30 | When the automatic fragmentation size is turned on, outgoing | |
31 | message payloads are broken up into multiple frames no larger | |
32 | than the write buffer size. | |
33 | ||
34 | The default setting is to fragment messages. | |
35 | ||
36 | @note Objects of this type are used with | |
37 | @ref beast::websocket::stream::set_option. | |
38 | ||
39 | @par Example | |
40 | Setting the automatic fragmentation option: | |
41 | @code | |
42 | ... | |
43 | websocket::stream<ip::tcp::socket> stream(ios); | |
44 | stream.set_option(auto_fragment{true}); | |
45 | @endcode | |
46 | */ | |
47 | #if BEAST_DOXYGEN | |
48 | using auto_fragment = implementation_defined; | |
49 | #else | |
50 | struct auto_fragment | |
51 | { | |
52 | bool value; | |
53 | ||
54 | explicit | |
55 | auto_fragment(bool v) | |
56 | : value(v) | |
57 | { | |
58 | } | |
59 | }; | |
60 | #endif | |
61 | ||
62 | /** HTTP decorator option. | |
63 | ||
64 | The decorator transforms the HTTP requests and responses used | |
65 | when requesting or responding to the WebSocket Upgrade. This may | |
66 | be used to set or change header fields. For example to set the | |
67 | Server or User-Agent fields. The default setting applies no | |
68 | transformation to the HTTP message. | |
69 | ||
70 | The context in which the decorator is called depends on the | |
71 | type of operation performed: | |
72 | ||
73 | @li For synchronous operations, the implementation will call the | |
74 | decorator before the operation unblocks. | |
75 | ||
76 | @li For asynchronous operations, the implementation guarantees | |
77 | that calls to the decorator will be made from the same implicit | |
78 | or explicit strand used to call the asynchronous initiation | |
79 | function. | |
80 | ||
81 | The default setting is no decorator. | |
82 | ||
83 | @note Objects of this type are used with | |
84 | @ref beast::websocket::stream::set_option. | |
85 | ||
86 | @par Example | |
87 | Setting the decorator. | |
88 | @code | |
89 | struct identity | |
90 | { | |
91 | template<bool isRequest, class Body, class Fields> | |
92 | void | |
93 | operator()(http::message<isRequest, Body, Fields>& m) | |
94 | { | |
95 | if(isRequest) | |
96 | m.fields.replace("User-Agent", "MyClient"); | |
97 | else | |
98 | m.fields.replace("Server", "MyServer"); | |
99 | } | |
100 | }; | |
101 | ... | |
102 | websocket::stream<ip::tcp::socket> ws(ios); | |
103 | ws.set_option(decorate(identity{})); | |
104 | @endcode | |
105 | */ | |
106 | #if BEAST_DOXYGEN | |
107 | using decorate = implementation_defined; | |
108 | #else | |
109 | using decorate = detail::decorator_type; | |
110 | #endif | |
111 | ||
112 | /** Keep-alive option. | |
113 | ||
114 | Determines if the connection is closed after a failed upgrade | |
115 | request. | |
116 | ||
117 | This setting only affects the behavior of HTTP requests that | |
118 | implicitly or explicitly ask for a keepalive. For HTTP requests | |
119 | that indicate the connection should be closed, the connection is | |
120 | closed as per rfc7230. | |
121 | ||
122 | The default setting is to close connections after a failed | |
123 | upgrade request. | |
124 | ||
125 | @note Objects of this type are used with | |
126 | @ref beast::websocket::stream::set_option. | |
127 | ||
128 | @par Example | |
129 | Setting the keep alive option. | |
130 | @code | |
131 | ... | |
132 | websocket::stream<ip::tcp::socket> ws(ios); | |
133 | ws.set_option(keep_alive{8192}); | |
134 | @endcode | |
135 | */ | |
136 | #if BEAST_DOXYGEN | |
137 | using keep_alive = implementation_defined; | |
138 | #else | |
139 | struct keep_alive | |
140 | { | |
141 | bool value; | |
142 | ||
143 | explicit | |
144 | keep_alive(bool v) | |
145 | : value(v) | |
146 | { | |
147 | } | |
148 | }; | |
149 | #endif | |
150 | ||
151 | /** Message type option. | |
152 | ||
153 | This controls the opcode set for outgoing messages. Valid | |
154 | choices are opcode::binary or opcode::text. The setting is | |
155 | only applied at the start when a caller begins a new message. | |
156 | Changing the opcode after a message is started will only | |
157 | take effect after the current message being sent is complete. | |
158 | ||
159 | The default setting is opcode::text. | |
160 | ||
161 | @note Objects of this type are used with | |
162 | @ref beast::websocket::stream::set_option. | |
163 | ||
164 | @par Example | |
165 | Setting the message type to binary. | |
166 | @code | |
167 | ... | |
168 | websocket::stream<ip::tcp::socket> ws(ios); | |
169 | ws.set_option(message_type{opcode::binary}); | |
170 | @endcode | |
171 | */ | |
172 | #if BEAST_DOXYGEN | |
173 | using message_type = implementation_defined; | |
174 | #else | |
175 | struct message_type | |
176 | { | |
177 | opcode value; | |
178 | ||
179 | explicit | |
180 | message_type(opcode op) | |
181 | { | |
182 | if(op != opcode::binary && op != opcode::text) | |
183 | throw beast::detail::make_exception<std::invalid_argument>( | |
184 | "bad opcode", __FILE__, __LINE__); | |
185 | value = op; | |
186 | } | |
187 | }; | |
188 | #endif | |
189 | ||
190 | namespace detail { | |
191 | ||
192 | using ping_cb = std::function<void(bool, ping_data const&)>; | |
193 | ||
194 | } // detail | |
195 | ||
196 | /** permessage-deflate extension options. | |
197 | ||
198 | These settings control the permessage-deflate extension, | |
199 | which allows messages to be compressed. | |
200 | ||
201 | @note Objects of this type are used with | |
202 | @ref beast::websocket::stream::set_option. | |
203 | */ | |
204 | struct permessage_deflate | |
205 | { | |
206 | /// `true` to offer the extension in the server role | |
207 | bool server_enable = false; | |
208 | ||
209 | /// `true` to offer the extension in the client role | |
210 | bool client_enable = false; | |
211 | ||
212 | /** Maximum server window bits to offer | |
213 | ||
214 | @note Due to a bug in ZLib, this value must be greater than 8. | |
215 | */ | |
216 | int server_max_window_bits = 15; | |
217 | ||
218 | /** Maximum client window bits to offer | |
219 | ||
220 | @note Due to a bug in ZLib, this value must be greater than 8. | |
221 | */ | |
222 | int client_max_window_bits = 15; | |
223 | ||
224 | /// `true` if server_no_context_takeover desired | |
225 | bool server_no_context_takeover = false; | |
226 | ||
227 | /// `true` if client_no_context_takeover desired | |
228 | bool client_no_context_takeover = false; | |
229 | ||
230 | /// Deflate compression level 0..9 | |
231 | int compLevel = 8; | |
232 | ||
233 | /// Deflate memory level, 1..9 | |
234 | int memLevel = 4; | |
235 | }; | |
236 | ||
237 | /** Ping callback option. | |
238 | ||
239 | Sets the callback to be invoked whenever a ping or pong is | |
240 | received during a call to one of the following functions: | |
241 | ||
242 | @li @ref beast::websocket::stream::read | |
243 | @li @ref beast::websocket::stream::read_frame | |
244 | @li @ref beast::websocket::stream::async_read | |
245 | @li @ref beast::websocket::stream::async_read_frame | |
246 | ||
247 | Unlike completion handlers, the callback will be invoked | |
248 | for each received ping and pong during a call to any | |
249 | synchronous or asynchronous read function. The operation is | |
250 | passive, with no associated error code, and triggered by reads. | |
251 | ||
252 | The signature of the callback must be: | |
253 | @code | |
254 | void | |
255 | callback( | |
256 | bool is_pong, // `true` if this is a pong | |
257 | ping_data const& payload // Payload of the pong frame | |
258 | ); | |
259 | @endcode | |
260 | ||
261 | The value of `is_pong` will be `true` if a pong control frame | |
262 | is received, and `false` if a ping control frame is received. | |
263 | ||
264 | If the read operation receiving a ping or pong frame is an | |
265 | asynchronous operation, the callback will be invoked using | |
266 | the same method as that used to invoke the final handler. | |
267 | ||
268 | @note Objects of this type are used with | |
269 | @ref beast::websocket::stream::set_option. | |
270 | To remove the ping callback, construct the option with | |
271 | no parameters: `set_option(ping_callback{})` | |
272 | */ | |
273 | #if BEAST_DOXYGEN | |
274 | using ping_callback = implementation_defined; | |
275 | #else | |
276 | struct ping_callback | |
277 | { | |
278 | detail::ping_cb value; | |
279 | ||
280 | ping_callback() = default; | |
281 | ping_callback(ping_callback&&) = default; | |
282 | ping_callback(ping_callback const&) = default; | |
283 | ||
284 | explicit | |
285 | ping_callback(detail::ping_cb f) | |
286 | : value(std::move(f)) | |
287 | { | |
288 | } | |
289 | }; | |
290 | #endif | |
291 | ||
292 | /** Read buffer size option. | |
293 | ||
294 | Sets the size of the read buffer used by the implementation to | |
295 | receive frames. The read buffer is needed when permessage-deflate | |
296 | is used. | |
297 | ||
298 | Lowering the size of the buffer can decrease the memory requirements | |
299 | for each connection, while increasing the size of the buffer can reduce | |
300 | the number of calls made to the next layer to read data. | |
301 | ||
302 | The default setting is 4096. The minimum value is 8. | |
303 | ||
304 | @note Objects of this type are used with | |
305 | @ref beast::websocket::stream::set_option. | |
306 | ||
307 | @par Example | |
308 | Setting the read buffer size. | |
309 | @code | |
310 | ... | |
311 | websocket::stream<ip::tcp::socket> ws(ios); | |
312 | ws.set_option(read_buffer_size{16 * 1024}); | |
313 | @endcode | |
314 | */ | |
315 | #if BEAST_DOXYGEN | |
316 | using read_buffer_size = implementation_defined; | |
317 | #else | |
318 | struct read_buffer_size | |
319 | { | |
320 | std::size_t value; | |
321 | ||
322 | explicit | |
323 | read_buffer_size(std::size_t n) | |
324 | : value(n) | |
325 | { | |
326 | if(n < 8) | |
327 | throw beast::detail::make_exception<std::invalid_argument>( | |
328 | "read buffer size is too small", __FILE__, __LINE__); | |
329 | } | |
330 | }; | |
331 | #endif | |
332 | ||
333 | /** Maximum incoming message size option. | |
334 | ||
335 | Sets the largest permissible incoming message size. Message | |
336 | frame fields indicating a size that would bring the total | |
337 | message size over this limit will cause a protocol failure. | |
338 | ||
339 | The default setting is 16 megabytes. A value of zero indicates | |
340 | a limit of the maximum value of a `std::uint64_t`. | |
341 | ||
342 | @note Objects of this type are used with | |
343 | @ref beast::websocket::stream::set_option. | |
344 | ||
345 | @par Example | |
346 | Setting the maximum read message size. | |
347 | @code | |
348 | ... | |
349 | websocket::stream<ip::tcp::socket> ws(ios); | |
350 | ws.set_option(read_message_max{65536}); | |
351 | @endcode | |
352 | */ | |
353 | #if BEAST_DOXYGEN | |
354 | using read_message_max = implementation_defined; | |
355 | #else | |
356 | struct read_message_max | |
357 | { | |
358 | std::size_t value; | |
359 | ||
360 | explicit | |
361 | read_message_max(std::size_t n) | |
362 | : value(n) | |
363 | { | |
364 | } | |
365 | }; | |
366 | #endif | |
367 | ||
368 | /** Write buffer size option. | |
369 | ||
370 | Sets the size of the write buffer used by the implementation to | |
371 | send frames. The write buffer is needed when masking payload data | |
372 | in the client role, compressing frames, or auto-fragmenting message | |
373 | data. | |
374 | ||
375 | Lowering the size of the buffer can decrease the memory requirements | |
376 | for each connection, while increasing the size of the buffer can reduce | |
377 | the number of calls made to the next layer to write data. | |
378 | ||
379 | The default setting is 4096. The minimum value is 8. | |
380 | ||
381 | The write buffer size can only be changed when the stream is not | |
382 | open. Undefined behavior results if the option is modified after a | |
383 | successful WebSocket handshake. | |
384 | ||
385 | @note Objects of this type are used with | |
386 | @ref beast::websocket::stream::set_option. | |
387 | ||
388 | @par Example | |
389 | Setting the write buffer size. | |
390 | @code | |
391 | ... | |
392 | websocket::stream<ip::tcp::socket> ws(ios); | |
393 | ws.set_option(write_buffer_size{8192}); | |
394 | @endcode | |
395 | */ | |
396 | #if BEAST_DOXYGEN | |
397 | using write_buffer_size = implementation_defined; | |
398 | #else | |
399 | struct write_buffer_size | |
400 | { | |
401 | std::size_t value; | |
402 | ||
403 | explicit | |
404 | write_buffer_size(std::size_t n) | |
405 | : value(n) | |
406 | { | |
407 | if(n < 8) | |
408 | throw beast::detail::make_exception<std::invalid_argument>( | |
409 | "write buffer size is too small", __FILE__, __LINE__); | |
410 | } | |
411 | }; | |
412 | #endif | |
413 | ||
414 | } // websocket | |
415 | } // beast | |
416 | ||
417 | #endif |