Skip to content

Commit

Permalink
fix permessage;overwrite 'extensions/permessage_deflate/enabled.hpp' …
Browse files Browse the repository at this point in the history
…from 'zaphoyd/websocketpp'
  • Loading branch information
Your Name authored and btsabc committed Feb 12, 2019
1 parent 792cb45 commit 33c7e7c
Showing 1 changed file with 85 additions and 19 deletions.
104 changes: 85 additions & 19 deletions websocketpp/extensions/permessage_deflate/enabled.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/error.hpp>

Expand All @@ -46,7 +47,7 @@
namespace websocketpp {
namespace extensions {

/// Implementation of the draft permessage-deflate WebSocket extension
/// Implementation of RFC 7692, the permessage-deflate WebSocket extension
/**
* ### permessage-deflate interface
*
Expand Down Expand Up @@ -174,18 +175,30 @@ namespace websocketpp {
namespace extensions {
namespace permessage_deflate {

/// Default value for server_max_window_bits as defined by draft 17
/// Default value for server_max_window_bits as defined by RFC 7692
static uint8_t const default_server_max_window_bits = 15;
/// Minimum value for server_max_window_bits as defined by draft 17
/// Minimum value for server_max_window_bits as defined by RFC 7692
/**
* NOTE: A value of 8 is not actually supported by zlib, the deflate
* library that WebSocket++ uses. To preserve backwards compatibility
* with RFC 7692 and previous versions of the library a value of 8
* is accepted by the library but will always be negotiated as 9.
*/
static uint8_t const min_server_max_window_bits = 8;
/// Maximum value for server_max_window_bits as defined by draft 17
/// Maximum value for server_max_window_bits as defined by RFC 7692
static uint8_t const max_server_max_window_bits = 15;

/// Default value for client_max_window_bits as defined by draft 17
/// Default value for client_max_window_bits as defined by RFC 7692
static uint8_t const default_client_max_window_bits = 15;
/// Minimum value for client_max_window_bits as defined by draft 17
/// Minimum value for client_max_window_bits as defined by RFC 7692
/**
* NOTE: A value of 8 is not actually supported by zlib, the deflate
* library that WebSocket++ uses. To preserve backwards compatibility
* with RFC 7692 and previous versions of the library a value of 8
* is accepted by the library but will always be negotiated as 9.
*/
static uint8_t const min_client_max_window_bits = 8;
/// Maximum value for client_max_window_bits as defined by draft 17
/// Maximum value for client_max_window_bits as defined by RFC 7692
static uint8_t const max_client_max_window_bits = 15;

namespace mode {
Expand Down Expand Up @@ -213,7 +226,7 @@ class enabled {
, m_server_max_window_bits_mode(mode::accept)
, m_client_max_window_bits_mode(mode::accept)
, m_initialized(false)
, m_compress_buffer_size(16384)
, m_compress_buffer_size(8192)
{
m_dstate.zalloc = Z_NULL;
m_dstate.zfree = Z_NULL;
Expand Down Expand Up @@ -292,6 +305,7 @@ class enabled {
}

m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
m_decompress_buffer.reset(new unsigned char[m_compress_buffer_size]);
if ((m_server_no_context_takeover && is_server) ||
(m_client_no_context_takeover && !is_server))
{
Expand Down Expand Up @@ -372,7 +386,7 @@ class enabled {
/**
* 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
* is 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB
* window. The default setting is 15.
*
* Mode Options:
Expand All @@ -386,6 +400,14 @@ class enabled {
* adjusted by the server. A server may unilaterally set this value without
* client support.
*
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
* zlib, the deflate compression library that WebSocket++ uses has always
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
* continues to perform the 8->9 conversion for backwards compatibility
* purposes but this should be considered deprecated functionality.
*
* @param bits The size to request for the outgoing window size
* @param mode The mode to use for negotiating this parameter
* @return A status code
Expand All @@ -394,6 +416,12 @@ class enabled {
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
return error::make_error_code(error::invalid_max_window_bits);
}

// See note in doc comment above about what is happening here
if (bits == 8) {
bits = 9;
}

m_server_max_window_bits = bits;
m_server_max_window_bits_mode = mode;

Expand All @@ -403,8 +431,8 @@ class enabled {
/// Limit client LZ77 sliding window size
/**
* 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.
* client must use to compress outgoing messages. The permitted range is 9
* to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window.
* The default setting is 15.
*
* Mode Options:
Expand All @@ -417,6 +445,14 @@ class enabled {
* outgoing window size unilaterally. A server may only limit the client's
* window size if the remote client supports that feature.
*
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
* zlib, the deflate compression library that WebSocket++ uses has always
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
* continues to perform the 8->9 conversion for backwards compatibility
* purposes but this should be considered deprecated functionality.
*
* @param bits The size to request for the outgoing window size
* @param mode The mode to use for negotiating this parameter
* @return A status code
Expand All @@ -425,6 +461,12 @@ class enabled {
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
return error::make_error_code(error::invalid_max_window_bits);
}

// See note in doc comment above about what is happening here
if (bits == 8) {
bits = 9;
}

m_client_max_window_bits = bits;
m_client_max_window_bits_mode = mode;

Expand Down Expand Up @@ -555,7 +597,7 @@ class enabled {

do {
m_istate.avail_out = m_compress_buffer_size;
m_istate.next_out = m_compress_buffer.get();
m_istate.next_out = m_decompress_buffer.get();

ret = inflate(&m_istate, Z_SYNC_FLUSH);

Expand All @@ -564,7 +606,7 @@ class enabled {
}

out.append(
reinterpret_cast<char *>(m_compress_buffer.get()),
reinterpret_cast<char *>(m_decompress_buffer.get()),
m_compress_buffer_size - m_istate.avail_out
);
} while (m_istate.avail_out == 0);
Expand Down Expand Up @@ -642,11 +684,17 @@ class enabled {
* client requested that we use.
*
* options:
* - decline (refuse to use the attribute)
* - accept (use whatever the client says)
* - largest (use largest possible value)
* - decline (ignore value, offer our default instead)
* - accept (use the value requested by the client)
* - largest (use largest value acceptable to both)
* - smallest (use smallest possible value)
*
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
* be requested for negotiation by an older client/server, if the result of
* the negotiation would be to send a value of 8, a value of 9 is offered
* instead. This ensures that WebSocket++ will only ever negotiate connections
* with compression settings explicitly supported by zlib.
*
* @param [in] value The value of the attribute from the offer
* @param [out] ec A reference to the error code to return errors via
*/
Expand Down Expand Up @@ -678,6 +726,11 @@ class enabled {
ec = make_error_code(error::invalid_mode);
m_server_max_window_bits = default_server_max_window_bits;
}

// See note in doc comment
if (m_server_max_window_bits == 8) {
m_server_max_window_bits = 9;
}
}

/// Negotiate client_max_window_bits attribute
Expand All @@ -687,11 +740,17 @@ class enabled {
* negotiation mode.
*
* options:
* - decline (refuse to use the attribute)
* - accept (use whatever the client says)
* - largest (use largest possible value)
* - decline (ignore value, offer our default instead)
* - accept (use the value requested by the client)
* - largest (use largest value acceptable to both)
* - smallest (use smallest possible value)
*
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
* be requested for negotiation by an older client/server, if the result of
* the negotiation would be to send a value of 8, a value of 9 is offered
* instead. This ensures that WebSocket++ will only ever negotiate connections
* with compression settings explicitly supported by zlib.
*
* @param [in] value The value of the attribute from the offer
* @param [out] ec A reference to the error code to return errors via
*/
Expand Down Expand Up @@ -727,6 +786,11 @@ class enabled {
ec = make_error_code(error::invalid_mode);
m_client_max_window_bits = default_client_max_window_bits;
}

// See note in doc comment
if (m_client_max_window_bits == 8) {
m_client_max_window_bits = 9;
}
}

bool m_enabled;
Expand All @@ -741,6 +805,7 @@ class enabled {
int m_flush;
size_t m_compress_buffer_size;
lib::unique_ptr_uchar_array m_compress_buffer;
lib::unique_ptr_uchar_array m_decompress_buffer;
z_stream m_dstate;
z_stream m_istate;
};
Expand All @@ -750,3 +815,4 @@ class enabled {
} // namespace websocketpp

#endif // WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP

0 comments on commit 33c7e7c

Please sign in to comment.