1 // Copyright 2014 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/spdy/hpack_output_stream.h" 6 7 #include <cstddef> 8 9 #include "base/basictypes.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 namespace net { 13 14 namespace { 15 16 using std::string; 17 18 // Make sure that AppendBits() appends bits starting from the most 19 // significant bit, and that it can handle crossing a byte boundary. 20 TEST(HpackOutputStreamTest, AppendBits) { 21 HpackOutputStream output_stream; 22 string expected_str; 23 24 output_stream.AppendBits(0x1, 1); 25 expected_str.append(1, 0x00); 26 *expected_str.rbegin() |= (0x1 << 7); 27 28 output_stream.AppendBits(0x0, 1); 29 30 output_stream.AppendBits(0x3, 2); 31 *expected_str.rbegin() |= (0x3 << 4); 32 33 output_stream.AppendBits(0x0, 2); 34 35 // Byte-crossing append. 36 output_stream.AppendBits(0x7, 3); 37 *expected_str.rbegin() |= (0x7 >> 1); 38 expected_str.append(1, 0x00); 39 *expected_str.rbegin() |= (0x7 << 7); 40 41 output_stream.AppendBits(0x0, 7); 42 43 string str; 44 output_stream.TakeString(&str); 45 EXPECT_EQ(expected_str, str); 46 } 47 48 // Utility function to return I as a string encoded with an N-bit 49 // prefix. 50 string EncodeUint32(uint8 N, uint32 I) { 51 HpackOutputStream output_stream; 52 if (N < 8) { 53 output_stream.AppendBits(0x00, 8 - N); 54 } 55 output_stream.AppendUint32(I); 56 string str; 57 output_stream.TakeString(&str); 58 return str; 59 } 60 61 // The {Number}ByteIntegersEightBitPrefix tests below test that 62 // certain integers are encoded correctly with an 8-bit prefix in 63 // exactly {Number} bytes. 64 65 TEST(HpackOutputStreamTest, OneByteIntegersEightBitPrefix) { 66 // Minimum. 67 EXPECT_EQ(string("\x00", 1), EncodeUint32(8, 0x00)); 68 EXPECT_EQ("\x7f", EncodeUint32(8, 0x7f)); 69 // Maximum. 70 EXPECT_EQ("\xfe", EncodeUint32(8, 0xfe)); 71 } 72 73 TEST(HpackOutputStreamTest, TwoByteIntegersEightBitPrefix) { 74 // Minimum. 75 EXPECT_EQ(string("\xff\x00", 2), EncodeUint32(8, 0xff)); 76 EXPECT_EQ("\xff\x01", EncodeUint32(8, 0x0100)); 77 // Maximum. 78 EXPECT_EQ("\xff\x7f", EncodeUint32(8, 0x017e)); 79 } 80 81 TEST(HpackOutputStreamTest, ThreeByteIntegersEightBitPrefix) { 82 // Minimum. 83 EXPECT_EQ("\xff\x80\x01", EncodeUint32(8, 0x017f)); 84 EXPECT_EQ("\xff\x80\x1e", EncodeUint32(8, 0x0fff)); 85 // Maximum. 86 EXPECT_EQ("\xff\xff\x7f", EncodeUint32(8, 0x40fe)); 87 } 88 89 TEST(HpackOutputStreamTest, FourByteIntegersEightBitPrefix) { 90 // Minimum. 91 EXPECT_EQ("\xff\x80\x80\x01", EncodeUint32(8, 0x40ff)); 92 EXPECT_EQ("\xff\x80\xfe\x03", EncodeUint32(8, 0xffff)); 93 // Maximum. 94 EXPECT_EQ("\xff\xff\xff\x7f", EncodeUint32(8, 0x002000fe)); 95 } 96 97 TEST(HpackOutputStreamTest, FiveByteIntegersEightBitPrefix) { 98 // Minimum. 99 EXPECT_EQ("\xff\x80\x80\x80\x01", EncodeUint32(8, 0x002000ff)); 100 EXPECT_EQ("\xff\x80\xfe\xff\x07", EncodeUint32(8, 0x00ffffff)); 101 // Maximum. 102 EXPECT_EQ("\xff\xff\xff\xff\x7f", EncodeUint32(8, 0x100000fe)); 103 } 104 105 TEST(HpackOutputStreamTest, SixByteIntegersEightBitPrefix) { 106 // Minimum. 107 EXPECT_EQ("\xff\x80\x80\x80\x80\x01", EncodeUint32(8, 0x100000ff)); 108 // Maximum. 109 EXPECT_EQ("\xff\x80\xfe\xff\xff\x0f", EncodeUint32(8, 0xffffffff)); 110 } 111 112 // The {Number}ByteIntegersOneToSevenBitPrefix tests below test that 113 // certain integers are encoded correctly with an N-bit prefix in 114 // exactly {Number} bytes for N in {1, 2, ..., 7}. 115 116 TEST(HpackOutputStreamTest, OneByteIntegersOneToSevenBitPrefixes) { 117 // Minimums. 118 EXPECT_EQ(string("\x00", 1), EncodeUint32(7, 0x00)); 119 EXPECT_EQ(string("\x00", 1), EncodeUint32(6, 0x00)); 120 EXPECT_EQ(string("\x00", 1), EncodeUint32(5, 0x00)); 121 EXPECT_EQ(string("\x00", 1), EncodeUint32(4, 0x00)); 122 EXPECT_EQ(string("\x00", 1), EncodeUint32(3, 0x00)); 123 EXPECT_EQ(string("\x00", 1), EncodeUint32(2, 0x00)); 124 EXPECT_EQ(string("\x00", 1), EncodeUint32(1, 0x00)); 125 126 // Maximums. 127 EXPECT_EQ("\x7e", EncodeUint32(7, 0x7e)); 128 EXPECT_EQ("\x3e", EncodeUint32(6, 0x3e)); 129 EXPECT_EQ("\x1e", EncodeUint32(5, 0x1e)); 130 EXPECT_EQ("\x0e", EncodeUint32(4, 0x0e)); 131 EXPECT_EQ("\x06", EncodeUint32(3, 0x06)); 132 EXPECT_EQ("\x02", EncodeUint32(2, 0x02)); 133 EXPECT_EQ(string("\x00", 1), EncodeUint32(1, 0x00)); 134 } 135 136 TEST(HpackOutputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) { 137 // Minimums. 138 EXPECT_EQ(string("\x7f\x00", 2), EncodeUint32(7, 0x7f)); 139 EXPECT_EQ(string("\x3f\x00", 2), EncodeUint32(6, 0x3f)); 140 EXPECT_EQ(string("\x1f\x00", 2), EncodeUint32(5, 0x1f)); 141 EXPECT_EQ(string("\x0f\x00", 2), EncodeUint32(4, 0x0f)); 142 EXPECT_EQ(string("\x07\x00", 2), EncodeUint32(3, 0x07)); 143 EXPECT_EQ(string("\x03\x00", 2), EncodeUint32(2, 0x03)); 144 EXPECT_EQ(string("\x01\x00", 2), EncodeUint32(1, 0x01)); 145 146 // Maximums. 147 EXPECT_EQ("\x7f\x7f", EncodeUint32(7, 0xfe)); 148 EXPECT_EQ("\x3f\x7f", EncodeUint32(6, 0xbe)); 149 EXPECT_EQ("\x1f\x7f", EncodeUint32(5, 0x9e)); 150 EXPECT_EQ("\x0f\x7f", EncodeUint32(4, 0x8e)); 151 EXPECT_EQ("\x07\x7f", EncodeUint32(3, 0x86)); 152 EXPECT_EQ("\x03\x7f", EncodeUint32(2, 0x82)); 153 EXPECT_EQ("\x01\x7f", EncodeUint32(1, 0x80)); 154 } 155 156 TEST(HpackOutputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) { 157 // Minimums. 158 EXPECT_EQ("\x7f\x80\x01", EncodeUint32(7, 0xff)); 159 EXPECT_EQ("\x3f\x80\x01", EncodeUint32(6, 0xbf)); 160 EXPECT_EQ("\x1f\x80\x01", EncodeUint32(5, 0x9f)); 161 EXPECT_EQ("\x0f\x80\x01", EncodeUint32(4, 0x8f)); 162 EXPECT_EQ("\x07\x80\x01", EncodeUint32(3, 0x87)); 163 EXPECT_EQ("\x03\x80\x01", EncodeUint32(2, 0x83)); 164 EXPECT_EQ("\x01\x80\x01", EncodeUint32(1, 0x81)); 165 166 // Maximums. 167 EXPECT_EQ("\x7f\xff\x7f", EncodeUint32(7, 0x407e)); 168 EXPECT_EQ("\x3f\xff\x7f", EncodeUint32(6, 0x403e)); 169 EXPECT_EQ("\x1f\xff\x7f", EncodeUint32(5, 0x401e)); 170 EXPECT_EQ("\x0f\xff\x7f", EncodeUint32(4, 0x400e)); 171 EXPECT_EQ("\x07\xff\x7f", EncodeUint32(3, 0x4006)); 172 EXPECT_EQ("\x03\xff\x7f", EncodeUint32(2, 0x4002)); 173 EXPECT_EQ("\x01\xff\x7f", EncodeUint32(1, 0x4000)); 174 } 175 176 TEST(HpackOutputStreamTest, FourByteIntegersOneToSevenBitPrefixes) { 177 // Minimums. 178 EXPECT_EQ("\x7f\x80\x80\x01", EncodeUint32(7, 0x407f)); 179 EXPECT_EQ("\x3f\x80\x80\x01", EncodeUint32(6, 0x403f)); 180 EXPECT_EQ("\x1f\x80\x80\x01", EncodeUint32(5, 0x401f)); 181 EXPECT_EQ("\x0f\x80\x80\x01", EncodeUint32(4, 0x400f)); 182 EXPECT_EQ("\x07\x80\x80\x01", EncodeUint32(3, 0x4007)); 183 EXPECT_EQ("\x03\x80\x80\x01", EncodeUint32(2, 0x4003)); 184 EXPECT_EQ("\x01\x80\x80\x01", EncodeUint32(1, 0x4001)); 185 186 // Maximums. 187 EXPECT_EQ("\x7f\xff\xff\x7f", EncodeUint32(7, 0x20007e)); 188 EXPECT_EQ("\x3f\xff\xff\x7f", EncodeUint32(6, 0x20003e)); 189 EXPECT_EQ("\x1f\xff\xff\x7f", EncodeUint32(5, 0x20001e)); 190 EXPECT_EQ("\x0f\xff\xff\x7f", EncodeUint32(4, 0x20000e)); 191 EXPECT_EQ("\x07\xff\xff\x7f", EncodeUint32(3, 0x200006)); 192 EXPECT_EQ("\x03\xff\xff\x7f", EncodeUint32(2, 0x200002)); 193 EXPECT_EQ("\x01\xff\xff\x7f", EncodeUint32(1, 0x200000)); 194 } 195 196 TEST(HpackOutputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) { 197 // Minimums. 198 EXPECT_EQ("\x7f\x80\x80\x80\x01", EncodeUint32(7, 0x20007f)); 199 EXPECT_EQ("\x3f\x80\x80\x80\x01", EncodeUint32(6, 0x20003f)); 200 EXPECT_EQ("\x1f\x80\x80\x80\x01", EncodeUint32(5, 0x20001f)); 201 EXPECT_EQ("\x0f\x80\x80\x80\x01", EncodeUint32(4, 0x20000f)); 202 EXPECT_EQ("\x07\x80\x80\x80\x01", EncodeUint32(3, 0x200007)); 203 EXPECT_EQ("\x03\x80\x80\x80\x01", EncodeUint32(2, 0x200003)); 204 EXPECT_EQ("\x01\x80\x80\x80\x01", EncodeUint32(1, 0x200001)); 205 206 // Maximums. 207 EXPECT_EQ("\x7f\xff\xff\xff\x7f", EncodeUint32(7, 0x1000007e)); 208 EXPECT_EQ("\x3f\xff\xff\xff\x7f", EncodeUint32(6, 0x1000003e)); 209 EXPECT_EQ("\x1f\xff\xff\xff\x7f", EncodeUint32(5, 0x1000001e)); 210 EXPECT_EQ("\x0f\xff\xff\xff\x7f", EncodeUint32(4, 0x1000000e)); 211 EXPECT_EQ("\x07\xff\xff\xff\x7f", EncodeUint32(3, 0x10000006)); 212 EXPECT_EQ("\x03\xff\xff\xff\x7f", EncodeUint32(2, 0x10000002)); 213 EXPECT_EQ("\x01\xff\xff\xff\x7f", EncodeUint32(1, 0x10000000)); 214 } 215 216 TEST(HpackOutputStreamTest, SixByteIntegersOneToSevenBitPrefixes) { 217 // Minimums. 218 EXPECT_EQ("\x7f\x80\x80\x80\x80\x01", EncodeUint32(7, 0x1000007f)); 219 EXPECT_EQ("\x3f\x80\x80\x80\x80\x01", EncodeUint32(6, 0x1000003f)); 220 EXPECT_EQ("\x1f\x80\x80\x80\x80\x01", EncodeUint32(5, 0x1000001f)); 221 EXPECT_EQ("\x0f\x80\x80\x80\x80\x01", EncodeUint32(4, 0x1000000f)); 222 EXPECT_EQ("\x07\x80\x80\x80\x80\x01", EncodeUint32(3, 0x10000007)); 223 EXPECT_EQ("\x03\x80\x80\x80\x80\x01", EncodeUint32(2, 0x10000003)); 224 EXPECT_EQ("\x01\x80\x80\x80\x80\x01", EncodeUint32(1, 0x10000001)); 225 226 // Maximums. 227 EXPECT_EQ("\x7f\x80\xff\xff\xff\x0f", EncodeUint32(7, 0xffffffff)); 228 EXPECT_EQ("\x3f\xc0\xff\xff\xff\x0f", EncodeUint32(6, 0xffffffff)); 229 EXPECT_EQ("\x1f\xe0\xff\xff\xff\x0f", EncodeUint32(5, 0xffffffff)); 230 EXPECT_EQ("\x0f\xf0\xff\xff\xff\x0f", EncodeUint32(4, 0xffffffff)); 231 EXPECT_EQ("\x07\xf8\xff\xff\xff\x0f", EncodeUint32(3, 0xffffffff)); 232 EXPECT_EQ("\x03\xfc\xff\xff\xff\x0f", EncodeUint32(2, 0xffffffff)); 233 EXPECT_EQ("\x01\xfe\xff\xff\xff\x0f", EncodeUint32(1, 0xffffffff)); 234 } 235 236 // Test that encoding an integer with an N-bit prefix preserves the 237 // upper (8-N) bits of the first byte. 238 TEST(HpackOutputStreamTest, AppendUint32PreservesUpperBits) { 239 HpackOutputStream output_stream; 240 output_stream.AppendBits(0x7f, 7); 241 output_stream.AppendUint32(0x01); 242 string str; 243 output_stream.TakeString(&str); 244 EXPECT_EQ(string("\xff\x00", 2), str); 245 } 246 247 TEST(HpackOutputStreamTest, AppendBytes) { 248 HpackOutputStream output_stream; 249 250 output_stream.AppendBytes("buffer1"); 251 output_stream.AppendBytes("buffer2"); 252 253 string str; 254 output_stream.TakeString(&str); 255 EXPECT_EQ("buffer1buffer2", str); 256 } 257 258 } // namespace 259 260 } // namespace net 261