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