xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/balsa/balsa_headers_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 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 // Note that several of the BalsaHeaders functions are
6 // tested in the balsa_frame_test as the BalsaFrame and
7 // BalsaHeaders classes are fairly related.
8 
9 #include "quiche/balsa/balsa_headers.h"
10 
11 #include <cstring>
12 #include <limits>
13 #include <memory>
14 #include <sstream>
15 #include <string>
16 #include <tuple>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/base/macros.h"
21 #include "absl/memory/memory.h"
22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/str_format.h"
24 #include "absl/strings/string_view.h"
25 #include "quiche/balsa/balsa_enums.h"
26 #include "quiche/balsa/balsa_frame.h"
27 #include "quiche/balsa/simple_buffer.h"
28 #include "quiche/common/platform/api/quiche_expect_bug.h"
29 #include "quiche/common/platform/api/quiche_logging.h"
30 #include "quiche/common/platform/api/quiche_test.h"
31 
32 using absl::make_unique;
33 using testing::AnyOf;
34 using testing::Combine;
35 using testing::ElementsAre;
36 using testing::Eq;
37 using testing::StrEq;
38 using testing::ValuesIn;
39 
40 namespace quiche {
41 
42 namespace test {
43 
44 class BalsaHeadersTestPeer {
45  public:
WriteFromFramer(BalsaHeaders * headers,const char * ptr,size_t size)46   static void WriteFromFramer(BalsaHeaders* headers, const char* ptr,
47                               size_t size) {
48     headers->WriteFromFramer(ptr, size);
49   }
50 };
51 
52 namespace {
53 
54 class BalsaBufferTest : public QuicheTest {
55  public:
CreateBuffer(size_t blocksize)56   void CreateBuffer(size_t blocksize) {
57     buffer_ = std::make_unique<BalsaBuffer>(blocksize);
58   }
CreateBuffer()59   void CreateBuffer() { buffer_ = std::make_unique<BalsaBuffer>(); }
CreateUnmanagedBuffer(size_t blocksize)60   static std::unique_ptr<BalsaBuffer> CreateUnmanagedBuffer(size_t blocksize) {
61     return std::make_unique<BalsaBuffer>(blocksize);
62   }
Write(absl::string_view sp,size_t * block_buffer_idx)63   absl::string_view Write(absl::string_view sp, size_t* block_buffer_idx) {
64     if (sp.empty()) {
65       return sp;
66     }
67     char* storage = buffer_->Reserve(sp.size(), block_buffer_idx);
68     memcpy(storage, sp.data(), sp.size());
69     return absl::string_view(storage, sp.size());
70   }
71 
72  protected:
73   std::unique_ptr<BalsaBuffer> buffer_;
74 };
75 
76 using BufferBlock = BalsaBuffer::BufferBlock;
77 
MakeBufferBlock(const std::string & s)78 BufferBlock MakeBufferBlock(const std::string& s) {
79   // Make the buffer twice the size needed to verify that CopyFrom copies our
80   // buffer_size (as opposed to shrinking to fit or reusing an old buffer).
81   BufferBlock block{make_unique<char[]>(s.size()), s.size() * 2, s.size()};
82   std::memcpy(block.buffer.get(), s.data(), s.size());
83   return block;
84 }
85 
CreateHTTPHeaders(bool request,absl::string_view s)86 BalsaHeaders CreateHTTPHeaders(bool request, absl::string_view s) {
87   BalsaHeaders headers;
88   BalsaFrame framer;
89   framer.set_is_request(request);
90   framer.set_balsa_headers(&headers);
91   QUICHE_CHECK_EQ(s.size(), framer.ProcessInput(s.data(), s.size()));
92   QUICHE_CHECK(framer.MessageFullyRead());
93   return headers;
94 }
95 
96 class BufferBlockTest
97     : public QuicheTestWithParam<std::tuple<const char*, const char*>> {};
98 
TEST_P(BufferBlockTest,CopyFrom)99 TEST_P(BufferBlockTest, CopyFrom) {
100   const std::string s1 = std::get<0>(GetParam());
101   const std::string s2 = std::get<1>(GetParam());
102   BufferBlock block;
103   block.CopyFrom(MakeBufferBlock(s1));
104   EXPECT_EQ(s1.size(), block.bytes_free);
105   ASSERT_EQ(2 * s1.size(), block.buffer_size);
106   EXPECT_EQ(0, memcmp(s1.data(), block.buffer.get(), s1.size()));
107   block.CopyFrom(MakeBufferBlock(s2));
108   EXPECT_EQ(s2.size(), block.bytes_free);
109   ASSERT_EQ(2 * s2.size(), block.buffer_size);
110   EXPECT_EQ(0, memcmp(s2.data(), block.buffer.get(), s2.size()));
111 }
112 
113 const char* block_strings[] = {"short string", "longer than the other string"};
114 INSTANTIATE_TEST_SUITE_P(VariousSizes, BufferBlockTest,
115                          Combine(ValuesIn(block_strings),
116                                  ValuesIn(block_strings)));
117 
TEST_F(BalsaBufferTest,BlocksizeSet)118 TEST_F(BalsaBufferTest, BlocksizeSet) {
119   CreateBuffer();
120   EXPECT_EQ(BalsaBuffer::kDefaultBlocksize, buffer_->blocksize());
121   CreateBuffer(1024);
122   EXPECT_EQ(1024u, buffer_->blocksize());
123 }
124 
TEST_F(BalsaBufferTest,GetMemorySize)125 TEST_F(BalsaBufferTest, GetMemorySize) {
126   CreateBuffer(10);
127   EXPECT_EQ(0u, buffer_->GetTotalBytesUsed());
128   EXPECT_EQ(0u, buffer_->GetTotalBufferBlockSize());
129   BalsaBuffer::Blocks::size_type index;
130   buffer_->Reserve(1024, &index);
131   EXPECT_EQ(10u + 1024u, buffer_->GetTotalBufferBlockSize());
132   EXPECT_EQ(1024u, buffer_->GetTotalBytesUsed());
133 }
134 
TEST_F(BalsaBufferTest,ManyWritesToContiguousBuffer)135 TEST_F(BalsaBufferTest, ManyWritesToContiguousBuffer) {
136   CreateBuffer(0);
137   // The test is that the process completes.  If it needs to do a resize on
138   // every write, it will timeout or run out of memory.
139   // ( 10 + 20 + 30 + ... + 1.2e6 bytes => ~1e11 bytes )
140   std::string data = "0123456789";
141   for (int i = 0; i < 120 * 1000; ++i) {
142     buffer_->WriteToContiguousBuffer(data);
143   }
144 }
145 
TEST_F(BalsaBufferTest,CopyFrom)146 TEST_F(BalsaBufferTest, CopyFrom) {
147   CreateBuffer(10);
148   std::unique_ptr<BalsaBuffer> ptr = CreateUnmanagedBuffer(1024);
149   ASSERT_EQ(1024u, ptr->blocksize());
150   EXPECT_EQ(0u, ptr->num_blocks());
151 
152   std::string data1 = "foobarbaz01";
153   buffer_->WriteToContiguousBuffer(data1);
154   buffer_->NoMoreWriteToContiguousBuffer();
155   std::string data2 = "12345";
156   Write(data2, nullptr);
157   std::string data3 = "6789";
158   Write(data3, nullptr);
159   std::string data4 = "123456789012345";
160   Write(data3, nullptr);
161 
162   ptr->CopyFrom(*buffer_);
163 
164   EXPECT_EQ(ptr->can_write_to_contiguous_buffer(),
165             buffer_->can_write_to_contiguous_buffer());
166   ASSERT_EQ(ptr->num_blocks(), buffer_->num_blocks());
167   for (size_t i = 0; i < buffer_->num_blocks(); ++i) {
168     ASSERT_EQ(ptr->bytes_used(i), buffer_->bytes_used(i));
169     ASSERT_EQ(ptr->buffer_size(i), buffer_->buffer_size(i));
170     EXPECT_EQ(0,
171               memcmp(ptr->GetPtr(i), buffer_->GetPtr(i), ptr->bytes_used(i)));
172   }
173 }
174 
TEST_F(BalsaBufferTest,ClearWorks)175 TEST_F(BalsaBufferTest, ClearWorks) {
176   CreateBuffer(10);
177 
178   std::string data1 = "foobarbaz01";
179   buffer_->WriteToContiguousBuffer(data1);
180   buffer_->NoMoreWriteToContiguousBuffer();
181   std::string data2 = "12345";
182   Write(data2, nullptr);
183   std::string data3 = "6789";
184   Write(data3, nullptr);
185   std::string data4 = "123456789012345";
186   Write(data3, nullptr);
187 
188   buffer_->Clear();
189 
190   EXPECT_TRUE(buffer_->can_write_to_contiguous_buffer());
191   EXPECT_EQ(10u, buffer_->blocksize());
192   EXPECT_EQ(0u, buffer_->num_blocks());
193 }
194 
TEST_F(BalsaBufferTest,ClearWorksWhenLargerThanBlocksize)195 TEST_F(BalsaBufferTest, ClearWorksWhenLargerThanBlocksize) {
196   CreateBuffer(10);
197 
198   std::string data1 = "foobarbaz01lkjasdlkjasdlkjasd";
199   buffer_->WriteToContiguousBuffer(data1);
200   buffer_->NoMoreWriteToContiguousBuffer();
201   std::string data2 = "12345";
202   Write(data2, nullptr);
203   std::string data3 = "6789";
204   Write(data3, nullptr);
205   std::string data4 = "123456789012345";
206   Write(data3, nullptr);
207 
208   buffer_->Clear();
209 
210   EXPECT_TRUE(buffer_->can_write_to_contiguous_buffer());
211   EXPECT_EQ(10u, buffer_->blocksize());
212   EXPECT_EQ(0u, buffer_->num_blocks());
213 }
214 
TEST_F(BalsaBufferTest,ContiguousWriteSmallerThanBlocksize)215 TEST_F(BalsaBufferTest, ContiguousWriteSmallerThanBlocksize) {
216   CreateBuffer(1024);
217 
218   std::string data1 = "foo";
219   buffer_->WriteToContiguousBuffer(data1);
220   std::string composite = data1;
221   const char* buf_ptr = buffer_->GetPtr(0);
222   ASSERT_LE(composite.size(), buffer_->buffer_size(0));
223   EXPECT_EQ(0, memcmp(composite.data(), buf_ptr, composite.size()));
224 
225   std::string data2 = "barbaz";
226   buffer_->WriteToContiguousBuffer(data2);
227   composite += data2;
228   buf_ptr = buffer_->GetPtr(0);
229   ASSERT_LE(composite.size(), buffer_->buffer_size(0));
230   EXPECT_EQ(0, memcmp(composite.data(), buf_ptr, composite.size()));
231 }
232 
TEST_F(BalsaBufferTest,SingleContiguousWriteLargerThanBlocksize)233 TEST_F(BalsaBufferTest, SingleContiguousWriteLargerThanBlocksize) {
234   CreateBuffer(10);
235 
236   std::string data1 = "abracadabrawords";
237   buffer_->WriteToContiguousBuffer(data1);
238   std::string composite = data1;
239   const char* buf_ptr = buffer_->GetPtr(0);
240   ASSERT_LE(data1.size(), buffer_->buffer_size(0));
241   EXPECT_EQ(0, memcmp(composite.data(), buf_ptr, composite.size()))
242       << composite << "\n"
243       << absl::string_view(buf_ptr, buffer_->bytes_used(0));
244 }
245 
TEST_F(BalsaBufferTest,ContiguousWriteLargerThanBlocksize)246 TEST_F(BalsaBufferTest, ContiguousWriteLargerThanBlocksize) {
247   CreateBuffer(10);
248 
249   std::string data1 = "123456789";
250   buffer_->WriteToContiguousBuffer(data1);
251   std::string composite = data1;
252   ASSERT_LE(10u, buffer_->buffer_size(0));
253 
254   std::string data2 = "0123456789";
255   buffer_->WriteToContiguousBuffer(data2);
256   composite += data2;
257 
258   const char* buf_ptr = buffer_->GetPtr(0);
259   ASSERT_LE(composite.size(), buffer_->buffer_size(0));
260   EXPECT_EQ(0, memcmp(composite.data(), buf_ptr, composite.size()))
261       << "composite: " << composite << "\n"
262       << "   actual: " << absl::string_view(buf_ptr, buffer_->bytes_used(0));
263 }
264 
TEST_F(BalsaBufferTest,TwoContiguousWritesLargerThanBlocksize)265 TEST_F(BalsaBufferTest, TwoContiguousWritesLargerThanBlocksize) {
266   CreateBuffer(5);
267 
268   std::string data1 = "123456";
269   buffer_->WriteToContiguousBuffer(data1);
270   std::string composite = data1;
271   ASSERT_LE(composite.size(), buffer_->buffer_size(0));
272 
273   std::string data2 = "7890123";
274   buffer_->WriteToContiguousBuffer(data2);
275   composite += data2;
276 
277   const char* buf_ptr = buffer_->GetPtr(0);
278   ASSERT_LE(composite.size(), buffer_->buffer_size(0));
279   EXPECT_EQ(0, memcmp(composite.data(), buf_ptr, composite.size()))
280       << "composite: " << composite << "\n"
281       << "   actual: " << absl::string_view(buf_ptr, buffer_->bytes_used(0));
282 }
283 
TEST_F(BalsaBufferTest,WriteSmallerThanBlocksize)284 TEST_F(BalsaBufferTest, WriteSmallerThanBlocksize) {
285   CreateBuffer(5);
286   std::string data1 = "1234";
287   size_t block_idx = 0;
288   absl::string_view write_result = Write(data1, &block_idx);
289   ASSERT_EQ(1u, block_idx);
290   EXPECT_THAT(write_result, StrEq(data1));
291 
292   CreateBuffer(5);
293   data1 = "1234";
294   block_idx = 0;
295   write_result = Write(data1, &block_idx);
296   ASSERT_EQ(1u, block_idx);
297   EXPECT_THAT(write_result, StrEq(data1));
298 }
299 
TEST_F(BalsaBufferTest,TwoWritesSmallerThanBlocksizeThenAnotherWrite)300 TEST_F(BalsaBufferTest, TwoWritesSmallerThanBlocksizeThenAnotherWrite) {
301   CreateBuffer(10);
302   std::string data1 = "12345";
303   size_t block_idx = 0;
304   absl::string_view write_result = Write(data1, &block_idx);
305   ASSERT_EQ(1u, block_idx);
306   EXPECT_THAT(write_result, StrEq(data1));
307 
308   std::string data2 = "data2";
309   block_idx = 0;
310   write_result = Write(data2, &block_idx);
311   ASSERT_EQ(1u, block_idx);
312   EXPECT_THAT(write_result, StrEq(data2));
313 
314   std::string data3 = "data3";
315   block_idx = 0;
316   write_result = Write(data3, &block_idx);
317   ASSERT_EQ(2u, block_idx);
318   EXPECT_THAT(write_result, StrEq(data3));
319 
320   CreateBuffer(10);
321   buffer_->NoMoreWriteToContiguousBuffer();
322   data1 = "12345";
323   block_idx = 0;
324   write_result = Write(data1, &block_idx);
325   ASSERT_EQ(0u, block_idx);
326   EXPECT_THAT(write_result, StrEq(data1));
327 
328   data2 = "data2";
329   block_idx = 0;
330   write_result = Write(data2, &block_idx);
331   ASSERT_EQ(0u, block_idx);
332   EXPECT_THAT(write_result, StrEq(data2));
333 
334   data3 = "data3";
335   block_idx = 0;
336   write_result = Write(data3, &block_idx);
337   ASSERT_EQ(1u, block_idx);
338   EXPECT_THAT(write_result, StrEq(data3));
339 }
340 
TEST_F(BalsaBufferTest,WriteLargerThanBlocksize)341 TEST_F(BalsaBufferTest, WriteLargerThanBlocksize) {
342   CreateBuffer(5);
343   std::string data1 = "123456789";
344   size_t block_idx = 0;
345   absl::string_view write_result = Write(data1, &block_idx);
346   ASSERT_EQ(1u, block_idx);
347   EXPECT_THAT(write_result, StrEq(data1));
348 
349   CreateBuffer(5);
350   buffer_->NoMoreWriteToContiguousBuffer();
351   data1 = "123456789";
352   block_idx = 0;
353   write_result = Write(data1, &block_idx);
354   ASSERT_EQ(1u, block_idx);
355   EXPECT_THAT(write_result, StrEq(data1));
356 }
357 
TEST_F(BalsaBufferTest,ContiguousThenTwoSmallerThanBlocksize)358 TEST_F(BalsaBufferTest, ContiguousThenTwoSmallerThanBlocksize) {
359   CreateBuffer(5);
360   std::string data1 = "1234567890";
361   buffer_->WriteToContiguousBuffer(data1);
362   size_t block_idx = 0;
363   std::string data2 = "1234";
364   absl::string_view write_result = Write(data2, &block_idx);
365   ASSERT_EQ(1u, block_idx);
366   std::string data3 = "1234";
367   write_result = Write(data3, &block_idx);
368   ASSERT_EQ(2u, block_idx);
369 }
370 
TEST_F(BalsaBufferTest,AccessFirstBlockUninitialized)371 TEST_F(BalsaBufferTest, AccessFirstBlockUninitialized) {
372   CreateBuffer(5);
373   EXPECT_EQ(0u, buffer_->GetReadableBytesOfFirstBlock());
374   EXPECT_QUICHE_BUG(buffer_->StartOfFirstBlock(),
375                     "First block not allocated yet!");
376   EXPECT_QUICHE_BUG(buffer_->EndOfFirstBlock(),
377                     "First block not allocated yet!");
378 }
379 
TEST_F(BalsaBufferTest,AccessFirstBlockInitialized)380 TEST_F(BalsaBufferTest, AccessFirstBlockInitialized) {
381   CreateBuffer(5);
382   std::string data1 = "1234567890";
383   buffer_->WriteToContiguousBuffer(data1);
384   const char* start = buffer_->StartOfFirstBlock();
385   EXPECT_TRUE(start != nullptr);
386   const char* end = buffer_->EndOfFirstBlock();
387   EXPECT_TRUE(end != nullptr);
388   EXPECT_EQ(data1.length(), static_cast<size_t>(end - start));
389   EXPECT_EQ(data1.length(), buffer_->GetReadableBytesOfFirstBlock());
390 }
391 
TEST(BalsaHeaders,CanAssignBeginToIterator)392 TEST(BalsaHeaders, CanAssignBeginToIterator) {
393   {
394     BalsaHeaders header;
395     BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
396     static_cast<void>(chli);
397   }
398   {
399     const BalsaHeaders header;
400     BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
401     static_cast<void>(chli);
402   }
403 }
404 
TEST(BalsaHeaders,CanAssignEndToIterator)405 TEST(BalsaHeaders, CanAssignEndToIterator) {
406   {
407     BalsaHeaders header;
408     BalsaHeaders::const_header_lines_iterator chli = header.lines().end();
409     static_cast<void>(chli);
410   }
411   {
412     const BalsaHeaders header;
413     BalsaHeaders::const_header_lines_iterator chli = header.lines().end();
414     static_cast<void>(chli);
415   }
416 }
417 
TEST(BalsaHeaders,ReplaceOrAppendHeaderTestAppending)418 TEST(BalsaHeaders, ReplaceOrAppendHeaderTestAppending) {
419   BalsaHeaders header;
420   std::string key_1 = "key_1";
421   std::string value_1 = "value_1";
422   header.ReplaceOrAppendHeader(key_1, value_1);
423 
424   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
425   ASSERT_EQ(absl::string_view("key_1"), chli->first);
426   ASSERT_EQ(absl::string_view("value_1"), chli->second);
427   ++chli;
428   ASSERT_NE(header.lines().begin(), chli);
429   ASSERT_EQ(header.lines().end(), chli);
430 }
431 
TEST(BalsaHeaders,ReplaceOrAppendHeaderTestReplacing)432 TEST(BalsaHeaders, ReplaceOrAppendHeaderTestReplacing) {
433   BalsaHeaders header;
434   std::string key_1 = "key_1";
435   std::string value_1 = "value_1";
436   std::string key_2 = "key_2";
437   header.ReplaceOrAppendHeader(key_1, value_1);
438   header.ReplaceOrAppendHeader(key_2, value_1);
439   std::string value_2 = "value_2_string";
440   header.ReplaceOrAppendHeader(key_1, value_2);
441 
442   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
443   ASSERT_EQ(key_1, chli->first);
444   ASSERT_EQ(value_2, chli->second);
445   ++chli;
446   ASSERT_EQ(key_2, chli->first);
447   ASSERT_EQ(value_1, chli->second);
448   ++chli;
449   ASSERT_NE(header.lines().begin(), chli);
450   ASSERT_EQ(header.lines().end(), chli);
451 }
452 
TEST(BalsaHeaders,ReplaceOrAppendHeaderTestReplacingMultiple)453 TEST(BalsaHeaders, ReplaceOrAppendHeaderTestReplacingMultiple) {
454   BalsaHeaders header;
455   std::string key_1 = "key_1";
456   std::string key_2 = "key_2";
457   std::string value_1 = "val_1";
458   std::string value_2 = "val_2";
459   std::string value_3 =
460       "value_3_is_longer_than_value_1_and_value_2_and_their_keys";
461   // Set up header keys 1, 1, 2.  We will replace the value of key 1 with a long
462   // enough string that it should be moved to the end.  This regression tests
463   // that replacement works if we move the header to the end.
464   header.AppendHeader(key_1, value_1);
465   header.AppendHeader(key_1, value_2);
466   header.AppendHeader(key_2, value_1);
467   header.ReplaceOrAppendHeader(key_1, value_3);
468 
469   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
470   ASSERT_EQ(key_1, chli->first);
471   ASSERT_EQ(value_3, chli->second);
472   ++chli;
473   ASSERT_EQ(key_2, chli->first);
474   ASSERT_EQ(value_1, chli->second);
475   ++chli;
476   ASSERT_NE(header.lines().begin(), chli);
477   ASSERT_EQ(header.lines().end(), chli);
478 
479   // Now test that replacement works with a shorter value, so that if we ever do
480   // in-place replacement it's tested.
481   header.ReplaceOrAppendHeader(key_1, value_1);
482   chli = header.lines().begin();
483   ASSERT_EQ(key_1, chli->first);
484   ASSERT_EQ(value_1, chli->second);
485   ++chli;
486   ASSERT_EQ(key_2, chli->first);
487   ASSERT_EQ(value_1, chli->second);
488   ++chli;
489   ASSERT_NE(header.lines().begin(), chli);
490   ASSERT_EQ(header.lines().end(), chli);
491 }
492 
TEST(BalsaHeaders,AppendHeaderAndIteratorTest1)493 TEST(BalsaHeaders, AppendHeaderAndIteratorTest1) {
494   BalsaHeaders header;
495   ASSERT_EQ(header.lines().begin(), header.lines().end());
496   {
497     std::string key_1 = "key_1";
498     std::string value_1 = "value_1";
499     header.AppendHeader(key_1, value_1);
500     key_1 = "garbage";
501     value_1 = "garbage";
502   }
503 
504   ASSERT_NE(header.lines().begin(), header.lines().end());
505   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
506   ASSERT_EQ(header.lines().begin(), chli);
507   ASSERT_NE(header.lines().end(), chli);
508   ASSERT_EQ(absl::string_view("key_1"), chli->first);
509   ASSERT_EQ(absl::string_view("value_1"), chli->second);
510 
511   ++chli;
512   ASSERT_NE(header.lines().begin(), chli);
513   ASSERT_EQ(header.lines().end(), chli);
514 }
515 
TEST(BalsaHeaders,AppendHeaderAndIteratorTest2)516 TEST(BalsaHeaders, AppendHeaderAndIteratorTest2) {
517   BalsaHeaders header;
518   ASSERT_EQ(header.lines().begin(), header.lines().end());
519   {
520     std::string key_1 = "key_1";
521     std::string value_1 = "value_1";
522     header.AppendHeader(key_1, value_1);
523     key_1 = "garbage";
524     value_1 = "garbage";
525   }
526   {
527     std::string key_2 = "key_2";
528     std::string value_2 = "value_2";
529     header.AppendHeader(key_2, value_2);
530     key_2 = "garbage";
531     value_2 = "garbage";
532   }
533 
534   ASSERT_NE(header.lines().begin(), header.lines().end());
535   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
536   ASSERT_EQ(header.lines().begin(), chli);
537   ASSERT_NE(header.lines().end(), chli);
538   ASSERT_EQ(absl::string_view("key_1"), chli->first);
539   ASSERT_EQ(absl::string_view("value_1"), chli->second);
540 
541   ++chli;
542   ASSERT_NE(header.lines().begin(), chli);
543   ASSERT_NE(header.lines().end(), chli);
544   ASSERT_EQ(absl::string_view("key_2"), chli->first);
545   ASSERT_EQ(absl::string_view("value_2"), chli->second);
546 
547   ++chli;
548   ASSERT_NE(header.lines().begin(), chli);
549   ASSERT_EQ(header.lines().end(), chli);
550 }
551 
TEST(BalsaHeaders,AppendHeaderAndIteratorTest3)552 TEST(BalsaHeaders, AppendHeaderAndIteratorTest3) {
553   BalsaHeaders header;
554   ASSERT_EQ(header.lines().begin(), header.lines().end());
555   {
556     std::string key_1 = "key_1";
557     std::string value_1 = "value_1";
558     header.AppendHeader(key_1, value_1);
559     key_1 = "garbage";
560     value_1 = "garbage";
561   }
562   {
563     std::string key_2 = "key_2";
564     std::string value_2 = "value_2";
565     header.AppendHeader(key_2, value_2);
566     key_2 = "garbage";
567     value_2 = "garbage";
568   }
569   {
570     std::string key_3 = "key_3";
571     std::string value_3 = "value_3";
572     header.AppendHeader(key_3, value_3);
573     key_3 = "garbage";
574     value_3 = "garbage";
575   }
576 
577   ASSERT_NE(header.lines().begin(), header.lines().end());
578   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
579   ASSERT_EQ(header.lines().begin(), chli);
580   ASSERT_NE(header.lines().end(), chli);
581   ASSERT_EQ(absl::string_view("key_1"), chli->first);
582   ASSERT_EQ(absl::string_view("value_1"), chli->second);
583 
584   ++chli;
585   ASSERT_NE(header.lines().begin(), chli);
586   ASSERT_NE(header.lines().end(), chli);
587   ASSERT_EQ(absl::string_view("key_2"), chli->first);
588   ASSERT_EQ(absl::string_view("value_2"), chli->second);
589 
590   ++chli;
591   ASSERT_NE(header.lines().begin(), chli);
592   ASSERT_NE(header.lines().end(), chli);
593   ASSERT_EQ(absl::string_view("key_3"), chli->first);
594   ASSERT_EQ(absl::string_view("value_3"), chli->second);
595 
596   ++chli;
597   ASSERT_NE(header.lines().begin(), chli);
598   ASSERT_EQ(header.lines().end(), chli);
599 }
600 
TEST(BalsaHeaders,AppendHeaderAndTestEraseWithIterator)601 TEST(BalsaHeaders, AppendHeaderAndTestEraseWithIterator) {
602   BalsaHeaders header;
603   ASSERT_EQ(header.lines().begin(), header.lines().end());
604   {
605     std::string key_1 = "key_1";
606     std::string value_1 = "value_1";
607     header.AppendHeader(key_1, value_1);
608     key_1 = "garbage";
609     value_1 = "garbage";
610   }
611   {
612     std::string key_2 = "key_2";
613     std::string value_2 = "value_2";
614     header.AppendHeader(key_2, value_2);
615     key_2 = "garbage";
616     value_2 = "garbage";
617   }
618   {
619     std::string key_3 = "key_3";
620     std::string value_3 = "value_3";
621     header.AppendHeader(key_3, value_3);
622     key_3 = "garbage";
623     value_3 = "garbage";
624   }
625   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
626   ++chli;  // should now point to key_2.
627   ASSERT_EQ(absl::string_view("key_2"), chli->first);
628   header.erase(chli);
629   chli = header.lines().begin();
630 
631   ASSERT_NE(header.lines().begin(), header.lines().end());
632   ASSERT_EQ(header.lines().begin(), chli);
633   ASSERT_NE(header.lines().end(), chli);
634   ASSERT_EQ(absl::string_view("key_1"), chli->first);
635   ASSERT_EQ(absl::string_view("value_1"), chli->second);
636 
637   ++chli;
638   ASSERT_NE(header.lines().begin(), chli);
639   ASSERT_NE(header.lines().end(), chli);
640   ASSERT_EQ(absl::string_view("key_3"), chli->first);
641   ASSERT_EQ(absl::string_view("value_3"), chli->second);
642 
643   ++chli;
644   ASSERT_NE(header.lines().begin(), chli);
645   ASSERT_EQ(header.lines().end(), chli);
646 }
647 
TEST(BalsaHeaders,TestSetFirstlineInAdditionalBuffer)648 TEST(BalsaHeaders, TestSetFirstlineInAdditionalBuffer) {
649   BalsaHeaders headers;
650   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
651   ASSERT_THAT(headers.first_line(), StrEq("GET / HTTP/1.0"));
652 }
653 
TEST(BalsaHeaders,TestSetFirstlineInOriginalBufferAndIsShorterThanOriginal)654 TEST(BalsaHeaders, TestSetFirstlineInOriginalBufferAndIsShorterThanOriginal) {
655   BalsaHeaders headers = CreateHTTPHeaders(true,
656                                            "GET /foobar HTTP/1.0\r\n"
657                                            "\r\n");
658   ASSERT_THAT(headers.first_line(), StrEq("GET /foobar HTTP/1.0"));
659   // Note that this SetRequestFirstlineFromStringPieces should replace the
660   // original one in the -non- 'additional' buffer.
661   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
662   ASSERT_THAT(headers.first_line(), StrEq("GET / HTTP/1.0"));
663 }
664 
TEST(BalsaHeaders,TestSetFirstlineInOriginalBufferAndIsLongerThanOriginal)665 TEST(BalsaHeaders, TestSetFirstlineInOriginalBufferAndIsLongerThanOriginal) {
666   // Similar to above, but this time the new firstline is larger than
667   // the original, yet it should still fit into the original -non-
668   // 'additional' buffer as the first header-line has been erased.
669   BalsaHeaders headers = CreateHTTPHeaders(true,
670                                            "GET / HTTP/1.0\r\n"
671                                            "some_key: some_value\r\n"
672                                            "another_key: another_value\r\n"
673                                            "\r\n");
674   ASSERT_THAT(headers.first_line(), StrEq("GET / HTTP/1.0"));
675   headers.erase(headers.lines().begin());
676   // Note that this SetRequestFirstlineFromStringPieces should replace the
677   // original one in the -non- 'additional' buffer.
678   headers.SetRequestFirstlineFromStringPieces("GET", "/foobar", "HTTP/1.0");
679   ASSERT_THAT(headers.first_line(), StrEq("GET /foobar HTTP/1.0"));
680 }
681 
TEST(BalsaHeaders,TestSetFirstlineInAdditionalDataAndIsShorterThanOriginal)682 TEST(BalsaHeaders, TestSetFirstlineInAdditionalDataAndIsShorterThanOriginal) {
683   BalsaHeaders headers;
684   headers.SetRequestFirstlineFromStringPieces("GET", "/foobar", "HTTP/1.0");
685   ASSERT_THAT(headers.first_line(), StrEq("GET /foobar HTTP/1.0"));
686   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
687   ASSERT_THAT(headers.first_line(), StrEq("GET / HTTP/1.0"));
688 }
689 
TEST(BalsaHeaders,TestSetFirstlineInAdditionalDataAndIsLongerThanOriginal)690 TEST(BalsaHeaders, TestSetFirstlineInAdditionalDataAndIsLongerThanOriginal) {
691   BalsaHeaders headers;
692   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
693   ASSERT_THAT(headers.first_line(), StrEq("GET / HTTP/1.0"));
694   headers.SetRequestFirstlineFromStringPieces("GET", "/foobar", "HTTP/1.0");
695   ASSERT_THAT(headers.first_line(), StrEq("GET /foobar HTTP/1.0"));
696 }
697 
TEST(BalsaHeaders,TestDeletingSubstring)698 TEST(BalsaHeaders, TestDeletingSubstring) {
699   BalsaHeaders headers;
700   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
701   headers.AppendHeader("key1", "value1");
702   headers.AppendHeader("key2", "value2");
703   headers.AppendHeader("key", "value");
704   headers.AppendHeader("unrelated", "value");
705 
706   // RemoveAllOfHeader should not delete key1 or key2 given a substring.
707   headers.RemoveAllOfHeader("key");
708   EXPECT_TRUE(headers.HasHeader("key1"));
709   EXPECT_TRUE(headers.HasHeader("key2"));
710   EXPECT_TRUE(headers.HasHeader("unrelated"));
711   EXPECT_FALSE(headers.HasHeader("key"));
712   EXPECT_TRUE(headers.HasHeadersWithPrefix("key"));
713   EXPECT_TRUE(headers.HasHeadersWithPrefix("KeY"));
714   EXPECT_TRUE(headers.HasHeadersWithPrefix("UNREL"));
715   EXPECT_FALSE(headers.HasHeadersWithPrefix("key3"));
716 
717   EXPECT_FALSE(headers.GetHeader("key1").empty());
718   EXPECT_FALSE(headers.GetHeader("KEY1").empty());
719   EXPECT_FALSE(headers.GetHeader("key2").empty());
720   EXPECT_FALSE(headers.GetHeader("unrelated").empty());
721   EXPECT_TRUE(headers.GetHeader("key").empty());
722 
723   // Add key back in.
724   headers.AppendHeader("key", "");
725   EXPECT_TRUE(headers.HasHeader("key"));
726   EXPECT_TRUE(headers.HasHeadersWithPrefix("key"));
727   EXPECT_TRUE(headers.GetHeader("key").empty());
728 
729   // RemoveAllHeadersWithPrefix should delete everything starting with key.
730   headers.RemoveAllHeadersWithPrefix("key");
731   EXPECT_FALSE(headers.HasHeader("key1"));
732   EXPECT_FALSE(headers.HasHeader("key2"));
733   EXPECT_TRUE(headers.HasHeader("unrelated"));
734   EXPECT_FALSE(headers.HasHeader("key"));
735   EXPECT_FALSE(headers.HasHeadersWithPrefix("key"));
736   EXPECT_FALSE(headers.HasHeadersWithPrefix("key1"));
737   EXPECT_FALSE(headers.HasHeadersWithPrefix("key2"));
738   EXPECT_FALSE(headers.HasHeadersWithPrefix("kEy"));
739   EXPECT_TRUE(headers.HasHeadersWithPrefix("unrelated"));
740 
741   EXPECT_TRUE(headers.GetHeader("key1").empty());
742   EXPECT_TRUE(headers.GetHeader("key2").empty());
743   EXPECT_FALSE(headers.GetHeader("unrelated").empty());
744   EXPECT_TRUE(headers.GetHeader("key").empty());
745 }
746 
TEST(BalsaHeaders,TestRemovingValues)747 TEST(BalsaHeaders, TestRemovingValues) {
748   // Remove entire line from headers, twice. Ensures working line-skipping.
749   // Skip consideration of a line whose key is larger than our search key.
750   // Skip consideration of a line whose key is smaller than our search key.
751   // Skip consideration of a line that is already marked for skipping.
752   // Skip consideration of a line whose value is too small.
753   // Skip consideration of a line whose key is correct in length but doesn't
754   // match.
755   {
756     BalsaHeaders headers;
757     headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
758     headers.AppendHeader("hi", "hello");
759     headers.AppendHeader("key1", "val1");
760     headers.AppendHeader("key1", "value2");
761     headers.AppendHeader("key1", "value3");
762     headers.AppendHeader("key2", "value4");
763     headers.AppendHeader("unrelated", "value");
764 
765     EXPECT_EQ(0u, headers.RemoveValue("key1", ""));
766     EXPECT_EQ(1u, headers.RemoveValue("key1", "value2"));
767 
768     std::string key1_vals = headers.GetAllOfHeaderAsString("key1");
769     EXPECT_THAT(key1_vals, StrEq("val1,value3"));
770 
771     EXPECT_TRUE(headers.HeaderHasValue("key1", "val1"));
772     EXPECT_TRUE(headers.HeaderHasValue("key1", "value3"));
773     EXPECT_EQ("value4", headers.GetHeader("key2"));
774     EXPECT_EQ("hello", headers.GetHeader("hi"));
775     EXPECT_EQ("value", headers.GetHeader("unrelated"));
776     EXPECT_FALSE(headers.HeaderHasValue("key1", "value2"));
777 
778     EXPECT_EQ(1u, headers.RemoveValue("key1", "value3"));
779 
780     key1_vals = headers.GetAllOfHeaderAsString("key1");
781     EXPECT_THAT(key1_vals, StrEq("val1"));
782 
783     EXPECT_TRUE(headers.HeaderHasValue("key1", "val1"));
784     EXPECT_EQ("value4", headers.GetHeader("key2"));
785     EXPECT_EQ("hello", headers.GetHeader("hi"));
786     EXPECT_EQ("value", headers.GetHeader("unrelated"));
787     EXPECT_FALSE(headers.HeaderHasValue("key1", "value3"));
788     EXPECT_FALSE(headers.HeaderHasValue("key1", "value2"));
789   }
790 
791   // Remove/keep values with surrounding spaces.
792   // Remove values from in between others in multi-value line.
793   // Remove entire multi-value line.
794   // Keep value in between removed values in multi-value line.
795   // Keep trailing value that is too small to be matched after removing a match.
796   // Keep value containing matched value (partial but not complete match).
797   // Keep an empty header.
798   {
799     BalsaHeaders headers;
800     headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
801     headers.AppendHeader("key1", "value1");
802     headers.AppendHeader("key1", "value2, value3,value2");
803     headers.AppendHeader("key1", "value4 ,value2,value5,val6");
804     headers.AppendHeader("key1", "value2,  value2   , value2");
805     headers.AppendHeader("key1", "  value2  ,   value2   ");
806     headers.AppendHeader("key1", " value2 a");
807     headers.AppendHeader("key1", "");
808     headers.AppendHeader("key1", ",  ,,");
809     headers.AppendHeader("unrelated", "value");
810 
811     EXPECT_EQ(8u, headers.RemoveValue("key1", "value2"));
812 
813     std::string key1_vals = headers.GetAllOfHeaderAsString("key1");
814     EXPECT_THAT(key1_vals,
815                 StrEq("value1,value3,value4 ,value5,val6,value2 a,,,  ,,"));
816 
817     EXPECT_EQ("value", headers.GetHeader("unrelated"));
818     EXPECT_TRUE(headers.HeaderHasValue("key1", "value1"));
819     EXPECT_TRUE(headers.HeaderHasValue("key1", "value3"));
820     EXPECT_TRUE(headers.HeaderHasValue("key1", "value4"));
821     EXPECT_TRUE(headers.HeaderHasValue("key1", "value5"));
822     EXPECT_TRUE(headers.HeaderHasValue("key1", "val6"));
823     EXPECT_FALSE(headers.HeaderHasValue("key1", "value2"));
824   }
825 
826   {
827     const absl::string_view key("key");
828     const absl::string_view value1("foo\0bar", 7);
829     const absl::string_view value2("value2");
830     const std::string value = absl::StrCat(value1, ",", value2);
831 
832     {
833       BalsaHeaders headers;
834       headers.AppendHeader(key, value);
835 
836       EXPECT_TRUE(headers.HeaderHasValue(key, value1));
837       EXPECT_TRUE(headers.HeaderHasValue(key, value2));
838       EXPECT_EQ(value, headers.GetAllOfHeaderAsString(key));
839 
840       EXPECT_EQ(1u, headers.RemoveValue(key, value2));
841 
842       EXPECT_TRUE(headers.HeaderHasValue(key, value1));
843       EXPECT_FALSE(headers.HeaderHasValue(key, value2));
844       EXPECT_EQ(value1, headers.GetAllOfHeaderAsString(key));
845     }
846 
847     {
848       BalsaHeaders headers;
849       headers.AppendHeader(key, value1);
850       headers.AppendHeader(key, value2);
851 
852       EXPECT_TRUE(headers.HeaderHasValue(key, value1));
853       EXPECT_TRUE(headers.HeaderHasValue(key, value2));
854       EXPECT_EQ(value, headers.GetAllOfHeaderAsString(key));
855 
856       EXPECT_EQ(1u, headers.RemoveValue(key, value2));
857 
858       EXPECT_TRUE(headers.HeaderHasValue(key, value1));
859       EXPECT_FALSE(headers.HeaderHasValue(key, value2));
860       EXPECT_EQ(value1, headers.GetAllOfHeaderAsString(key));
861     }
862   }
863 }
864 
TEST(BalsaHeaders,ZeroAppendToHeaderWithCommaAndSpace)865 TEST(BalsaHeaders, ZeroAppendToHeaderWithCommaAndSpace) {
866   // Create an initial header with zero 'X-Forwarded-For' headers.
867   BalsaHeaders headers = CreateHTTPHeaders(true,
868                                            "GET / HTTP/1.0\r\n"
869                                            "\r\n");
870 
871   // Use AppendToHeaderWithCommaAndSpace to add 4 new 'X-Forwarded-For' headers.
872   // Appending these headers should preserve the order in which they are added.
873   // i.e. 1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4
874   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "1.1.1.1");
875   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "2.2.2.2");
876   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "3.3.3.3");
877   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "4.4.4.4");
878 
879   // Fetch the 'X-Forwarded-For' headers and compare them to the expected order.
880   EXPECT_THAT(headers.GetAllOfHeader("X-Forwarded-For"),
881               ElementsAre("1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4"));
882 }
883 
TEST(BalsaHeaders,SingleAppendToHeaderWithCommaAndSpace)884 TEST(BalsaHeaders, SingleAppendToHeaderWithCommaAndSpace) {
885   // Create an initial header with one 'X-Forwarded-For' header.
886   BalsaHeaders headers = CreateHTTPHeaders(true,
887                                            "GET / HTTP/1.0\r\n"
888                                            "X-Forwarded-For: 1.1.1.1\r\n"
889                                            "\r\n");
890 
891   // Use AppendToHeaderWithCommaAndSpace to add 4 new 'X-Forwarded-For' headers.
892   // Appending these headers should preserve the order in which they are added.
893   // i.e. 1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4, 5.5.5.5
894   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "2.2.2.2");
895   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "3.3.3.3");
896   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "4.4.4.4");
897   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "5.5.5.5");
898 
899   // Fetch the 'X-Forwarded-For' headers and compare them to the expected order.
900   EXPECT_THAT(headers.GetAllOfHeader("X-Forwarded-For"),
901               ElementsAre("1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4, 5.5.5.5"));
902 }
903 
TEST(BalsaHeaders,MultipleAppendToHeaderWithCommaAndSpace)904 TEST(BalsaHeaders, MultipleAppendToHeaderWithCommaAndSpace) {
905   // Create an initial header with two 'X-Forwarded-For' headers.
906   BalsaHeaders headers = CreateHTTPHeaders(true,
907                                            "GET / HTTP/1.0\r\n"
908                                            "X-Forwarded-For: 1.1.1.1\r\n"
909                                            "X-Forwarded-For: 2.2.2.2\r\n"
910                                            "\r\n");
911 
912   // Use AppendToHeaderWithCommaAndSpace to add 4 new 'X-Forwarded-For' headers.
913   // Appending these headers should preserve the order in which they are added.
914   // i.e. 1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4, 5.5.5.5, 6.6.6.6
915   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "3.3.3.3");
916   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "4.4.4.4");
917   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "5.5.5.5");
918   headers.AppendToHeaderWithCommaAndSpace("X-Forwarded-For", "6.6.6.6");
919 
920   // Fetch the 'X-Forwarded-For' headers and compare them to the expected order.
921   EXPECT_THAT(
922       headers.GetAllOfHeader("X-Forwarded-For"),
923       ElementsAre("1.1.1.1", "2.2.2.2, 3.3.3.3, 4.4.4.4, 5.5.5.5, 6.6.6.6"));
924 }
925 
TEST(BalsaHeaders,HeaderHasValues)926 TEST(BalsaHeaders, HeaderHasValues) {
927   BalsaHeaders headers;
928   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
929   // Make sure we find values at the beginning, middle, and end, and we handle
930   // multiple .find() calls correctly.
931   headers.AppendHeader("key", "val1,val2val2,val2,val3");
932   // Make sure we don't mess up comma/boundary checks for beginning, middle and
933   // end.
934   headers.AppendHeader("key", "val4val5val6");
935   headers.AppendHeader("key", "val11 val12");
936   headers.AppendHeader("key", "v val13");
937   // Make sure we catch the line header
938   headers.AppendHeader("key", "val7");
939   // Make sure there's no out-of-bounds indexing on an empty line.
940   headers.AppendHeader("key", "");
941   // Make sure it works when there's spaces before or after a comma.
942   headers.AppendHeader("key", "val8 , val9 , val10");
943   // Make sure it works when val is surrounded by spaces.
944   headers.AppendHeader("key", " val14 ");
945   // Make sure other keys aren't used.
946   headers.AppendHeader("key2", "val15");
947   // Mixed case.
948   headers.AppendHeader("key", "Val16");
949   headers.AppendHeader("key", "foo, Val17, bar");
950 
951   // All case-sensitive.
952   EXPECT_TRUE(headers.HeaderHasValue("key", "val1"));
953   EXPECT_TRUE(headers.HeaderHasValue("key", "val2"));
954   EXPECT_TRUE(headers.HeaderHasValue("key", "val3"));
955   EXPECT_TRUE(headers.HeaderHasValue("key", "val7"));
956   EXPECT_TRUE(headers.HeaderHasValue("key", "val8"));
957   EXPECT_TRUE(headers.HeaderHasValue("key", "val9"));
958   EXPECT_TRUE(headers.HeaderHasValue("key", "val10"));
959   EXPECT_TRUE(headers.HeaderHasValue("key", "val14"));
960   EXPECT_FALSE(headers.HeaderHasValue("key", "val4"));
961   EXPECT_FALSE(headers.HeaderHasValue("key", "val5"));
962   EXPECT_FALSE(headers.HeaderHasValue("key", "val6"));
963   EXPECT_FALSE(headers.HeaderHasValue("key", "val11"));
964   EXPECT_FALSE(headers.HeaderHasValue("key", "val12"));
965   EXPECT_FALSE(headers.HeaderHasValue("key", "val13"));
966   EXPECT_FALSE(headers.HeaderHasValue("key", "val15"));
967   EXPECT_FALSE(headers.HeaderHasValue("key", "val16"));
968   EXPECT_FALSE(headers.HeaderHasValue("key", "val17"));
969 
970   // All case-insensitive, only change is for val16 and val17.
971   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val1"));
972   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val2"));
973   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val3"));
974   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val7"));
975   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val8"));
976   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val9"));
977   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val10"));
978   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val14"));
979   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val4"));
980   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val5"));
981   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val6"));
982   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val11"));
983   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val12"));
984   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val13"));
985   EXPECT_FALSE(headers.HeaderHasValueIgnoreCase("key", "val15"));
986   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val16"));
987   EXPECT_TRUE(headers.HeaderHasValueIgnoreCase("key", "val17"));
988 }
989 
990 // Because we're dealing with one giant buffer, make sure we don't go beyond
991 // the bounds of the key when doing compares!
TEST(BalsaHeaders,TestNotDeletingBeyondString)992 TEST(BalsaHeaders, TestNotDeletingBeyondString) {
993   BalsaHeaders headers;
994   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
995   headers.AppendHeader("key1", "value1");
996 
997   headers.RemoveAllHeadersWithPrefix("key1: value1");
998   EXPECT_NE(headers.lines().begin(), headers.lines().end());
999 }
1000 
TEST(BalsaHeaders,TestIteratingOverErasedHeaders)1001 TEST(BalsaHeaders, TestIteratingOverErasedHeaders) {
1002   BalsaHeaders headers;
1003   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
1004   headers.AppendHeader("key1", "value1");
1005   headers.AppendHeader("key2", "value2");
1006   headers.AppendHeader("key3", "value3");
1007   headers.AppendHeader("key4", "value4");
1008   headers.AppendHeader("key5", "value5");
1009   headers.AppendHeader("key6", "value6");
1010 
1011   headers.RemoveAllOfHeader("key6");
1012   headers.RemoveAllOfHeader("key5");
1013   headers.RemoveAllOfHeader("key4");
1014 
1015   BalsaHeaders::const_header_lines_iterator chli = headers.lines().begin();
1016   EXPECT_NE(headers.lines().end(), chli);
1017   EXPECT_EQ(headers.lines().begin(), chli);
1018   EXPECT_THAT(chli->first, StrEq("key1"));
1019   EXPECT_THAT(chli->second, StrEq("value1"));
1020 
1021   ++chli;
1022   EXPECT_NE(headers.lines().end(), chli);
1023   EXPECT_NE(headers.lines().begin(), chli);
1024   EXPECT_THAT(chli->first, StrEq("key2"));
1025   EXPECT_THAT(chli->second, StrEq("value2"));
1026 
1027   ++chli;
1028   EXPECT_NE(headers.lines().end(), chli);
1029   EXPECT_NE(headers.lines().begin(), chli);
1030   EXPECT_THAT(chli->first, StrEq("key3"));
1031   EXPECT_THAT(chli->second, StrEq("value3"));
1032 
1033   ++chli;
1034   EXPECT_EQ(headers.lines().end(), chli);
1035   EXPECT_NE(headers.lines().begin(), chli);
1036 
1037   headers.RemoveAllOfHeader("key1");
1038   headers.RemoveAllOfHeader("key2");
1039   chli = headers.lines().begin();
1040   EXPECT_THAT(chli->first, StrEq("key3"));
1041   EXPECT_THAT(chli->second, StrEq("value3"));
1042   EXPECT_NE(headers.lines().end(), chli);
1043   EXPECT_EQ(headers.lines().begin(), chli);
1044 
1045   ++chli;
1046   EXPECT_EQ(headers.lines().end(), chli);
1047   EXPECT_NE(headers.lines().begin(), chli);
1048 }
1049 
TEST(BalsaHeaders,CanCompareIterators)1050 TEST(BalsaHeaders, CanCompareIterators) {
1051   BalsaHeaders header;
1052   ASSERT_EQ(header.lines().begin(), header.lines().end());
1053   {
1054     std::string key_1 = "key_1";
1055     std::string value_1 = "value_1";
1056     header.AppendHeader(key_1, value_1);
1057     key_1 = "garbage";
1058     value_1 = "garbage";
1059   }
1060   {
1061     std::string key_2 = "key_2";
1062     std::string value_2 = "value_2";
1063     header.AppendHeader(key_2, value_2);
1064     key_2 = "garbage";
1065     value_2 = "garbage";
1066   }
1067   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
1068   BalsaHeaders::const_header_lines_iterator chlj = header.lines().begin();
1069   EXPECT_EQ(chli, chlj);
1070   ++chlj;
1071   EXPECT_NE(chli, chlj);
1072   EXPECT_LT(chli, chlj);
1073   EXPECT_LE(chli, chlj);
1074   EXPECT_LE(chli, chli);
1075   EXPECT_GT(chlj, chli);
1076   EXPECT_GE(chlj, chli);
1077   EXPECT_GE(chlj, chlj);
1078 }
1079 
TEST(BalsaHeaders,AppendHeaderAndTestThatYouCanEraseEverything)1080 TEST(BalsaHeaders, AppendHeaderAndTestThatYouCanEraseEverything) {
1081   BalsaHeaders header;
1082   ASSERT_EQ(header.lines().begin(), header.lines().end());
1083   {
1084     std::string key_1 = "key_1";
1085     std::string value_1 = "value_1";
1086     header.AppendHeader(key_1, value_1);
1087     key_1 = "garbage";
1088     value_1 = "garbage";
1089   }
1090   {
1091     std::string key_2 = "key_2";
1092     std::string value_2 = "value_2";
1093     header.AppendHeader(key_2, value_2);
1094     key_2 = "garbage";
1095     value_2 = "garbage";
1096   }
1097   {
1098     std::string key_3 = "key_3";
1099     std::string value_3 = "value_3";
1100     header.AppendHeader(key_3, value_3);
1101     key_3 = "garbage";
1102     value_3 = "garbage";
1103   }
1104   EXPECT_NE(header.lines().begin(), header.lines().end());
1105   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
1106   while (chli != header.lines().end()) {
1107     header.erase(chli);
1108     chli = header.lines().begin();
1109   }
1110   ASSERT_EQ(header.lines().begin(), header.lines().end());
1111 }
1112 
TEST(BalsaHeaders,GetHeaderPositionWorksAsExpectedWithNoHeaderLines)1113 TEST(BalsaHeaders, GetHeaderPositionWorksAsExpectedWithNoHeaderLines) {
1114   BalsaHeaders header;
1115   BalsaHeaders::const_header_lines_iterator i = header.GetHeaderPosition("foo");
1116   EXPECT_EQ(i, header.lines().end());
1117 }
1118 
TEST(BalsaHeaders,GetHeaderPositionWorksAsExpectedWithBalsaFrameProcessInput)1119 TEST(BalsaHeaders, GetHeaderPositionWorksAsExpectedWithBalsaFrameProcessInput) {
1120   BalsaHeaders headers = CreateHTTPHeaders(
1121       true,
1122       "GET / HTTP/1.0\r\n"
1123       "key1: value_1\r\n"
1124       "key1: value_foo\r\n"  // this one cannot be fetched via GetHeader
1125       "key2: value_2\r\n"
1126       "key3: value_3\r\n"
1127       "a: value_a\r\n"
1128       "b: value_b\r\n"
1129       "\r\n");
1130 
1131   BalsaHeaders::const_header_lines_iterator header_position_b =
1132       headers.GetHeaderPosition("b");
1133   ASSERT_NE(header_position_b, headers.lines().end());
1134   absl::string_view header_key_b_value = header_position_b->second;
1135   ASSERT_FALSE(header_key_b_value.empty());
1136   EXPECT_EQ(std::string("value_b"), header_key_b_value);
1137 
1138   BalsaHeaders::const_header_lines_iterator header_position_1 =
1139       headers.GetHeaderPosition("key1");
1140   ASSERT_NE(header_position_1, headers.lines().end());
1141   absl::string_view header_key_1_value = header_position_1->second;
1142   ASSERT_FALSE(header_key_1_value.empty());
1143   EXPECT_EQ(std::string("value_1"), header_key_1_value);
1144 
1145   BalsaHeaders::const_header_lines_iterator header_position_3 =
1146       headers.GetHeaderPosition("key3");
1147   ASSERT_NE(header_position_3, headers.lines().end());
1148   absl::string_view header_key_3_value = header_position_3->second;
1149   ASSERT_FALSE(header_key_3_value.empty());
1150   EXPECT_EQ(std::string("value_3"), header_key_3_value);
1151 
1152   BalsaHeaders::const_header_lines_iterator header_position_2 =
1153       headers.GetHeaderPosition("key2");
1154   ASSERT_NE(header_position_2, headers.lines().end());
1155   absl::string_view header_key_2_value = header_position_2->second;
1156   ASSERT_FALSE(header_key_2_value.empty());
1157   EXPECT_EQ(std::string("value_2"), header_key_2_value);
1158 
1159   BalsaHeaders::const_header_lines_iterator header_position_a =
1160       headers.GetHeaderPosition("a");
1161   ASSERT_NE(header_position_a, headers.lines().end());
1162   absl::string_view header_key_a_value = header_position_a->second;
1163   ASSERT_FALSE(header_key_a_value.empty());
1164   EXPECT_EQ(std::string("value_a"), header_key_a_value);
1165 }
1166 
TEST(BalsaHeaders,GetHeaderWorksAsExpectedWithNoHeaderLines)1167 TEST(BalsaHeaders, GetHeaderWorksAsExpectedWithNoHeaderLines) {
1168   BalsaHeaders header;
1169   absl::string_view value = header.GetHeader("foo");
1170   EXPECT_TRUE(value.empty());
1171   value = header.GetHeader("");
1172   EXPECT_TRUE(value.empty());
1173 }
1174 
TEST(BalsaHeaders,HasHeaderWorksAsExpectedWithNoHeaderLines)1175 TEST(BalsaHeaders, HasHeaderWorksAsExpectedWithNoHeaderLines) {
1176   BalsaHeaders header;
1177   EXPECT_FALSE(header.HasHeader("foo"));
1178   EXPECT_FALSE(header.HasHeader(""));
1179   EXPECT_FALSE(header.HasHeadersWithPrefix("foo"));
1180   EXPECT_FALSE(header.HasHeadersWithPrefix(""));
1181 }
1182 
TEST(BalsaHeaders,HasHeaderWorksAsExpectedWithBalsaFrameProcessInput)1183 TEST(BalsaHeaders, HasHeaderWorksAsExpectedWithBalsaFrameProcessInput) {
1184   BalsaHeaders headers = CreateHTTPHeaders(true,
1185                                            "GET / HTTP/1.0\r\n"
1186                                            "key1: value_1\r\n"
1187                                            "key1: value_foo\r\n"
1188                                            "key2:\r\n"
1189                                            "\r\n");
1190 
1191   EXPECT_FALSE(headers.HasHeader("foo"));
1192   EXPECT_TRUE(headers.HasHeader("key1"));
1193   EXPECT_TRUE(headers.HasHeader("key2"));
1194   EXPECT_FALSE(headers.HasHeadersWithPrefix("foo"));
1195   EXPECT_TRUE(headers.HasHeadersWithPrefix("key"));
1196   EXPECT_TRUE(headers.HasHeadersWithPrefix("KEY"));
1197 }
1198 
TEST(BalsaHeaders,GetHeaderWorksAsExpectedWithBalsaFrameProcessInput)1199 TEST(BalsaHeaders, GetHeaderWorksAsExpectedWithBalsaFrameProcessInput) {
1200   BalsaHeaders headers = CreateHTTPHeaders(
1201       true,
1202       "GET / HTTP/1.0\r\n"
1203       "key1: value_1\r\n"
1204       "key1: value_foo\r\n"  // this one cannot be fetched via GetHeader
1205       "key2: value_2\r\n"
1206       "key3: value_3\r\n"
1207       "key4:\r\n"
1208       "a: value_a\r\n"
1209       "b: value_b\r\n"
1210       "\r\n");
1211 
1212   absl::string_view header_key_b_value = headers.GetHeader("b");
1213   ASSERT_FALSE(header_key_b_value.empty());
1214   EXPECT_EQ(std::string("value_b"), header_key_b_value);
1215 
1216   absl::string_view header_key_1_value = headers.GetHeader("key1");
1217   ASSERT_FALSE(header_key_1_value.empty());
1218   EXPECT_EQ(std::string("value_1"), header_key_1_value);
1219 
1220   absl::string_view header_key_3_value = headers.GetHeader("key3");
1221   ASSERT_FALSE(header_key_3_value.empty());
1222   EXPECT_EQ(std::string("value_3"), header_key_3_value);
1223 
1224   absl::string_view header_key_2_value = headers.GetHeader("key2");
1225   ASSERT_FALSE(header_key_2_value.empty());
1226   EXPECT_EQ(std::string("value_2"), header_key_2_value);
1227 
1228   absl::string_view header_key_a_value = headers.GetHeader("a");
1229   ASSERT_FALSE(header_key_a_value.empty());
1230   EXPECT_EQ(std::string("value_a"), header_key_a_value);
1231 
1232   EXPECT_TRUE(headers.GetHeader("key4").empty());
1233 }
1234 
TEST(BalsaHeaders,GetHeaderWorksAsExpectedWithAppendHeader)1235 TEST(BalsaHeaders, GetHeaderWorksAsExpectedWithAppendHeader) {
1236   BalsaHeaders header;
1237 
1238   header.AppendHeader("key1", "value_1");
1239   // note that this (following) one cannot be found using GetHeader.
1240   header.AppendHeader("key1", "value_2");
1241   header.AppendHeader("key2", "value_2");
1242   header.AppendHeader("key3", "value_3");
1243   header.AppendHeader("a", "value_a");
1244   header.AppendHeader("b", "value_b");
1245 
1246   absl::string_view header_key_b_value = header.GetHeader("b");
1247   absl::string_view header_key_1_value = header.GetHeader("key1");
1248   absl::string_view header_key_3_value = header.GetHeader("key3");
1249   absl::string_view header_key_2_value = header.GetHeader("key2");
1250   absl::string_view header_key_a_value = header.GetHeader("a");
1251 
1252   ASSERT_FALSE(header_key_1_value.empty());
1253   ASSERT_FALSE(header_key_2_value.empty());
1254   ASSERT_FALSE(header_key_3_value.empty());
1255   ASSERT_FALSE(header_key_a_value.empty());
1256   ASSERT_FALSE(header_key_b_value.empty());
1257 
1258   EXPECT_TRUE(header.HasHeader("key1"));
1259   EXPECT_TRUE(header.HasHeader("key2"));
1260   EXPECT_TRUE(header.HasHeader("key3"));
1261   EXPECT_TRUE(header.HasHeader("a"));
1262   EXPECT_TRUE(header.HasHeader("b"));
1263 
1264   EXPECT_TRUE(header.HasHeadersWithPrefix("key1"));
1265   EXPECT_TRUE(header.HasHeadersWithPrefix("key2"));
1266   EXPECT_TRUE(header.HasHeadersWithPrefix("key3"));
1267   EXPECT_TRUE(header.HasHeadersWithPrefix("a"));
1268   EXPECT_TRUE(header.HasHeadersWithPrefix("b"));
1269 
1270   EXPECT_EQ(std::string("value_1"), header_key_1_value);
1271   EXPECT_EQ(std::string("value_2"), header_key_2_value);
1272   EXPECT_EQ(std::string("value_3"), header_key_3_value);
1273   EXPECT_EQ(std::string("value_a"), header_key_a_value);
1274   EXPECT_EQ(std::string("value_b"), header_key_b_value);
1275 }
1276 
TEST(BalsaHeaders,HasHeaderWorksAsExpectedWithAppendHeader)1277 TEST(BalsaHeaders, HasHeaderWorksAsExpectedWithAppendHeader) {
1278   BalsaHeaders header;
1279 
1280   ASSERT_FALSE(header.HasHeader("key1"));
1281   EXPECT_FALSE(header.HasHeadersWithPrefix("K"));
1282   EXPECT_FALSE(header.HasHeadersWithPrefix("ke"));
1283   EXPECT_FALSE(header.HasHeadersWithPrefix("key"));
1284   EXPECT_FALSE(header.HasHeadersWithPrefix("key1"));
1285   EXPECT_FALSE(header.HasHeadersWithPrefix("key2"));
1286   header.AppendHeader("key1", "value_1");
1287   EXPECT_TRUE(header.HasHeader("key1"));
1288   EXPECT_TRUE(header.HasHeadersWithPrefix("K"));
1289   EXPECT_TRUE(header.HasHeadersWithPrefix("ke"));
1290   EXPECT_TRUE(header.HasHeadersWithPrefix("key"));
1291   EXPECT_TRUE(header.HasHeadersWithPrefix("key1"));
1292   EXPECT_FALSE(header.HasHeadersWithPrefix("key2"));
1293 
1294   header.AppendHeader("key1", "value_2");
1295   EXPECT_TRUE(header.HasHeader("key1"));
1296   EXPECT_FALSE(header.HasHeader("key2"));
1297   EXPECT_TRUE(header.HasHeadersWithPrefix("k"));
1298   EXPECT_TRUE(header.HasHeadersWithPrefix("ke"));
1299   EXPECT_TRUE(header.HasHeadersWithPrefix("key"));
1300   EXPECT_TRUE(header.HasHeadersWithPrefix("key1"));
1301   EXPECT_FALSE(header.HasHeadersWithPrefix("key2"));
1302 }
1303 
TEST(BalsaHeaders,GetHeaderWorksAsExpectedWithHeadersErased)1304 TEST(BalsaHeaders, GetHeaderWorksAsExpectedWithHeadersErased) {
1305   BalsaHeaders header;
1306   header.AppendHeader("key1", "value_1");
1307   header.AppendHeader("key1", "value_2");
1308   header.AppendHeader("key2", "value_2");
1309   header.AppendHeader("key3", "value_3");
1310   header.AppendHeader("a", "value_a");
1311   header.AppendHeader("b", "value_b");
1312 
1313   header.erase(header.GetHeaderPosition("key2"));
1314 
1315   absl::string_view header_key_b_value = header.GetHeader("b");
1316   absl::string_view header_key_1_value = header.GetHeader("key1");
1317   absl::string_view header_key_3_value = header.GetHeader("key3");
1318   absl::string_view header_key_2_value = header.GetHeader("key2");
1319   absl::string_view header_key_a_value = header.GetHeader("a");
1320 
1321   ASSERT_FALSE(header_key_1_value.empty());
1322   ASSERT_TRUE(header_key_2_value.empty());
1323   ASSERT_FALSE(header_key_3_value.empty());
1324   ASSERT_FALSE(header_key_a_value.empty());
1325   ASSERT_FALSE(header_key_b_value.empty());
1326 
1327   EXPECT_EQ(std::string("value_1"), header_key_1_value);
1328   EXPECT_EQ(std::string("value_3"), header_key_3_value);
1329   EXPECT_EQ(std::string("value_a"), header_key_a_value);
1330   EXPECT_EQ(std::string("value_b"), header_key_b_value);
1331 
1332   // Erasing one makes the next one visible:
1333   header.erase(header.GetHeaderPosition("key1"));
1334   header_key_1_value = header.GetHeader("key1");
1335   ASSERT_FALSE(header_key_1_value.empty());
1336   EXPECT_EQ(std::string("value_2"), header_key_1_value);
1337 
1338   // Erase both:
1339   header.erase(header.GetHeaderPosition("key1"));
1340   ASSERT_TRUE(header.GetHeader("key1").empty());
1341 }
1342 
TEST(BalsaHeaders,HasHeaderWorksAsExpectedWithHeadersErased)1343 TEST(BalsaHeaders, HasHeaderWorksAsExpectedWithHeadersErased) {
1344   BalsaHeaders header;
1345   header.AppendHeader("key1", "value_1");
1346   header.AppendHeader("key2", "value_2a");
1347   header.AppendHeader("key2", "value_2b");
1348 
1349   ASSERT_TRUE(header.HasHeader("key1"));
1350   ASSERT_TRUE(header.HasHeadersWithPrefix("key1"));
1351   ASSERT_TRUE(header.HasHeadersWithPrefix("key2"));
1352   ASSERT_TRUE(header.HasHeadersWithPrefix("kEY"));
1353   header.erase(header.GetHeaderPosition("key1"));
1354   EXPECT_FALSE(header.HasHeader("key1"));
1355   EXPECT_FALSE(header.HasHeadersWithPrefix("key1"));
1356   EXPECT_TRUE(header.HasHeadersWithPrefix("key2"));
1357   EXPECT_TRUE(header.HasHeadersWithPrefix("kEY"));
1358 
1359   ASSERT_TRUE(header.HasHeader("key2"));
1360   header.erase(header.GetHeaderPosition("key2"));
1361   ASSERT_TRUE(header.HasHeader("key2"));
1362   EXPECT_FALSE(header.HasHeadersWithPrefix("key1"));
1363   EXPECT_TRUE(header.HasHeadersWithPrefix("key2"));
1364   EXPECT_TRUE(header.HasHeadersWithPrefix("kEY"));
1365   header.erase(header.GetHeaderPosition("key2"));
1366   EXPECT_FALSE(header.HasHeader("key2"));
1367   EXPECT_FALSE(header.HasHeadersWithPrefix("key1"));
1368   EXPECT_FALSE(header.HasHeadersWithPrefix("key2"));
1369   EXPECT_FALSE(header.HasHeadersWithPrefix("kEY"));
1370 }
1371 
TEST(BalsaHeaders,HasNonEmptyHeaderWorksAsExpectedWithNoHeaderLines)1372 TEST(BalsaHeaders, HasNonEmptyHeaderWorksAsExpectedWithNoHeaderLines) {
1373   BalsaHeaders header;
1374   EXPECT_FALSE(header.HasNonEmptyHeader("foo"));
1375   EXPECT_FALSE(header.HasNonEmptyHeader(""));
1376 }
1377 
TEST(BalsaHeaders,HasNonEmptyHeaderWorksAsExpectedWithAppendHeader)1378 TEST(BalsaHeaders, HasNonEmptyHeaderWorksAsExpectedWithAppendHeader) {
1379   BalsaHeaders header;
1380 
1381   EXPECT_FALSE(header.HasNonEmptyHeader("key1"));
1382   header.AppendHeader("key1", "");
1383   EXPECT_FALSE(header.HasNonEmptyHeader("key1"));
1384 
1385   header.AppendHeader("key1", "value_2");
1386   EXPECT_TRUE(header.HasNonEmptyHeader("key1"));
1387   EXPECT_FALSE(header.HasNonEmptyHeader("key2"));
1388 }
1389 
TEST(BalsaHeaders,HasNonEmptyHeaderWorksAsExpectedWithHeadersErased)1390 TEST(BalsaHeaders, HasNonEmptyHeaderWorksAsExpectedWithHeadersErased) {
1391   BalsaHeaders header;
1392   header.AppendHeader("key1", "value_1");
1393   header.AppendHeader("key2", "value_2a");
1394   header.AppendHeader("key2", "");
1395 
1396   EXPECT_TRUE(header.HasNonEmptyHeader("key1"));
1397   header.erase(header.GetHeaderPosition("key1"));
1398   EXPECT_FALSE(header.HasNonEmptyHeader("key1"));
1399 
1400   EXPECT_TRUE(header.HasNonEmptyHeader("key2"));
1401   header.erase(header.GetHeaderPosition("key2"));
1402   EXPECT_FALSE(header.HasNonEmptyHeader("key2"));
1403   header.erase(header.GetHeaderPosition("key2"));
1404   EXPECT_FALSE(header.HasNonEmptyHeader("key2"));
1405 }
1406 
TEST(BalsaHeaders,HasNonEmptyHeaderWorksAsExpectedWithBalsaFrameProcessInput)1407 TEST(BalsaHeaders, HasNonEmptyHeaderWorksAsExpectedWithBalsaFrameProcessInput) {
1408   BalsaHeaders headers = CreateHTTPHeaders(true,
1409                                            "GET / HTTP/1.0\r\n"
1410                                            "key1: value_1\r\n"
1411                                            "key2:\r\n"
1412                                            "key3:\r\n"
1413                                            "key3: value_3\r\n"
1414                                            "key4:\r\n"
1415                                            "key4:\r\n"
1416                                            "key5: value_5\r\n"
1417                                            "key5:\r\n"
1418                                            "\r\n");
1419 
1420   EXPECT_FALSE(headers.HasNonEmptyHeader("foo"));
1421   EXPECT_TRUE(headers.HasNonEmptyHeader("key1"));
1422   EXPECT_FALSE(headers.HasNonEmptyHeader("key2"));
1423   EXPECT_TRUE(headers.HasNonEmptyHeader("key3"));
1424   EXPECT_FALSE(headers.HasNonEmptyHeader("key4"));
1425   EXPECT_TRUE(headers.HasNonEmptyHeader("key5"));
1426 
1427   headers.erase(headers.GetHeaderPosition("key5"));
1428   EXPECT_FALSE(headers.HasNonEmptyHeader("key5"));
1429 }
1430 
TEST(BalsaHeaders,GetAllOfHeader)1431 TEST(BalsaHeaders, GetAllOfHeader) {
1432   BalsaHeaders header;
1433   header.AppendHeader("key", "value_1");
1434   header.AppendHeader("Key", "value_2,value_3");
1435   header.AppendHeader("key", "");
1436   header.AppendHeader("KEY", "value_4");
1437 
1438   std::vector<absl::string_view> result;
1439   header.GetAllOfHeader("key", &result);
1440   ASSERT_EQ(4u, result.size());
1441   EXPECT_EQ("value_1", result[0]);
1442   EXPECT_EQ("value_2,value_3", result[1]);
1443   EXPECT_EQ("", result[2]);
1444   EXPECT_EQ("value_4", result[3]);
1445 
1446   EXPECT_EQ(header.GetAllOfHeader("key"), result);
1447 }
1448 
TEST(BalsaHeaders,GetAllOfHeaderDoesWhatItSays)1449 TEST(BalsaHeaders, GetAllOfHeaderDoesWhatItSays) {
1450   BalsaHeaders header;
1451   // Multiple values for a given header.
1452   // Some values appear multiple times
1453   header.AppendHeader("key", "value_1");
1454   header.AppendHeader("key", "value_2");
1455   header.AppendHeader("key", "");
1456   header.AppendHeader("key", "value_1");
1457 
1458   ASSERT_NE(header.lines().begin(), header.lines().end());
1459   std::vector<absl::string_view> out;
1460 
1461   header.GetAllOfHeader("key", &out);
1462   ASSERT_EQ(4u, out.size());
1463   EXPECT_EQ("value_1", out[0]);
1464   EXPECT_EQ("value_2", out[1]);
1465   EXPECT_EQ("", out[2]);
1466   EXPECT_EQ("value_1", out[3]);
1467 
1468   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1469 }
1470 
TEST(BalsaHeaders,GetAllOfHeaderWithPrefix)1471 TEST(BalsaHeaders, GetAllOfHeaderWithPrefix) {
1472   BalsaHeaders header;
1473   header.AppendHeader("foo-Foo", "value_1");
1474   header.AppendHeader("Foo-bar", "value_2,value_3");
1475   header.AppendHeader("foo-Foo", "");
1476   header.AppendHeader("bar", "value_not");
1477   header.AppendHeader("fOO-fOO", "value_4");
1478 
1479   std::vector<std::pair<absl::string_view, absl::string_view>> result;
1480   header.GetAllOfHeaderWithPrefix("abc", &result);
1481   ASSERT_EQ(0u, result.size());
1482 
1483   header.GetAllOfHeaderWithPrefix("foo", &result);
1484   ASSERT_EQ(4u, result.size());
1485   EXPECT_EQ("foo-Foo", result[0].first);
1486   EXPECT_EQ("value_1", result[0].second);
1487   EXPECT_EQ("Foo-bar", result[1].first);
1488   EXPECT_EQ("value_2,value_3", result[1].second);
1489   EXPECT_EQ("", result[2].second);
1490   EXPECT_EQ("value_4", result[3].second);
1491 
1492   std::vector<std::pair<absl::string_view, absl::string_view>> result2;
1493   header.GetAllOfHeaderWithPrefix("FoO", &result2);
1494   ASSERT_EQ(4u, result2.size());
1495 }
1496 
TEST(BalsaHeaders,GetAllHeadersWithLimit)1497 TEST(BalsaHeaders, GetAllHeadersWithLimit) {
1498   BalsaHeaders header;
1499   header.AppendHeader("foo-Foo", "value_1");
1500   header.AppendHeader("Foo-bar", "value_2,value_3");
1501   header.AppendHeader("foo-Foo", "");
1502   header.AppendHeader("bar", "value_4");
1503   header.AppendHeader("fOO-fOO", "value_5");
1504 
1505   std::vector<std::pair<absl::string_view, absl::string_view>> result;
1506   header.GetAllHeadersWithLimit(&result, 4);
1507   ASSERT_EQ(4u, result.size());
1508   EXPECT_EQ("foo-Foo", result[0].first);
1509   EXPECT_EQ("value_1", result[0].second);
1510   EXPECT_EQ("Foo-bar", result[1].first);
1511   EXPECT_EQ("value_2,value_3", result[1].second);
1512   EXPECT_EQ("", result[2].second);
1513   EXPECT_EQ("value_4", result[3].second);
1514 
1515   std::vector<std::pair<absl::string_view, absl::string_view>> result2;
1516   header.GetAllHeadersWithLimit(&result2, -1);
1517   ASSERT_EQ(5u, result2.size());
1518 }
1519 
TEST(BalsaHeaders,RangeFor)1520 TEST(BalsaHeaders, RangeFor) {
1521   BalsaHeaders header;
1522   // Multiple values for a given header.
1523   // Some values appear multiple times
1524   header.AppendHeader("key1", "value_1a");
1525   header.AppendHeader("key1", "value_1b");
1526   header.AppendHeader("key2", "");
1527   header.AppendHeader("key3", "value_3");
1528 
1529   std::vector<std::pair<absl::string_view, absl::string_view>> out;
1530   for (const auto& line : header.lines()) {
1531     out.push_back(line);
1532   }
1533   const std::vector<std::pair<absl::string_view, absl::string_view>> expected =
1534       {{"key1", "value_1a"},
1535        {"key1", "value_1b"},
1536        {"key2", ""},
1537        {"key3", "value_3"}};
1538   EXPECT_EQ(expected, out);
1539 }
1540 
TEST(BalsaHeaders,GetAllOfHeaderWithNonExistentKey)1541 TEST(BalsaHeaders, GetAllOfHeaderWithNonExistentKey) {
1542   BalsaHeaders header;
1543   header.AppendHeader("key", "value_1");
1544   header.AppendHeader("key", "value_2");
1545   std::vector<absl::string_view> out;
1546 
1547   header.GetAllOfHeader("key_non_existent", &out);
1548   ASSERT_EQ(0u, out.size());
1549 
1550   EXPECT_EQ(header.GetAllOfHeader("key_non_existent"), out);
1551 }
1552 
TEST(BalsaHeaders,GetAllOfHeaderEmptyValVariation1)1553 TEST(BalsaHeaders, GetAllOfHeaderEmptyValVariation1) {
1554   BalsaHeaders header;
1555   header.AppendHeader("key", "");
1556   header.AppendHeader("key", "");
1557   header.AppendHeader("key", "v1");
1558   std::vector<absl::string_view> out;
1559   header.GetAllOfHeader("key", &out);
1560   ASSERT_EQ(3u, out.size());
1561   EXPECT_EQ("", out[0]);
1562   EXPECT_EQ("", out[1]);
1563   EXPECT_EQ("v1", out[2]);
1564 
1565   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1566 }
1567 
TEST(BalsaHeaders,GetAllOfHeaderEmptyValVariation2)1568 TEST(BalsaHeaders, GetAllOfHeaderEmptyValVariation2) {
1569   BalsaHeaders header;
1570   header.AppendHeader("key", "");
1571   header.AppendHeader("key", "v1");
1572   header.AppendHeader("key", "");
1573   std::vector<absl::string_view> out;
1574   header.GetAllOfHeader("key", &out);
1575   ASSERT_EQ(3u, out.size());
1576   EXPECT_EQ("", out[0]);
1577   EXPECT_EQ("v1", out[1]);
1578   EXPECT_EQ("", out[2]);
1579 
1580   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1581 }
1582 
TEST(BalsaHeaders,GetAllOfHeaderEmptyValVariation3)1583 TEST(BalsaHeaders, GetAllOfHeaderEmptyValVariation3) {
1584   BalsaHeaders header;
1585   header.AppendHeader("key", "");
1586   header.AppendHeader("key", "v1");
1587   std::vector<absl::string_view> out;
1588   header.GetAllOfHeader("key", &out);
1589   ASSERT_EQ(2u, out.size());
1590   EXPECT_EQ("", out[0]);
1591   EXPECT_EQ("v1", out[1]);
1592 
1593   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1594 }
1595 
TEST(BalsaHeaders,GetAllOfHeaderEmptyValVariation4)1596 TEST(BalsaHeaders, GetAllOfHeaderEmptyValVariation4) {
1597   BalsaHeaders header;
1598   header.AppendHeader("key", "v1");
1599   header.AppendHeader("key", "");
1600   std::vector<absl::string_view> out;
1601   header.GetAllOfHeader("key", &out);
1602   ASSERT_EQ(2u, out.size());
1603   EXPECT_EQ("v1", out[0]);
1604   EXPECT_EQ("", out[1]);
1605 
1606   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1607 }
1608 
TEST(BalsaHeaders,GetAllOfHeaderWithAppendHeaders)1609 TEST(BalsaHeaders, GetAllOfHeaderWithAppendHeaders) {
1610   BalsaHeaders header;
1611   header.AppendHeader("key", "value_1");
1612   header.AppendHeader("key", "value_2");
1613   std::vector<absl::string_view> out;
1614 
1615   header.GetAllOfHeader("key_new", &out);
1616   ASSERT_EQ(0u, out.size());
1617   EXPECT_EQ(header.GetAllOfHeader("key_new"), out);
1618 
1619   // Add key_new to the header
1620   header.AppendHeader("key_new", "value_3");
1621   header.GetAllOfHeader("key_new", &out);
1622   ASSERT_EQ(1u, out.size());
1623   EXPECT_EQ("value_3", out[0]);
1624   EXPECT_EQ(header.GetAllOfHeader("key_new"), out);
1625 
1626   // Get the keys that are not modified
1627   header.GetAllOfHeader("key", &out);
1628   ASSERT_EQ(3u, out.size());
1629   EXPECT_EQ("value_1", out[1]);
1630   EXPECT_EQ("value_2", out[2]);
1631   EXPECT_THAT(header.GetAllOfHeader("key"), ElementsAre("value_1", "value_2"));
1632 }
1633 
TEST(BalsaHeaders,GetAllOfHeaderWithRemoveHeaders)1634 TEST(BalsaHeaders, GetAllOfHeaderWithRemoveHeaders) {
1635   BalsaHeaders header;
1636   header.AppendHeader("key", "value_1");
1637   header.AppendHeader("key", "value_2");
1638   header.AppendHeader("a", "va");
1639 
1640   header.RemoveAllOfHeader("key");
1641   std::vector<absl::string_view> out;
1642   header.GetAllOfHeader("key", &out);
1643   ASSERT_EQ(0u, out.size());
1644   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1645 
1646   header.GetAllOfHeader("a", &out);
1647   ASSERT_EQ(1u, out.size());
1648   EXPECT_EQ(header.GetAllOfHeader("a"), out);
1649 
1650   out.clear();
1651   header.RemoveAllOfHeader("a");
1652   header.GetAllOfHeader("a", &out);
1653   ASSERT_EQ(0u, out.size());
1654   EXPECT_EQ(header.GetAllOfHeader("a"), out);
1655 }
1656 
TEST(BalsaHeaders,GetAllOfHeaderWithRemoveNonExistentHeaders)1657 TEST(BalsaHeaders, GetAllOfHeaderWithRemoveNonExistentHeaders) {
1658   BalsaHeaders headers;
1659   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
1660   headers.AppendHeader("Accept-Encoding", "deflate,compress");
1661   EXPECT_EQ(0u, headers.RemoveValue("Accept-Encoding", "gzip(gfe)"));
1662   std::string accept_encoding_vals =
1663       headers.GetAllOfHeaderAsString("Accept-Encoding");
1664   EXPECT_EQ("deflate,compress", accept_encoding_vals);
1665 }
1666 
TEST(BalsaHeaders,GetAllOfHeaderWithEraseHeaders)1667 TEST(BalsaHeaders, GetAllOfHeaderWithEraseHeaders) {
1668   BalsaHeaders header;
1669   header.AppendHeader("key", "value_1");
1670   header.AppendHeader("key", "value_2");
1671   header.AppendHeader("a", "va");
1672 
1673   std::vector<absl::string_view> out;
1674 
1675   header.erase(header.GetHeaderPosition("key"));
1676   header.GetAllOfHeader("key", &out);
1677   ASSERT_EQ(1u, out.size());
1678   EXPECT_EQ("value_2", out[0]);
1679   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1680 
1681   out.clear();
1682   header.erase(header.GetHeaderPosition("key"));
1683   header.GetAllOfHeader("key", &out);
1684   ASSERT_EQ(0u, out.size());
1685   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1686 
1687   out.clear();
1688   header.GetAllOfHeader("a", &out);
1689   ASSERT_EQ(1u, out.size());
1690   EXPECT_EQ(header.GetAllOfHeader("a"), out);
1691 
1692   out.clear();
1693   header.erase(header.GetHeaderPosition("a"));
1694   header.GetAllOfHeader("a", &out);
1695   ASSERT_EQ(0u, out.size());
1696   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1697 }
1698 
TEST(BalsaHeaders,GetAllOfHeaderWithNoHeaderLines)1699 TEST(BalsaHeaders, GetAllOfHeaderWithNoHeaderLines) {
1700   BalsaHeaders header;
1701   std::vector<absl::string_view> out;
1702   header.GetAllOfHeader("key", &out);
1703   EXPECT_EQ(0u, out.size());
1704   EXPECT_EQ(header.GetAllOfHeader("key"), out);
1705 }
1706 
TEST(BalsaHeaders,GetAllOfHeaderDoesWhatItSaysForVariousKeys)1707 TEST(BalsaHeaders, GetAllOfHeaderDoesWhatItSaysForVariousKeys) {
1708   BalsaHeaders header;
1709   header.AppendHeader("key1", "value_11");
1710   header.AppendHeader("key2", "value_21");
1711   header.AppendHeader("key1", "value_12");
1712   header.AppendHeader("key2", "value_22");
1713 
1714   std::vector<absl::string_view> out;
1715 
1716   header.GetAllOfHeader("key1", &out);
1717   EXPECT_EQ("value_11", out[0]);
1718   EXPECT_EQ("value_12", out[1]);
1719   EXPECT_EQ(header.GetAllOfHeader("key1"), out);
1720 
1721   header.GetAllOfHeader("key2", &out);
1722   EXPECT_EQ("value_21", out[2]);
1723   EXPECT_EQ("value_22", out[3]);
1724   EXPECT_THAT(header.GetAllOfHeader("key2"),
1725               ElementsAre("value_21", "value_22"));
1726 }
1727 
TEST(BalsaHeaders,GetAllOfHeaderWithBalsaFrameProcessInput)1728 TEST(BalsaHeaders, GetAllOfHeaderWithBalsaFrameProcessInput) {
1729   BalsaHeaders header = CreateHTTPHeaders(true,
1730                                           "GET / HTTP/1.0\r\n"
1731                                           "key1: value_1\r\n"
1732                                           "key1: value_foo\r\n"
1733                                           "key2: value_2\r\n"
1734                                           "a: value_a\r\n"
1735                                           "key2: \r\n"
1736                                           "b: value_b\r\n"
1737                                           "\r\n");
1738 
1739   std::vector<absl::string_view> out;
1740   int index = 0;
1741   header.GetAllOfHeader("key1", &out);
1742   EXPECT_EQ("value_1", out[index++]);
1743   EXPECT_EQ("value_foo", out[index++]);
1744   EXPECT_EQ(header.GetAllOfHeader("key1"), out);
1745 
1746   header.GetAllOfHeader("key2", &out);
1747   EXPECT_EQ("value_2", out[index++]);
1748   EXPECT_EQ("", out[index++]);
1749   EXPECT_THAT(header.GetAllOfHeader("key2"), ElementsAre("value_2", ""));
1750 
1751   header.GetAllOfHeader("a", &out);
1752   EXPECT_EQ("value_a", out[index++]);
1753   EXPECT_THAT(header.GetAllOfHeader("a"), ElementsAre("value_a"));
1754 
1755   header.GetAllOfHeader("b", &out);
1756   EXPECT_EQ("value_b", out[index++]);
1757   EXPECT_THAT(header.GetAllOfHeader("b"), ElementsAre("value_b"));
1758 }
1759 
TEST(BalsaHeaders,GetAllOfHeaderIncludeRemovedDoesWhatItSays)1760 TEST(BalsaHeaders, GetAllOfHeaderIncludeRemovedDoesWhatItSays) {
1761   BalsaHeaders header;
1762   header.AppendHeader("key1", "value_11");
1763   header.AppendHeader("key2", "value_21");
1764   header.AppendHeader("key1", "value_12");
1765   header.AppendHeader("key2", "value_22");
1766   header.AppendHeader("key1", "");
1767 
1768   std::vector<absl::string_view> out;
1769   header.GetAllOfHeaderIncludeRemoved("key1", &out);
1770   ASSERT_EQ(3u, out.size());
1771   EXPECT_EQ("value_11", out[0]);
1772   EXPECT_EQ("value_12", out[1]);
1773   EXPECT_EQ("", out[2]);
1774   header.GetAllOfHeaderIncludeRemoved("key2", &out);
1775   ASSERT_EQ(5u, out.size());
1776   EXPECT_EQ("value_21", out[3]);
1777   EXPECT_EQ("value_22", out[4]);
1778 
1779   header.erase(header.GetHeaderPosition("key1"));
1780   out.clear();
1781   header.GetAllOfHeaderIncludeRemoved("key1", &out);
1782   ASSERT_EQ(3u, out.size());
1783   EXPECT_EQ("value_12", out[0]);
1784   EXPECT_EQ("", out[1]);
1785   EXPECT_EQ("value_11", out[2]);
1786   header.GetAllOfHeaderIncludeRemoved("key2", &out);
1787   ASSERT_EQ(5u, out.size());
1788   EXPECT_EQ("value_21", out[3]);
1789   EXPECT_EQ("value_22", out[4]);
1790 
1791   header.RemoveAllOfHeader("key1");
1792   out.clear();
1793   header.GetAllOfHeaderIncludeRemoved("key1", &out);
1794   ASSERT_EQ(3u, out.size());
1795   EXPECT_EQ("value_11", out[0]);
1796   EXPECT_EQ("value_12", out[1]);
1797   EXPECT_EQ("", out[2]);
1798   header.GetAllOfHeaderIncludeRemoved("key2", &out);
1799   ASSERT_EQ(5u, out.size());
1800   EXPECT_EQ("value_21", out[3]);
1801   EXPECT_EQ("value_22", out[4]);
1802 
1803   header.Clear();
1804   out.clear();
1805   header.GetAllOfHeaderIncludeRemoved("key1", &out);
1806   ASSERT_EQ(0u, out.size());
1807   header.GetAllOfHeaderIncludeRemoved("key2", &out);
1808   ASSERT_EQ(0u, out.size());
1809 }
1810 
TEST(BalsaHeaders,GetAllOfHeaderIncludeRemovedWithNonExistentKey)1811 TEST(BalsaHeaders, GetAllOfHeaderIncludeRemovedWithNonExistentKey) {
1812   BalsaHeaders header;
1813   header.AppendHeader("key", "value_1");
1814   header.AppendHeader("key", "value_2");
1815   std::vector<absl::string_view> out;
1816   header.GetAllOfHeaderIncludeRemoved("key_non_existent", &out);
1817   ASSERT_EQ(0u, out.size());
1818 }
1819 
TEST(BalsaHeaders,GetIteratorForKeyDoesWhatItSays)1820 TEST(BalsaHeaders, GetIteratorForKeyDoesWhatItSays) {
1821   BalsaHeaders header;
1822   // Multiple values for a given header.
1823   // Some values appear multiple times
1824   header.AppendHeader("key", "value_1");
1825   header.AppendHeader("Key", "value_2");
1826   header.AppendHeader("key", "");
1827   header.AppendHeader("KEY", "value_1");
1828 
1829   BalsaHeaders::const_header_lines_key_iterator key_it =
1830       header.GetIteratorForKey("key");
1831   EXPECT_NE(header.lines().end(), key_it);
1832   EXPECT_NE(header.header_lines_key_end(), key_it);
1833   EXPECT_EQ("key", key_it->first);
1834   EXPECT_EQ("value_1", key_it->second);
1835   ++key_it;
1836   EXPECT_NE(header.lines().end(), key_it);
1837   EXPECT_NE(header.header_lines_key_end(), key_it);
1838   EXPECT_EQ("Key", key_it->first);
1839   EXPECT_EQ("value_2", key_it->second);
1840   ++key_it;
1841   EXPECT_NE(header.lines().end(), key_it);
1842   EXPECT_NE(header.header_lines_key_end(), key_it);
1843   EXPECT_EQ("key", key_it->first);
1844   EXPECT_EQ("", key_it->second);
1845   ++key_it;
1846   EXPECT_NE(header.lines().end(), key_it);
1847   EXPECT_NE(header.header_lines_key_end(), key_it);
1848   EXPECT_EQ("KEY", key_it->first);
1849   EXPECT_EQ("value_1", key_it->second);
1850   ++key_it;
1851   EXPECT_EQ(header.lines().end(), key_it);
1852   EXPECT_EQ(header.header_lines_key_end(), key_it);
1853 }
1854 
TEST(BalsaHeaders,GetIteratorForKeyWithNonExistentKey)1855 TEST(BalsaHeaders, GetIteratorForKeyWithNonExistentKey) {
1856   BalsaHeaders header;
1857   header.AppendHeader("key", "value_1");
1858   header.AppendHeader("key", "value_2");
1859 
1860   BalsaHeaders::const_header_lines_key_iterator key_it =
1861       header.GetIteratorForKey("key_non_existent");
1862   EXPECT_EQ(header.lines().end(), key_it);
1863   EXPECT_EQ(header.header_lines_key_end(), key_it);
1864   const auto lines = header.lines("key_non_existent");
1865   EXPECT_EQ(lines.begin(), header.lines().end());
1866   EXPECT_EQ(lines.end(), header.header_lines_key_end());
1867 }
1868 
TEST(BalsaHeaders,GetIteratorForKeyWithAppendHeaders)1869 TEST(BalsaHeaders, GetIteratorForKeyWithAppendHeaders) {
1870   BalsaHeaders header;
1871   header.AppendHeader("key", "value_1");
1872   header.AppendHeader("key", "value_2");
1873 
1874   BalsaHeaders::const_header_lines_key_iterator key_it =
1875       header.GetIteratorForKey("key_new");
1876   EXPECT_EQ(header.lines().end(), key_it);
1877   EXPECT_EQ(header.header_lines_key_end(), key_it);
1878 
1879   // Add key_new to the header
1880   header.AppendHeader("key_new", "value_3");
1881   key_it = header.GetIteratorForKey("key_new");
1882   const auto lines1 = header.lines("key_new");
1883   EXPECT_EQ(lines1.begin(), key_it);
1884   EXPECT_EQ(lines1.end(), header.header_lines_key_end());
1885 
1886   EXPECT_NE(header.lines().end(), key_it);
1887   EXPECT_NE(header.header_lines_key_end(), key_it);
1888   EXPECT_EQ("key_new", key_it->first);
1889   EXPECT_EQ("value_3", key_it->second);
1890   ++key_it;
1891   EXPECT_EQ(header.lines().end(), key_it);
1892   EXPECT_EQ(header.header_lines_key_end(), key_it);
1893 
1894   // Get the keys that are not modified
1895   key_it = header.GetIteratorForKey("key");
1896   const auto lines2 = header.lines("key");
1897   EXPECT_EQ(lines2.begin(), key_it);
1898   EXPECT_EQ(lines2.end(), header.header_lines_key_end());
1899   EXPECT_NE(header.lines().end(), key_it);
1900   EXPECT_NE(header.header_lines_key_end(), key_it);
1901   EXPECT_EQ("key", key_it->first);
1902   EXPECT_EQ("value_1", key_it->second);
1903   ++key_it;
1904   EXPECT_NE(header.lines().end(), key_it);
1905   EXPECT_NE(header.header_lines_key_end(), key_it);
1906   EXPECT_EQ("key", key_it->first);
1907   EXPECT_EQ("value_2", key_it->second);
1908   ++key_it;
1909   EXPECT_EQ(header.lines().end(), key_it);
1910   EXPECT_EQ(header.header_lines_key_end(), key_it);
1911 }
1912 
TEST(BalsaHeaders,GetIteratorForKeyWithRemoveHeaders)1913 TEST(BalsaHeaders, GetIteratorForKeyWithRemoveHeaders) {
1914   BalsaHeaders header;
1915   header.AppendHeader("key", "value_1");
1916   header.AppendHeader("key", "value_2");
1917   header.AppendHeader("a", "va");
1918 
1919   header.RemoveAllOfHeader("a");
1920   BalsaHeaders::const_header_lines_key_iterator key_it =
1921       header.GetIteratorForKey("key");
1922   EXPECT_NE(header.lines().end(), key_it);
1923   const auto lines1 = header.lines("key");
1924   EXPECT_EQ(lines1.begin(), key_it);
1925   EXPECT_EQ(lines1.end(), header.header_lines_key_end());
1926   EXPECT_EQ("value_1", key_it->second);
1927   ++key_it;
1928   EXPECT_NE(header.lines().end(), key_it);
1929   EXPECT_NE(header.header_lines_key_end(), key_it);
1930   EXPECT_EQ("key", key_it->first);
1931   EXPECT_EQ("value_2", key_it->second);
1932   ++key_it;
1933   EXPECT_EQ(header.lines().end(), key_it);
1934   EXPECT_EQ(header.header_lines_key_end(), key_it);
1935 
1936   // Check that a typical loop works properly.
1937   for (BalsaHeaders::const_header_lines_key_iterator it =
1938            header.GetIteratorForKey("key");
1939        it != header.lines().end(); ++it) {
1940     EXPECT_EQ("key", it->first);
1941   }
1942 }
1943 
TEST(BalsaHeaders,GetIteratorForKeyWithEraseHeaders)1944 TEST(BalsaHeaders, GetIteratorForKeyWithEraseHeaders) {
1945   BalsaHeaders header;
1946   header.AppendHeader("key", "value_1");
1947   header.AppendHeader("key", "value_2");
1948   header.AppendHeader("a", "va");
1949   header.erase(header.GetHeaderPosition("key"));
1950 
1951   BalsaHeaders::const_header_lines_key_iterator key_it =
1952       header.GetIteratorForKey("key");
1953   EXPECT_NE(header.lines().end(), key_it);
1954   const auto lines1 = header.lines("key");
1955   EXPECT_EQ(lines1.begin(), key_it);
1956   EXPECT_EQ(lines1.end(), header.header_lines_key_end());
1957   EXPECT_NE(header.header_lines_key_end(), key_it);
1958   EXPECT_EQ("key", key_it->first);
1959   EXPECT_EQ("value_2", key_it->second);
1960   ++key_it;
1961   EXPECT_EQ(header.lines().end(), key_it);
1962   EXPECT_EQ(header.header_lines_key_end(), key_it);
1963 
1964   header.erase(header.GetHeaderPosition("key"));
1965   key_it = header.GetIteratorForKey("key");
1966   const auto lines2 = header.lines("key");
1967   EXPECT_EQ(lines2.begin(), key_it);
1968   EXPECT_EQ(lines2.end(), header.header_lines_key_end());
1969   EXPECT_EQ(header.lines().end(), key_it);
1970   EXPECT_EQ(header.header_lines_key_end(), key_it);
1971 
1972   key_it = header.GetIteratorForKey("a");
1973   const auto lines3 = header.lines("a");
1974   EXPECT_EQ(lines3.begin(), key_it);
1975   EXPECT_EQ(lines3.end(), header.header_lines_key_end());
1976   EXPECT_NE(header.lines().end(), key_it);
1977   EXPECT_NE(header.header_lines_key_end(), key_it);
1978   EXPECT_EQ("a", key_it->first);
1979   EXPECT_EQ("va", key_it->second);
1980   ++key_it;
1981   EXPECT_EQ(header.lines().end(), key_it);
1982   EXPECT_EQ(header.header_lines_key_end(), key_it);
1983 
1984   header.erase(header.GetHeaderPosition("a"));
1985   key_it = header.GetIteratorForKey("a");
1986   const auto lines4 = header.lines("a");
1987   EXPECT_EQ(lines4.begin(), key_it);
1988   EXPECT_EQ(lines4.end(), header.header_lines_key_end());
1989   EXPECT_EQ(header.lines().end(), key_it);
1990   EXPECT_EQ(header.header_lines_key_end(), key_it);
1991 }
1992 
TEST(BalsaHeaders,GetIteratorForKeyWithNoHeaderLines)1993 TEST(BalsaHeaders, GetIteratorForKeyWithNoHeaderLines) {
1994   BalsaHeaders header;
1995   BalsaHeaders::const_header_lines_key_iterator key_it =
1996       header.GetIteratorForKey("key");
1997   const auto lines = header.lines("key");
1998   EXPECT_EQ(lines.begin(), key_it);
1999   EXPECT_EQ(lines.end(), header.header_lines_key_end());
2000   EXPECT_EQ(header.lines().end(), key_it);
2001   EXPECT_EQ(header.header_lines_key_end(), key_it);
2002 }
2003 
TEST(BalsaHeaders,GetIteratorForKeyWithBalsaFrameProcessInput)2004 TEST(BalsaHeaders, GetIteratorForKeyWithBalsaFrameProcessInput) {
2005   BalsaHeaders header = CreateHTTPHeaders(true,
2006                                           "GET / HTTP/1.0\r\n"
2007                                           "key1: value_1\r\n"
2008                                           "Key1: value_foo\r\n"
2009                                           "key2: value_2\r\n"
2010                                           "a: value_a\r\n"
2011                                           "key2: \r\n"
2012                                           "b: value_b\r\n"
2013                                           "\r\n");
2014 
2015   BalsaHeaders::const_header_lines_key_iterator key_it =
2016       header.GetIteratorForKey("Key1");
2017   const auto lines1 = header.lines("Key1");
2018   EXPECT_EQ(lines1.begin(), key_it);
2019   EXPECT_EQ(lines1.end(), header.header_lines_key_end());
2020   EXPECT_NE(header.lines().end(), key_it);
2021   EXPECT_NE(header.header_lines_key_end(), key_it);
2022   EXPECT_EQ("key1", key_it->first);
2023   EXPECT_EQ("value_1", key_it->second);
2024   ++key_it;
2025   EXPECT_NE(header.lines().end(), key_it);
2026   EXPECT_NE(header.header_lines_key_end(), key_it);
2027   EXPECT_EQ("Key1", key_it->first);
2028   EXPECT_EQ("value_foo", key_it->second);
2029   ++key_it;
2030   EXPECT_EQ(header.lines().end(), key_it);
2031   EXPECT_EQ(header.header_lines_key_end(), key_it);
2032 
2033   key_it = header.GetIteratorForKey("key2");
2034   EXPECT_NE(header.lines().end(), key_it);
2035   const auto lines2 = header.lines("key2");
2036   EXPECT_EQ(lines2.begin(), key_it);
2037   EXPECT_EQ(lines2.end(), header.header_lines_key_end());
2038   EXPECT_NE(header.header_lines_key_end(), key_it);
2039   EXPECT_EQ("key2", key_it->first);
2040   EXPECT_EQ("value_2", key_it->second);
2041   ++key_it;
2042   EXPECT_NE(header.lines().end(), key_it);
2043   EXPECT_NE(header.header_lines_key_end(), key_it);
2044   EXPECT_EQ("key2", key_it->first);
2045   EXPECT_EQ("", key_it->second);
2046   ++key_it;
2047   EXPECT_EQ(header.lines().end(), key_it);
2048   EXPECT_EQ(header.header_lines_key_end(), key_it);
2049 
2050   key_it = header.GetIteratorForKey("a");
2051   EXPECT_NE(header.lines().end(), key_it);
2052   const auto lines3 = header.lines("a");
2053   EXPECT_EQ(lines3.begin(), key_it);
2054   EXPECT_EQ(lines3.end(), header.header_lines_key_end());
2055   EXPECT_NE(header.header_lines_key_end(), key_it);
2056   EXPECT_EQ("a", key_it->first);
2057   EXPECT_EQ("value_a", key_it->second);
2058   ++key_it;
2059   EXPECT_EQ(header.lines().end(), key_it);
2060   EXPECT_EQ(header.header_lines_key_end(), key_it);
2061 
2062   key_it = header.GetIteratorForKey("b");
2063   EXPECT_NE(header.lines().end(), key_it);
2064   const auto lines4 = header.lines("b");
2065   EXPECT_EQ(lines4.begin(), key_it);
2066   EXPECT_EQ(lines4.end(), header.header_lines_key_end());
2067   EXPECT_NE(header.header_lines_key_end(), key_it);
2068   EXPECT_EQ("b", key_it->first);
2069   EXPECT_EQ("value_b", key_it->second);
2070   ++key_it;
2071   EXPECT_EQ(header.lines().end(), key_it);
2072   EXPECT_EQ(header.header_lines_key_end(), key_it);
2073 }
2074 
TEST(BalsaHeaders,GetAllOfHeaderAsStringDoesWhatItSays)2075 TEST(BalsaHeaders, GetAllOfHeaderAsStringDoesWhatItSays) {
2076   BalsaHeaders header;
2077   // Multiple values for a given header.
2078   // Some values appear multiple times
2079   header.AppendHeader("key", "value_1");
2080   header.AppendHeader("Key", "value_2");
2081   header.AppendHeader("key", "");
2082   header.AppendHeader("KEY", "value_1");
2083 
2084   std::string result = header.GetAllOfHeaderAsString("key");
2085   EXPECT_EQ("value_1,value_2,,value_1", result);
2086 }
2087 
TEST(BalsaHeaders,RemoveAllOfHeaderDoesWhatItSays)2088 TEST(BalsaHeaders, RemoveAllOfHeaderDoesWhatItSays) {
2089   BalsaHeaders header;
2090   header.AppendHeader("key", "value_1");
2091   header.AppendHeader("key", "value_2");
2092   ASSERT_NE(header.lines().begin(), header.lines().end());
2093   header.RemoveAllOfHeader("key");
2094   ASSERT_EQ(header.lines().begin(), header.lines().end());
2095 }
2096 
TEST(BalsaHeaders,RemoveAllOfHeaderDoesWhatItSaysEvenWhenThingsHaveBeenErased)2097 TEST(BalsaHeaders,
2098      RemoveAllOfHeaderDoesWhatItSaysEvenWhenThingsHaveBeenErased) {
2099   BalsaHeaders header;
2100   header.AppendHeader("key1", "value_1");
2101   header.AppendHeader("key1", "value_2");
2102   header.AppendHeader("key2", "value_3");
2103   header.AppendHeader("key1", "value_4");
2104   header.AppendHeader("key2", "value_5");
2105   header.AppendHeader("key1", "value_6");
2106   ASSERT_NE(header.lines().begin(), header.lines().end());
2107 
2108   BalsaHeaders::const_header_lines_iterator chli = header.lines().begin();
2109   ++chli;
2110   ++chli;
2111   ++chli;
2112   header.erase(chli);
2113 
2114   chli = header.lines().begin();
2115   ++chli;
2116   header.erase(chli);
2117 
2118   header.RemoveAllOfHeader("key1");
2119   for (const auto& line : header.lines()) {
2120     EXPECT_NE(std::string("key1"), line.first);
2121   }
2122 }
2123 
TEST(BalsaHeaders,RemoveAllOfHeaderDoesNothingWhenNoKeyOfThatNameExists)2124 TEST(BalsaHeaders, RemoveAllOfHeaderDoesNothingWhenNoKeyOfThatNameExists) {
2125   BalsaHeaders header;
2126   header.AppendHeader("key", "value_1");
2127   header.AppendHeader("key", "value_2");
2128   ASSERT_NE(header.lines().begin(), header.lines().end());
2129   header.RemoveAllOfHeader("foo");
2130   int num_found = 0;
2131   for (const auto& line : header.lines()) {
2132     ++num_found;
2133     EXPECT_EQ(absl::string_view("key"), line.first);
2134   }
2135   EXPECT_EQ(2, num_found);
2136   EXPECT_NE(header.lines().begin(), header.lines().end());
2137 }
2138 
TEST(BalsaHeaders,WriteHeaderEndingToBuffer)2139 TEST(BalsaHeaders, WriteHeaderEndingToBuffer) {
2140   BalsaHeaders header;
2141   SimpleBuffer simple_buffer;
2142   header.WriteHeaderEndingToBuffer(&simple_buffer);
2143   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq("\r\n"));
2144 }
2145 
TEST(BalsaHeaders,WriteToBufferDoesntCrashWithUninitializedHeader)2146 TEST(BalsaHeaders, WriteToBufferDoesntCrashWithUninitializedHeader) {
2147   BalsaHeaders header;
2148   SimpleBuffer simple_buffer;
2149   header.WriteHeaderAndEndingToBuffer(&simple_buffer);
2150 }
2151 
TEST(BalsaHeaders,WriteToBufferWorksWithBalsaHeadersParsedByFramer)2152 TEST(BalsaHeaders, WriteToBufferWorksWithBalsaHeadersParsedByFramer) {
2153   std::string input =
2154       "GET / HTTP/1.0\r\n"
2155       "key_with_value: value\r\n"
2156       "key_with_continuation_value: \r\n"
2157       " with continuation\r\n"
2158       "key_with_two_continuation_value: \r\n"
2159       " continuation 1\r\n"
2160       " continuation 2\r\n"
2161       "a: foo    \r\n"
2162       "b-s:\n"
2163       " bar\t\n"
2164       "foo: \r\n"
2165       "bazzzzzzzleriffic!: snaps\n"
2166       "\n";
2167   std::string expected =
2168       "GET / HTTP/1.0\r\n"
2169       "key_with_value: value\r\n"
2170       "key_with_continuation_value: with continuation\r\n"
2171       "key_with_two_continuation_value: continuation 1\r\n"
2172       " continuation 2\r\n"
2173       "a: foo\r\n"
2174       "b-s: bar\r\n"
2175       "foo: \r\n"
2176       "bazzzzzzzleriffic!: snaps\r\n"
2177       "\r\n";
2178 
2179   BalsaHeaders headers = CreateHTTPHeaders(true, input);
2180   SimpleBuffer simple_buffer;
2181   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2182   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
2183   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2184   EXPECT_EQ(expected_write_buffer_size,
2185             static_cast<size_t>(simple_buffer.ReadableBytes()));
2186 }
2187 
TEST(BalsaHeaders,WriteToBufferWorksWithBalsaHeadersParsedByFramerTabContinuations)2188 TEST(BalsaHeaders,
2189      WriteToBufferWorksWithBalsaHeadersParsedByFramerTabContinuations) {
2190   std::string input =
2191       "GET / HTTP/1.0\r\n"
2192       "key_with_value: value\r\n"
2193       "key_with_continuation_value: \r\n"
2194       "\twith continuation\r\n"
2195       "key_with_two_continuation_value: \r\n"
2196       "\tcontinuation 1\r\n"
2197       "\tcontinuation 2\r\n"
2198       "a: foo    \r\n"
2199       "b-s:\n"
2200       "\tbar\t\n"
2201       "foo: \r\n"
2202       "bazzzzzzzleriffic!: snaps\n"
2203       "\n";
2204   std::string expected =
2205       "GET / HTTP/1.0\r\n"
2206       "key_with_value: value\r\n"
2207       "key_with_continuation_value: with continuation\r\n"
2208       "key_with_two_continuation_value: continuation 1\r\n"
2209       "\tcontinuation 2\r\n"
2210       "a: foo\r\n"
2211       "b-s: bar\r\n"
2212       "foo: \r\n"
2213       "bazzzzzzzleriffic!: snaps\r\n"
2214       "\r\n";
2215 
2216   BalsaHeaders headers = CreateHTTPHeaders(true, input);
2217   SimpleBuffer simple_buffer;
2218   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2219   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
2220   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2221   EXPECT_EQ(expected_write_buffer_size,
2222             static_cast<size_t>(simple_buffer.ReadableBytes()));
2223 }
2224 
TEST(BalsaHeaders,WriteToBufferWorksWhenFirstlineSetThroughHeaders)2225 TEST(BalsaHeaders, WriteToBufferWorksWhenFirstlineSetThroughHeaders) {
2226   BalsaHeaders headers;
2227   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
2228   std::string expected =
2229       "GET / HTTP/1.0\r\n"
2230       "\r\n";
2231   SimpleBuffer simple_buffer;
2232   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2233   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
2234   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2235   EXPECT_EQ(expected_write_buffer_size,
2236             static_cast<size_t>(simple_buffer.ReadableBytes()));
2237 }
2238 
TEST(BalsaHeaders,WriteToBufferWorksWhenSetThroughHeaders)2239 TEST(BalsaHeaders, WriteToBufferWorksWhenSetThroughHeaders) {
2240   BalsaHeaders headers;
2241   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
2242   headers.AppendHeader("key1", "value1");
2243   headers.AppendHeader("key 2", "value\n 2");
2244   headers.AppendHeader("key\n 3", "value3");
2245   std::string expected =
2246       "GET / HTTP/1.0\r\n"
2247       "key1: value1\r\n"
2248       "key 2: value\n"
2249       " 2\r\n"
2250       "key\n"
2251       " 3: value3\r\n"
2252       "\r\n";
2253   SimpleBuffer simple_buffer;
2254   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2255   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
2256   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2257   EXPECT_EQ(expected_write_buffer_size,
2258             static_cast<size_t>(simple_buffer.ReadableBytes()));
2259 }
2260 
TEST(BalsaHeaders,WriteToBufferWorkWhensOnlyLinesSetThroughHeaders)2261 TEST(BalsaHeaders, WriteToBufferWorkWhensOnlyLinesSetThroughHeaders) {
2262   BalsaHeaders headers;
2263   headers.AppendHeader("key1", "value1");
2264   headers.AppendHeader("key 2", "value\n 2");
2265   headers.AppendHeader("key\n 3", "value3");
2266   std::string expected =
2267       "\r\n"
2268       "key1: value1\r\n"
2269       "key 2: value\n"
2270       " 2\r\n"
2271       "key\n"
2272       " 3: value3\r\n"
2273       "\r\n";
2274   SimpleBuffer simple_buffer;
2275   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2276   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
2277   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2278   EXPECT_EQ(expected_write_buffer_size,
2279             static_cast<size_t>(simple_buffer.ReadableBytes()));
2280 }
2281 
TEST(BalsaHeaders,WriteToBufferWorksWhenSetThroughHeadersWithElementsErased)2282 TEST(BalsaHeaders, WriteToBufferWorksWhenSetThroughHeadersWithElementsErased) {
2283   BalsaHeaders headers;
2284   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
2285   headers.AppendHeader("key1", "value1");
2286   headers.AppendHeader("key 2", "value\n 2");
2287   headers.AppendHeader("key\n 3", "value3");
2288   headers.RemoveAllOfHeader("key1");
2289   headers.RemoveAllOfHeader("key\n 3");
2290   std::string expected =
2291       "GET / HTTP/1.0\r\n"
2292       "key 2: value\n"
2293       " 2\r\n"
2294       "\r\n";
2295   SimpleBuffer simple_buffer;
2296   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2297   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
2298   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2299   EXPECT_EQ(expected_write_buffer_size,
2300             static_cast<size_t>(simple_buffer.ReadableBytes()));
2301 }
2302 
TEST(BalsaHeaders,WriteToBufferWithManuallyAppendedHeaderLine)2303 TEST(BalsaHeaders, WriteToBufferWithManuallyAppendedHeaderLine) {
2304   BalsaHeaders headers;
2305   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
2306   headers.AppendHeader("key1", "value1");
2307   headers.AppendHeader("key 2", "value\n 2");
2308   std::string expected =
2309       "GET / HTTP/1.0\r\n"
2310       "key1: value1\r\n"
2311       "key 2: value\n"
2312       " 2\r\n"
2313       "key 3: value 3\r\n"
2314       "\r\n";
2315 
2316   SimpleBuffer simple_buffer;
2317   size_t expected_write_buffer_size = headers.GetSizeForWriteBuffer();
2318   headers.WriteToBuffer(&simple_buffer);
2319   headers.WriteHeaderLineToBuffer(&simple_buffer, "key 3", "value 3",
2320                                   BalsaHeaders::CaseOption::kNoModification);
2321   headers.WriteHeaderEndingToBuffer(&simple_buffer);
2322   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected));
2323   EXPECT_EQ(expected_write_buffer_size + 16,
2324             static_cast<size_t>(simple_buffer.ReadableBytes()));
2325 }
2326 
TEST(BalsaHeaders,DumpToStringEmptyHeaders)2327 TEST(BalsaHeaders, DumpToStringEmptyHeaders) {
2328   BalsaHeaders headers;
2329   std::string headers_str;
2330   headers.DumpToString(&headers_str);
2331   EXPECT_EQ("\n <empty header>\n", headers_str);
2332 }
2333 
TEST(BalsaHeaders,DumpToStringParsedHeaders)2334 TEST(BalsaHeaders, DumpToStringParsedHeaders) {
2335   std::string input =
2336       "GET / HTTP/1.0\r\n"
2337       "Header1: value\r\n"
2338       "Header2: value\r\n"
2339       "\r\n";
2340   std::string output =
2341       "\n"
2342       " GET / HTTP/1.0\n"
2343       " Header1: value\n"
2344       " Header2: value\n";
2345 
2346   BalsaHeaders headers = CreateHTTPHeaders(true, input);
2347   std::string headers_str;
2348   headers.DumpToString(&headers_str);
2349   EXPECT_EQ(output, headers_str);
2350   EXPECT_TRUE(headers.FramerIsDoneWriting());
2351 }
2352 
TEST(BalsaHeaders,DumpToStringPartialHeaders)2353 TEST(BalsaHeaders, DumpToStringPartialHeaders) {
2354   BalsaHeaders headers;
2355   BalsaFrame balsa_frame;
2356   balsa_frame.set_is_request(true);
2357   balsa_frame.set_balsa_headers(&headers);
2358   std::string input =
2359       "GET / HTTP/1.0\r\n"
2360       "Header1: value\r\n"
2361       "Header2: value\r\n";
2362   std::string output = absl::StrFormat("\n <incomplete header len: %d>\n ",
2363                                        static_cast<int>(input.size()));
2364   output += input;
2365   output += '\n';
2366 
2367   ASSERT_EQ(input.size(), balsa_frame.ProcessInput(input.data(), input.size()));
2368   ASSERT_FALSE(balsa_frame.MessageFullyRead());
2369   std::string headers_str;
2370   headers.DumpToString(&headers_str);
2371   EXPECT_EQ(output, headers_str);
2372   EXPECT_FALSE(headers.FramerIsDoneWriting());
2373 }
2374 
TEST(BalsaHeaders,DumpToStringParsingNonHeadersData)2375 TEST(BalsaHeaders, DumpToStringParsingNonHeadersData) {
2376   BalsaHeaders headers;
2377   BalsaFrame balsa_frame;
2378   balsa_frame.set_is_request(true);
2379   balsa_frame.set_balsa_headers(&headers);
2380   std::string input =
2381       "This is not a header. "
2382       "Just some random data to simulate mismatch.";
2383   std::string output = absl::StrFormat("\n <incomplete header len: %d>\n ",
2384                                        static_cast<int>(input.size()));
2385   output += input;
2386   output += '\n';
2387 
2388   ASSERT_EQ(input.size(), balsa_frame.ProcessInput(input.data(), input.size()));
2389   ASSERT_FALSE(balsa_frame.MessageFullyRead());
2390   std::string headers_str;
2391   headers.DumpToString(&headers_str);
2392   EXPECT_EQ(output, headers_str);
2393 }
2394 
TEST(BalsaHeaders,Clear)2395 TEST(BalsaHeaders, Clear) {
2396   BalsaHeaders headers;
2397   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
2398   headers.AppendHeader("key1", "value1");
2399   headers.AppendHeader("key 2", "value\n 2");
2400   headers.AppendHeader("key\n 3", "value3");
2401   headers.RemoveAllOfHeader("key1");
2402   headers.RemoveAllOfHeader("key\n 3");
2403   headers.Clear();
2404   EXPECT_TRUE(headers.first_line().empty());
2405   EXPECT_EQ(headers.lines().begin(), headers.lines().end());
2406   EXPECT_TRUE(headers.IsEmpty());
2407 }
2408 
TEST(BalsaHeaders,TestSetFromStringPiecesWithInitialFirstlineInHeaderStreamAndNewToo)2409 TEST(BalsaHeaders,
2410      TestSetFromStringPiecesWithInitialFirstlineInHeaderStreamAndNewToo) {
2411   BalsaHeaders headers = CreateHTTPHeaders(false,
2412                                            "HTTP/1.1 200 reason phrase\r\n"
2413                                            "content-length: 0\r\n"
2414                                            "\r\n");
2415   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.1"));
2416   EXPECT_THAT(headers.response_code(), StrEq("200"));
2417   EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2418 
2419   headers.SetResponseFirstline("HTTP/1.0", 404, "a reason");
2420   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.0"));
2421   EXPECT_THAT(headers.response_code(), StrEq("404"));
2422   EXPECT_THAT(headers.parsed_response_code(), Eq(404));
2423   EXPECT_THAT(headers.response_reason_phrase(), StrEq("a reason"));
2424   EXPECT_THAT(headers.first_line(), StrEq("HTTP/1.0 404 a reason"));
2425 }
2426 
TEST(BalsaHeaders,TestSetFromStringPiecesWithInitialFirstlineInHeaderStreamButNotNew)2427 TEST(BalsaHeaders,
2428      TestSetFromStringPiecesWithInitialFirstlineInHeaderStreamButNotNew) {
2429   BalsaHeaders headers = CreateHTTPHeaders(false,
2430                                            "HTTP/1.1 200 reason phrase\r\n"
2431                                            "content-length: 0\r\n"
2432                                            "\r\n");
2433   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.1"));
2434   EXPECT_THAT(headers.response_code(), StrEq("200"));
2435   EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2436 
2437   headers.SetResponseFirstline("HTTP/1.000", 404000,
2438                                "supercalifragilisticexpealidocious");
2439   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.000"));
2440   EXPECT_THAT(headers.response_code(), StrEq("404000"));
2441   EXPECT_THAT(headers.parsed_response_code(), Eq(404000));
2442   EXPECT_THAT(headers.response_reason_phrase(),
2443               StrEq("supercalifragilisticexpealidocious"));
2444   EXPECT_THAT(headers.first_line(),
2445               StrEq("HTTP/1.000 404000 supercalifragilisticexpealidocious"));
2446 }
2447 
TEST(BalsaHeaders,TestSetFromStringPiecesWithFirstFirstlineInHeaderStreamButNotNew2)2448 TEST(BalsaHeaders,
2449      TestSetFromStringPiecesWithFirstFirstlineInHeaderStreamButNotNew2) {
2450   SCOPED_TRACE(
2451       "This test tests the codepath where the new firstline is"
2452       " too large to fit within the space used by the original"
2453       " firstline, but large enuogh to space in the free space"
2454       " available in both firstline plus the space made available"
2455       " with deleted header lines (specifically, the first one");
2456   BalsaHeaders headers = CreateHTTPHeaders(
2457       false,
2458       "HTTP/1.1 200 reason phrase\r\n"
2459       "a: 0987123409871234078130948710938471093827401983740198327401982374\r\n"
2460       "content-length: 0\r\n"
2461       "\r\n");
2462   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.1"));
2463   EXPECT_THAT(headers.response_code(), StrEq("200"));
2464   EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2465 
2466   headers.erase(headers.lines().begin());
2467   headers.SetResponseFirstline("HTTP/1.000", 404000,
2468                                "supercalifragilisticexpealidocious");
2469   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.000"));
2470   EXPECT_THAT(headers.response_code(), StrEq("404000"));
2471   EXPECT_THAT(headers.parsed_response_code(), Eq(404000));
2472   EXPECT_THAT(headers.response_reason_phrase(),
2473               StrEq("supercalifragilisticexpealidocious"));
2474   EXPECT_THAT(headers.first_line(),
2475               StrEq("HTTP/1.000 404000 supercalifragilisticexpealidocious"));
2476 }
2477 
TEST(BalsaHeaders,TestSetFirstlineFromStringPiecesWithNoInitialFirstline)2478 TEST(BalsaHeaders, TestSetFirstlineFromStringPiecesWithNoInitialFirstline) {
2479   BalsaHeaders headers;
2480   headers.SetResponseFirstline("HTTP/1.1", 200, "don't need a reason");
2481   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.1"));
2482   EXPECT_THAT(headers.response_code(), StrEq("200"));
2483   EXPECT_THAT(headers.parsed_response_code(), Eq(200));
2484   EXPECT_THAT(headers.response_reason_phrase(), StrEq("don't need a reason"));
2485   EXPECT_THAT(headers.first_line(), StrEq("HTTP/1.1 200 don't need a reason"));
2486 }
2487 
TEST(BalsaHeaders,TestSettingFirstlineElementsWithOtherElementsMissing)2488 TEST(BalsaHeaders, TestSettingFirstlineElementsWithOtherElementsMissing) {
2489   {
2490     BalsaHeaders headers;
2491     headers.SetRequestMethod("GET");
2492     headers.SetRequestUri("/");
2493     EXPECT_THAT(headers.first_line(), StrEq("GET / "));
2494   }
2495   {
2496     BalsaHeaders headers;
2497     headers.SetRequestMethod("GET");
2498     headers.SetRequestVersion("HTTP/1.1");
2499     EXPECT_THAT(headers.first_line(), StrEq("GET  HTTP/1.1"));
2500   }
2501   {
2502     BalsaHeaders headers;
2503     headers.SetRequestUri("/");
2504     headers.SetRequestVersion("HTTP/1.1");
2505     EXPECT_THAT(headers.first_line(), StrEq(" / HTTP/1.1"));
2506   }
2507 }
2508 
TEST(BalsaHeaders,TestSettingMissingFirstlineElementsAfterBalsaHeadersParsed)2509 TEST(BalsaHeaders, TestSettingMissingFirstlineElementsAfterBalsaHeadersParsed) {
2510   {
2511     BalsaHeaders headers = CreateHTTPHeaders(true, "GET /foo\r\n");
2512     ASSERT_THAT(headers.first_line(), StrEq("GET /foo"));
2513 
2514     headers.SetRequestVersion("HTTP/1.1");
2515     EXPECT_THAT(headers.first_line(), StrEq("GET /foo HTTP/1.1"));
2516   }
2517   {
2518     BalsaHeaders headers = CreateHTTPHeaders(true, "GET\r\n");
2519     ASSERT_THAT(headers.first_line(), StrEq("GET"));
2520 
2521     headers.SetRequestUri("/foo");
2522     EXPECT_THAT(headers.first_line(), StrEq("GET /foo "));
2523   }
2524 }
2525 
2526 // Here we exersize the codepaths involved in setting a new firstine when the
2527 // previously set firstline is stored in the 'additional_data_stream_'
2528 // variable, and the new firstline is larger than the previously set firstline.
TEST(BalsaHeaders,SetFirstlineFromStringPiecesFirstInAdditionalDataAndNewLarger)2529 TEST(BalsaHeaders,
2530      SetFirstlineFromStringPiecesFirstInAdditionalDataAndNewLarger) {
2531   BalsaHeaders headers;
2532   // This one will end up being put into the additional data stream
2533   headers.SetResponseFirstline("HTTP/1.1", 200, "don't need a reason");
2534   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.1"));
2535   EXPECT_THAT(headers.response_code(), StrEq("200"));
2536   EXPECT_THAT(headers.parsed_response_code(), Eq(200));
2537   EXPECT_THAT(headers.response_reason_phrase(), StrEq("don't need a reason"));
2538   EXPECT_THAT(headers.first_line(), StrEq("HTTP/1.1 200 don't need a reason"));
2539 
2540   // Now, we set it again, this time we're extending what exists
2541   // here.
2542   headers.SetResponseFirstline("HTTP/1.10", 2000, "REALLY don't need a reason");
2543   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.10"));
2544   EXPECT_THAT(headers.response_code(), StrEq("2000"));
2545   EXPECT_THAT(headers.parsed_response_code(), Eq(2000));
2546   EXPECT_THAT(headers.response_reason_phrase(),
2547               StrEq("REALLY don't need a reason"));
2548   EXPECT_THAT(headers.first_line(),
2549               StrEq("HTTP/1.10 2000 REALLY don't need a reason"));
2550 }
2551 
2552 // Here we exersize the codepaths involved in setting a new firstine when the
2553 // previously set firstline is stored in the 'additional_data_stream_'
2554 // variable, and the new firstline is smaller than the previously set firstline.
TEST(BalsaHeaders,TestSetFirstlineFromStringPiecesWithPreviousInAdditionalDataNewSmaller)2555 TEST(BalsaHeaders,
2556      TestSetFirstlineFromStringPiecesWithPreviousInAdditionalDataNewSmaller) {
2557   BalsaHeaders headers;
2558   // This one will end up being put into the additional data stream
2559   //
2560   headers.SetResponseFirstline("HTTP/1.10", 2000, "REALLY don't need a reason");
2561   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.10"));
2562   EXPECT_THAT(headers.response_code(), StrEq("2000"));
2563   EXPECT_THAT(headers.parsed_response_code(), Eq(2000));
2564   EXPECT_THAT(headers.response_reason_phrase(),
2565               StrEq("REALLY don't need a reason"));
2566   EXPECT_THAT(headers.first_line(),
2567               StrEq("HTTP/1.10 2000 REALLY don't need a reason"));
2568 
2569   // Now, we set it again, this time we're extending what exists
2570   // here.
2571   headers.SetResponseFirstline("HTTP/1.0", 200, "a reason");
2572   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.0"));
2573   EXPECT_THAT(headers.response_code(), StrEq("200"));
2574   EXPECT_THAT(headers.parsed_response_code(), Eq(200));
2575   EXPECT_THAT(headers.response_reason_phrase(), StrEq("a reason"));
2576   EXPECT_THAT(headers.first_line(), StrEq("HTTP/1.0 200 a reason"));
2577 }
2578 
TEST(BalsaHeaders,CopyFrom)2579 TEST(BalsaHeaders, CopyFrom) {
2580   BalsaHeaders headers1, headers2;
2581   absl::string_view method("GET");
2582   absl::string_view uri("/foo");
2583   absl::string_view version("HTTP/1.0");
2584   headers1.SetRequestFirstlineFromStringPieces(method, uri, version);
2585   headers1.AppendHeader("key1", "value1");
2586   headers1.AppendHeader("key 2", "value\n 2");
2587   headers1.AppendHeader("key\n 3", "value3");
2588 
2589   // "GET /foo HTTP/1.0"     // 17
2590   // "key1: value1\r\n"      // 14
2591   // "key 2: value\n 2\r\n"  // 17
2592   // "key\n 3: value3\r\n"   // 16
2593 
2594   headers2.CopyFrom(headers1);
2595 
2596   EXPECT_THAT(headers1.first_line(), StrEq("GET /foo HTTP/1.0"));
2597   BalsaHeaders::const_header_lines_iterator chli = headers1.lines().begin();
2598   EXPECT_THAT(chli->first, StrEq("key1"));
2599   EXPECT_THAT(chli->second, StrEq("value1"));
2600   ++chli;
2601   EXPECT_THAT(chli->first, StrEq("key 2"));
2602   EXPECT_THAT(chli->second, StrEq("value\n 2"));
2603   ++chli;
2604   EXPECT_THAT(chli->first, StrEq("key\n 3"));
2605   EXPECT_THAT(chli->second, StrEq("value3"));
2606   ++chli;
2607   EXPECT_EQ(headers1.lines().end(), chli);
2608 
2609   EXPECT_THAT(headers1.request_method(),
2610               StrEq((std::string(headers2.request_method()))));
2611   EXPECT_THAT(headers1.request_uri(),
2612               StrEq((std::string(headers2.request_uri()))));
2613   EXPECT_THAT(headers1.request_version(),
2614               StrEq((std::string(headers2.request_version()))));
2615 
2616   EXPECT_THAT(headers2.first_line(), StrEq("GET /foo HTTP/1.0"));
2617   chli = headers2.lines().begin();
2618   EXPECT_THAT(chli->first, StrEq("key1"));
2619   EXPECT_THAT(chli->second, StrEq("value1"));
2620   ++chli;
2621   EXPECT_THAT(chli->first, StrEq("key 2"));
2622   EXPECT_THAT(chli->second, StrEq("value\n 2"));
2623   ++chli;
2624   EXPECT_THAT(chli->first, StrEq("key\n 3"));
2625   EXPECT_THAT(chli->second, StrEq("value3"));
2626   ++chli;
2627   EXPECT_EQ(headers2.lines().end(), chli);
2628 
2629   version = absl::string_view("HTTP/1.1");
2630   int code = 200;
2631   absl::string_view reason_phrase("reason phrase asdf");
2632 
2633   headers1.RemoveAllOfHeader("key1");
2634   headers1.AppendHeader("key4", "value4");
2635 
2636   headers1.SetResponseFirstline(version, code, reason_phrase);
2637 
2638   headers2.CopyFrom(headers1);
2639 
2640   // "GET /foo HTTP/1.0"     // 17
2641   // "XXXXXXXXXXXXXX"        // 14
2642   // "key 2: value\n 2\r\n"  // 17
2643   // "key\n 3: value3\r\n"   // 16
2644   // "key4: value4\r\n"      // 14
2645   //
2646   //       ->
2647   //
2648   // "HTTP/1.1 200 reason phrase asdf"  // 31 = (17 + 14)
2649   // "key 2: value\n 2\r\n"             // 17
2650   // "key\n 3: value3\r\n"              // 16
2651   // "key4: value4\r\n"                 // 14
2652 
2653   EXPECT_THAT(headers1.request_method(),
2654               StrEq((std::string(headers2.request_method()))));
2655   EXPECT_THAT(headers1.request_uri(),
2656               StrEq((std::string(headers2.request_uri()))));
2657   EXPECT_THAT(headers1.request_version(),
2658               StrEq((std::string(headers2.request_version()))));
2659 
2660   EXPECT_THAT(headers2.first_line(), StrEq("HTTP/1.1 200 reason phrase asdf"));
2661   chli = headers2.lines().begin();
2662   EXPECT_THAT(chli->first, StrEq("key 2"));
2663   EXPECT_THAT(chli->second, StrEq("value\n 2"));
2664   ++chli;
2665   EXPECT_THAT(chli->first, StrEq("key\n 3"));
2666   EXPECT_THAT(chli->second, StrEq("value3"));
2667   ++chli;
2668   EXPECT_THAT(chli->first, StrEq("key4"));
2669   EXPECT_THAT(chli->second, StrEq("value4"));
2670   ++chli;
2671   EXPECT_EQ(headers2.lines().end(), chli);
2672 }
2673 
2674 // Test BalsaHeaders move constructor and move assignment operator.
TEST(BalsaHeaders,Move)2675 TEST(BalsaHeaders, Move) {
2676   BalsaHeaders headers1, headers3;
2677   absl::string_view method("GET");
2678   absl::string_view uri("/foo");
2679   absl::string_view version("HTTP/1.0");
2680   headers1.SetRequestFirstlineFromStringPieces(method, uri, version);
2681   headers1.AppendHeader("key1", "value1");
2682   headers1.AppendHeader("key 2", "value\n 2");
2683   headers1.AppendHeader("key\n 3", "value3");
2684 
2685   // "GET /foo HTTP/1.0"     // 17
2686   // "key1: value1\r\n"      // 14
2687   // "key 2: value\n 2\r\n"  // 17
2688   // "key\n 3: value3\r\n"   // 16
2689 
2690   BalsaHeaders headers2 = std::move(headers1);
2691 
2692   EXPECT_EQ("GET /foo HTTP/1.0", headers2.first_line());
2693   BalsaHeaders::const_header_lines_iterator chli = headers2.lines().begin();
2694   EXPECT_EQ("key1", chli->first);
2695   EXPECT_EQ("value1", chli->second);
2696   ++chli;
2697   EXPECT_EQ("key 2", chli->first);
2698   EXPECT_EQ("value\n 2", chli->second);
2699   ++chli;
2700   EXPECT_EQ("key\n 3", chli->first);
2701   EXPECT_EQ("value3", chli->second);
2702   ++chli;
2703   EXPECT_EQ(headers2.lines().end(), chli);
2704 
2705   EXPECT_EQ("GET", headers2.request_method());
2706   EXPECT_EQ("/foo", headers2.request_uri());
2707   EXPECT_EQ("HTTP/1.0", headers2.request_version());
2708 
2709   headers3 = std::move(headers2);
2710   version = absl::string_view("HTTP/1.1");
2711   int code = 200;
2712   absl::string_view reason_phrase("reason phrase asdf");
2713 
2714   headers3.RemoveAllOfHeader("key1");
2715   headers3.AppendHeader("key4", "value4");
2716 
2717   headers3.SetResponseFirstline(version, code, reason_phrase);
2718 
2719   BalsaHeaders headers4 = std::move(headers3);
2720 
2721   // "GET /foo HTTP/1.0"     // 17
2722   // "XXXXXXXXXXXXXX"        // 14
2723   // "key 2: value\n 2\r\n"  // 17
2724   // "key\n 3: value3\r\n"   // 16
2725   // "key4: value4\r\n"      // 14
2726   //
2727   //       ->
2728   //
2729   // "HTTP/1.1 200 reason phrase asdf"  // 31 = (17 + 14)
2730   // "key 2: value\n 2\r\n"             // 17
2731   // "key\n 3: value3\r\n"              // 16
2732   // "key4: value4\r\n"                 // 14
2733 
2734   EXPECT_EQ("200", headers4.response_code());
2735   EXPECT_EQ("reason phrase asdf", headers4.response_reason_phrase());
2736   EXPECT_EQ("HTTP/1.1", headers4.response_version());
2737 
2738   EXPECT_EQ("HTTP/1.1 200 reason phrase asdf", headers4.first_line());
2739   chli = headers4.lines().begin();
2740   EXPECT_EQ("key 2", chli->first);
2741   EXPECT_EQ("value\n 2", chli->second);
2742   ++chli;
2743   EXPECT_EQ("key\n 3", chli->first);
2744   EXPECT_EQ("value3", chli->second);
2745   ++chli;
2746   EXPECT_EQ("key4", chli->first);
2747   EXPECT_EQ("value4", chli->second);
2748   ++chli;
2749   EXPECT_EQ(headers4.lines().end(), chli);
2750 }
2751 
TEST(BalsaHeaders,IteratorWorksWithOStreamAsExpected)2752 TEST(BalsaHeaders, IteratorWorksWithOStreamAsExpected) {
2753   {
2754     std::stringstream actual;
2755     BalsaHeaders::const_header_lines_iterator chli;
2756     actual << chli;
2757     // Note that the output depends on the flavor of standard library in use.
2758     EXPECT_THAT(actual.str(), AnyOf(StrEq("[0, 0]"),      // libstdc++
2759                                     StrEq("[(nil), 0]"),  // libc++
2760                                     StrEq("[0x0, 0]")));  // libc++ on Mac
2761   }
2762   {
2763     BalsaHeaders headers;
2764     std::stringstream actual;
2765     BalsaHeaders::const_header_lines_iterator chli = headers.lines().begin();
2766     actual << chli;
2767     std::stringstream expected;
2768     expected << "[" << &headers << ", 0]";
2769     EXPECT_THAT(expected.str(), StrEq(actual.str()));
2770   }
2771 }
2772 
TEST(BalsaHeaders,TestSetResponseReasonPhraseWithNoInitialFirstline)2773 TEST(BalsaHeaders, TestSetResponseReasonPhraseWithNoInitialFirstline) {
2774   BalsaHeaders balsa_headers;
2775   balsa_headers.SetResponseReasonPhrase("don't need a reason");
2776   EXPECT_THAT(balsa_headers.first_line(), StrEq("  don't need a reason"));
2777   EXPECT_TRUE(balsa_headers.response_version().empty());
2778   EXPECT_TRUE(balsa_headers.response_code().empty());
2779   EXPECT_THAT(balsa_headers.response_reason_phrase(),
2780               StrEq("don't need a reason"));
2781 }
2782 
2783 // Testing each of 9 combinations separately was taking up way too much of this
2784 // file (not to mention the inordinate amount of stupid code duplication), thus
2785 // this test tests all 9 combinations of smaller, equal, and larger in one
2786 // place.
TEST(BalsaHeaders,TestSetResponseReasonPhrase)2787 TEST(BalsaHeaders, TestSetResponseReasonPhrase) {
2788   const char* response_reason_phrases[] = {
2789       "qwerty asdfgh",
2790       "qwerty",
2791       "qwerty asdfghjkl",
2792   };
2793   size_t arraysize_squared = (ABSL_ARRAYSIZE(response_reason_phrases) *
2794                               ABSL_ARRAYSIZE(response_reason_phrases));
2795   // We go through the 9 different permutations of (response_reason_phrases
2796   // choose 2) in the loop below. For each permutation, we mutate the firstline
2797   // twice-- once from the original, and once from the previous.
2798   for (size_t iteration = 0; iteration < arraysize_squared; ++iteration) {
2799     SCOPED_TRACE("Original firstline: \"HTTP/1.0 200 reason phrase\"");
2800     BalsaHeaders headers = CreateHTTPHeaders(true,
2801                                              "HTTP/1.0 200 reason phrase\r\n"
2802                                              "content-length: 0\r\n"
2803                                              "\r\n");
2804     ASSERT_THAT(headers.first_line(), StrEq("HTTP/1.0 200 reason phrase"));
2805 
2806     {
2807       int first = iteration / ABSL_ARRAYSIZE(response_reason_phrases);
2808       const char* response_reason_phrase_first = response_reason_phrases[first];
2809       std::string expected_new_firstline =
2810           absl::StrFormat("HTTP/1.0 200 %s", response_reason_phrase_first);
2811       SCOPED_TRACE(absl::StrFormat("Then set response_reason_phrase(\"%s\")",
2812                                    response_reason_phrase_first));
2813 
2814       headers.SetResponseReasonPhrase(response_reason_phrase_first);
2815       EXPECT_THAT(headers.first_line(),
2816                   StrEq(absl::StrFormat("HTTP/1.0 200 %s",
2817                                         response_reason_phrase_first)));
2818       EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.0"));
2819       EXPECT_THAT(headers.response_code(), StrEq("200"));
2820       EXPECT_THAT(headers.response_reason_phrase(),
2821                   StrEq(response_reason_phrase_first));
2822     }
2823 
2824     // Note that each iteration of the outer loop causes the headers to be left
2825     // in a different state. Nothing wrong with that, but we should use each of
2826     // these states, and try each of our scenarios again. This inner loop does
2827     // that.
2828     {
2829       int second = iteration % ABSL_ARRAYSIZE(response_reason_phrases);
2830       const char* response_reason_phrase_second =
2831           response_reason_phrases[second];
2832       std::string expected_new_firstline =
2833           absl::StrFormat("HTTP/1.0 200 %s", response_reason_phrase_second);
2834       SCOPED_TRACE(absl::StrFormat("Then set response_reason_phrase(\"%s\")",
2835                                    response_reason_phrase_second));
2836 
2837       headers.SetResponseReasonPhrase(response_reason_phrase_second);
2838       EXPECT_THAT(headers.first_line(),
2839                   StrEq(absl::StrFormat("HTTP/1.0 200 %s",
2840                                         response_reason_phrase_second)));
2841       EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.0"));
2842       EXPECT_THAT(headers.response_code(), StrEq("200"));
2843       EXPECT_THAT(headers.response_reason_phrase(),
2844                   StrEq(response_reason_phrase_second));
2845     }
2846   }
2847 }
2848 
TEST(BalsaHeaders,TestSetResponseVersionWithNoInitialFirstline)2849 TEST(BalsaHeaders, TestSetResponseVersionWithNoInitialFirstline) {
2850   BalsaHeaders balsa_headers;
2851   balsa_headers.SetResponseVersion("HTTP/1.1");
2852   EXPECT_THAT(balsa_headers.first_line(), StrEq("HTTP/1.1  "));
2853   EXPECT_THAT(balsa_headers.response_version(), StrEq("HTTP/1.1"));
2854   EXPECT_TRUE(balsa_headers.response_code().empty());
2855   EXPECT_TRUE(balsa_headers.response_reason_phrase().empty());
2856 }
2857 
2858 // Testing each of 9 combinations separately was taking up way too much of this
2859 // file (not to mention the inordinate amount of stupid code duplication), thus
2860 // this test tests all 9 combinations of smaller, equal, and larger in one
2861 // place.
TEST(BalsaHeaders,TestSetResponseVersion)2862 TEST(BalsaHeaders, TestSetResponseVersion) {
2863   const char* response_versions[] = {
2864       "ABCD/123",
2865       "ABCD",
2866       "ABCD/123456",
2867   };
2868   size_t arraysize_squared =
2869       (ABSL_ARRAYSIZE(response_versions) * ABSL_ARRAYSIZE(response_versions));
2870   // We go through the 9 different permutations of (response_versions choose 2)
2871   // in the loop below. For each permutation, we mutate the firstline twice--
2872   // once from the original, and once from the previous.
2873   for (size_t iteration = 0; iteration < arraysize_squared; ++iteration) {
2874     SCOPED_TRACE("Original firstline: \"HTTP/1.0 200 reason phrase\"");
2875     BalsaHeaders headers = CreateHTTPHeaders(false,
2876                                              "HTTP/1.0 200 reason phrase\r\n"
2877                                              "content-length: 0\r\n"
2878                                              "\r\n");
2879     ASSERT_THAT(headers.first_line(), StrEq("HTTP/1.0 200 reason phrase"));
2880 
2881     // This structure guarantees that we'll visit all of the possible
2882     // variations of setting.
2883 
2884     {
2885       int first = iteration / ABSL_ARRAYSIZE(response_versions);
2886       const char* response_version_first = response_versions[first];
2887       std::string expected_new_firstline =
2888           absl::StrFormat("%s 200 reason phrase", response_version_first);
2889       SCOPED_TRACE(absl::StrFormat("Then set response_version(\"%s\")",
2890                                    response_version_first));
2891 
2892       headers.SetResponseVersion(response_version_first);
2893       EXPECT_THAT(headers.first_line(), StrEq(expected_new_firstline));
2894       EXPECT_THAT(headers.response_version(), StrEq(response_version_first));
2895       EXPECT_THAT(headers.response_code(), StrEq("200"));
2896       EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2897     }
2898     {
2899       int second = iteration % ABSL_ARRAYSIZE(response_versions);
2900       const char* response_version_second = response_versions[second];
2901       std::string expected_new_firstline =
2902           absl::StrFormat("%s 200 reason phrase", response_version_second);
2903       SCOPED_TRACE(absl::StrFormat("Then set response_version(\"%s\")",
2904                                    response_version_second));
2905 
2906       headers.SetResponseVersion(response_version_second);
2907       EXPECT_THAT(headers.first_line(), StrEq(expected_new_firstline));
2908       EXPECT_THAT(headers.response_version(), StrEq(response_version_second));
2909       EXPECT_THAT(headers.response_code(), StrEq("200"));
2910       EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2911     }
2912   }
2913 }
2914 
TEST(BalsaHeaders,TestSetResponseReasonAndVersionWithNoInitialFirstline)2915 TEST(BalsaHeaders, TestSetResponseReasonAndVersionWithNoInitialFirstline) {
2916   BalsaHeaders headers;
2917   headers.SetResponseVersion("HTTP/1.1");
2918   headers.SetResponseReasonPhrase("don't need a reason");
2919   EXPECT_THAT(headers.first_line(), StrEq("HTTP/1.1  don't need a reason"));
2920   EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.1"));
2921   EXPECT_TRUE(headers.response_code().empty());
2922   EXPECT_THAT(headers.response_reason_phrase(), StrEq("don't need a reason"));
2923 }
2924 
TEST(BalsaHeaders,TestSetResponseCodeWithNoInitialFirstline)2925 TEST(BalsaHeaders, TestSetResponseCodeWithNoInitialFirstline) {
2926   BalsaHeaders balsa_headers;
2927   balsa_headers.SetParsedResponseCodeAndUpdateFirstline(2002);
2928   EXPECT_THAT(balsa_headers.first_line(), StrEq(" 2002 "));
2929   EXPECT_TRUE(balsa_headers.response_version().empty());
2930   EXPECT_THAT(balsa_headers.response_code(), StrEq("2002"));
2931   EXPECT_TRUE(balsa_headers.response_reason_phrase().empty());
2932   EXPECT_THAT(balsa_headers.parsed_response_code(), Eq(2002));
2933 }
2934 
TEST(BalsaHeaders,TestSetParsedResponseCode)2935 TEST(BalsaHeaders, TestSetParsedResponseCode) {
2936   BalsaHeaders balsa_headers;
2937   balsa_headers.set_parsed_response_code(std::numeric_limits<int>::max());
2938   EXPECT_THAT(balsa_headers.parsed_response_code(),
2939               Eq(std::numeric_limits<int>::max()));
2940 }
2941 
TEST(BalsaHeaders,TestSetResponseCode)2942 TEST(BalsaHeaders, TestSetResponseCode) {
2943   const char* response_codes[] = {
2944       "200"
2945       "23",
2946       "200200",
2947   };
2948   size_t arraysize_squared =
2949       (ABSL_ARRAYSIZE(response_codes) * ABSL_ARRAYSIZE(response_codes));
2950   // We go through the 9 different permutations of (response_codes choose 2)
2951   // in the loop below. For each permutation, we mutate the firstline twice--
2952   // once from the original, and once from the previous.
2953   for (size_t iteration = 0; iteration < arraysize_squared; ++iteration) {
2954     SCOPED_TRACE("Original firstline: \"HTTP/1.0 200 reason phrase\"");
2955     BalsaHeaders headers = CreateHTTPHeaders(false,
2956                                              "HTTP/1.0 200 reason phrase\r\n"
2957                                              "content-length: 0\r\n"
2958                                              "\r\n");
2959     ASSERT_THAT(headers.first_line(), StrEq("HTTP/1.0 200 reason phrase"));
2960 
2961     // This structure guarantees that we'll visit all of the possible
2962     // variations of setting.
2963 
2964     {
2965       int first = iteration / ABSL_ARRAYSIZE(response_codes);
2966       const char* response_code_first = response_codes[first];
2967       std::string expected_new_firstline =
2968           absl::StrFormat("HTTP/1.0 %s reason phrase", response_code_first);
2969       SCOPED_TRACE(absl::StrFormat("Then set response_code(\"%s\")",
2970                                    response_code_first));
2971 
2972       headers.SetResponseCode(response_code_first);
2973 
2974       EXPECT_THAT(headers.first_line(), StrEq(expected_new_firstline));
2975       EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.0"));
2976       EXPECT_THAT(headers.response_code(), StrEq(response_code_first));
2977       EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2978     }
2979     {
2980       int second = iteration % ABSL_ARRAYSIZE(response_codes);
2981       const char* response_code_second = response_codes[second];
2982       std::string expected_new_secondline =
2983           absl::StrFormat("HTTP/1.0 %s reason phrase", response_code_second);
2984       SCOPED_TRACE(absl::StrFormat("Then set response_code(\"%s\")",
2985                                    response_code_second));
2986 
2987       headers.SetResponseCode(response_code_second);
2988 
2989       EXPECT_THAT(headers.first_line(), StrEq(expected_new_secondline));
2990       EXPECT_THAT(headers.response_version(), StrEq("HTTP/1.0"));
2991       EXPECT_THAT(headers.response_code(), StrEq(response_code_second));
2992       EXPECT_THAT(headers.response_reason_phrase(), StrEq("reason phrase"));
2993     }
2994   }
2995 }
2996 
TEST(BalsaHeaders,TestAppendToHeader)2997 TEST(BalsaHeaders, TestAppendToHeader) {
2998   // Test the basic case of appending to a header.
2999   BalsaHeaders headers;
3000   headers.AppendHeader("foo", "foo_value");
3001   headers.AppendHeader("bar", "bar_value");
3002   headers.AppendToHeader("foo", "foo_value2");
3003 
3004   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value,foo_value2"));
3005   EXPECT_THAT(headers.GetHeader("bar"), StrEq("bar_value"));
3006 }
3007 
TEST(BalsaHeaders,TestInitialAppend)3008 TEST(BalsaHeaders, TestInitialAppend) {
3009   // Test that AppendToHeader works properly when the header did not already
3010   // exist.
3011   BalsaHeaders headers;
3012   headers.AppendToHeader("foo", "foo_value");
3013   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value"));
3014   headers.AppendToHeader("foo", "foo_value2");
3015   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value,foo_value2"));
3016 }
3017 
TEST(BalsaHeaders,TestAppendAndRemove)3018 TEST(BalsaHeaders, TestAppendAndRemove) {
3019   // Test that AppendToHeader works properly with removing.
3020   BalsaHeaders headers;
3021   headers.AppendToHeader("foo", "foo_value");
3022   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value"));
3023   headers.AppendToHeader("foo", "foo_value2");
3024   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value,foo_value2"));
3025   headers.RemoveAllOfHeader("foo");
3026   headers.AppendToHeader("foo", "foo_value3");
3027   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value3"));
3028   headers.AppendToHeader("foo", "foo_value4");
3029   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value3,foo_value4"));
3030 }
3031 
TEST(BalsaHeaders,TestAppendToHeaderWithCommaAndSpace)3032 TEST(BalsaHeaders, TestAppendToHeaderWithCommaAndSpace) {
3033   // Test the basic case of appending to a header with comma and space.
3034   BalsaHeaders headers;
3035   headers.AppendHeader("foo", "foo_value");
3036   headers.AppendHeader("bar", "bar_value");
3037   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value2");
3038 
3039   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value, foo_value2"));
3040   EXPECT_THAT(headers.GetHeader("bar"), StrEq("bar_value"));
3041 }
3042 
TEST(BalsaHeaders,TestInitialAppendWithCommaAndSpace)3043 TEST(BalsaHeaders, TestInitialAppendWithCommaAndSpace) {
3044   // Test that AppendToHeadeWithCommaAndSpace works properly when the
3045   // header did not already exist.
3046   BalsaHeaders headers;
3047   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value");
3048   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value"));
3049   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value2");
3050   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value, foo_value2"));
3051 }
3052 
TEST(BalsaHeaders,TestAppendWithCommaAndSpaceAndRemove)3053 TEST(BalsaHeaders, TestAppendWithCommaAndSpaceAndRemove) {
3054   // Test that AppendToHeadeWithCommaAndSpace works properly with removing.
3055   BalsaHeaders headers;
3056   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value");
3057   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value"));
3058   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value2");
3059   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value, foo_value2"));
3060   headers.RemoveAllOfHeader("foo");
3061   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value3");
3062   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value3"));
3063   headers.AppendToHeaderWithCommaAndSpace("foo", "foo_value4");
3064   EXPECT_THAT(headers.GetHeader("foo"), StrEq("foo_value3, foo_value4"));
3065 }
3066 
TEST(BalsaHeaders,SetContentLength)3067 TEST(BalsaHeaders, SetContentLength) {
3068   // Test that SetContentLength correctly sets the content-length header and
3069   // sets the content length status.
3070   BalsaHeaders headers;
3071   headers.SetContentLength(10);
3072   EXPECT_THAT(headers.GetHeader("Content-length"), StrEq("10"));
3073   EXPECT_EQ(BalsaHeadersEnums::VALID_CONTENT_LENGTH,
3074             headers.content_length_status());
3075   EXPECT_TRUE(headers.content_length_valid());
3076 
3077   // Test overwriting the content-length.
3078   headers.SetContentLength(0);
3079   EXPECT_THAT(headers.GetHeader("Content-length"), StrEq("0"));
3080   EXPECT_EQ(BalsaHeadersEnums::VALID_CONTENT_LENGTH,
3081             headers.content_length_status());
3082   EXPECT_TRUE(headers.content_length_valid());
3083 
3084   // Make sure there is only one header line after the overwrite.
3085   BalsaHeaders::const_header_lines_iterator iter =
3086       headers.GetHeaderPosition("Content-length");
3087   EXPECT_EQ(headers.lines().begin(), iter);
3088   EXPECT_EQ(headers.lines().end(), ++iter);
3089 
3090   // Test setting the same content-length again, this should be no-op.
3091   headers.SetContentLength(0);
3092   EXPECT_THAT(headers.GetHeader("Content-length"), StrEq("0"));
3093   EXPECT_EQ(BalsaHeadersEnums::VALID_CONTENT_LENGTH,
3094             headers.content_length_status());
3095   EXPECT_TRUE(headers.content_length_valid());
3096 
3097   // Make sure the number of header lines didn't change.
3098   iter = headers.GetHeaderPosition("Content-length");
3099   EXPECT_EQ(headers.lines().begin(), iter);
3100   EXPECT_EQ(headers.lines().end(), ++iter);
3101 }
3102 
TEST(BalsaHeaders,ToggleChunkedEncoding)3103 TEST(BalsaHeaders, ToggleChunkedEncoding) {
3104   // Test that SetTransferEncodingToChunkedAndClearContentLength correctly adds
3105   // chunk-encoding header and sets the transfer_encoding_is_chunked_
3106   // flag.
3107   BalsaHeaders headers;
3108   headers.SetTransferEncodingToChunkedAndClearContentLength();
3109   EXPECT_EQ("chunked", headers.GetAllOfHeaderAsString("Transfer-Encoding"));
3110   EXPECT_TRUE(headers.HasHeadersWithPrefix("Transfer-Encoding"));
3111   EXPECT_TRUE(headers.HasHeadersWithPrefix("transfer-encoding"));
3112   EXPECT_TRUE(headers.HasHeadersWithPrefix("transfer"));
3113   EXPECT_TRUE(headers.transfer_encoding_is_chunked());
3114 
3115   // Set it to the same value, nothing should change.
3116   headers.SetTransferEncodingToChunkedAndClearContentLength();
3117   EXPECT_EQ("chunked", headers.GetAllOfHeaderAsString("Transfer-Encoding"));
3118   EXPECT_TRUE(headers.HasHeadersWithPrefix("Transfer-Encoding"));
3119   EXPECT_TRUE(headers.HasHeadersWithPrefix("transfer-encoding"));
3120   EXPECT_TRUE(headers.HasHeadersWithPrefix("transfer"));
3121   EXPECT_TRUE(headers.transfer_encoding_is_chunked());
3122   BalsaHeaders::const_header_lines_iterator iter =
3123       headers.GetHeaderPosition("Transfer-Encoding");
3124   EXPECT_EQ(headers.lines().begin(), iter);
3125   EXPECT_EQ(headers.lines().end(), ++iter);
3126 
3127   // Removes the chunked encoding, and there should be no transfer-encoding
3128   // headers left.
3129   headers.SetNoTransferEncoding();
3130   EXPECT_FALSE(headers.HasHeader("Transfer-Encoding"));
3131   EXPECT_FALSE(headers.HasHeadersWithPrefix("Transfer-Encoding"));
3132   EXPECT_FALSE(headers.HasHeadersWithPrefix("transfer-encoding"));
3133   EXPECT_FALSE(headers.HasHeadersWithPrefix("transfer"));
3134   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3135   EXPECT_EQ(headers.lines().end(), headers.lines().begin());
3136 
3137   // Clear chunked again, this should be a no-op and the header should not
3138   // change.
3139   headers.SetNoTransferEncoding();
3140   EXPECT_FALSE(headers.HasHeader("Transfer-Encoding"));
3141   EXPECT_FALSE(headers.HasHeadersWithPrefix("Transfer-Encoding"));
3142   EXPECT_FALSE(headers.HasHeadersWithPrefix("transfer-encoding"));
3143   EXPECT_FALSE(headers.HasHeadersWithPrefix("transfer"));
3144   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3145   EXPECT_EQ(headers.lines().end(), headers.lines().begin());
3146 }
3147 
TEST(BalsaHeaders,SetNoTransferEncodingByRemoveHeader)3148 TEST(BalsaHeaders, SetNoTransferEncodingByRemoveHeader) {
3149   // Tests that calling Remove() methods to clear the Transfer-Encoding
3150   // header correctly resets transfer_encoding_is_chunked_ internal state.
3151   BalsaHeaders headers;
3152   headers.SetTransferEncodingToChunkedAndClearContentLength();
3153   headers.RemoveAllOfHeader("Transfer-Encoding");
3154   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3155 
3156   headers.SetTransferEncodingToChunkedAndClearContentLength();
3157   std::vector<absl::string_view> headers_to_remove;
3158   headers_to_remove.emplace_back("Transfer-Encoding");
3159   headers.RemoveAllOfHeaderInList(headers_to_remove);
3160   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3161 
3162   headers.SetTransferEncodingToChunkedAndClearContentLength();
3163   headers.RemoveAllHeadersWithPrefix("Transfer");
3164   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3165 }
3166 
TEST(BalsaHeaders,ClearContentLength)3167 TEST(BalsaHeaders, ClearContentLength) {
3168   // Test that ClearContentLength() removes the content-length header and
3169   // resets content_length_status().
3170   BalsaHeaders headers;
3171   headers.SetContentLength(10);
3172   headers.ClearContentLength();
3173   EXPECT_FALSE(headers.HasHeader("Content-length"));
3174   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3175             headers.content_length_status());
3176   EXPECT_FALSE(headers.content_length_valid());
3177 
3178   // Clear it again; nothing should change.
3179   headers.ClearContentLength();
3180   EXPECT_FALSE(headers.HasHeader("Content-length"));
3181   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3182             headers.content_length_status());
3183   EXPECT_FALSE(headers.content_length_valid());
3184 
3185   // Set chunked encoding and test that ClearContentLength() has no effect.
3186   headers.SetTransferEncodingToChunkedAndClearContentLength();
3187   headers.ClearContentLength();
3188   EXPECT_EQ("chunked", headers.GetAllOfHeaderAsString("Transfer-Encoding"));
3189   EXPECT_TRUE(headers.transfer_encoding_is_chunked());
3190   BalsaHeaders::const_header_lines_iterator iter =
3191       headers.GetHeaderPosition("Transfer-Encoding");
3192   EXPECT_EQ(headers.lines().begin(), iter);
3193   EXPECT_EQ(headers.lines().end(), ++iter);
3194 
3195   // Remove chunked encoding, and verify that the state is the same as after
3196   // ClearContentLength().
3197   headers.SetNoTransferEncoding();
3198   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3199             headers.content_length_status());
3200   EXPECT_FALSE(headers.content_length_valid());
3201 }
3202 
TEST(BalsaHeaders,ClearContentLengthByRemoveHeader)3203 TEST(BalsaHeaders, ClearContentLengthByRemoveHeader) {
3204   // Test that calling Remove() methods to clear the content-length header
3205   // correctly resets internal content length fields.
3206   BalsaHeaders headers;
3207   headers.SetContentLength(10);
3208   headers.RemoveAllOfHeader("Content-Length");
3209   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3210             headers.content_length_status());
3211   EXPECT_EQ(0u, headers.content_length());
3212   EXPECT_FALSE(headers.content_length_valid());
3213 
3214   headers.SetContentLength(11);
3215   std::vector<absl::string_view> headers_to_remove;
3216   headers_to_remove.emplace_back("Content-Length");
3217   headers.RemoveAllOfHeaderInList(headers_to_remove);
3218   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3219             headers.content_length_status());
3220   EXPECT_EQ(0u, headers.content_length());
3221   EXPECT_FALSE(headers.content_length_valid());
3222 
3223   headers.SetContentLength(12);
3224   headers.RemoveAllHeadersWithPrefix("Content");
3225   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3226             headers.content_length_status());
3227   EXPECT_EQ(0u, headers.content_length());
3228   EXPECT_FALSE(headers.content_length_valid());
3229 }
3230 
3231 // Chunk-encoding an identity-coded BalsaHeaders removes the identity-coding.
TEST(BalsaHeaders,IdentityCodingToChunked)3232 TEST(BalsaHeaders, IdentityCodingToChunked) {
3233   std::string message =
3234       "HTTP/1.1 200 OK\r\n"
3235       "Transfer-Encoding: identity\r\n\r\n";
3236   BalsaHeaders headers;
3237   BalsaFrame balsa_frame;
3238   balsa_frame.set_is_request(false);
3239   balsa_frame.set_balsa_headers(&headers);
3240   EXPECT_EQ(message.size(),
3241             balsa_frame.ProcessInput(message.data(), message.size()));
3242 
3243   EXPECT_TRUE(headers.is_framed_by_connection_close());
3244   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3245   EXPECT_THAT(headers.GetAllOfHeader("Transfer-Encoding"),
3246               ElementsAre("identity"));
3247 
3248   headers.SetTransferEncodingToChunkedAndClearContentLength();
3249 
3250   EXPECT_FALSE(headers.is_framed_by_connection_close());
3251   EXPECT_TRUE(headers.transfer_encoding_is_chunked());
3252   EXPECT_THAT(headers.GetAllOfHeader("Transfer-Encoding"),
3253               ElementsAre("chunked"));
3254 }
3255 
TEST(BalsaHeaders,SwitchContentLengthToChunk)3256 TEST(BalsaHeaders, SwitchContentLengthToChunk) {
3257   // Test that a header originally with content length header is correctly
3258   // switched to using chunk encoding.
3259   BalsaHeaders headers;
3260   headers.SetContentLength(10);
3261   EXPECT_THAT(headers.GetHeader("Content-length"), StrEq("10"));
3262   EXPECT_EQ(BalsaHeadersEnums::VALID_CONTENT_LENGTH,
3263             headers.content_length_status());
3264   EXPECT_TRUE(headers.content_length_valid());
3265 
3266   headers.SetTransferEncodingToChunkedAndClearContentLength();
3267   EXPECT_EQ("chunked", headers.GetAllOfHeaderAsString("Transfer-Encoding"));
3268   EXPECT_TRUE(headers.transfer_encoding_is_chunked());
3269   EXPECT_FALSE(headers.HasHeader("Content-length"));
3270   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3271             headers.content_length_status());
3272   EXPECT_FALSE(headers.content_length_valid());
3273 }
3274 
TEST(BalsaHeaders,SwitchChunkedToContentLength)3275 TEST(BalsaHeaders, SwitchChunkedToContentLength) {
3276   // Test that a header originally with chunk encoding is correctly
3277   // switched to using content length.
3278   BalsaHeaders headers;
3279   headers.SetTransferEncodingToChunkedAndClearContentLength();
3280   EXPECT_EQ("chunked", headers.GetAllOfHeaderAsString("Transfer-Encoding"));
3281   EXPECT_TRUE(headers.transfer_encoding_is_chunked());
3282   EXPECT_FALSE(headers.HasHeader("Content-length"));
3283   EXPECT_EQ(BalsaHeadersEnums::NO_CONTENT_LENGTH,
3284             headers.content_length_status());
3285   EXPECT_FALSE(headers.content_length_valid());
3286 
3287   headers.SetContentLength(10);
3288   EXPECT_THAT(headers.GetHeader("Content-length"), StrEq("10"));
3289   EXPECT_EQ(BalsaHeadersEnums::VALID_CONTENT_LENGTH,
3290             headers.content_length_status());
3291   EXPECT_TRUE(headers.content_length_valid());
3292   EXPECT_FALSE(headers.HasHeader("Transfer-Encoding"));
3293   EXPECT_FALSE(headers.transfer_encoding_is_chunked());
3294 }
3295 
TEST(BalsaHeaders,OneHundredResponseMessagesNoFramedByClose)3296 TEST(BalsaHeaders, OneHundredResponseMessagesNoFramedByClose) {
3297   BalsaHeaders headers;
3298   headers.SetResponseFirstline("HTTP/1.1", 100, "Continue");
3299   EXPECT_FALSE(headers.is_framed_by_connection_close());
3300 }
3301 
TEST(BalsaHeaders,TwoOhFourResponseMessagesNoFramedByClose)3302 TEST(BalsaHeaders, TwoOhFourResponseMessagesNoFramedByClose) {
3303   BalsaHeaders headers;
3304   headers.SetResponseFirstline("HTTP/1.1", 204, "Continue");
3305   EXPECT_FALSE(headers.is_framed_by_connection_close());
3306 }
3307 
TEST(BalsaHeaders,ThreeOhFourResponseMessagesNoFramedByClose)3308 TEST(BalsaHeaders, ThreeOhFourResponseMessagesNoFramedByClose) {
3309   BalsaHeaders headers;
3310   headers.SetResponseFirstline("HTTP/1.1", 304, "Continue");
3311   EXPECT_FALSE(headers.is_framed_by_connection_close());
3312 }
3313 
TEST(BalsaHeaders,InvalidCharInHeaderValue)3314 TEST(BalsaHeaders, InvalidCharInHeaderValue) {
3315   std::string message =
3316       "GET http://www.256.com/foo HTTP/1.1\r\n"
3317       "Host: \x01\x01www.265.com\r\n"
3318       "\r\n";
3319   BalsaHeaders headers = CreateHTTPHeaders(true, message);
3320   EXPECT_EQ("www.265.com", headers.GetHeader("Host"));
3321   SimpleBuffer buffer;
3322   headers.WriteHeaderAndEndingToBuffer(&buffer);
3323   message.replace(message.find_first_of(0x1), 2, "");
3324   EXPECT_EQ(message, buffer.GetReadableRegion());
3325 }
3326 
TEST(BalsaHeaders,CarriageReturnAtStartOfLine)3327 TEST(BalsaHeaders, CarriageReturnAtStartOfLine) {
3328   std::string message =
3329       "GET /foo HTTP/1.1\r\n"
3330       "Host: www.265.com\r\n"
3331       "Foo: bar\r\n"
3332       "\rX-User-Ip: 1.2.3.4\r\n"
3333       "\r\n";
3334   BalsaHeaders headers;
3335   BalsaFrame balsa_frame;
3336   balsa_frame.set_is_request(true);
3337   balsa_frame.set_balsa_headers(&headers);
3338   EXPECT_EQ(message.size(),
3339             balsa_frame.ProcessInput(message.data(), message.size()));
3340   EXPECT_EQ(BalsaFrameEnums::INVALID_HEADER_FORMAT, balsa_frame.ErrorCode());
3341   EXPECT_TRUE(balsa_frame.Error());
3342 }
3343 
TEST(BalsaHeaders,CheckEmpty)3344 TEST(BalsaHeaders, CheckEmpty) {
3345   BalsaHeaders headers;
3346   EXPECT_TRUE(headers.IsEmpty());
3347 }
3348 
TEST(BalsaHeaders,CheckNonEmpty)3349 TEST(BalsaHeaders, CheckNonEmpty) {
3350   BalsaHeaders headers;
3351   BalsaHeadersTestPeer::WriteFromFramer(&headers, "a b c", 5);
3352   EXPECT_FALSE(headers.IsEmpty());
3353 }
3354 
TEST(BalsaHeaders,ForEachHeader)3355 TEST(BalsaHeaders, ForEachHeader) {
3356   BalsaHeaders headers;
3357   headers.AppendHeader(":host", "SomeHost");
3358   headers.AppendHeader("key", "val1,val2val2,val2,val3");
3359   headers.AppendHeader("key", "val4val5val6");
3360   headers.AppendHeader("key", "val11 val12");
3361   headers.AppendHeader("key", "v val13");
3362   headers.AppendHeader("key", "val7");
3363   headers.AppendHeader("key", "");
3364   headers.AppendHeader("key", "val8 , val9 ,, val10");
3365   headers.AppendHeader("key", " val14 ");
3366   headers.AppendHeader("key2", "val15");
3367   headers.AppendHeader("key", "Val16");
3368   headers.AppendHeader("key", "foo, Val17, bar");
3369   headers.AppendHeader("date", "2 Jan 1970");
3370   headers.AppendHeader("AcceptEncoding", "MyFavoriteEncoding");
3371 
3372   {
3373     std::string result;
3374     EXPECT_TRUE(headers.ForEachHeader(
3375         [&result](const absl::string_view key, absl::string_view value) {
3376           result.append("<")
3377               .append(key.data(), key.size())
3378               .append("> = <")
3379               .append(value.data(), value.size())
3380               .append(">\n");
3381           return true;
3382         }));
3383 
3384     EXPECT_EQ(result,
3385               "<:host> = <SomeHost>\n"
3386               "<key> = <val1,val2val2,val2,val3>\n"
3387               "<key> = <val4val5val6>\n"
3388               "<key> = <val11 val12>\n"
3389               "<key> = <v val13>\n"
3390               "<key> = <val7>\n"
3391               "<key> = <>\n"
3392               "<key> = <val8 , val9 ,, val10>\n"
3393               "<key> = < val14 >\n"
3394               "<key2> = <val15>\n"
3395               "<key> = <Val16>\n"
3396               "<key> = <foo, Val17, bar>\n"
3397               "<date> = <2 Jan 1970>\n"
3398               "<AcceptEncoding> = <MyFavoriteEncoding>\n");
3399   }
3400 
3401   {
3402     std::string result;
3403     EXPECT_FALSE(headers.ForEachHeader(
3404         [&result](const absl::string_view key, absl::string_view value) {
3405           result.append("<")
3406               .append(key.data(), key.size())
3407               .append("> = <")
3408               .append(value.data(), value.size())
3409               .append(">\n");
3410           return !value.empty();
3411         }));
3412 
3413     EXPECT_EQ(result,
3414               "<:host> = <SomeHost>\n"
3415               "<key> = <val1,val2val2,val2,val3>\n"
3416               "<key> = <val4val5val6>\n"
3417               "<key> = <val11 val12>\n"
3418               "<key> = <v val13>\n"
3419               "<key> = <val7>\n"
3420               "<key> = <>\n");
3421   }
3422 }
3423 
TEST(BalsaHeaders,WriteToBufferWithLowerCasedHeaderKey)3424 TEST(BalsaHeaders, WriteToBufferWithLowerCasedHeaderKey) {
3425   BalsaHeaders headers;
3426   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
3427   headers.AppendHeader("Key1", "value1");
3428   headers.AppendHeader("Key2", "value2");
3429   std::string expected_lower_case =
3430       "GET / HTTP/1.0\r\n"
3431       "key1: value1\r\n"
3432       "key2: value2\r\n";
3433   std::string expected_lower_case_with_end =
3434       "GET / HTTP/1.0\r\n"
3435       "key1: value1\r\n"
3436       "key2: value2\r\n\r\n";
3437   std::string expected_upper_case =
3438       "GET / HTTP/1.0\r\n"
3439       "Key1: value1\r\n"
3440       "Key2: value2\r\n";
3441   std::string expected_upper_case_with_end =
3442       "GET / HTTP/1.0\r\n"
3443       "Key1: value1\r\n"
3444       "Key2: value2\r\n\r\n";
3445 
3446   SimpleBuffer simple_buffer;
3447   headers.WriteToBuffer(&simple_buffer, BalsaHeaders::CaseOption::kLowercase,
3448                         BalsaHeaders::CoalesceOption::kNoCoalesce);
3449   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected_lower_case));
3450 
3451   simple_buffer.Clear();
3452   headers.WriteToBuffer(&simple_buffer);
3453   EXPECT_THAT(simple_buffer.GetReadableRegion(), StrEq(expected_upper_case));
3454 
3455   simple_buffer.Clear();
3456   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
3457   EXPECT_THAT(simple_buffer.GetReadableRegion(),
3458               StrEq(expected_upper_case_with_end));
3459 
3460   simple_buffer.Clear();
3461   headers.WriteHeaderAndEndingToBuffer(
3462       &simple_buffer, BalsaHeaders::CaseOption::kLowercase,
3463       BalsaHeaders::CoalesceOption::kNoCoalesce);
3464   EXPECT_THAT(simple_buffer.GetReadableRegion(),
3465               StrEq(expected_lower_case_with_end));
3466 }
3467 
TEST(BalsaHeaders,WriteToBufferWithProperCasedHeaderKey)3468 TEST(BalsaHeaders, WriteToBufferWithProperCasedHeaderKey) {
3469   BalsaHeaders headers;
3470   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
3471   headers.AppendHeader("Te", "value1");
3472   headers.AppendHeader("my-Test-header", "value2");
3473   std::string expected_proper_case =
3474       "GET / HTTP/1.0\r\n"
3475       "TE: value1\r\n"
3476       "My-Test-Header: value2\r\n";
3477   std::string expected_proper_case_with_end =
3478       "GET / HTTP/1.0\r\n"
3479       "TE: value1\r\n"
3480       "My-Test-Header: value2\r\n\r\n";
3481   std::string expected_unmodified =
3482       "GET / HTTP/1.0\r\n"
3483       "Te: value1\r\n"
3484       "my-Test-header: value2\r\n";
3485   std::string expected_unmodified_with_end =
3486       "GET / HTTP/1.0\r\n"
3487       "Te: value1\r\n"
3488       "my-Test-header: value2\r\n\r\n";
3489 
3490   SimpleBuffer simple_buffer;
3491   headers.WriteToBuffer(&simple_buffer, BalsaHeaders::CaseOption::kPropercase,
3492                         BalsaHeaders::CoalesceOption::kNoCoalesce);
3493   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_proper_case);
3494 
3495   simple_buffer.Clear();
3496   headers.WriteToBuffer(&simple_buffer,
3497                         BalsaHeaders::CaseOption::kNoModification,
3498                         BalsaHeaders::CoalesceOption::kNoCoalesce);
3499   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_unmodified);
3500 
3501   simple_buffer.Clear();
3502   headers.WriteHeaderAndEndingToBuffer(
3503       &simple_buffer, BalsaHeaders::CaseOption::kNoModification,
3504       BalsaHeaders::CoalesceOption::kNoCoalesce);
3505   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_unmodified_with_end);
3506 
3507   simple_buffer.Clear();
3508   headers.WriteHeaderAndEndingToBuffer(
3509       &simple_buffer, BalsaHeaders::CaseOption::kPropercase,
3510       BalsaHeaders::CoalesceOption::kNoCoalesce);
3511   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_proper_case_with_end);
3512 }
3513 
TEST(BalsaHeadersTest,ToPropercaseTest)3514 TEST(BalsaHeadersTest, ToPropercaseTest) {
3515   EXPECT_EQ(BalsaHeaders::ToPropercase(""), "");
3516   EXPECT_EQ(BalsaHeaders::ToPropercase("Foo"), "Foo");
3517   EXPECT_EQ(BalsaHeaders::ToPropercase("foO"), "Foo");
3518   EXPECT_EQ(BalsaHeaders::ToPropercase("my-test-header"), "My-Test-Header");
3519   EXPECT_EQ(BalsaHeaders::ToPropercase("my--test-header"), "My--Test-Header");
3520 }
3521 
TEST(BalsaHeaders,WriteToBufferCoalescingMultivaluedHeaders)3522 TEST(BalsaHeaders, WriteToBufferCoalescingMultivaluedHeaders) {
3523   BalsaHeaders::MultivaluedHeadersSet multivalued_headers;
3524   multivalued_headers.insert("KeY1");
3525   multivalued_headers.insert("another_KEY");
3526 
3527   BalsaHeaders headers;
3528   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
3529   headers.AppendHeader("Key1", "value1");
3530   headers.AppendHeader("Key2", "value2");
3531   headers.AppendHeader("Key1", "value11");
3532   headers.AppendHeader("Key2", "value21");
3533   headers.AppendHeader("Key1", "multiples, values, already");
3534   std::string expected_non_coalesced =
3535       "GET / HTTP/1.0\r\n"
3536       "Key1: value1\r\n"
3537       "Key2: value2\r\n"
3538       "Key1: value11\r\n"
3539       "Key2: value21\r\n"
3540       "Key1: multiples, values, already\r\n";
3541   std::string expected_coalesced =
3542       "Key1: value1,value11,multiples, values, already\r\n"
3543       "Key2: value2\r\n"
3544       "Key2: value21\r\n";
3545 
3546   SimpleBuffer simple_buffer;
3547   headers.WriteToBuffer(&simple_buffer);
3548   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_non_coalesced);
3549 
3550   simple_buffer.Clear();
3551   headers.WriteToBufferCoalescingMultivaluedHeaders(
3552       &simple_buffer, multivalued_headers,
3553       BalsaHeaders::CaseOption::kNoModification);
3554   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_coalesced);
3555 }
3556 
TEST(BalsaHeaders,WriteToBufferCoalescingMultivaluedHeadersMultiLine)3557 TEST(BalsaHeaders, WriteToBufferCoalescingMultivaluedHeadersMultiLine) {
3558   BalsaHeaders::MultivaluedHeadersSet multivalued_headers;
3559   multivalued_headers.insert("Key 2");
3560   multivalued_headers.insert("key\n 3");
3561 
3562   BalsaHeaders headers;
3563   headers.AppendHeader("key1", "value1");
3564   headers.AppendHeader("key 2", "value\n 2");
3565   headers.AppendHeader("key\n 3", "value3");
3566   headers.AppendHeader("key 2", "value 21");
3567   headers.AppendHeader("key 3", "value 33");
3568   std::string expected_non_coalesced =
3569       "\r\n"
3570       "key1: value1\r\n"
3571       "key 2: value\n"
3572       " 2\r\n"
3573       "key\n"
3574       " 3: value3\r\n"
3575       "key 2: value 21\r\n"
3576       "key 3: value 33\r\n";
3577 
3578   SimpleBuffer simple_buffer;
3579   headers.WriteToBuffer(&simple_buffer);
3580   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_non_coalesced);
3581 
3582   std::string expected_coalesced =
3583       "key1: value1\r\n"
3584       "key 2: value\n"
3585       " 2,value 21\r\n"
3586       "key\n"
3587       " 3: value3\r\n"
3588       "key 3: value 33\r\n";
3589 
3590   simple_buffer.Clear();
3591   headers.WriteToBufferCoalescingMultivaluedHeaders(
3592       &simple_buffer, multivalued_headers,
3593       BalsaHeaders::CaseOption::kNoModification);
3594   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_coalesced);
3595 }
3596 
TEST(BalsaHeaders,WriteToBufferCoalescingEnvoyHeaders)3597 TEST(BalsaHeaders, WriteToBufferCoalescingEnvoyHeaders) {
3598   BalsaHeaders headers;
3599   headers.SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
3600   headers.AppendHeader("User-Agent", "UserAgent1");
3601   headers.AppendHeader("Key2", "value2");
3602   headers.AppendHeader("USER-AGENT", "UA2");
3603   headers.AppendHeader("Set-Cookie", "Cookie1=aaa");
3604   headers.AppendHeader("user-agent", "agent3");
3605   headers.AppendHeader("Set-Cookie", "Cookie2=bbb");
3606   std::string expected_non_coalesced =
3607       "GET / HTTP/1.0\r\n"
3608       "User-Agent: UserAgent1\r\n"
3609       "Key2: value2\r\n"
3610       "USER-AGENT: UA2\r\n"
3611       "Set-Cookie: Cookie1=aaa\r\n"
3612       "user-agent: agent3\r\n"
3613       "Set-Cookie: Cookie2=bbb\r\n"
3614       "\r\n";
3615   std::string expected_coalesced =
3616       "GET / HTTP/1.0\r\n"
3617       "User-Agent: UserAgent1,UA2,agent3\r\n"
3618       "Key2: value2\r\n"
3619       "Set-Cookie: Cookie1=aaa\r\n"
3620       "Set-Cookie: Cookie2=bbb\r\n"
3621       "\r\n";
3622 
3623   SimpleBuffer simple_buffer;
3624   headers.WriteHeaderAndEndingToBuffer(&simple_buffer);
3625   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_non_coalesced);
3626 
3627   simple_buffer.Clear();
3628   headers.WriteHeaderAndEndingToBuffer(
3629       &simple_buffer, BalsaHeaders::CaseOption::kNoModification,
3630       BalsaHeaders::CoalesceOption::kCoalesce);
3631   EXPECT_EQ(simple_buffer.GetReadableRegion(), expected_coalesced);
3632 }
3633 
TEST(BalsaHeadersTest,RemoveLastTokenFromOneLineHeader)3634 TEST(BalsaHeadersTest, RemoveLastTokenFromOneLineHeader) {
3635   BalsaHeaders headers =
3636       CreateHTTPHeaders(true,
3637                         "GET /foo HTTP/1.1\r\n"
3638                         "Content-Length: 0\r\n"
3639                         "Content-Encoding: gzip, 3des, tar, prc\r\n\r\n");
3640 
3641   BalsaHeaders::const_header_lines_key_iterator it =
3642       headers.GetIteratorForKey("Content-Encoding");
3643   ASSERT_EQ("gzip, 3des, tar, prc", it->second);
3644   EXPECT_EQ(headers.header_lines_key_end(), ++it);
3645 
3646   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3647   it = headers.GetIteratorForKey("Content-Encoding");
3648   ASSERT_EQ("gzip, 3des, tar", it->second);
3649   EXPECT_EQ(headers.header_lines_key_end(), ++it);
3650 
3651   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3652   it = headers.GetIteratorForKey("Content-Encoding");
3653   ASSERT_EQ("gzip, 3des", it->second);
3654   EXPECT_EQ(headers.header_lines_key_end(), ++it);
3655 
3656   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3657   it = headers.GetIteratorForKey("Content-Encoding");
3658   ASSERT_EQ("gzip", it->second);
3659   EXPECT_EQ(headers.header_lines_key_end(), ++it);
3660 
3661   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3662 
3663   EXPECT_FALSE(headers.HasHeader("Content-Encoding"));
3664 }
3665 
TEST(BalsaHeadersTest,RemoveLastTokenFromMultiLineHeader)3666 TEST(BalsaHeadersTest, RemoveLastTokenFromMultiLineHeader) {
3667   BalsaHeaders headers =
3668       CreateHTTPHeaders(true,
3669                         "GET /foo HTTP/1.1\r\n"
3670                         "Content-Length: 0\r\n"
3671                         "Content-Encoding: gzip, 3des\r\n"
3672                         "Content-Encoding: tar, prc\r\n\r\n");
3673 
3674   BalsaHeaders::const_header_lines_key_iterator it =
3675       headers.GetIteratorForKey("Content-Encoding");
3676   ASSERT_EQ("gzip, 3des", it->second);
3677   ASSERT_EQ("tar, prc", (++it)->second);
3678   ASSERT_EQ(headers.header_lines_key_end(), ++it);
3679 
3680   // First, we should start removing tokens from the second line.
3681   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3682   it = headers.GetIteratorForKey("Content-Encoding");
3683   ASSERT_EQ("gzip, 3des", it->second);
3684   ASSERT_EQ("tar", (++it)->second);
3685   ASSERT_EQ(headers.header_lines_key_end(), ++it);
3686 
3687   // Second line should be entirely removed after all its tokens are gone.
3688   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3689   it = headers.GetIteratorForKey("Content-Encoding");
3690   ASSERT_EQ("gzip, 3des", it->second);
3691   ASSERT_EQ(headers.header_lines_key_end(), ++it);
3692 
3693   // Now we should be removing the tokens from the first line.
3694   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3695   it = headers.GetIteratorForKey("Content-Encoding");
3696   ASSERT_EQ("gzip", it->second);
3697   ASSERT_EQ(headers.header_lines_key_end(), ++it);
3698 
3699   headers.RemoveLastTokenFromHeaderValue("Content-Encoding");
3700   EXPECT_FALSE(headers.HasHeader("Content-Encoding"));
3701 }
3702 
TEST(BalsaHeadersTest,ResponseCanHaveBody)3703 TEST(BalsaHeadersTest, ResponseCanHaveBody) {
3704   // 1xx, 204 no content and 304 not modified responses can't have bodies.
3705   EXPECT_FALSE(BalsaHeaders::ResponseCanHaveBody(100));
3706   EXPECT_FALSE(BalsaHeaders::ResponseCanHaveBody(101));
3707   EXPECT_FALSE(BalsaHeaders::ResponseCanHaveBody(102));
3708   EXPECT_FALSE(BalsaHeaders::ResponseCanHaveBody(204));
3709   EXPECT_FALSE(BalsaHeaders::ResponseCanHaveBody(304));
3710 
3711   // Other responses can have body.
3712   EXPECT_TRUE(BalsaHeaders::ResponseCanHaveBody(200));
3713   EXPECT_TRUE(BalsaHeaders::ResponseCanHaveBody(302));
3714   EXPECT_TRUE(BalsaHeaders::ResponseCanHaveBody(404));
3715   EXPECT_TRUE(BalsaHeaders::ResponseCanHaveBody(502));
3716 }
3717 
3718 }  // namespace
3719 
3720 }  // namespace test
3721 
3722 }  // namespace quiche
3723