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.
5 #include "net/websockets/websocket_inflater.h"
11 #include "base/memory/ref_counted.h"
12 #include "net/base/io_buffer.h"
13 #include "net/websockets/websocket_deflater.h"
14 #include "net/websockets/websocket_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
21 std::string
ToString(IOBufferWithSize
* buffer
) {
22 return std::string(buffer
->data(), buffer
->size());
25 TEST(WebSocketInflaterTest
, Construct
) {
26 WebSocketInflater inflater
;
27 ASSERT_TRUE(inflater
.Initialize(15));
29 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
32 TEST(WebSocketInflaterTest
, InflateHelloTakeOverContext
) {
33 WebSocketInflater inflater
;
34 ASSERT_TRUE(inflater
.Initialize(15));
35 scoped_refptr
<IOBufferWithSize
> actual1
, actual2
;
37 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
38 ASSERT_TRUE(inflater
.Finish());
39 actual1
= inflater
.GetOutput(inflater
.CurrentOutputSize());
41 EXPECT_EQ("Hello", ToString(actual1
.get()));
42 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
44 ASSERT_TRUE(inflater
.AddBytes("\xf2\x00\x11\x00\x00", 5));
45 ASSERT_TRUE(inflater
.Finish());
46 actual2
= inflater
.GetOutput(inflater
.CurrentOutputSize());
48 EXPECT_EQ("Hello", ToString(actual2
.get()));
49 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
52 TEST(WebSocketInflaterTest
, InflateHelloSmallCapacity
) {
53 WebSocketInflater
inflater(1, 1);
54 ASSERT_TRUE(inflater
.Initialize(15));
57 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
58 ASSERT_TRUE(inflater
.Finish());
59 for (size_t i
= 0; i
< 5; ++i
) {
60 ASSERT_EQ(1u, inflater
.CurrentOutputSize());
61 scoped_refptr
<IOBufferWithSize
> buffer
= inflater
.GetOutput(1);
63 ASSERT_EQ(1, buffer
->size());
64 actual
+= ToString(buffer
.get());
66 EXPECT_EQ("Hello", actual
);
67 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
70 TEST(WebSocketInflaterTest
, InflateHelloSmallCapacityGetTotalOutput
) {
71 WebSocketInflater
inflater(1, 1);
72 ASSERT_TRUE(inflater
.Initialize(15));
73 scoped_refptr
<IOBufferWithSize
> actual
;
75 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
76 ASSERT_TRUE(inflater
.Finish());
77 ASSERT_EQ(1u, inflater
.CurrentOutputSize());
78 actual
= inflater
.GetOutput(1024);
79 EXPECT_EQ("Hello", ToString(actual
));
80 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
83 TEST(WebSocketInflaterTest
, InflateInvalidData
) {
84 WebSocketInflater inflater
;
85 ASSERT_TRUE(inflater
.Initialize(15));
86 EXPECT_FALSE(inflater
.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
89 TEST(WebSocketInflaterTest
, ChokedInvalidData
) {
90 WebSocketInflater
inflater(1, 1);
91 ASSERT_TRUE(inflater
.Initialize(15));
93 EXPECT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
94 EXPECT_TRUE(inflater
.Finish());
95 EXPECT_EQ(1u, inflater
.CurrentOutputSize());
96 EXPECT_FALSE(inflater
.GetOutput(1024));
99 TEST(WebSocketInflaterTest
, MultipleAddBytesCalls
) {
100 WebSocketInflater inflater
;
101 ASSERT_TRUE(inflater
.Initialize(15));
102 std::string
input("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
103 scoped_refptr
<IOBufferWithSize
> actual
;
105 for (size_t i
= 0; i
< input
.size(); ++i
) {
106 ASSERT_TRUE(inflater
.AddBytes(&input
[i
], 1));
108 ASSERT_TRUE(inflater
.Finish());
109 actual
= inflater
.GetOutput(5);
111 EXPECT_EQ("Hello", ToString(actual
.get()));
114 TEST(WebSocketInflaterTest
, Reset
) {
115 WebSocketInflater inflater
;
116 ASSERT_TRUE(inflater
.Initialize(15));
117 scoped_refptr
<IOBufferWithSize
> actual1
, actual2
;
119 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
120 ASSERT_TRUE(inflater
.Finish());
121 actual1
= inflater
.GetOutput(inflater
.CurrentOutputSize());
122 ASSERT_TRUE(actual1
);
123 EXPECT_EQ("Hello", ToString(actual1
.get()));
124 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
126 // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
127 ASSERT_TRUE(inflater
.AddBytes("\x01", 1));
128 ASSERT_TRUE(inflater
.Finish());
129 ASSERT_EQ(0u, inflater
.CurrentOutputSize());
131 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
132 ASSERT_TRUE(inflater
.Finish());
133 actual2
= inflater
.GetOutput(inflater
.CurrentOutputSize());
134 ASSERT_TRUE(actual2
);
135 EXPECT_EQ("Hello", ToString(actual2
.get()));
136 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
139 TEST(WebSocketInflaterTest
, ResetAndLostContext
) {
140 WebSocketInflater inflater
;
141 scoped_refptr
<IOBufferWithSize
> actual1
, actual2
;
142 ASSERT_TRUE(inflater
.Initialize(15));
144 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
145 ASSERT_TRUE(inflater
.Finish());
146 actual1
= inflater
.GetOutput(inflater
.CurrentOutputSize());
147 ASSERT_TRUE(actual1
);
148 EXPECT_EQ("Hello", ToString(actual1
.get()));
149 EXPECT_EQ(0u, inflater
.CurrentOutputSize());
151 // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
152 ASSERT_TRUE(inflater
.AddBytes("\x01", 1));
153 ASSERT_TRUE(inflater
.Finish());
154 ASSERT_EQ(0u, inflater
.CurrentOutputSize());
156 // The context is already reset.
157 ASSERT_FALSE(inflater
.AddBytes("\xf2\x00\x11\x00\x00", 5));
160 TEST(WebSocketInflaterTest
, CallAddBytesAndFinishWithoutGetOutput
) {
161 WebSocketInflater inflater
;
162 scoped_refptr
<IOBufferWithSize
> actual1
, actual2
;
163 ASSERT_TRUE(inflater
.Initialize(15));
165 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
166 ASSERT_TRUE(inflater
.Finish());
167 EXPECT_EQ(5u, inflater
.CurrentOutputSize());
169 // This is a test for detecting memory leaks with valgrind.
172 TEST(WebSocketInflaterTest
, CallAddBytesAndFinishWithoutGetOutputChoked
) {
173 WebSocketInflater
inflater(1, 1);
174 scoped_refptr
<IOBufferWithSize
> actual1
, actual2
;
175 ASSERT_TRUE(inflater
.Initialize(15));
177 ASSERT_TRUE(inflater
.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
178 ASSERT_TRUE(inflater
.Finish());
179 EXPECT_EQ(1u, inflater
.CurrentOutputSize());
181 // This is a test for detecting memory leaks with valgrind.
184 TEST(WebSocketInflaterTest
, LargeRandomDeflateInflate
) {
185 const size_t size
= 64 * 1024;
186 LinearCongruentialGenerator
generator(133);
187 std::vector
<char> input
;
188 std::vector
<char> output
;
189 scoped_refptr
<IOBufferWithSize
> compressed
;
191 WebSocketDeflater
deflater(WebSocketDeflater::TAKE_OVER_CONTEXT
);
192 ASSERT_TRUE(deflater
.Initialize(8));
193 WebSocketInflater
inflater(256, 256);
194 ASSERT_TRUE(inflater
.Initialize(8));
196 for (size_t i
= 0; i
< size
; ++i
)
197 input
.push_back(static_cast<char>(generator
.Generate()));
199 ASSERT_TRUE(deflater
.AddBytes(&input
[0], input
.size()));
200 ASSERT_TRUE(deflater
.Finish());
202 compressed
= deflater
.GetOutput(deflater
.CurrentOutputSize());
204 ASSERT_TRUE(compressed
);
205 ASSERT_EQ(0u, deflater
.CurrentOutputSize());
207 ASSERT_TRUE(inflater
.AddBytes(compressed
->data(), compressed
->size()));
208 ASSERT_TRUE(inflater
.Finish());
210 while (inflater
.CurrentOutputSize() > 0) {
211 scoped_refptr
<IOBufferWithSize
> uncompressed
=
212 inflater
.GetOutput(inflater
.CurrentOutputSize());
213 ASSERT_TRUE(uncompressed
);
214 output
.insert(output
.end(),
215 uncompressed
->data(),
216 uncompressed
->data() + uncompressed
->size());
219 EXPECT_EQ(output
, input
);
222 } // unnamed namespace