1 // Copyright 2015 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_ 6 #define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_ 7 8 #include <stdint.h> 9 10 #include <string> 11 12 #include "base/check.h" 13 #include "net/base/net_export.h" 14 #include "net/websockets/websocket_deflater.h" 15 #include "net/websockets/websocket_extension.h" 16 17 namespace net { 18 19 // A WebSocketDeflateParameters represents permessage-deflate extension 20 // parameters. This class is used either for request and response. 21 class NET_EXPORT_PRIVATE WebSocketDeflateParameters { 22 public: 23 using ContextTakeOverMode = WebSocketDeflater::ContextTakeOverMode; 24 25 // Returns a WebSocketExtension instance containing the parameters stored in 26 // this object. 27 WebSocketExtension AsExtension() const; 28 29 // Returns true when succeeded. 30 // Returns false and stores the failure message to |failure_message| 31 // otherwise. 32 // Note that even if this function succeeds it is not guaranteed that the 33 // object is valid. To check it, call IsValidAsRequest or IsValidAsResponse. 34 bool Initialize(const WebSocketExtension& input, 35 std::string* failure_message); 36 37 // Returns true when |*this| and |response| are compatible. 38 // |*this| must be valid as a request and |response| must be valid as a 39 // response. 40 bool IsCompatibleWith(const WebSocketDeflateParameters& response) const; 41 42 bool IsValidAsRequest(std::string* failure_message) const; 43 bool IsValidAsResponse(std::string* failure_message) const; IsValidAsRequest()44 bool IsValidAsRequest() const { 45 std::string message; 46 return IsValidAsRequest(&message); 47 } IsValidAsResponse()48 bool IsValidAsResponse() const { 49 std::string message; 50 return IsValidAsResponse(&message); 51 } 52 server_context_take_over_mode()53 ContextTakeOverMode server_context_take_over_mode() const { 54 return server_context_take_over_mode_; 55 } client_context_take_over_mode()56 ContextTakeOverMode client_context_take_over_mode() const { 57 return client_context_take_over_mode_; 58 } is_server_max_window_bits_specified()59 bool is_server_max_window_bits_specified() const { 60 return server_max_window_bits_.is_specified; 61 } server_max_window_bits()62 int server_max_window_bits() const { 63 DCHECK(is_server_max_window_bits_specified()); 64 return server_max_window_bits_.bits; 65 } is_client_max_window_bits_specified()66 bool is_client_max_window_bits_specified() const { 67 return client_max_window_bits_.is_specified; 68 } has_client_max_window_bits_value()69 bool has_client_max_window_bits_value() const { 70 DCHECK(is_client_max_window_bits_specified()); 71 return client_max_window_bits_.has_value; 72 } client_max_window_bits()73 int client_max_window_bits() const { 74 DCHECK(has_client_max_window_bits_value()); 75 return client_max_window_bits_.bits; 76 } SetServerNoContextTakeOver()77 void SetServerNoContextTakeOver() { 78 server_context_take_over_mode_ = 79 WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT; 80 } SetClientNoContextTakeOver()81 void SetClientNoContextTakeOver() { 82 client_context_take_over_mode_ = 83 WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT; 84 } 85 // |bits| must be valid as a max_window_bits value. SetServerMaxWindowBits(int bits)86 void SetServerMaxWindowBits(int bits) { 87 DCHECK(IsValidWindowBits(bits)); 88 server_max_window_bits_ = WindowBits(bits, true, true); 89 } SetClientMaxWindowBits()90 void SetClientMaxWindowBits() { 91 client_max_window_bits_ = WindowBits(0, true, false); 92 } 93 // |bits| must be valid as a max_window_bits value. SetClientMaxWindowBits(int bits)94 void SetClientMaxWindowBits(int bits) { 95 DCHECK(IsValidWindowBits(bits)); 96 client_max_window_bits_ = WindowBits(bits, true, true); 97 } 98 PermissiveServerMaxWindowBits()99 int PermissiveServerMaxWindowBits() const { 100 return server_max_window_bits_.PermissiveBits(); 101 } PermissiveClientMaxWindowBits()102 int PermissiveClientMaxWindowBits() const { 103 return client_max_window_bits_.PermissiveBits(); 104 } 105 106 // Return true if |bits| is valid as a max_window_bits value. IsValidWindowBits(int bits)107 static bool IsValidWindowBits(int bits) { return 8 <= bits && bits <= 15; } 108 109 private: 110 struct WindowBits { WindowBitsWindowBits111 WindowBits() : WindowBits(0, false, false) {} WindowBitsWindowBits112 WindowBits(int16_t bits, bool is_specified, bool has_value) 113 : bits(bits), is_specified(is_specified), has_value(has_value) {} 114 PermissiveBitsWindowBits115 int PermissiveBits() const { 116 return (is_specified && has_value) ? bits : 15; 117 } 118 119 int16_t bits; 120 // True when "window bits" parameter appears in the parameters. 121 bool is_specified; 122 // True when "window bits" parameter has the value. 123 bool has_value; 124 }; 125 126 // |server_context_take_over_mode| is set to DO_NOT_TAKE_OVER_CONTEXT if and 127 // only if |server_no_context_takeover| is set in the parameters. 128 ContextTakeOverMode server_context_take_over_mode_ = 129 WebSocketDeflater::TAKE_OVER_CONTEXT; 130 // |client_context_take_over_mode| is set to DO_NOT_TAKE_OVER_CONTEXT if and 131 // only if |client_no_context_takeover| is set in the parameters. 132 ContextTakeOverMode client_context_take_over_mode_ = 133 WebSocketDeflater::TAKE_OVER_CONTEXT; 134 WindowBits server_max_window_bits_; 135 WindowBits client_max_window_bits_; 136 }; 137 138 } // namespace net 139 140 #endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_ 141