1 // Copyright 2013 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_deflater.h"
6
7 #include <string>
8
9 #include "net/base/io_buffer.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace net {
13
14 namespace {
15
ToString(IOBufferWithSize * buffer)16 std::string ToString(IOBufferWithSize* buffer) {
17 return std::string(buffer->data(), buffer->size());
18 }
19
TEST(WebSocketDeflaterTest,Construct)20 TEST(WebSocketDeflaterTest, Construct) {
21 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
22 deflater.Initialize(8);
23 ASSERT_EQ(0u, deflater.CurrentOutputSize());
24 ASSERT_TRUE(deflater.Finish());
25 scoped_refptr<IOBufferWithSize> actual =
26 deflater.GetOutput(deflater.CurrentOutputSize());
27 EXPECT_EQ(std::string("\00", 1), ToString(actual.get()));
28 ASSERT_EQ(0u, deflater.CurrentOutputSize());
29 }
30
TEST(WebSocketDeflaterTest,DeflateHelloTakeOverContext)31 TEST(WebSocketDeflaterTest, DeflateHelloTakeOverContext) {
32 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
33 deflater.Initialize(15);
34 scoped_refptr<IOBufferWithSize> actual1, actual2;
35
36 ASSERT_TRUE(deflater.AddBytes("Hello", 5));
37 ASSERT_TRUE(deflater.Finish());
38 actual1 = deflater.GetOutput(deflater.CurrentOutputSize());
39 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
40 ToString(actual1.get()));
41
42 ASSERT_TRUE(deflater.AddBytes("Hello", 5));
43 ASSERT_TRUE(deflater.Finish());
44 actual2 = deflater.GetOutput(deflater.CurrentOutputSize());
45 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(actual2.get()));
46 }
47
TEST(WebSocketDeflaterTest,DeflateHelloDoNotTakeOverContext)48 TEST(WebSocketDeflaterTest, DeflateHelloDoNotTakeOverContext) {
49 WebSocketDeflater deflater(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT);
50 deflater.Initialize(15);
51 scoped_refptr<IOBufferWithSize> actual1, actual2;
52
53 ASSERT_TRUE(deflater.AddBytes("Hello", 5));
54 ASSERT_TRUE(deflater.Finish());
55 actual1 = deflater.GetOutput(deflater.CurrentOutputSize());
56 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
57 ToString(actual1.get()));
58
59 ASSERT_TRUE(deflater.AddBytes("Hello", 5));
60 ASSERT_TRUE(deflater.Finish());
61 actual2 = deflater.GetOutput(deflater.CurrentOutputSize());
62 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
63 ToString(actual2.get()));
64 }
65
TEST(WebSocketDeflaterTest,MultipleAddBytesCalls)66 TEST(WebSocketDeflaterTest, MultipleAddBytesCalls) {
67 WebSocketDeflater deflater(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT);
68 deflater.Initialize(15);
69 std::string input(32, 'a');
70 scoped_refptr<IOBufferWithSize> actual;
71
72 for (char& c : input) {
73 ASSERT_TRUE(deflater.AddBytes(&c, 1));
74 }
75 ASSERT_TRUE(deflater.Finish());
76 actual = deflater.GetOutput(deflater.CurrentOutputSize());
77 EXPECT_EQ(std::string("\x4a\x4c\xc4\x0f\x00\x00", 6), ToString(actual.get()));
78 }
79
TEST(WebSocketDeflaterTest,GetMultipleDeflatedOutput)80 TEST(WebSocketDeflaterTest, GetMultipleDeflatedOutput) {
81 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
82 deflater.Initialize(15);
83 scoped_refptr<IOBufferWithSize> actual;
84
85 ASSERT_TRUE(deflater.AddBytes("Hello", 5));
86 ASSERT_TRUE(deflater.Finish());
87 deflater.PushSyncMark();
88 ASSERT_TRUE(deflater.Finish());
89 deflater.PushSyncMark();
90 ASSERT_TRUE(deflater.AddBytes("Hello", 5));
91 ASSERT_TRUE(deflater.Finish());
92
93 actual = deflater.GetOutput(deflater.CurrentOutputSize());
94 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00\x00\x00\xff\xff"
95 "\x00\x00\x00\xff\xff"
96 "\xf2\x00\x11\x00\x00", 21),
97 ToString(actual.get()));
98 ASSERT_EQ(0u, deflater.CurrentOutputSize());
99 }
100
TEST(WebSocketDeflaterTest,WindowBits8)101 TEST(WebSocketDeflaterTest, WindowBits8) {
102 WebSocketDeflater deflater(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT);
103 deflater.Initialize(8);
104 // Set the head and tail of |input| so that back-reference
105 // can be used if the window size is sufficiently-large.
106 const std::string word = "Chromium";
107 std::string input = word + std::string(256, 'a') + word;
108 scoped_refptr<IOBufferWithSize> actual;
109
110 ASSERT_TRUE(deflater.AddBytes(input.data(), input.size()));
111 ASSERT_TRUE(deflater.Finish());
112 actual = deflater.GetOutput(deflater.CurrentOutputSize());
113 EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
114 "(?7\xb3\x34\x17\x00", 21),
115 ToString(actual.get()));
116 }
117
TEST(WebSocketDeflaterTest,WindowBits10)118 TEST(WebSocketDeflaterTest, WindowBits10) {
119 WebSocketDeflater deflater(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT);
120 deflater.Initialize(10);
121 // Set the head and tail of |input| so that back-reference
122 // can be used if the window size is sufficiently-large.
123 const std::string word = "Chromium";
124 std::string input = word + std::string(256, 'a') + word;
125 scoped_refptr<IOBufferWithSize> actual;
126
127 ASSERT_TRUE(deflater.AddBytes(input.data(), input.size()));
128 ASSERT_TRUE(deflater.Finish());
129 actual = deflater.GetOutput(deflater.CurrentOutputSize());
130 EXPECT_EQ(
131 std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
132 ToString(actual.get()));
133 }
134
135 } // namespace
136
137 } // namespace net
138