Home | History | Annotate | Download | only in spdy
      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