// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_ #define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_ #include #include #include "base/logging.h" #include "net/base/net_export.h" #include "net/websockets/websocket_deflater.h" #include "net/websockets/websocket_extension.h" namespace net { // A WebSocketDeflateParameters represents permessage-deflate extension // parameters. This class is used either for request and response. class NET_EXPORT_PRIVATE WebSocketDeflateParameters { public: using ContextTakeOverMode = WebSocketDeflater::ContextTakeOverMode; // Returns a WebSocketExtension instance containing the parameters stored in // this object. WebSocketExtension AsExtension() const; // Returns true when succeeded. // Returns false and stores the failure message to |failure_message| // otherwise. // Note that even if this function succeeds it is not guaranteed that the // object is valid. To check it, call IsValidAsRequest or IsValidAsResponse. bool Initialize(const WebSocketExtension& input, std::string* failure_message); // Returns true when |*this| and |response| are compatible. // |*this| must be valid as a request and |response| must be valid as a // response. bool IsCompatibleWith(const WebSocketDeflateParameters& response) const; bool IsValidAsRequest(std::string* failure_message) const; bool IsValidAsResponse(std::string* failure_message) const; bool IsValidAsRequest() const { std::string message; return IsValidAsRequest(&message); } bool IsValidAsResponse() const { std::string message; return IsValidAsResponse(&message); } ContextTakeOverMode server_context_take_over_mode() const { return server_context_take_over_mode_; } ContextTakeOverMode client_context_take_over_mode() const { return client_context_take_over_mode_; } bool is_server_max_window_bits_specified() const { return server_max_window_bits_.is_specified; } int server_max_window_bits() const { DCHECK(is_server_max_window_bits_specified()); return server_max_window_bits_.bits; } bool is_client_max_window_bits_specified() const { return client_max_window_bits_.is_specified; } bool has_client_max_window_bits_value() const { DCHECK(is_client_max_window_bits_specified()); return client_max_window_bits_.has_value; } int client_max_window_bits() const { DCHECK(has_client_max_window_bits_value()); return client_max_window_bits_.bits; } void SetServerNoContextTakeOver() { server_context_take_over_mode_ = WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT; } void SetClientNoContextTakeOver() { client_context_take_over_mode_ = WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT; } // |bits| must be valid as a max_window_bits value. void SetServerMaxWindowBits(int bits) { DCHECK(IsValidWindowBits(bits)); server_max_window_bits_ = WindowBits(bits, true, true); } void SetClientMaxWindowBits() { client_max_window_bits_ = WindowBits(0, true, false); } // |bits| must be valid as a max_window_bits value. void SetClientMaxWindowBits(int bits) { DCHECK(IsValidWindowBits(bits)); client_max_window_bits_ = WindowBits(bits, true, true); } int PermissiveServerMaxWindowBits() const { return server_max_window_bits_.PermissiveBits(); } int PermissiveClientMaxWindowBits() const { return client_max_window_bits_.PermissiveBits(); } // Return true if |bits| is valid as a max_window_bits value. static bool IsValidWindowBits(int bits) { return 8 <= bits && bits <= 15; } private: struct WindowBits { WindowBits() : WindowBits(0, false, false) {} WindowBits(int16_t bits, bool is_specified, bool has_value) : bits(bits), is_specified(is_specified), has_value(has_value) {} int PermissiveBits() const { return (is_specified && has_value) ? bits : 15; } int16_t bits; // True when "window bits" parameter appears in the parameters. bool is_specified; // True when "window bits" parameter has the value. bool has_value; }; // |server_context_take_over_mode| is set to DO_NOT_TAKE_OVER_CONTEXT if and // only if |server_no_context_takeover| is set in the parameters. ContextTakeOverMode server_context_take_over_mode_ = WebSocketDeflater::TAKE_OVER_CONTEXT; // |client_context_take_over_mode| is set to DO_NOT_TAKE_OVER_CONTEXT if and // only if |client_no_context_takeover| is set in the parameters. ContextTakeOverMode client_context_take_over_mode_ = WebSocketDeflater::TAKE_OVER_CONTEXT; WindowBits server_max_window_bits_; WindowBits client_max_window_bits_; }; } // namespace net #endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_