xref: /aosp_15_r20/external/cronet/net/websockets/websocket_deflate_parameters.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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