Home | History | Annotate | Download | only in balsa
      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/tools/balsa/balsa_headers.h"
      6 
      7 #include <iterator>
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/strings/string_piece.h"
     13 #include "net/tools/balsa/balsa_enums.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace net {
     17 
     18 using ::base::StringPiece;
     19 
     20 class BalsaBufferTest : public ::testing::Test {
     21  public:
     22   virtual void SetUp() OVERRIDE {
     23     buffer_.reset(new BalsaBuffer);
     24     anotherBuffer_.reset(new BalsaBuffer);
     25   }
     26 
     27  protected:
     28   scoped_ptr<BalsaBuffer> buffer_;
     29   scoped_ptr<BalsaBuffer> anotherBuffer_;
     30 };
     31 
     32 namespace {
     33 
     34 class BalsaHeadersTest: public ::testing::Test {
     35  public:
     36   virtual void SetUp() OVERRIDE {
     37     headers_.reset(new BalsaHeaders);
     38   }
     39 
     40  protected:
     41   scoped_ptr<BalsaHeaders> headers_;
     42 };
     43 
     44 class StringBuffer {
     45  public:
     46   void Write(const char* p, size_t size) {
     47     string_ += std::string(p, size);
     48   }
     49   const std::string& string() {return string_;}
     50 
     51  private:
     52   std::string string_;
     53 };
     54 
     55 TEST_F(BalsaBufferTest, EmptyBuffer) {
     56   ASSERT_EQ(1u, buffer_->num_blocks());
     57 }
     58 
     59 TEST_F(BalsaBufferTest, Write) {
     60   size_t index1, index2;
     61   StringPiece sp1 = buffer_->Write(StringPiece("hello"), &index1);
     62   StringPiece sp2 = buffer_->Write(StringPiece(", world"), &index2);
     63 
     64   ASSERT_EQ(2u, buffer_->num_blocks());
     65   ASSERT_EQ("hello", sp1);
     66   ASSERT_EQ(", world", sp2);
     67   ASSERT_EQ(1u, index1);
     68   ASSERT_EQ(1u, index2);
     69   ASSERT_EQ("hello, world",
     70             StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
     71 }
     72 
     73 TEST_F(BalsaBufferTest, WriteLongData) {
     74   size_t index1, index2, index3;
     75   std::string as(2, 'a');
     76   std::string bs(BalsaBuffer::kDefaultBlocksize + 1, 'b');
     77   std::string cs(4, 'c');
     78 
     79   StringPiece sp1 = buffer_->Write(as, &index1);
     80   StringPiece sp2 = buffer_->Write(bs, &index2);
     81   StringPiece sp3 = buffer_->Write(cs, &index3);
     82 
     83   ASSERT_EQ(3u, buffer_->num_blocks());
     84   ASSERT_EQ(as, sp1);
     85   ASSERT_EQ(bs, sp2);
     86   ASSERT_EQ(cs, sp3);
     87   ASSERT_EQ(1u, index1);
     88   ASSERT_EQ(2u, index2);
     89   ASSERT_EQ(1u, index3);
     90   ASSERT_EQ("aacccc", StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
     91   ASSERT_EQ(sp2, StringPiece(buffer_->GetPtr(2), buffer_->bytes_used(2)));
     92 }
     93 
     94 TEST_F(BalsaBufferTest, WriteToContiguousBuffer) {
     95   std::string as(2, 'a');
     96   std::string bs(BalsaBuffer::kDefaultBlocksize + 1, 'b');
     97   std::string cs(4, 'c');
     98 
     99   buffer_->WriteToContiguousBuffer(as);
    100   buffer_->WriteToContiguousBuffer(bs);
    101   buffer_->WriteToContiguousBuffer(cs);
    102 
    103   ASSERT_EQ(1u, buffer_->num_blocks());
    104   ASSERT_EQ(as + bs + cs,
    105             StringPiece(buffer_->GetPtr(0), buffer_->bytes_used(0)));
    106 }
    107 
    108 TEST_F(BalsaBufferTest, NoMoreWriteToContiguousBuffer) {
    109   size_t index1, index2;
    110   StringPiece sp1 = buffer_->Write(StringPiece("hello"), &index1);
    111   buffer_->NoMoreWriteToContiguousBuffer();
    112   StringPiece sp2 = buffer_->Write(StringPiece(", world"), &index2);
    113 
    114   ASSERT_EQ(2u, buffer_->num_blocks());
    115   ASSERT_EQ("hello", sp1);
    116   ASSERT_EQ(", world", sp2);
    117   ASSERT_EQ(1u, index1);
    118   ASSERT_EQ(0u, index2);
    119   ASSERT_EQ(sp1, StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
    120   ASSERT_EQ(sp2, StringPiece(buffer_->GetPtr(0), buffer_->bytes_used(0)));
    121 }
    122 
    123 TEST_F(BalsaBufferTest, Clear) {
    124   buffer_->Write("hello", NULL);
    125   ASSERT_EQ(2u, buffer_->num_blocks());
    126   buffer_->Clear();
    127   ASSERT_EQ(1u, buffer_->num_blocks());
    128 }
    129 
    130 TEST_F(BalsaBufferTest, Swap) {
    131   buffer_->Write("hello", NULL);
    132 
    133   ASSERT_EQ(2u, buffer_->num_blocks());
    134   ASSERT_EQ(1u, anotherBuffer_->num_blocks());
    135 
    136   buffer_->Swap(anotherBuffer_.get());
    137 
    138   ASSERT_EQ(1u, buffer_->num_blocks());
    139   ASSERT_EQ(2u, anotherBuffer_->num_blocks());
    140   ASSERT_EQ("hello",
    141             StringPiece(anotherBuffer_->GetPtr(1),
    142                         anotherBuffer_->bytes_used(1)));
    143 }
    144 
    145 TEST_F(BalsaBufferTest, CopyFrom) {
    146   buffer_->Write("hello", NULL);
    147 
    148   ASSERT_EQ(2u, buffer_->num_blocks());
    149   ASSERT_EQ(1u, anotherBuffer_->num_blocks());
    150 
    151   anotherBuffer_->CopyFrom(*buffer_);
    152 
    153   ASSERT_EQ(2u, buffer_->num_blocks());
    154   ASSERT_EQ(2u, anotherBuffer_->num_blocks());
    155   ASSERT_EQ("hello", StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
    156   ASSERT_EQ("hello",
    157             StringPiece(anotherBuffer_->GetPtr(1),
    158                         anotherBuffer_->bytes_used(1)));
    159 }
    160 
    161 TEST_F(BalsaHeadersTest, AppendHeader) {
    162   headers_->AppendHeader("key1", "value1");
    163   headers_->AppendHeader("key2", "value2");
    164   headers_->AppendHeader("key3", "value3");
    165   headers_->AppendHeader("key3", "value3.1");
    166   headers_->AppendHeader("key3", "value3.2");
    167 
    168   ASSERT_EQ(5, std::distance(headers_->header_lines_begin(),
    169                              headers_->header_lines_end()));
    170   ASSERT_EQ("value1", headers_->GetHeader("key1"));
    171   ASSERT_EQ("value2", headers_->GetHeader("key2"));
    172   ASSERT_EQ("value3", headers_->GetHeader("key3"));
    173 
    174   std::vector<base::StringPiece> v1, v2, v3;
    175   std::string s1, s2, s3;
    176   headers_->GetAllOfHeader("key1", &v1);
    177   headers_->GetAllOfHeader("key2", &v2);
    178   headers_->GetAllOfHeader("key3", &v3);
    179   headers_->GetAllOfHeaderAsString("key1", &s1);
    180   headers_->GetAllOfHeaderAsString("key2", &s2);
    181   headers_->GetAllOfHeaderAsString("key3", &s3);
    182 
    183   ASSERT_EQ(1u, v1.size());
    184   ASSERT_EQ(1u, v2.size());
    185   ASSERT_EQ(3u, v3.size());
    186   ASSERT_EQ("value1", v1[0]);
    187   ASSERT_EQ("value2", v2[0]);
    188   ASSERT_EQ("value3", v3[0]);
    189   ASSERT_EQ("value3.1", v3[1]);
    190   ASSERT_EQ("value3.2", v3[2]);
    191   ASSERT_EQ("value1", s1);
    192   ASSERT_EQ("value2", s2);
    193   ASSERT_EQ("value3,value3.1,value3.2", s3);
    194 }
    195 
    196 TEST_F(BalsaHeadersTest, ReplaceOrAppendHeader) {
    197   headers_->ReplaceOrAppendHeader("key1", "value1");
    198   headers_->ReplaceOrAppendHeader("key1", "value2");
    199 
    200   ASSERT_EQ(1, std::distance(headers_->header_lines_begin(),
    201                              headers_->header_lines_end()));
    202   ASSERT_EQ("value2", headers_->GetHeader("key1"));
    203 
    204   std::vector<base::StringPiece> v;
    205   headers_->GetAllOfHeader("key1", &v);
    206 
    207   ASSERT_EQ(1u, v.size());
    208   ASSERT_EQ("value2", v[0]);
    209 }
    210 
    211 TEST_F(BalsaHeadersTest, AppendToHeader) {
    212   headers_->AppendToHeader("key1", "value1");
    213   headers_->AppendToHeader("keY1", "value2");
    214 
    215   ASSERT_EQ(1, std::distance(headers_->header_lines_begin(),
    216                              headers_->header_lines_end()));
    217   ASSERT_EQ("value1,value2", headers_->GetHeader("key1"));
    218 
    219   std::vector<base::StringPiece> v;
    220   std::string s;
    221   headers_->GetAllOfHeader("key1", &v);
    222   headers_->GetAllOfHeaderAsString("keY1", &s);
    223 
    224   ASSERT_EQ(1u, v.size());
    225   ASSERT_EQ("value1,value2", v[0]);
    226   ASSERT_EQ("value1,value2", s);
    227 }
    228 
    229 TEST_F(BalsaHeadersTest, PrepentToHeader) {
    230   headers_->PrependToHeader("key1", "value1");
    231   headers_->PrependToHeader("key1", "value2");
    232 
    233   ASSERT_EQ(1, std::distance(headers_->header_lines_begin(),
    234                              headers_->header_lines_end()));
    235   ASSERT_EQ("value2,value1", headers_->GetHeader("key1"));
    236 
    237   std::vector<base::StringPiece> v;
    238   std::string s;
    239   headers_->GetAllOfHeader("key1", &v);
    240   headers_->GetAllOfHeaderAsString("key1", &s);
    241 
    242   ASSERT_EQ(1u, v.size());
    243   ASSERT_EQ("value2,value1", v[0]);
    244   ASSERT_EQ("value2,value1", s);
    245 }
    246 
    247 TEST_F(BalsaHeadersTest, HasHeader) {
    248   headers_->AppendHeader("key1", "value1");
    249 
    250   ASSERT_TRUE(headers_->HasHeader("key1"));
    251   ASSERT_FALSE(headers_->HasHeader("value1"));
    252   ASSERT_FALSE(headers_->HasHeader("key2"));
    253 }
    254 
    255 TEST_F(BalsaHeadersTest, HasNonEmptyHeader) {
    256   headers_->AppendHeader("key1", "value1");
    257   headers_->AppendHeader("key2", "");
    258 
    259   ASSERT_TRUE(headers_->HasNonEmptyHeader("key1"));
    260   ASSERT_FALSE(headers_->HasNonEmptyHeader("key2"));
    261   ASSERT_FALSE(headers_->HasNonEmptyHeader("key3"));
    262 }
    263 
    264 TEST_F(BalsaHeadersTest, GetHeaderPosition) {
    265   headers_->AppendHeader("key1", "value1");
    266   headers_->AppendHeader("key2", "value2");
    267   headers_->AppendHeader("key3", "value3");
    268 
    269   BalsaHeaders::const_header_lines_iterator i =
    270       headers_->GetHeaderPosition("key2");
    271 
    272   ASSERT_EQ(headers_->header_lines_end(),
    273             headers_->GetHeaderPosition("foobar"));
    274   ASSERT_EQ(headers_->header_lines_begin(),
    275             headers_->GetHeaderPosition("key1"));
    276   ASSERT_NE(headers_->header_lines_end(), i);
    277   ASSERT_EQ("key2", i->first);
    278   ASSERT_EQ("value2", i->second);
    279   ++i;
    280   ASSERT_EQ("key3", i->first);
    281   ASSERT_EQ("value3", i->second);
    282   ++i;
    283   ASSERT_EQ(headers_->header_lines_end(), i);
    284 }
    285 
    286 TEST_F(BalsaHeadersTest, GetIteratorForKey) {
    287   headers_->AppendHeader("key1", "value1");
    288   headers_->AppendHeader("key2", "value2");
    289   headers_->AppendHeader("key1", "value1.1");
    290   headers_->AppendHeader("key3", "value3");
    291   headers_->AppendHeader("KEY1", "value1.2");
    292 
    293   BalsaHeaders::const_header_lines_key_iterator i =
    294       headers_->GetIteratorForKey("key1");
    295 
    296   ASSERT_EQ(headers_->header_lines_key_end(),
    297             headers_->GetIteratorForKey("foobar"));
    298   ASSERT_NE(headers_->header_lines_key_end(), i);
    299   ASSERT_EQ("key1", i->first);
    300   ASSERT_EQ("value1", i->second);
    301   ++i;
    302   ASSERT_EQ("key1", i->first);
    303   ASSERT_EQ("value1.1", i->second);
    304   ++i;
    305   ASSERT_EQ("KEY1", i->first);
    306   ASSERT_EQ("value1.2", i->second);
    307   ++i;
    308   ASSERT_EQ(headers_->header_lines_key_end(), i);
    309 }
    310 
    311 TEST_F(BalsaHeadersTest, RemoveAllOfHeader) {
    312   headers_->AppendHeader("key1", "value1");
    313   headers_->AppendHeader("key2", "value2");
    314   headers_->AppendHeader("key1", "value1.1");
    315   headers_->AppendHeader("key3", "value3");
    316   headers_->AppendHeader("key1", "value1.2");
    317   headers_->AppendHeader("kEY1", "value1.3");
    318 
    319   ASSERT_EQ(6, std::distance(headers_->header_lines_begin(),
    320                              headers_->header_lines_end()));
    321   headers_->RemoveAllOfHeader("key1");
    322   ASSERT_EQ(2, std::distance(headers_->header_lines_begin(),
    323                              headers_->header_lines_end()));
    324 }
    325 
    326 TEST_F(BalsaHeadersTest, RemoveAllHeadersWithPrefix) {
    327   headers_->AppendHeader("1key", "value1");
    328   headers_->AppendHeader("2key", "value2");
    329   headers_->AppendHeader("1kEz", "value1.1");
    330   headers_->AppendHeader("key3", "value3");
    331   headers_->AppendHeader("1KEEjkladf", "value1.2");
    332 
    333   ASSERT_EQ(5, std::distance(headers_->header_lines_begin(),
    334                              headers_->header_lines_end()));
    335   headers_->RemoveAllHeadersWithPrefix("1ke");
    336   ASSERT_EQ(2, std::distance(headers_->header_lines_begin(),
    337                              headers_->header_lines_end()));
    338 }
    339 
    340 TEST_F(BalsaHeadersTest, WriteRequestHeaderAndEndingToBuffer) {
    341   headers_->AppendHeader("key1", "value1");
    342   headers_->AppendHeader("key2", "value2");
    343   headers_->AppendHeader("key1", "value1.1");
    344 
    345   headers_->SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
    346 
    347   std::string expected = "GET / HTTP/1.0\r\n"
    348       "key1: value1\r\n"
    349       "key2: value2\r\n"
    350       "key1: value1.1\r\n\r\n";
    351   StringBuffer buffer;
    352   headers_->WriteHeaderAndEndingToBuffer(&buffer);
    353   ASSERT_EQ(expected, buffer.string());
    354 }
    355 
    356 TEST_F(BalsaHeadersTest, WriteResponseHeaderAndEndingToBuffer) {
    357   headers_->AppendHeader("key1", "value1");
    358   headers_->AppendHeader("key2", "value2");
    359   headers_->AppendHeader("key1", "value1.1");
    360 
    361   headers_->SetResponseFirstlineFromStringPieces("HTTP/1.0", "200", "OK");
    362 
    363   std::string expected = "HTTP/1.0 200 OK\r\n"
    364       "key1: value1\r\n"
    365       "key2: value2\r\n"
    366       "key1: value1.1\r\n\r\n";
    367   StringBuffer buffer;
    368   headers_->WriteHeaderAndEndingToBuffer(&buffer);
    369   ASSERT_EQ(expected, buffer.string());
    370 }
    371 
    372 TEST_F(BalsaHeadersTest, RequestFirstLine) {
    373   headers_->SetRequestFirstlineFromStringPieces("HEAD", "/path", "HTTP/1.1");
    374 
    375   ASSERT_EQ("HEAD /path HTTP/1.1", headers_->first_line());
    376   ASSERT_EQ("HEAD", headers_->request_method());
    377   ASSERT_EQ("/path", headers_->request_uri());
    378   ASSERT_EQ("HTTP/1.1", headers_->request_version());
    379 }
    380 
    381 TEST_F(BalsaHeadersTest, ResponseFirstLine) {
    382   headers_->SetRequestFirstlineFromStringPieces("HTTP/1.0", "403", "FORBIDDEN");
    383 
    384   ASSERT_EQ("HTTP/1.0 403 FORBIDDEN", headers_->first_line());
    385   ASSERT_EQ("HTTP/1.0", headers_->response_version());
    386   ASSERT_EQ("403", headers_->response_code());
    387   ASSERT_EQ("FORBIDDEN", headers_->response_reason_phrase());
    388 }
    389 
    390 }  // namespace
    391 
    392 }  // namespace net
    393