xref: /aosp_15_r20/external/cronet/net/websockets/websocket_deflate_parameters_test.cc (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 #include "net/websockets/websocket_deflate_parameters.h"
6 
7 #include <iterator>
8 #include <ostream>
9 #include <string>
10 #include <vector>
11 
12 #include "net/websockets/websocket_extension_parser.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace net {
16 
17 namespace {
18 
CheckExtension(const WebSocketDeflateParameters & params,const std::string & name,const std::string & value)19 void CheckExtension(const WebSocketDeflateParameters& params,
20                     const std::string& name,
21                     const std::string& value) {
22   WebSocketExtension e = params.AsExtension();
23   EXPECT_EQ("permessage-deflate", e.name());
24   if (e.parameters().size() != 1)
25     FAIL() << "parameters must have one element.";
26   EXPECT_EQ(name, e.parameters()[0].name());
27   EXPECT_EQ(value, e.parameters()[0].value());
28 }
29 
TEST(WebSocketDeflateParametersTest,Empty)30 TEST(WebSocketDeflateParametersTest, Empty) {
31   WebSocketDeflateParameters r;
32 
33   EXPECT_EQ(WebSocketDeflater::TAKE_OVER_CONTEXT,
34             r.server_context_take_over_mode());
35   EXPECT_EQ(WebSocketDeflater::TAKE_OVER_CONTEXT,
36             r.client_context_take_over_mode());
37   EXPECT_FALSE(r.is_server_max_window_bits_specified());
38   EXPECT_FALSE(r.is_client_max_window_bits_specified());
39   EXPECT_TRUE(r.IsValidAsRequest());
40   EXPECT_TRUE(r.IsValidAsResponse());
41   WebSocketExtension e = r.AsExtension();
42   EXPECT_EQ("permessage-deflate", e.name());
43   EXPECT_TRUE(e.parameters().empty());
44 }
45 
TEST(WebSocketDeflateParametersTest,ServerContextTakeover)46 TEST(WebSocketDeflateParametersTest, ServerContextTakeover) {
47   WebSocketDeflateParameters r;
48 
49   r.SetServerNoContextTakeOver();
50   CheckExtension(r, "server_no_context_takeover", "");
51   EXPECT_TRUE(r.IsValidAsRequest());
52   EXPECT_TRUE(r.IsValidAsResponse());
53 }
54 
TEST(WebSocketDeflateParametersTest,ClientContextTakeover)55 TEST(WebSocketDeflateParametersTest, ClientContextTakeover) {
56   WebSocketDeflateParameters r;
57 
58   r.SetClientNoContextTakeOver();
59   CheckExtension(r, "client_no_context_takeover", "");
60   EXPECT_TRUE(r.IsValidAsRequest());
61   EXPECT_TRUE(r.IsValidAsResponse());
62 }
63 
TEST(WebSocketDeflateParametersTest,ServerMaxWindowBits)64 TEST(WebSocketDeflateParametersTest, ServerMaxWindowBits) {
65   WebSocketDeflateParameters r;
66 
67   r.SetServerMaxWindowBits(13);
68   CheckExtension(r, "server_max_window_bits", "13");
69   EXPECT_TRUE(r.IsValidAsRequest());
70   EXPECT_TRUE(r.IsValidAsResponse());
71 }
72 
TEST(WebSocketDeflateParametersTest,ClientMaxWindowBitsWithoutValue)73 TEST(WebSocketDeflateParametersTest, ClientMaxWindowBitsWithoutValue) {
74   WebSocketDeflateParameters r;
75   std::string failure_message;
76 
77   r.SetClientMaxWindowBits();
78   CheckExtension(r, "client_max_window_bits", "");
79   EXPECT_TRUE(r.IsValidAsRequest());
80   EXPECT_FALSE(r.IsValidAsResponse(&failure_message));
81   EXPECT_EQ("client_max_window_bits must have value", failure_message);
82 }
83 
TEST(WebSocketDeflateParametersTest,ClientMaxWindowBitsWithValue)84 TEST(WebSocketDeflateParametersTest, ClientMaxWindowBitsWithValue) {
85   WebSocketDeflateParameters r;
86 
87   r.SetClientMaxWindowBits(12);
88   CheckExtension(r, "client_max_window_bits", "12");
89   EXPECT_TRUE(r.IsValidAsRequest());
90   EXPECT_TRUE(r.IsValidAsResponse());
91 }
92 
93 struct InitializeTestParameter {
94   const std::string query;
95   struct Expectation {
96     bool result;
97     std::string failure_message;
98   } const expected;
99 };
100 
PrintTo(const InitializeTestParameter & p,std::ostream * o)101 void PrintTo(const InitializeTestParameter& p, std::ostream* o) {
102   *o << p.query;
103 }
104 
105 class WebSocketDeflateParametersInitializeTest
106     : public ::testing::TestWithParam<InitializeTestParameter> {};
107 
TEST_P(WebSocketDeflateParametersInitializeTest,Initialize)108 TEST_P(WebSocketDeflateParametersInitializeTest, Initialize) {
109   const std::string query = GetParam().query;
110   const bool expected = GetParam().expected.result;
111   const std::string expected_failure_message =
112       GetParam().expected.failure_message;
113 
114   WebSocketExtensionParser parser;
115   ASSERT_TRUE(parser.Parse("permessage-deflate" + query));
116   ASSERT_EQ(1u, parser.extensions().size());
117   WebSocketExtension extension = parser.extensions()[0];
118 
119   WebSocketDeflateParameters parameters;
120   std::string failure_message;
121   bool actual = parameters.Initialize(extension, &failure_message);
122 
123   if (expected) {
124     EXPECT_TRUE(actual);
125     EXPECT_TRUE(extension.Equivalent(parameters.AsExtension()));
126   } else {
127     EXPECT_FALSE(actual);
128   }
129   EXPECT_EQ(expected_failure_message, failure_message);
130 }
131 
132 struct CompatibilityTestParameter {
133   const char* request_query;
134   const char* response_query;
135   const bool expected;
136 };
137 
PrintTo(const CompatibilityTestParameter & p,std::ostream * o)138 void PrintTo(const CompatibilityTestParameter& p, std::ostream* o) {
139   *o << "req = \"" << p.request_query << "\", res = \"" << p.response_query
140      << "\"";
141 }
142 
143 class WebSocketDeflateParametersCompatibilityTest
144     : public ::testing::TestWithParam<CompatibilityTestParameter> {};
145 
TEST_P(WebSocketDeflateParametersCompatibilityTest,CheckCompatiblity)146 TEST_P(WebSocketDeflateParametersCompatibilityTest, CheckCompatiblity) {
147   const std::string request_query = GetParam().request_query;
148   const std::string response_query = GetParam().response_query;
149   const bool expected = GetParam().expected;
150 
151   std::string message;
152   WebSocketDeflateParameters request, response;
153 
154   WebSocketExtensionParser request_parser;
155   ASSERT_TRUE(request_parser.Parse("permessage-deflate" + request_query));
156   ASSERT_EQ(1u, request_parser.extensions().size());
157   ASSERT_TRUE(request.Initialize(request_parser.extensions()[0], &message));
158   ASSERT_TRUE(request.IsValidAsRequest(&message));
159 
160   WebSocketExtensionParser response_parser;
161   ASSERT_TRUE(response_parser.Parse("permessage-deflate" + response_query));
162   ASSERT_EQ(1u, response_parser.extensions().size());
163   ASSERT_TRUE(response.Initialize(response_parser.extensions()[0], &message));
164   ASSERT_TRUE(response.IsValidAsResponse(&message));
165 
166   EXPECT_EQ(expected, request.IsCompatibleWith(response));
167 }
168 
Duplicate(const std::string & name)169 InitializeTestParameter::Expectation Duplicate(const std::string& name) {
170   return {false,
171           "Received duplicate permessage-deflate extension parameter " + name};
172 }
173 
Invalid(const std::string & name)174 InitializeTestParameter::Expectation Invalid(const std::string& name) {
175   return {false, "Received invalid " + name + " parameter"};
176 }
177 
178 // We need this function in order to avoid global non-pod variables.
InitializeTestParameters()179 std::vector<InitializeTestParameter> InitializeTestParameters() {
180   const InitializeTestParameter::Expectation kInitialized = {true, ""};
181   const InitializeTestParameter::Expectation kUnknownParameter = {
182       false, "Received an unexpected permessage-deflate extension parameter"};
183 
184   const InitializeTestParameter parameters[] = {
185       {"", kInitialized},
186       {"; server_no_context_takeover", kInitialized},
187       {"; server_no_context_takeover=0", Invalid("server_no_context_takeover")},
188       {"; server_no_context_takeover; server_no_context_takeover",
189        Duplicate("server_no_context_takeover")},
190       {"; client_no_context_takeover", kInitialized},
191       {"; client_no_context_takeover=0", Invalid("client_no_context_takeover")},
192       {"; client_no_context_takeover; client_no_context_takeover",
193        Duplicate("client_no_context_takeover")},
194       {"; server_max_window_bits=8", kInitialized},
195       {"; server_max_window_bits=15", kInitialized},
196       {"; server_max_window_bits=15; server_max_window_bits=15",
197        Duplicate("server_max_window_bits")},
198       {"; server_max_window_bits=a", Invalid("server_max_window_bits")},
199       {"; server_max_window_bits=09", Invalid("server_max_window_bits")},
200       {"; server_max_window_bits=+9", Invalid("server_max_window_bits")},
201       {"; server_max_window_bits=9a", Invalid("server_max_window_bits")},
202       {"; server_max_window_bits", Invalid("server_max_window_bits")},
203       {"; server_max_window_bits=7", Invalid("server_max_window_bits")},
204       {"; server_max_window_bits=16", Invalid("server_max_window_bits")},
205       {"; client_max_window_bits=8", kInitialized},
206       {"; client_max_window_bits=15", kInitialized},
207       {"; client_max_window_bits=15; client_max_window_bits=15",
208        Duplicate("client_max_window_bits")},
209       {"; client_max_window_bits=a", Invalid("client_max_window_bits")},
210       {"; client_max_window_bits=09", Invalid("client_max_window_bits")},
211       {"; client_max_window_bits=+9", Invalid("client_max_window_bits")},
212       {"; client_max_window_bits=9a", Invalid("client_max_window_bits")},
213       {"; client_max_window_bits", kInitialized},
214       {"; client_max_window_bits=7", Invalid("client_max_window_bits")},
215       {"; client_max_window_bits=16", Invalid("client_max_window_bits")},
216       {"; server_no_context_takeover; client_no_context_takeover"
217        "; server_max_window_bits=12; client_max_window_bits=13",
218        kInitialized},
219       {"; hogefuga", kUnknownParameter},
220   };
221   return std::vector<InitializeTestParameter>(
222       parameters, parameters + std::size(parameters));
223 }
224 
225 constexpr CompatibilityTestParameter kCompatibilityTestParameters[] = {
226     {"", "", true},
227     // server_no_context_takeover
228     {"", "; server_no_context_takeover", true},
229     {"; server_no_context_takeover", "", false},
230     {"; server_no_context_takeover", "; server_no_context_takeover", true},
231     // client_no_context_takeover
232     {"", "; client_no_context_takeover", true},
233     {"; client_no_context_takeover", "", true},
234     {"; client_no_context_takeover", "; client_no_context_takeover", true},
235     // server_max_window_bits
236     {"", "; server_max_window_bits=14", true},
237     {"; server_max_window_bits=12", "", false},
238     {"; server_max_window_bits=12", "; server_max_window_bits=12", true},
239     {"; server_max_window_bits=12", "; server_max_window_bits=11", true},
240     {"; server_max_window_bits=12", "; server_max_window_bits=13", false},
241     // client_max_window_bits
242     {"", "; client_max_window_bits=14", false},
243     {"; client_max_window_bits", "", true},
244     {"; client_max_window_bits", "; client_max_window_bits=15", true},
245     {"; client_max_window_bits=12", "", true},
246     {"; client_max_window_bits=12", "; client_max_window_bits=12", true},
247     {"; client_max_window_bits=12", "; client_max_window_bits=11", true},
248     {"; client_max_window_bits=12", "; client_max_window_bits=13", true},
249 };
250 
251 INSTANTIATE_TEST_SUITE_P(WebSocketDeflateParametersInitializeTest,
252                          WebSocketDeflateParametersInitializeTest,
253                          ::testing::ValuesIn(InitializeTestParameters()));
254 
255 INSTANTIATE_TEST_SUITE_P(WebSocketDeflateParametersCompatibilityTest,
256                          WebSocketDeflateParametersCompatibilityTest,
257                          ::testing::ValuesIn(kCompatibilityTestParameters));
258 
259 }  // namespace
260 
261 }  // namespace net
262