websocket_deflate_parameters_test.cc 9.9 KB

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