Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
websocketpp::extensions::permessage_deflate::enabled< config > Class Template Reference

#include <enabled.hpp>

Public Member Functions

 enabled ()
 
 ~enabled ()
 
lib::error_code init (bool is_server)
 Initialize zlib state.
 
bool is_implemented () const
 Test if this object implements the permessage-deflate specification.
 
bool is_enabled () const
 Test if the extension was negotiated for this connection.
 
void enable_server_no_context_takeover ()
 Reset server's outgoing LZ77 sliding window for each new message.
 
void enable_client_no_context_takeover ()
 Reset client's outgoing LZ77 sliding window for each new message.
 
lib::error_code set_server_max_window_bits (uint8_t bits, mode::value mode)
 Limit server LZ77 sliding window size.
 
lib::error_code set_client_max_window_bits (uint8_t bits, mode::value mode)
 Limit client LZ77 sliding window size.
 
std::string generate_offer () const
 Generate extension offer.
 
lib::error_code validate_offer (http::attribute_list const &)
 Validate extension response.
 
err_str_pair negotiate (http::attribute_list const &offer)
 Negotiate extension.
 
lib::error_code compress (std::string const &in, std::string &out)
 Compress bytes.
 
lib::error_code decompress (uint8_t const *buf, size_t len, std::string &out)
 Decompress bytes.
 

Detailed Description

template<typename config>
class websocketpp::extensions::permessage_deflate::enabled< config >

Definition at line 205 of file enabled.hpp.

Constructor & Destructor Documentation

◆ enabled()

template<typename config >
websocketpp::extensions::permessage_deflate::enabled< config >::enabled ( )
inline

Definition at line 207 of file enabled.hpp.

208 : m_enabled(false)
209 , m_server_no_context_takeover(false)
210 , m_client_no_context_takeover(false)
211 , m_server_max_window_bits(15)
212 , m_client_max_window_bits(15)
213 , m_server_max_window_bits_mode(mode::accept)
214 , m_client_max_window_bits_mode(mode::accept)
215 , m_initialized(false)
216 , m_compress_buffer_size(16384)
217 {
218 m_dstate.zalloc = Z_NULL;
219 m_dstate.zfree = Z_NULL;
220 m_dstate.opaque = Z_NULL;
221
222 m_istate.zalloc = Z_NULL;
223 m_istate.zfree = Z_NULL;
224 m_istate.opaque = Z_NULL;
225 m_istate.avail_in = 0;
226 m_istate.next_in = Z_NULL;
227 }
@ accept
Accept any value the remote endpoint offers.
Definition enabled.hpp:194

◆ ~enabled()

Definition at line 229 of file enabled.hpp.

229 {
230 if (!m_initialized) {
231 return;
232 }
233
234 int ret = deflateEnd(&m_dstate);
235
236 if (ret != Z_OK) {
237 //std::cout << "error cleaning up zlib compression state"
238 // << std::endl;
239 }
240
241 ret = inflateEnd(&m_istate);
242
243 if (ret != Z_OK) {
244 //std::cout << "error cleaning up zlib decompression state"
245 // << std::endl;
246 }
247 }
CK_RV ret

Member Function Documentation

◆ compress()

template<typename config >
lib::error_code websocketpp::extensions::permessage_deflate::enabled< config >::compress ( std::string const & in,
std::string & out )
inline
Todo
: avail_in/out is 32 bit, need to fix for cases of >32 bit frames on 64 bit machines.
Parameters
[in]inString to compress
[out]outString to append compressed bytes to
Returns
Error or status code

Definition at line 506 of file enabled.hpp.

506 {
507 if (!m_initialized) {
508 return make_error_code(error::uninitialized);
509 }
510
511 size_t output;
512
513 if (in.empty()) {
514 uint8_t buf[6] = {0x02, 0x00, 0x00, 0x00, 0xff, 0xff};
515 out.append((char *)(buf),6);
516 return lib::error_code();
517 }
518
519 m_dstate.avail_in = in.size();
520 m_dstate.next_in = (unsigned char *)(const_cast<char *>(in.data()));
521
522 do {
523 // Output to local buffer
524 m_dstate.avail_out = m_compress_buffer_size;
525 m_dstate.next_out = m_compress_buffer.get();
526
527 deflate(&m_dstate, m_flush);
528
529 output = m_compress_buffer_size - m_dstate.avail_out;
530
531 out.append((char *)(m_compress_buffer.get()),output);
532 } while (m_dstate.avail_out == 0);
533
534 return lib::error_code();
535 }
unsigned char uint8_t
Definition stdint.h:124
uint8_t buf[2048]
Here is the caller graph for this function:

◆ decompress()

template<typename config >
lib::error_code websocketpp::extensions::permessage_deflate::enabled< config >::decompress ( uint8_t const * buf,
size_t len,
std::string & out )
inline
Parameters
bufByte buffer to decompress
lenLength of buf
outString to append decompressed bytes to
Returns
Error or status code

Definition at line 544 of file enabled.hpp.

546 {
547 if (!m_initialized) {
548 return make_error_code(error::uninitialized);
549 }
550
551 int ret;
552
553 m_istate.avail_in = len;
554 m_istate.next_in = const_cast<unsigned char *>(buf);
555
556 do {
557 m_istate.avail_out = m_compress_buffer_size;
558 m_istate.next_out = m_compress_buffer.get();
559
560 ret = inflate(&m_istate, Z_SYNC_FLUSH);
561
562 if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) {
563 return make_error_code(error::zlib_error);
564 }
565
566 out.append(
567 reinterpret_cast<char *>(m_compress_buffer.get()),
568 m_compress_buffer_size - m_istate.avail_out
569 );
570 } while (m_istate.avail_out == 0);
571
572 return lib::error_code();
573 }
size_t len
Here is the caller graph for this function:

◆ enable_client_no_context_takeover()

template<typename config >
void websocketpp::extensions::permessage_deflate::enabled< config >::enable_client_no_context_takeover ( )
inline

Enabling this setting will cause the client's compressor to reset the compression state (the LZ77 sliding window) for every message. This means that the compressor will not look back to patterns in previous messages to improve compression. This will reduce the compression efficiency for large messages somewhat and small messages drastically.

This option may reduce client compressor memory usage and server decompressor memory usage.

Todo
Document to what extent memory usage will be reduced

This option is supported by all compliant clients and servers. Enabling it via either endpoint should be sufficient to ensure it is used.

Definition at line 367 of file enabled.hpp.

367 {
368 m_client_no_context_takeover = true;
369 }
Here is the caller graph for this function:

◆ enable_server_no_context_takeover()

template<typename config >
void websocketpp::extensions::permessage_deflate::enabled< config >::enable_server_no_context_takeover ( )
inline

Enabling this setting will cause the server's compressor to reset the compression state (the LZ77 sliding window) for every message. This means that the compressor will not look back to patterns in previous messages to improve compression. This will reduce the compression efficiency for large messages somewhat and small messages drastically.

This option may reduce server compressor memory usage and client decompressor memory usage.

Todo
Document to what extent memory usage will be reduced

For clients, this option is dependent on server support. Enabling it via this method does not guarantee that it will be successfully negotiated, only that it will be requested.

For servers, no client support is required. Enabling this option on a server will result in its use. The server will signal to clients that the option will be in use so they can optimize resource usage if they are able.

Definition at line 348 of file enabled.hpp.

348 {
349 m_server_no_context_takeover = true;
350 }
Here is the caller graph for this function:

◆ generate_offer()

template<typename config >
std::string websocketpp::extensions::permessage_deflate::enabled< config >::generate_offer ( ) const
inline

Creates an offer string to include in the Sec-WebSocket-Extensions header of outgoing client requests.

Returns
A WebSocket extension offer string for this extension

Definition at line 441 of file enabled.hpp.

441 {
442 // TODO: this should be dynamically generated based on user settings
443 return "permessage-deflate; client_no_context_takeover; client_max_window_bits";
444 }

◆ init()

template<typename config >
lib::error_code websocketpp::extensions::permessage_deflate::enabled< config >::init ( bool is_server)
inline

Note: this should be called after the negotiation methods. It will use information from the negotiation to determine how to initialize the zlib data structures.

Todo
memory level, strategy, etc are hardcoded
Parameters
is_serverTrue to initialize as a server, false for a client.
Returns
A code representing the error that occurred, if any

Definition at line 260 of file enabled.hpp.

260 {
261 uint8_t deflate_bits;
262 uint8_t inflate_bits;
263
264 if (is_server) {
265 deflate_bits = m_server_max_window_bits;
266 inflate_bits = m_client_max_window_bits;
267 } else {
268 deflate_bits = m_client_max_window_bits;
269 inflate_bits = m_server_max_window_bits;
270 }
271
272 int ret = deflateInit2(
273 &m_dstate,
274 Z_DEFAULT_COMPRESSION,
275 Z_DEFLATED,
276 -1*deflate_bits,
277 4, // memory level 1-9
278 Z_DEFAULT_STRATEGY
279 );
280
281 if (ret != Z_OK) {
282 return make_error_code(error::zlib_error);
283 }
284
285 ret = inflateInit2(
286 &m_istate,
287 -1*inflate_bits
288 );
289
290 if (ret != Z_OK) {
291 return make_error_code(error::zlib_error);
292 }
293
294 m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
295 if ((m_server_no_context_takeover && is_server) ||
296 (m_client_no_context_takeover && !is_server))
297 {
298 m_flush = Z_FULL_FLUSH;
299 } else {
300 m_flush = Z_SYNC_FLUSH;
301 }
302 m_initialized = true;
303 return lib::error_code();
304 }
Here is the caller graph for this function:

◆ is_enabled()

template<typename config >
bool websocketpp::extensions::permessage_deflate::enabled< config >::is_enabled ( ) const
inline

Retrieves whether or not this extension is in use based on the initial handshake extension negotiations.

Returns
Whether or not the extension is in use

Definition at line 323 of file enabled.hpp.

323 {
324 return m_enabled;
325 }
Here is the caller graph for this function:

◆ is_implemented()

template<typename config >
bool websocketpp::extensions::permessage_deflate::enabled< config >::is_implemented ( ) const
inline

Because this object does implieent it, it will always return true.

Returns
Whether or not this object implements permessage-deflate

Definition at line 312 of file enabled.hpp.

312 {
313 return true;
314 }
Here is the caller graph for this function:

◆ negotiate()

template<typename config >
err_str_pair websocketpp::extensions::permessage_deflate::enabled< config >::negotiate ( http::attribute_list const & offer)
inline

Confirm that the client's extension negotiation offer has settings compatible with local policy. If so, generate a reply and apply those settings to the extension state.

Parameters
offerAttribute from client's offer
Returns
Status code and value to return to remote endpoint

Definition at line 467 of file enabled.hpp.

467 {
469
470 http::attribute_list::const_iterator it;
471 for (it = offer.begin(); it != offer.end(); ++it) {
472 if (it->first == "server_no_context_takeover") {
473 negotiate_server_no_context_takeover(it->second,ret.first);
474 } else if (it->first == "client_no_context_takeover") {
475 negotiate_client_no_context_takeover(it->second,ret.first);
476 } else if (it->first == "server_max_window_bits") {
477 negotiate_server_max_window_bits(it->second,ret.first);
478 } else if (it->first == "client_max_window_bits") {
479 negotiate_client_max_window_bits(it->second,ret.first);
480 } else {
481 ret.first = make_error_code(error::invalid_attributes);
482 }
483
484 if (ret.first) {
485 break;
486 }
487 }
488
489 if (ret.first == lib::error_code()) {
490 m_enabled = true;
491 ret.second = generate_response();
492 }
493
494 return ret;
495 }
@ invalid_attributes
Invalid extension attributes.
Definition enabled.hpp:96
std::pair< lib::error_code, std::string > err_str_pair
Combination error code / string type for returning two values.
Definition error.hpp:41
Here is the caller graph for this function:

◆ set_client_max_window_bits()

template<typename config >
lib::error_code websocketpp::extensions::permessage_deflate::enabled< config >::set_client_max_window_bits ( uint8_t bits,
mode::value mode )
inline

The bits setting is the base 2 logarithm of the window size that the client must use to compress outgoing messages. The permitted range is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window. The default setting is 15.

Mode Options:

  • accept: Accept whatever the remote endpoint offers.
  • decline: Decline any offers to deviate from the defaults
  • largest: Accept largest window size acceptable to both endpoints
  • smallest: Accept smallest window size acceptiable to both endpoints

This setting is dependent on client support. A client may limit its own outgoing window size unilaterally. A server may only limit the client's window size if the remote client supports that feature.

Parameters
bitsThe size to request for the outgoing window size
modeThe mode to use for negotiating this parameter
Returns
A status code

Definition at line 424 of file enabled.hpp.

424 {
425 if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
427 }
428 m_client_max_window_bits = bits;
429 m_client_max_window_bits_mode = mode;
430
431 return lib::error_code();
432 }
@ invalid_max_window_bits
Invalid value for max_window_bits.
Definition enabled.hpp:108
lib::error_code make_error_code(error::value e)
Create an error code in the permessage-deflate category.
Definition enabled.hpp:157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_server_max_window_bits()

template<typename config >
lib::error_code websocketpp::extensions::permessage_deflate::enabled< config >::set_server_max_window_bits ( uint8_t bits,
mode::value mode )
inline

The bits setting is the base 2 logarithm of the maximum window size that the server must use to compress outgoing messages. The permitted range is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window. The default setting is 15.

Mode Options:

  • accept: Accept whatever the remote endpoint offers.
  • decline: Decline any offers to deviate from the defaults
  • largest: Accept largest window size acceptable to both endpoints
  • smallest: Accept smallest window size acceptiable to both endpoints

This setting is dependent on server support. A client requesting this setting may be rejected by the server or have the exact value used adjusted by the server. A server may unilaterally set this value without client support.

Parameters
bitsThe size to request for the outgoing window size
modeThe mode to use for negotiating this parameter
Returns
A status code

Definition at line 393 of file enabled.hpp.

393 {
394 if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
396 }
397 m_server_max_window_bits = bits;
398 m_server_max_window_bits_mode = mode;
399
400 return lib::error_code();
401 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_offer()

template<typename config >
lib::error_code websocketpp::extensions::permessage_deflate::enabled< config >::validate_offer ( http::attribute_list const & )
inline

Confirm that the server has negotiated settings compatible with our original offer and apply those settings to the extension state.

Parameters
responseThe server response attribute list to validate
Returns
Validation error or 0 on success

Definition at line 454 of file enabled.hpp.

454 {
455 return lib::error_code();
456 }

The documentation for this class was generated from the following file: