websocket_inflater_test.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2013 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_inflater.h"
  5. #include <stdint.h>
  6. #include <string>
  7. #include <vector>
  8. #include "net/base/io_buffer.h"
  9. #include "net/websockets/websocket_deflater.h"
  10. #include "net/websockets/websocket_test_util.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace net {
  13. namespace {
  14. std::string ToString(IOBufferWithSize* buffer) {
  15. return std::string(buffer->data(), buffer->size());
  16. }
  17. TEST(WebSocketInflaterTest, Construct) {
  18. WebSocketInflater inflater;
  19. ASSERT_TRUE(inflater.Initialize(15));
  20. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  21. }
  22. TEST(WebSocketInflaterTest, InflateHelloTakeOverContext) {
  23. WebSocketInflater inflater;
  24. ASSERT_TRUE(inflater.Initialize(15));
  25. scoped_refptr<IOBufferWithSize> actual1, actual2;
  26. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  27. ASSERT_TRUE(inflater.Finish());
  28. actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
  29. ASSERT_TRUE(actual1.get());
  30. EXPECT_EQ("Hello", ToString(actual1.get()));
  31. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  32. ASSERT_TRUE(inflater.AddBytes("\xf2\x00\x11\x00\x00", 5));
  33. ASSERT_TRUE(inflater.Finish());
  34. actual2 = inflater.GetOutput(inflater.CurrentOutputSize());
  35. ASSERT_TRUE(actual2.get());
  36. EXPECT_EQ("Hello", ToString(actual2.get()));
  37. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  38. }
  39. TEST(WebSocketInflaterTest, InflateHelloSmallCapacity) {
  40. WebSocketInflater inflater(1, 1);
  41. ASSERT_TRUE(inflater.Initialize(15));
  42. std::string actual;
  43. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  44. ASSERT_TRUE(inflater.Finish());
  45. for (size_t i = 0; i < 5; ++i) {
  46. ASSERT_EQ(1u, inflater.CurrentOutputSize());
  47. scoped_refptr<IOBufferWithSize> buffer = inflater.GetOutput(1);
  48. ASSERT_TRUE(buffer.get());
  49. ASSERT_EQ(1, buffer->size());
  50. actual += ToString(buffer.get());
  51. }
  52. EXPECT_EQ("Hello", actual);
  53. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  54. }
  55. TEST(WebSocketInflaterTest, InflateHelloSmallCapacityGetTotalOutput) {
  56. WebSocketInflater inflater(1, 1);
  57. ASSERT_TRUE(inflater.Initialize(15));
  58. scoped_refptr<IOBufferWithSize> actual;
  59. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  60. ASSERT_TRUE(inflater.Finish());
  61. ASSERT_EQ(1u, inflater.CurrentOutputSize());
  62. actual = inflater.GetOutput(1024);
  63. EXPECT_EQ("Hello", ToString(actual.get()));
  64. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  65. }
  66. TEST(WebSocketInflaterTest, InflateInvalidData) {
  67. WebSocketInflater inflater;
  68. ASSERT_TRUE(inflater.Initialize(15));
  69. EXPECT_FALSE(inflater.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
  70. }
  71. TEST(WebSocketInflaterTest, ChokedInvalidData) {
  72. WebSocketInflater inflater(1, 1);
  73. ASSERT_TRUE(inflater.Initialize(15));
  74. EXPECT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
  75. EXPECT_TRUE(inflater.Finish());
  76. EXPECT_EQ(1u, inflater.CurrentOutputSize());
  77. EXPECT_FALSE(inflater.GetOutput(1024).get());
  78. }
  79. TEST(WebSocketInflaterTest, MultipleAddBytesCalls) {
  80. WebSocketInflater inflater;
  81. ASSERT_TRUE(inflater.Initialize(15));
  82. std::string input("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
  83. scoped_refptr<IOBufferWithSize> actual;
  84. for (char& c : input) {
  85. ASSERT_TRUE(inflater.AddBytes(&c, 1));
  86. }
  87. ASSERT_TRUE(inflater.Finish());
  88. actual = inflater.GetOutput(5);
  89. ASSERT_TRUE(actual.get());
  90. EXPECT_EQ("Hello", ToString(actual.get()));
  91. }
  92. TEST(WebSocketInflaterTest, Reset) {
  93. WebSocketInflater inflater;
  94. ASSERT_TRUE(inflater.Initialize(15));
  95. scoped_refptr<IOBufferWithSize> actual1, actual2;
  96. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  97. ASSERT_TRUE(inflater.Finish());
  98. actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
  99. ASSERT_TRUE(actual1.get());
  100. EXPECT_EQ("Hello", ToString(actual1.get()));
  101. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  102. // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
  103. ASSERT_TRUE(inflater.AddBytes("\x01", 1));
  104. ASSERT_TRUE(inflater.Finish());
  105. ASSERT_EQ(0u, inflater.CurrentOutputSize());
  106. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  107. ASSERT_TRUE(inflater.Finish());
  108. actual2 = inflater.GetOutput(inflater.CurrentOutputSize());
  109. ASSERT_TRUE(actual2.get());
  110. EXPECT_EQ("Hello", ToString(actual2.get()));
  111. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  112. }
  113. TEST(WebSocketInflaterTest, ResetAndLostContext) {
  114. WebSocketInflater inflater;
  115. scoped_refptr<IOBufferWithSize> actual1, actual2;
  116. ASSERT_TRUE(inflater.Initialize(15));
  117. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  118. ASSERT_TRUE(inflater.Finish());
  119. actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
  120. ASSERT_TRUE(actual1.get());
  121. EXPECT_EQ("Hello", ToString(actual1.get()));
  122. EXPECT_EQ(0u, inflater.CurrentOutputSize());
  123. // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
  124. ASSERT_TRUE(inflater.AddBytes("\x01", 1));
  125. ASSERT_TRUE(inflater.Finish());
  126. ASSERT_EQ(0u, inflater.CurrentOutputSize());
  127. // The context is already reset.
  128. ASSERT_FALSE(inflater.AddBytes("\xf2\x00\x11\x00\x00", 5));
  129. }
  130. TEST(WebSocketInflaterTest, CallAddBytesAndFinishWithoutGetOutput) {
  131. WebSocketInflater inflater;
  132. scoped_refptr<IOBufferWithSize> actual1, actual2;
  133. ASSERT_TRUE(inflater.Initialize(15));
  134. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  135. ASSERT_TRUE(inflater.Finish());
  136. EXPECT_EQ(5u, inflater.CurrentOutputSize());
  137. // This is a test for memory leak detectors.
  138. }
  139. TEST(WebSocketInflaterTest, CallAddBytesAndFinishWithoutGetOutputChoked) {
  140. WebSocketInflater inflater(1, 1);
  141. scoped_refptr<IOBufferWithSize> actual1, actual2;
  142. ASSERT_TRUE(inflater.Initialize(15));
  143. ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  144. ASSERT_TRUE(inflater.Finish());
  145. EXPECT_EQ(1u, inflater.CurrentOutputSize());
  146. // This is a test for memory leak detectors.
  147. }
  148. TEST(WebSocketInflaterTest, LargeRandomDeflateInflate) {
  149. const size_t size = 64 * 1024;
  150. LinearCongruentialGenerator generator(133);
  151. std::vector<char> input;
  152. std::vector<char> output;
  153. scoped_refptr<IOBufferWithSize> compressed;
  154. WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
  155. ASSERT_TRUE(deflater.Initialize(8));
  156. WebSocketInflater inflater(256, 256);
  157. ASSERT_TRUE(inflater.Initialize(8));
  158. for (size_t i = 0; i < size; ++i)
  159. input.push_back(static_cast<char>(generator.Generate()));
  160. ASSERT_TRUE(deflater.AddBytes(input.data(), input.size()));
  161. ASSERT_TRUE(deflater.Finish());
  162. compressed = deflater.GetOutput(deflater.CurrentOutputSize());
  163. ASSERT_TRUE(compressed.get());
  164. ASSERT_EQ(0u, deflater.CurrentOutputSize());
  165. ASSERT_TRUE(inflater.AddBytes(compressed->data(), compressed->size()));
  166. ASSERT_TRUE(inflater.Finish());
  167. while (inflater.CurrentOutputSize() > 0) {
  168. scoped_refptr<IOBufferWithSize> uncompressed =
  169. inflater.GetOutput(inflater.CurrentOutputSize());
  170. ASSERT_TRUE(uncompressed.get());
  171. output.insert(output.end(),
  172. uncompressed->data(),
  173. uncompressed->data() + uncompressed->size());
  174. }
  175. EXPECT_EQ(output, input);
  176. }
  177. } // unnamed namespace
  178. } // namespace net