1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/websockets/websocket_deflate_parameters.h"
10 #include "base/macros.h"
11 #include "net/websockets/websocket_extension_parser.h"
12 #include "testing/gtest/include/gtest/gtest.h"
18 void CheckExtension(const WebSocketDeflateParameters
& params
,
19 const std::string
& name
,
20 const std::string
& value
) {
21 WebSocketExtension e
= params
.AsExtension();
22 EXPECT_EQ("permessage-deflate", e
.name());
23 if (e
.parameters().size() != 1)
24 FAIL() << "parameters must have one element.";
25 EXPECT_EQ(name
, e
.parameters()[0].name());
26 EXPECT_EQ(value
, e
.parameters()[0].value());
29 TEST(WebSocketDeflateParametersTest
, Empty
) {
30 WebSocketDeflateParameters r
;
32 EXPECT_EQ(WebSocketDeflater::TAKE_OVER_CONTEXT
,
33 r
.server_context_take_over_mode());
34 EXPECT_EQ(WebSocketDeflater::TAKE_OVER_CONTEXT
,
35 r
.client_context_take_over_mode());
36 EXPECT_FALSE(r
.is_server_max_window_bits_specified());
37 EXPECT_FALSE(r
.is_client_max_window_bits_specified());
38 EXPECT_TRUE(r
.IsValidAsRequest());
39 EXPECT_TRUE(r
.IsValidAsResponse());
40 WebSocketExtension e
= r
.AsExtension();
41 EXPECT_EQ("permessage-deflate", e
.name());
42 EXPECT_TRUE(e
.parameters().empty());
45 TEST(WebSocketDeflateParametersTest
, ServerContextTakeover
) {
46 WebSocketDeflateParameters r
;
48 r
.SetServerNoContextTakeOver();
49 CheckExtension(r
, "server_no_context_takeover", "");
50 EXPECT_TRUE(r
.IsValidAsRequest());
51 EXPECT_TRUE(r
.IsValidAsResponse());
54 TEST(WebSocketDeflateParametersTest
, ClientContextTakeover
) {
55 WebSocketDeflateParameters r
;
57 r
.SetClientNoContextTakeOver();
58 CheckExtension(r
, "client_no_context_takeover", "");
59 EXPECT_TRUE(r
.IsValidAsRequest());
60 EXPECT_TRUE(r
.IsValidAsResponse());
63 TEST(WebSocketDeflateParametersTest
, ServerMaxWindowBits
) {
64 WebSocketDeflateParameters r
;
66 r
.SetServerMaxWindowBits(13);
67 CheckExtension(r
, "server_max_window_bits", "13");
68 EXPECT_TRUE(r
.IsValidAsRequest());
69 EXPECT_TRUE(r
.IsValidAsResponse());
72 TEST(WebSocketDeflateParametersTest
, ClientMaxWindowBitsWithoutValue
) {
73 WebSocketDeflateParameters r
;
74 std::string failure_message
;
76 r
.SetClientMaxWindowBits();
77 CheckExtension(r
, "client_max_window_bits", "");
78 EXPECT_TRUE(r
.IsValidAsRequest());
79 EXPECT_FALSE(r
.IsValidAsResponse(&failure_message
));
80 EXPECT_EQ("client_max_window_bits must have value", failure_message
);
83 TEST(WebSocketDeflateParametersTest
, ClientMaxWindowBitsWithValue
) {
84 WebSocketDeflateParameters r
;
86 r
.SetClientMaxWindowBits(12);
87 CheckExtension(r
, "client_max_window_bits", "12");
88 EXPECT_TRUE(r
.IsValidAsRequest());
89 EXPECT_TRUE(r
.IsValidAsResponse());
92 struct InitializeTestParameter
{
93 const std::string query
;
96 std::string failure_message
;
100 void PrintTo(const InitializeTestParameter
& p
, std::ostream
* o
) {
104 class WebSocketDeflateParametersInitializeTest
105 : public ::testing::TestWithParam
<InitializeTestParameter
> {};
107 TEST_P(WebSocketDeflateParametersInitializeTest
, Initialize
) {
108 const std::string query
= GetParam().query
;
109 const bool expected
= GetParam().expected
.result
;
110 const std::string expected_failure_message
=
111 GetParam().expected
.failure_message
;
113 WebSocketExtensionParser parser
;
114 ASSERT_TRUE(parser
.Parse("permessage-deflate" + query
));
115 ASSERT_EQ(1u, parser
.extensions().size());
116 WebSocketExtension extension
= parser
.extensions()[0];
118 WebSocketDeflateParameters parameters
;
119 std::string failure_message
;
120 bool actual
= parameters
.Initialize(extension
, &failure_message
);
124 EXPECT_TRUE(extension
.Equals(parameters
.AsExtension()));
126 EXPECT_FALSE(actual
);
128 EXPECT_EQ(expected_failure_message
, failure_message
);
131 struct CompatibilityTestParameter
{
132 const char* request_query
;
133 const char* response_query
;
137 void PrintTo(const CompatibilityTestParameter
& p
, std::ostream
* o
) {
138 *o
<< "req = \"" << p
.request_query
<< "\", res = \"" << p
.response_query
142 class WebSocketDeflateParametersCompatibilityTest
143 : public ::testing::TestWithParam
<CompatibilityTestParameter
> {};
145 TEST_P(WebSocketDeflateParametersCompatibilityTest
, CheckCompatiblity
) {
146 const std::string request_query
= GetParam().request_query
;
147 const std::string response_query
= GetParam().response_query
;
148 const bool expected
= GetParam().expected
;
151 WebSocketDeflateParameters request
, response
;
153 WebSocketExtensionParser request_parser
;
154 ASSERT_TRUE(request_parser
.Parse("permessage-deflate" + request_query
));
155 ASSERT_EQ(1u, request_parser
.extensions().size());
156 ASSERT_TRUE(request
.Initialize(request_parser
.extensions()[0], &message
));
157 ASSERT_TRUE(request
.IsValidAsRequest(&message
));
159 WebSocketExtensionParser response_parser
;
160 ASSERT_TRUE(response_parser
.Parse("permessage-deflate" + response_query
));
161 ASSERT_EQ(1u, response_parser
.extensions().size());
162 ASSERT_TRUE(response
.Initialize(response_parser
.extensions()[0], &message
));
163 ASSERT_TRUE(response
.IsValidAsResponse(&message
));
165 EXPECT_EQ(expected
, request
.IsCompatibleWith(response
));
168 InitializeTestParameter::Expectation
Duplicate(const std::string
& name
) {
170 "Received duplicate permessage-deflate extension parameter " + name
};
173 InitializeTestParameter::Expectation
Invalid(const std::string
& name
) {
174 return {false, "Received invalid " + name
+ " parameter"};
177 // We need this function in order to avoid global non-pod variables.
178 std::vector
<InitializeTestParameter
> InitializeTestParameters() {
179 const InitializeTestParameter::Expectation kInitialized
= {true, ""};
180 const InitializeTestParameter::Expectation kUnknownParameter
= {
181 false, "Received an unexpected permessage-deflate extension parameter"};
183 const InitializeTestParameter parameters
[] = {
185 {"; server_no_context_takeover", kInitialized
},
186 {"; server_no_context_takeover=0", Invalid("server_no_context_takeover")},
187 {"; server_no_context_takeover; server_no_context_takeover",
188 Duplicate("server_no_context_takeover")},
189 {"; client_no_context_takeover", kInitialized
},
190 {"; client_no_context_takeover=0", Invalid("client_no_context_takeover")},
191 {"; client_no_context_takeover; client_no_context_takeover",
192 Duplicate("client_no_context_takeover")},
193 {"; server_max_window_bits=8", kInitialized
},
194 {"; server_max_window_bits=15", kInitialized
},
195 {"; server_max_window_bits=15; server_max_window_bits=15",
196 Duplicate("server_max_window_bits")},
197 {"; server_max_window_bits=a", Invalid("server_max_window_bits")},
198 {"; server_max_window_bits=09", Invalid("server_max_window_bits")},
199 {"; server_max_window_bits=+9", Invalid("server_max_window_bits")},
200 {"; server_max_window_bits=9a", Invalid("server_max_window_bits")},
201 {"; server_max_window_bits", Invalid("server_max_window_bits")},
202 {"; server_max_window_bits=7", Invalid("server_max_window_bits")},
203 {"; server_max_window_bits=16", Invalid("server_max_window_bits")},
204 {"; client_max_window_bits=8", kInitialized
},
205 {"; client_max_window_bits=15", kInitialized
},
206 {"; client_max_window_bits=15; client_max_window_bits=15",
207 Duplicate("client_max_window_bits")},
208 {"; client_max_window_bits=a", Invalid("client_max_window_bits")},
209 {"; client_max_window_bits=09", Invalid("client_max_window_bits")},
210 {"; client_max_window_bits=+9", Invalid("client_max_window_bits")},
211 {"; client_max_window_bits=9a", Invalid("client_max_window_bits")},
212 {"; client_max_window_bits", kInitialized
},
213 {"; client_max_window_bits=7", Invalid("client_max_window_bits")},
214 {"; client_max_window_bits=16", Invalid("client_max_window_bits")},
215 {"; server_no_context_takeover; client_no_context_takeover"
216 "; server_max_window_bits=12; client_max_window_bits=13",
218 {"; hogefuga", kUnknownParameter
},
220 return std::vector
<InitializeTestParameter
>(
221 parameters
, parameters
+ arraysize(parameters
));
224 const CompatibilityTestParameter kCompatibilityTestParameters
[] = {
226 // server_no_context_takeover
227 {"", "; server_no_context_takeover", true},
228 {"; server_no_context_takeover", "", false},
229 {"; server_no_context_takeover", "; server_no_context_takeover", true},
230 // client_no_context_takeover
231 {"", "; client_no_context_takeover", true},
232 {"; client_no_context_takeover", "", true},
233 {"; client_no_context_takeover", "; client_no_context_takeover", true},
234 // server_max_window_bits
235 {"", "; server_max_window_bits=14", true},
236 {"; server_max_window_bits=12", "", false},
237 {"; server_max_window_bits=12", "; server_max_window_bits=12", true},
238 {"; server_max_window_bits=12", "; server_max_window_bits=11", true},
239 {"; server_max_window_bits=12", "; server_max_window_bits=13", false},
240 // client_max_window_bits
241 {"", "; client_max_window_bits=14", false},
242 {"; client_max_window_bits", "", true},
243 {"; client_max_window_bits", "; client_max_window_bits=15", true},
244 {"; client_max_window_bits=12", "", true},
245 {"; client_max_window_bits=12", "; client_max_window_bits=12", true},
246 {"; client_max_window_bits=12", "; client_max_window_bits=11", true},
247 {"; client_max_window_bits=12", "; client_max_window_bits=13", true},
250 INSTANTIATE_TEST_CASE_P(WebSocketDeflateParametersInitializeTest
,
251 WebSocketDeflateParametersInitializeTest
,
252 ::testing::ValuesIn(InitializeTestParameters()));
254 INSTANTIATE_TEST_CASE_P(WebSocketDeflateParametersCompatibilityTest
,
255 WebSocketDeflateParametersCompatibilityTest
,
256 ::testing::ValuesIn(kCompatibilityTestParameters
));