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