Home | History | Annotate | Download | only in flip_server
      1 // Copyright (c) 2009 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 #ifndef NET_TOOLS_FLIP_SERVER_BALSA_HEADERS_H_
      6 #define NET_TOOLS_FLIP_SERVER_BALSA_HEADERS_H_
      7 
      8 #include <algorithm>
      9 #include <iostream>
     10 #include <iterator>
     11 #include <string>
     12 #include <utility>
     13 #include <vector>
     14 
     15 #include "base/port.h"
     16 #include "base/logging.h"
     17 #include "base/string_piece.h"
     18 #include "net/tools/flip_server/balsa_enums.h"
     19 #include "net/tools/flip_server/string_piece_utils.h"
     20 
     21 namespace net {
     22 
     23 // WARNING:
     24 // Note that -no- char* returned by any function in this
     25 // file is null-terminated.
     26 
     27 // This class exists to service the specific needs of BalsaHeaders.
     28 //
     29 // Functional goals:
     30 //   1) provide a backing-store for all of the StringPieces that BalsaHeaders
     31 //      returns. Every StringPiece returned from BalsaHeaders should remain
     32 //      valid until the BalsaHeader's object is cleared, or the header-line is
     33 //      erased.
     34 //   2) provide a backing-store for BalsaFrame, which requires contiguous memory
     35 //      for its fast-path parsing functions. Note that the cost of copying is
     36 //      less than the cost of requiring the parser to do slow-path parsing, as
     37 //      it would have to check for bounds every byte, instead of every 16 bytes.
     38 //
     39 // This class is optimized for the case where headers are stored in one of two
     40 // buffers. It doesn't make a lot of effort to densely pack memory-- in fact,
     41 // it -may- be somewhat memory inefficient. This possible inefficiency allows a
     42 // certain simplicity of implementation and speed which makes it worthwhile.
     43 // If, in the future, better memory density is required, it should be possible
     44 // to reuse the abstraction presented by this object to achieve those goals.
     45 //
     46 // In the most common use-case, this memory inefficiency should be relatively
     47 // small.
     48 //
     49 // Alternate implementations of BalsaBuffer may include:
     50 //  - vector of strings, one per header line (similar to HTTPHeaders)
     51 //  - densely packed strings:
     52 //    - keep a sorted array/map of free-space linked lists or numbers.
     53 //      - use the entry that most closely first your needs.
     54 //    - at this point, perhaps just use a vector of strings, and let
     55 //      the allocator do the right thing.
     56 //
     57 class BalsaBuffer {
     58  public:
     59   static const size_t kDefaultBlocksize = 4096;
     60   // We have two friends here. These exist as friends as we
     61   // want to allow access to the constructors for the test
     62   // class and the Balsa* classes. We put this into the
     63   // header file as we want this class to be inlined into the
     64   // BalsaHeaders implementation, yet be testable.
     65   friend class BalsaBufferTestSpouse;
     66   friend class BalsaHeaders;
     67 
     68   // The BufferBlock is a structure used internally by the
     69   // BalsaBuffer class to store the base buffer pointers to
     70   // each block, as well as the important metadata for buffer
     71   // sizes and bytes free.
     72   struct BufferBlock {
     73    public:
     74     char* buffer;
     75     size_t buffer_size;
     76     size_t bytes_free;
     77 
     78     size_t bytes_used() const {
     79       return buffer_size - bytes_free;
     80     }
     81     char* start_of_unused_bytes() const {
     82       return buffer + bytes_used();
     83     }
     84 
     85     BufferBlock() : buffer(NULL), buffer_size(0), bytes_free(0) {}
     86     ~BufferBlock() {}
     87 
     88     BufferBlock(char* buf, size_t size, size_t free) :
     89         buffer(buf), buffer_size(size), bytes_free(free) {}
     90     // Yes we want this to be copyable (it gets stuck into vectors).
     91     // For this reason, we don't use scoped ptrs, etc. here-- it
     92     // is more efficient to manage this memory externally to this
     93     // object.
     94   };
     95 
     96   typedef std::vector<BufferBlock> Blocks;
     97 
     98   ~BalsaBuffer() {
     99     CleanupBlocksStartingFrom(0);
    100   }
    101 
    102   // Returns the total amount of memory used by the buffer blocks.
    103   size_t GetTotalBufferBlockSize() const {
    104     size_t buffer_size = 0;
    105     for (Blocks::const_iterator iter = blocks_.begin();
    106          iter != blocks_.end();
    107          ++iter) {
    108       buffer_size += iter->buffer_size;
    109     }
    110     return buffer_size;
    111   }
    112 
    113   const char* GetPtr(Blocks::size_type block_idx) const {
    114     DCHECK_LT(block_idx, blocks_.size())
    115       << block_idx << ", " << blocks_.size();
    116     return blocks_[block_idx].buffer;
    117   }
    118 
    119   char* GetPtr(Blocks::size_type block_idx) {
    120     DCHECK_LT(block_idx, blocks_.size())
    121       << block_idx << ", " << blocks_.size();
    122     return blocks_[block_idx].buffer;
    123   }
    124 
    125   // This function is different from Write(), as it ensures that the data
    126   // stored via subsequent calls to this function are all contiguous (and in
    127   // the order in which these writes happened). This is essentially the same
    128   // as a string append.
    129   //
    130   // You may call this function at any time between object
    131   // construction/Clear(), and the calling of the
    132   // NoMoreWriteToContiguousBuffer() function.
    133   //
    134   // You must not call this function after the NoMoreWriteToContiguousBuffer()
    135   // function is called, unless a Clear() has been called since.
    136   // If you do, the program will abort().
    137   //
    138   // This condition is placed upon this code so that calls to Write() can
    139   // append to the buffer in the first block safely, and without invaliding
    140   // the StringPiece which it returns.
    141   //
    142   // This function's main intended user is the BalsaFrame class, which,
    143   // for reasons of efficiency, requires that the buffer from which it parses
    144   // the headers be contiguous.
    145   //
    146   void WriteToContiguousBuffer(const base::StringPiece& sp) {
    147     if (sp.empty()) {
    148       return;
    149     }
    150     CHECK(can_write_to_contiguous_buffer_);
    151     DCHECK_GE(blocks_.size(), 1u);
    152     if (blocks_[0].buffer == NULL && sp.size() <= blocksize_) {
    153       blocks_[0] = AllocBlock();
    154       memcpy(blocks_[0].start_of_unused_bytes(), sp.data(), sp.size());
    155     } else if (blocks_[0].bytes_free < sp.size()) {
    156       // the first block isn't big enough, resize it.
    157       const size_t old_storage_size_used = blocks_[0].bytes_used();
    158       const size_t new_storage_size = old_storage_size_used + sp.size();
    159       char* new_storage = new char[new_storage_size];
    160       char* old_storage = blocks_[0].buffer;
    161       if (old_storage_size_used) {
    162         memcpy(new_storage, old_storage, old_storage_size_used);
    163       }
    164       memcpy(new_storage + old_storage_size_used, sp.data(), sp.size());
    165       blocks_[0].buffer = new_storage;
    166       blocks_[0].bytes_free = sp.size();
    167       blocks_[0].buffer_size = new_storage_size;
    168       delete[] old_storage;
    169     } else {
    170       memcpy(blocks_[0].start_of_unused_bytes(), sp.data(), sp.size());
    171     }
    172     blocks_[0].bytes_free -= sp.size();
    173   }
    174 
    175   void NoMoreWriteToContiguousBuffer() {
    176     can_write_to_contiguous_buffer_ = false;
    177   }
    178 
    179   // Takes a StringPiece and writes it to "permanent" storage, then returns a
    180   // StringPiece which points to that data.  If block_idx != NULL, it will be
    181   // assigned the index of the block into which the data was stored.
    182   // Note that the 'permanent' storage in which it stores data may be in
    183   // the first block IFF the NoMoreWriteToContiguousBuffer function has
    184   // been called since the last Clear/Construction.
    185   base::StringPiece Write(const base::StringPiece& sp,
    186                     Blocks::size_type* block_buffer_idx) {
    187     if (sp.empty()) {
    188       return sp;
    189     }
    190     char* storage = Reserve(sp.size(), block_buffer_idx);
    191     memcpy(storage, sp.data(), sp.size());
    192     return base::StringPiece(storage, sp.size());
    193   }
    194 
    195   // Reserves "permanent" storage of the size indicated. Returns a pointer to
    196   // the beginning of that storage, and assigns the index of the block used to
    197   // block_buffer_idx. This function uses the first block IFF the
    198   // NoMoreWriteToContiguousBuffer function has been called since the last
    199   // Clear/Construction.
    200   char* Reserve(size_t size,
    201                 Blocks::size_type* block_buffer_idx) {
    202     // There should always be a 'first_block', even if it
    203     // contains nothing.
    204     DCHECK_GE(blocks_.size(), 1u);
    205     BufferBlock* block = NULL;
    206     Blocks::size_type block_idx = can_write_to_contiguous_buffer_ ? 1 : 0;
    207     for (; block_idx < blocks_.size(); ++block_idx) {
    208       if (blocks_[block_idx].bytes_free >= size) {
    209         block = &blocks_[block_idx];
    210         break;
    211       }
    212     }
    213     if (block == NULL) {
    214       if (blocksize_ < size) {
    215         blocks_.push_back(AllocCustomBlock(size));
    216       } else {
    217         blocks_.push_back(AllocBlock());
    218       }
    219       block = &blocks_.back();
    220     }
    221 
    222     char* storage = block->start_of_unused_bytes();
    223     block->bytes_free -= size;
    224     if (block_buffer_idx) {
    225       *block_buffer_idx = block_idx;
    226     }
    227     return storage;
    228   }
    229 
    230   void Clear() {
    231     CHECK(!blocks_.empty());
    232     if (blocksize_ == blocks_[0].buffer_size) {
    233       CleanupBlocksStartingFrom(1);
    234       blocks_[0].bytes_free = blocks_[0].buffer_size;
    235     } else {
    236       CleanupBlocksStartingFrom(0);
    237       blocks_.push_back(AllocBlock());
    238     }
    239     DCHECK_GE(blocks_.size(), 1u);
    240     can_write_to_contiguous_buffer_ = true;
    241   }
    242 
    243   void Swap(BalsaBuffer* b) {
    244     blocks_.swap(b->blocks_);
    245     std::swap(can_write_to_contiguous_buffer_,
    246               b->can_write_to_contiguous_buffer_);
    247     std::swap(blocksize_, b->blocksize_);
    248   }
    249 
    250   void CopyFrom(const BalsaBuffer& b) {
    251     CleanupBlocksStartingFrom(0);
    252     blocks_.resize(b.blocks_.size());
    253     for (Blocks::size_type i = 0; i < blocks_.size(); ++i) {
    254       blocks_[i] = CopyBlock(b.blocks_[i]);
    255     }
    256     blocksize_ = b.blocksize_;
    257     can_write_to_contiguous_buffer_ = b.can_write_to_contiguous_buffer_;
    258   }
    259 
    260   const char* StartOfFirstBlock() const {
    261     return blocks_[0].buffer;
    262   }
    263 
    264   const char* EndOfFirstBlock() const {
    265     return blocks_[0].buffer + blocks_[0].bytes_used();
    266   }
    267 
    268   bool can_write_to_contiguous_buffer() const {
    269     return can_write_to_contiguous_buffer_;
    270   }
    271   size_t blocksize() const { return blocksize_; }
    272   Blocks::size_type num_blocks() const { return blocks_.size(); }
    273   size_t buffer_size(size_t idx) const { return blocks_[idx].buffer_size; }
    274   size_t bytes_used(size_t idx) const { return blocks_[idx].bytes_used(); }
    275 
    276  protected:
    277   BalsaBuffer() :
    278       blocksize_(kDefaultBlocksize), can_write_to_contiguous_buffer_(true) {
    279     blocks_.push_back(AllocBlock());
    280   }
    281 
    282   explicit BalsaBuffer(size_t blocksize) :
    283       blocksize_(blocksize), can_write_to_contiguous_buffer_(true) {
    284     blocks_.push_back(AllocBlock());
    285   }
    286 
    287   BufferBlock AllocBlock() {
    288     return AllocCustomBlock(blocksize_);
    289   }
    290 
    291   BufferBlock AllocCustomBlock(size_t blocksize) {
    292     return BufferBlock(new char[blocksize], blocksize, blocksize);
    293   }
    294 
    295   BufferBlock CopyBlock(const BufferBlock& b) {
    296     BufferBlock block = b;
    297     if (b.buffer == NULL) {
    298       return block;
    299     }
    300 
    301     block.buffer = new char[b.buffer_size];
    302     memcpy(block.buffer, b.buffer, b.bytes_used());
    303     return block;
    304   }
    305 
    306   // Cleans up the object.
    307   // The block at start_idx, and all subsequent blocks
    308   // will be cleared and have associated memory deleted.
    309   void CleanupBlocksStartingFrom(Blocks::size_type start_idx) {
    310     for (Blocks::size_type i = start_idx; i < blocks_.size(); ++i) {
    311       delete[] blocks_[i].buffer;
    312     }
    313     blocks_.resize(start_idx);
    314   }
    315 
    316   // A container of BufferBlocks
    317   Blocks blocks_;
    318 
    319   // The default allocation size for a block.
    320   // In general, blocksize_ bytes will be allocated for
    321   // each buffer.
    322   size_t blocksize_;
    323 
    324   // If set to true, then the first block cannot be used for Write() calls as
    325   // the WriteToContiguous... function will modify the base pointer for this
    326   // block, and the Write() calls need to be sure that the base pointer will
    327   // not be changing in order to provide the user with StringPieces which
    328   // continue to be valid.
    329   bool can_write_to_contiguous_buffer_;
    330 };
    331 
    332 ////////////////////////////////////////////////////////////////////////////////
    333 
    334 // All of the functions in the BalsaHeaders class use string pieces, by either
    335 // using the StringPiece class, or giving an explicit size and char* (as these
    336 // are the native representation for these string pieces).
    337 // This is done for several reasons.
    338 //  1) This minimizes copying/allocation/deallocation as compared to using
    339 //  string parameters
    340 //  2) This reduces the number of strlen() calls done (as the length of any
    341 //  string passed in is relatively likely to be known at compile time, and for
    342 //  those strings passed back we obviate the need for a strlen() to determine
    343 //  the size of new storage allocations if a new allocation is required.
    344 //  3) This class attempts to store all of its data in two linear buffers in
    345 //  order to enhance the speed of parsing and writing out to a buffer. As a
    346 //  result, many string pieces are -not- terminated by '\0', and are not
    347 //  c-strings.  Since this is the case, we must delineate the length of the
    348 //  string explicitly via a length.
    349 //
    350 //  WARNING:  The side effect of using StringPiece is that if the underlying
    351 //  buffer changes (due to modifying the headers) the StringPieces which point
    352 //  to the data which was modified, may now contain "garbage", and should not
    353 //  be dereferenced.
    354 //  For example, If you fetch some component of the first-line, (request or
    355 //  response), and then you modify the first line, the StringPieces you
    356 //  originally received from the original first-line may no longer be valid).
    357 //
    358 //  StringPieces pointing to pieces of header lines which have not been
    359 //  erased() or modified should be valid until the object is cleared or
    360 //  destroyed.
    361 
    362 class BalsaHeaders {
    363  public:
    364   struct HeaderLineDescription {
    365     HeaderLineDescription(size_t first_character_index,
    366                           size_t key_end_index,
    367                           size_t value_begin_index,
    368                           size_t last_character_index,
    369                           size_t buffer_base_index) :
    370         first_char_idx(first_character_index),
    371         key_end_idx(key_end_index),
    372         value_begin_idx(value_begin_index),
    373         last_char_idx(last_character_index),
    374         buffer_base_idx(buffer_base_index),
    375         skip(false) {}
    376 
    377     HeaderLineDescription() :
    378         first_char_idx(0),
    379         key_end_idx(0),
    380         value_begin_idx(0),
    381         last_char_idx(0),
    382         buffer_base_idx(0),
    383         skip(false) {}
    384 
    385     size_t first_char_idx;
    386     size_t key_end_idx;
    387     size_t value_begin_idx;
    388     size_t last_char_idx;
    389     BalsaBuffer::Blocks::size_type buffer_base_idx;
    390     bool skip;
    391   };
    392 
    393   typedef std::vector<base::StringPiece> HeaderTokenList;
    394   friend bool net::ParseHTTPFirstLine(const char* begin,
    395                                        const char* end,
    396                                        bool is_request,
    397                                        size_t max_request_uri_length,
    398                                        BalsaHeaders* headers,
    399                                        BalsaFrameEnums::ErrorCode* error_code);
    400 
    401  protected:
    402   typedef std::vector<HeaderLineDescription> HeaderLines;
    403 
    404   // Why these base classes (iterator_base, reverse_iterator_base)?  Well, if
    405   // we do want to export both iterator and const_iterator types (currently we
    406   // only have const_iterator), then this is useful to avoid code duplication.
    407   // Additionally, having this base class makes comparisons of iterators of
    408   // different types (they're different types to ensure that operator= and
    409   // constructors do not work in the places where they're expected to not work)
    410   // work properly. There could be as many as 4 iterator types, all based on
    411   // the same data as iterator_base... so it makes sense to simply have some
    412   // base classes.
    413 
    414   class iterator_base {
    415    public:
    416     friend class BalsaHeaders;
    417     friend class reverse_iterator_base;
    418     typedef std::pair<base::StringPiece, base::StringPiece> StringPiecePair;
    419     typedef StringPiecePair value_type;
    420     typedef value_type& reference;
    421     typedef value_type* pointer;
    422 
    423     typedef std::forward_iterator_tag iterator_category;
    424     typedef ptrdiff_t difference_type;
    425 
    426     typedef iterator_base self;
    427 
    428     // default constructor.
    429     iterator_base() : headers_(NULL), idx_(0) { }
    430 
    431     // copy constructor.
    432     iterator_base(const iterator_base& it)
    433       : headers_(it.headers_),
    434         idx_(it.idx_) {}
    435 
    436     reference operator*() const {
    437       return Lookup(idx_);
    438     }
    439 
    440     pointer operator->() const {
    441       return &(this->operator*());
    442     }
    443 
    444     bool operator==(const self& it) const {
    445       return idx_ == it.idx_;
    446     }
    447 
    448     bool operator<(const self& it) const {
    449       return idx_ < it.idx_;
    450     }
    451 
    452     bool operator<=(const self& it) const {
    453       return idx_ <= it.idx_;
    454     }
    455 
    456     bool operator!=(const self& it) const {
    457       return !(*this == it);
    458     }
    459 
    460     bool operator>(const self& it) const {
    461       return it < *this;
    462     }
    463 
    464     bool operator>=(const self& it) const {
    465       return it <= *this;
    466     }
    467 
    468     // This mainly exists so that we can have interesting output for
    469     // unittesting. The EXPECT_EQ, EXPECT_NE functions require that
    470     // operator<< work for the classes it sees.  It would be better if there
    471     // was an additional traits-like system for the gUnit output... but oh
    472     // well.
    473     friend std::ostream& operator<<(std::ostream& os, const iterator_base& it) {
    474       os << "[" << it.headers_ << ", " << it.idx_ << "]";
    475       return os;
    476     }
    477 
    478    protected:
    479     iterator_base(const BalsaHeaders* headers, HeaderLines::size_type index) :
    480         headers_(headers),
    481         idx_(index) {}
    482 
    483     void increment() {
    484       const HeaderLines& header_lines = headers_->header_lines_;
    485       const HeaderLines::size_type header_lines_size = header_lines.size();
    486       const HeaderLines::size_type original_idx = idx_;
    487       do {
    488         ++idx_;
    489       } while (idx_ < header_lines_size && header_lines[idx_].skip == true);
    490       // The condition below exists so that ++(end() - 1) == end(), even
    491       // if there are only 'skip == true' elements between the end() iterator
    492       // and the end of the vector of HeaderLineDescriptions.
    493       // TODO(fenix): refactor this list so that we don't have to do
    494       // linear scanning through skipped headers (and this condition is
    495       // then unnecessary)
    496       if (idx_ == header_lines_size) {
    497         idx_ = original_idx + 1;
    498       }
    499     }
    500 
    501     void decrement() {
    502       const HeaderLines& header_lines = headers_->header_lines_;
    503       const HeaderLines::size_type header_lines_size = header_lines.size();
    504       const HeaderLines::size_type original_idx = idx_;
    505       do {
    506         --idx_;
    507       } while (idx_ >= 0 &&
    508               idx_ < header_lines_size &&
    509               header_lines[idx_].skip == true);
    510       // The condition below exists so that --(rbegin() + 1) == rbegin(), even
    511       // if there are only 'skip == true' elements between the rbegin() iterator
    512       // and the beginning of the vector of HeaderLineDescriptions.
    513       // TODO(fenix): refactor this list so that we don't have to do
    514       // linear scanning through skipped headers (and this condition is
    515       // then unnecessary)
    516       if (idx_ < 0 || idx_ > header_lines_size) {
    517         idx_ = original_idx - 1;
    518       }
    519     }
    520 
    521     reference Lookup(HeaderLines::size_type index) const {
    522       DCHECK_LT(index, headers_->header_lines_.size());
    523       const HeaderLineDescription& line = headers_->header_lines_[index];
    524       const char* stream_begin = headers_->GetPtr(line.buffer_base_idx);
    525       value_ = value_type(
    526           base::StringPiece(stream_begin + line.first_char_idx,
    527                       line.key_end_idx - line.first_char_idx),
    528           base::StringPiece(stream_begin + line.value_begin_idx,
    529                       line.last_char_idx - line.value_begin_idx));
    530       DCHECK_GE(line.key_end_idx, line.first_char_idx);
    531       DCHECK_GE(line.last_char_idx, line.value_begin_idx);
    532       return value_;
    533     }
    534 
    535     const BalsaHeaders* headers_;
    536     HeaderLines::size_type idx_;
    537     mutable StringPiecePair value_;
    538   };
    539 
    540   class reverse_iterator_base : public iterator_base {
    541    public:
    542     typedef reverse_iterator_base self;
    543     typedef iterator_base::reference reference;
    544     typedef iterator_base::pointer pointer;
    545     using iterator_base::headers_;
    546     using iterator_base::idx_;
    547 
    548     reverse_iterator_base() : iterator_base() {}
    549 
    550     // This constructor is no explicit purposely.
    551     reverse_iterator_base(const iterator_base& it) :  // NOLINT
    552         iterator_base(it) {
    553     }
    554 
    555     self& operator=(const iterator_base& it) {
    556       idx_ = it.idx_;
    557       headers_ = it.headers_;
    558       return *this;
    559     }
    560 
    561     self& operator=(const reverse_iterator_base& it) {
    562       idx_ = it.idx_;
    563       headers_ = it.headers_;
    564       return *this;
    565     }
    566 
    567     reference operator*() const {
    568       return Lookup(idx_ - 1);
    569     }
    570 
    571     pointer operator->() const {
    572       return &(this->operator*());
    573     }
    574 
    575     reverse_iterator_base(const reverse_iterator_base& it) :
    576         iterator_base(it) { }
    577 
    578    protected:
    579     void increment() {
    580       --idx_;
    581       iterator_base::decrement();
    582       ++idx_;
    583     }
    584 
    585     void decrement() {
    586       ++idx_;
    587       iterator_base::increment();
    588       --idx_;
    589     }
    590 
    591     reverse_iterator_base(const BalsaHeaders* headers,
    592                           HeaderLines::size_type index) :
    593         iterator_base(headers, index) {}
    594   };
    595 
    596  public:
    597   class const_header_lines_iterator : public iterator_base {
    598     friend class BalsaHeaders;
    599    public:
    600     typedef const_header_lines_iterator self;
    601     const_header_lines_iterator() : iterator_base() {}
    602 
    603     const_header_lines_iterator(const const_header_lines_iterator& it) :
    604         iterator_base(it.headers_, it.idx_) {}
    605 
    606     self& operator++() {
    607       iterator_base::increment();
    608       return *this;
    609     }
    610 
    611     self& operator--() {
    612       iterator_base::decrement();
    613       return *this;
    614     }
    615    protected:
    616     const_header_lines_iterator(const BalsaHeaders* headers,
    617                                 HeaderLines::size_type index) :
    618         iterator_base(headers, index) {}
    619   };
    620 
    621   class const_reverse_header_lines_iterator : public reverse_iterator_base {
    622    public:
    623     typedef const_reverse_header_lines_iterator self;
    624     const_reverse_header_lines_iterator() : reverse_iterator_base() {}
    625 
    626     const_reverse_header_lines_iterator(
    627       const const_header_lines_iterator& it) :
    628         reverse_iterator_base(it.headers_, it.idx_) {}
    629 
    630     const_reverse_header_lines_iterator(
    631       const const_reverse_header_lines_iterator& it) :
    632         reverse_iterator_base(it.headers_, it.idx_) {}
    633 
    634     const_header_lines_iterator base() {
    635       return const_header_lines_iterator(headers_, idx_);
    636     }
    637 
    638     self& operator++() {
    639       reverse_iterator_base::increment();
    640       return *this;
    641     }
    642 
    643     self& operator--() {
    644       reverse_iterator_base::decrement();
    645       return *this;
    646     }
    647    protected:
    648     const_reverse_header_lines_iterator(const BalsaHeaders* headers,
    649                                         HeaderLines::size_type index) :
    650         reverse_iterator_base(headers, index) {}
    651 
    652     friend class BalsaHeaders;
    653   };
    654 
    655   // An iterator that only stops at lines with a particular key.
    656   // See also GetIteratorForKey.
    657   //
    658   // Check against header_lines_key_end() to determine when iteration is
    659   // finished. header_lines_end() will also work.
    660   class const_header_lines_key_iterator : public iterator_base {
    661     friend class BalsaHeaders;
    662    public:
    663     typedef const_header_lines_key_iterator self;
    664 
    665     self& operator++() {
    666       do {
    667         iterator_base::increment();
    668       } while (!AtEnd() &&
    669                !StringPieceUtils::EqualIgnoreCase(key_, (**this).first));
    670       return *this;
    671     }
    672 
    673     void operator++(int ignore) {
    674       ++(*this);
    675     }
    676 
    677     // Only forward-iteration makes sense, so no operator-- defined.
    678 
    679    private:
    680     const_header_lines_key_iterator(const BalsaHeaders* headers,
    681                                     HeaderLines::size_type index,
    682                                     const base::StringPiece& key)
    683         : iterator_base(headers, index),
    684           key_(key) {
    685     }
    686 
    687     // Should only be used for creating an end iterator.
    688     const_header_lines_key_iterator(const BalsaHeaders* headers,
    689                                     HeaderLines::size_type index)
    690         : iterator_base(headers, index) {
    691     }
    692 
    693     bool AtEnd() const {
    694       return *this >= headers_->header_lines_end();
    695     }
    696 
    697     base::StringPiece key_;
    698   };
    699 
    700   // TODO(fenix): Revisit the amount of bytes initially allocated to the second
    701   // block of the balsa_buffer_. It may make sense to pre-allocate some amount
    702   // (roughly the amount we'd append in new headers such as X-User-Ip, etc.)
    703   BalsaHeaders() :
    704       balsa_buffer_(4096),
    705       content_length_(0),
    706       content_length_status_(BalsaHeadersEnums::NO_CONTENT_LENGTH),
    707       parsed_response_code_(0),
    708       firstline_buffer_base_idx_(0),
    709       whitespace_1_idx_(0),
    710       non_whitespace_1_idx_(0),
    711       whitespace_2_idx_(0),
    712       non_whitespace_2_idx_(0),
    713       whitespace_3_idx_(0),
    714       non_whitespace_3_idx_(0),
    715       whitespace_4_idx_(0),
    716       end_of_firstline_idx_(0),
    717       transfer_encoding_is_chunked_(false) { }
    718 
    719   const_header_lines_iterator header_lines_begin() {
    720     return HeaderLinesBeginHelper<const_header_lines_iterator>();
    721   }
    722 
    723   const_header_lines_iterator header_lines_begin() const {
    724     return HeaderLinesBeginHelper<const_header_lines_iterator>();
    725   }
    726 
    727   const_header_lines_iterator header_lines_end() {
    728     return HeaderLinesEndHelper<const_header_lines_iterator>();
    729   }
    730 
    731   const_header_lines_iterator header_lines_end() const {
    732     return HeaderLinesEndHelper<const_header_lines_iterator>();
    733   }
    734 
    735   const_reverse_header_lines_iterator header_lines_rbegin() {
    736     return const_reverse_header_lines_iterator(header_lines_end());
    737   }
    738 
    739   const_reverse_header_lines_iterator header_lines_rbegin() const {
    740     return const_reverse_header_lines_iterator(header_lines_end());
    741   }
    742 
    743   const_reverse_header_lines_iterator header_lines_rend() {
    744     return const_reverse_header_lines_iterator(header_lines_begin());
    745   }
    746 
    747   const_reverse_header_lines_iterator header_lines_rend() const {
    748     return const_reverse_header_lines_iterator(header_lines_begin());
    749   }
    750 
    751   const_header_lines_key_iterator header_lines_key_end() const {
    752     return HeaderLinesEndHelper<const_header_lines_key_iterator>();
    753   }
    754 
    755   void erase(const const_header_lines_iterator& it) {
    756     DCHECK_EQ(it.headers_, this);
    757     DCHECK_LT(it.idx_, header_lines_.size());
    758     DCHECK_GE(it.idx_, 0u);
    759     header_lines_[it.idx_].skip = true;
    760   }
    761 
    762   void Clear();
    763 
    764   void Swap(BalsaHeaders* other);
    765 
    766   void CopyFrom(const BalsaHeaders& other);
    767 
    768   void HackHeader(const base::StringPiece& key, const base::StringPiece& value);
    769 
    770   // Same as AppendToHeader, except that it will attempt to preserve
    771   // header ordering.
    772   // Note that this will always append to an existing header, if available,
    773   // without moving the header around, or collapsing multiple header lines
    774   // with the same key together. For this reason, it only 'attempts' to
    775   // preserve header ordering.
    776   // TODO(fenix): remove this function and rename all occurances
    777   // of it in the code to AppendToHeader when the condition above
    778   // has been satisified.
    779   void HackAppendToHeader(const base::StringPiece& key,
    780                           const base::StringPiece& value);
    781 
    782   // Replaces header entries with key 'key' if they exist, or appends
    783   // a new header if none exist.  See 'AppendHeader' below for additional
    784   // comments about ContentLength and TransferEncoding headers. Note that this
    785   // will allocate new storage every time that it is called.
    786   // TODO(fenix): modify this function to reuse existing storage
    787   // if it is available.
    788   void ReplaceOrAppendHeader(const base::StringPiece& key,
    789                              const base::StringPiece& value);
    790 
    791   // Append a new header entry to the header object. Clients who wish to append
    792   // Content-Length header should use SetContentLength() method instead of
    793   // adding the content length header using AppendHeader (manually adding the
    794   // content length header will not update the content_length_ and
    795   // content_length_status_ values).
    796   // Similarly, clients who wish to add or remove the transfer encoding header
    797   // in order to apply or remove chunked encoding should use SetChunkEncoding()
    798   // instead.
    799   void AppendHeader(const base::StringPiece& key,
    800                     const base::StringPiece& value);
    801 
    802   // Appends ',value' to an existing header named 'key'.  If no header with the
    803   // correct key exists, it will call AppendHeader(key, value).  Calling this
    804   // function on a key which exists several times in the headers will produce
    805   // unpredictable results.
    806   void AppendToHeader(const base::StringPiece& key,
    807                       const base::StringPiece& value);
    808 
    809   // Prepends 'value,' to an existing header named 'key'.  If no header with the
    810   // correct key exists, it will call AppendHeader(key, value).  Calling this
    811   // function on a key which exists several times in the headers will produce
    812   // unpredictable results.
    813   void PrependToHeader(const base::StringPiece& key,
    814                        const base::StringPiece& value);
    815 
    816   const base::StringPiece GetHeader(const base::StringPiece& key) const;
    817 
    818   // Iterates over all currently valid header lines, appending their
    819   // values into the vector 'out', in top-to-bottom order.
    820   // Header-lines which have been erased are not currently valid, and
    821   // will not have their values appended. Empty values will be
    822   // represented as empty string. If 'key' doesn't exist in the headers at
    823   // all, out will not be changed. We do not clear the vector out
    824   // before adding new entries. If there are header lines with matching
    825   // key but empty value then they are also added to the vector out.
    826   // (Basically empty values are not treated in any special manner).
    827   //
    828   // Example:
    829   // Input header:
    830   // "GET / HTTP/1.0\r\n"
    831   //    "key1: v1\r\n"
    832   //    "key1: \r\n"
    833   //    "key1:\r\n"
    834   //    "key1:  v1\r\n"
    835   //    "key1:v2\r\n"
    836   //
    837   //  vector out is initially: ["foo"]
    838   //  vector out after GetAllOfHeader("key1", &out) is:
    839   // ["foo", "v1", "", "", "v2", "v1", "v2"]
    840 
    841   void GetAllOfHeader(const base::StringPiece& key,
    842                       std::vector<base::StringPiece>* out) const;
    843 
    844   // Joins all values for key into a comma-separated string in out.
    845   // More efficient than calling JoinStrings on result of GetAllOfHeader if
    846   // you don't need the intermediate vector<StringPiece>.
    847   void GetAllOfHeaderAsString(const base::StringPiece& key,
    848                               std::string* out) const;
    849 
    850   // Returns true if RFC 2616 Section 14 indicates that header can
    851   // have multiple values.
    852   static bool IsMultivaluedHeader(const base::StringPiece& header);
    853 
    854   // Determine if a given header is present.
    855   inline bool HasHeader(const base::StringPiece& key) const {
    856     return (GetConstHeaderLinesIterator(key, header_lines_.begin()) !=
    857             header_lines_.end());
    858   }
    859 
    860   // Returns true iff any header 'key' exists with non-empty value.
    861   bool HasNonEmptyHeader(const base::StringPiece& key) const;
    862 
    863   const_header_lines_iterator GetHeaderPosition(
    864       const base::StringPiece& key) const;
    865 
    866   // Returns a forward-only iterator that only stops at lines matching key.
    867   // String backing 'key' must remain valid for lifetime of iterator.
    868   //
    869   // Check returned iterator against header_lines_key_end() to determine when
    870   // iteration is finished.
    871   const_header_lines_key_iterator GetIteratorForKey(
    872       const base::StringPiece& key) const;
    873 
    874   void RemoveAllOfHeader(const base::StringPiece& key);
    875 
    876   // Removes all headers starting with 'key' [case insensitive]
    877   void RemoveAllHeadersWithPrefix(const base::StringPiece& key);
    878 
    879   // Returns the lower bound of memory  used by this header object, including
    880   // all internal buffers and data structure. Some of the memory used cannot be
    881   // directly measure. For example, memory used for bookkeeping by standard
    882   // containers.
    883   size_t GetMemoryUsedLowerBound() const;
    884 
    885   // Returns the upper bound on the required buffer space to fully write out
    886   // the header object (this include the first line, all header lines, and the
    887   // final CRLF that marks the ending of the header).
    888   size_t GetSizeForWriteBuffer() const;
    889 
    890   // The following WriteHeader* methods are template member functions that
    891   // place one requirement on the Buffer class: it must implement a Write
    892   // method that takes a pointer and a length. The buffer passed in is not
    893   // required to be stretchable. For non-stretchable buffers, the user must
    894   // call GetSizeForWriteBuffer() to find out the upper bound on the output
    895   // buffer space required to make sure that the entire header is serialized.
    896   // BalsaHeaders will not check that there is adequate space in the buffer
    897   // object during the write.
    898 
    899   // Writes the entire header and the final CRLF that marks the end of the HTTP
    900   // header section to the buffer. After this method returns, no more header
    901   // data should be written to the buffer.
    902   template <typename Buffer>
    903   void WriteHeaderAndEndingToBuffer(Buffer* buffer) const {
    904     WriteToBuffer(buffer);
    905     WriteHeaderEndingToBuffer(buffer);
    906   }
    907 
    908   // Writes the final CRLF to the buffer to terminate the HTTP header section.
    909   // After this method returns, no more header data should be written to the
    910   // buffer.
    911   template <typename Buffer>
    912   static void WriteHeaderEndingToBuffer(Buffer* buffer) {
    913     buffer->Write("\r\n", 2);
    914   }
    915 
    916   // Writes the entire header to the buffer without the CRLF that terminates
    917   // the HTTP header. This lets users append additional header lines using
    918   // WriteHeaderLineToBuffer and then terminate the header with
    919   // WriteHeaderEndingToBuffer as the header is serialized to the
    920   // buffer, without having to first copy the header.
    921   template <typename Buffer>
    922   void WriteToBuffer(Buffer* buffer) const {
    923     // write the first line.
    924     const size_t firstline_len = whitespace_4_idx_ - non_whitespace_1_idx_;
    925     const char* stream_begin = GetPtr(firstline_buffer_base_idx_);
    926     buffer->Write(stream_begin + non_whitespace_1_idx_, firstline_len);
    927     buffer->Write("\r\n", 2);
    928     const HeaderLines::size_type end = header_lines_.size();
    929     for (HeaderLines::size_type i = 0; i < end; ++i) {
    930       const HeaderLineDescription& line = header_lines_[i];
    931       if (line.skip) {
    932         continue;
    933       }
    934       const char* line_ptr = GetPtr(line.buffer_base_idx);
    935       WriteHeaderLineToBuffer(
    936           buffer,
    937           base::StringPiece(line_ptr + line.first_char_idx,
    938                       line.key_end_idx - line.first_char_idx),
    939           base::StringPiece(line_ptr + line.value_begin_idx,
    940                       line.last_char_idx - line.value_begin_idx));
    941     }
    942   }
    943 
    944   // Takes a header line in the form of a key/value pair and append it to the
    945   // buffer. This function should be called after WriteToBuffer to
    946   // append additional header lines to the header without copying the header.
    947   // When the user is done with appending to the buffer,
    948   // WriteHeaderEndingToBuffer must be used to terminate the HTTP
    949   // header in the buffer. This method is a no-op if key is empty.
    950   template <typename Buffer>
    951   static void WriteHeaderLineToBuffer(Buffer* buffer,
    952                                       const base::StringPiece& key,
    953                                       const base::StringPiece& value) {
    954     // if the key is empty, we don't want to write the rest because it
    955     // will not be a well-formed header line.
    956     if (key.size() > 0) {
    957       buffer->Write(key.data(), key.size());
    958       buffer->Write(": ", 2);
    959       buffer->Write(value.data(), value.size());
    960       buffer->Write("\r\n", 2);
    961     }
    962   }
    963 
    964   // Dump the textural representation of the header object to a string, which
    965   // is suitable for writing out to logs. All CRLF will be printed out as \n.
    966   // This function can be called on a header object in any state. Raw header
    967   // data will be printed out if the header object is not completely parsed,
    968   // e.g., when there was an error in the middle of parsing.
    969   // The header content is appended to the string; the original content is not
    970   // cleared.
    971   void DumpToString(std::string* str) const;
    972 
    973   const base::StringPiece first_line() const {
    974     DCHECK_GE(whitespace_4_idx_, non_whitespace_1_idx_);
    975     return base::StringPiece(BeginningOfFirstLine() + non_whitespace_1_idx_,
    976                        whitespace_4_idx_ - non_whitespace_1_idx_);
    977   }
    978 
    979   // Returns the parsed value of the response code if it has been parsed.
    980   // Guaranteed to return 0 when unparsed (though it is a much better idea to
    981   // verify that the BalsaFrame had no errors while parsing).
    982   // This may return response codes which are outside the normal bounds of
    983   // HTTP response codes-- it is up to the user of this class to ensure that
    984   // the response code is one which is interpretable.
    985   size_t parsed_response_code() const { return parsed_response_code_; }
    986 
    987   const base::StringPiece request_method() const {
    988     DCHECK_GE(whitespace_2_idx_, non_whitespace_1_idx_);
    989     return base::StringPiece(BeginningOfFirstLine() + non_whitespace_1_idx_,
    990                        whitespace_2_idx_ - non_whitespace_1_idx_);
    991   }
    992 
    993   const base::StringPiece response_version() const {
    994     // Note: There is no difference between request_method() and
    995     // response_version(). They both could be called
    996     // GetFirstTokenFromFirstline()... but that wouldn't be anywhere near as
    997     // descriptive.
    998     return request_method();
    999   }
   1000 
   1001   const base::StringPiece request_uri() const {
   1002     DCHECK_GE(whitespace_3_idx_, non_whitespace_2_idx_);
   1003     return base::StringPiece(BeginningOfFirstLine() + non_whitespace_2_idx_,
   1004                        whitespace_3_idx_ - non_whitespace_2_idx_);
   1005   }
   1006 
   1007   const base::StringPiece response_code() const {
   1008     // Note: There is no difference between request_uri() and response_code().
   1009     // They both could be called GetSecondtTokenFromFirstline(), but, as noted
   1010     // in an earlier comment, that wouldn't be as descriptive.
   1011     return request_uri();
   1012   }
   1013 
   1014   const base::StringPiece request_version() const {
   1015     DCHECK_GE(whitespace_4_idx_, non_whitespace_3_idx_);
   1016     return base::StringPiece(BeginningOfFirstLine() + non_whitespace_3_idx_,
   1017                        whitespace_4_idx_ - non_whitespace_3_idx_);
   1018   }
   1019 
   1020   const base::StringPiece response_reason_phrase() const {
   1021     // Note: There is no difference between request_version() and
   1022     // response_reason_phrase(). They both could be called
   1023     // GetThirdTokenFromFirstline(), but, as noted in an earlier comment, that
   1024     // wouldn't be as descriptive.
   1025     return request_version();
   1026   }
   1027 
   1028   // Note that SetFirstLine will not update the internal indices for the
   1029   // various bits of the first-line (and may set them all to zero).
   1030   // If you'd like to use the accessors for the various bits of the firstline,
   1031   // then you should use the Set* functions, or SetFirstlineFromStringPieces,
   1032   // below, instead.
   1033   //
   1034   void SetFirstlineFromStringPieces(const base::StringPiece& firstline_a,
   1035                                     const base::StringPiece& firstline_b,
   1036                                     const base::StringPiece& firstline_c);
   1037 
   1038   void SetRequestFirstlineFromStringPieces(const base::StringPiece& method,
   1039                                            const base::StringPiece& uri,
   1040                                            const base::StringPiece& version) {
   1041     SetFirstlineFromStringPieces(method, uri, version);
   1042   }
   1043 
   1044   void SetResponseFirstlineFromStringPieces(
   1045       const base::StringPiece& version,
   1046       const base::StringPiece& code,
   1047       const base::StringPiece& reason_phrase) {
   1048     SetFirstlineFromStringPieces(version, code, reason_phrase);
   1049   }
   1050 
   1051   // These functions are exactly the same, except that their names are
   1052   // different. This is done so that the code using this class is more
   1053   // expressive.
   1054   void SetRequestMethod(const base::StringPiece& method);
   1055   void SetResponseVersion(const base::StringPiece& version);
   1056 
   1057   void SetRequestUri(const base::StringPiece& uri);
   1058   void SetResponseCode(const base::StringPiece& code);
   1059   void set_parsed_response_code(size_t parsed_response_code) {
   1060     parsed_response_code_ = parsed_response_code;
   1061   }
   1062   void SetParsedResponseCodeAndUpdateFirstline(size_t parsed_response_code);
   1063 
   1064   // These functions are exactly the same, except that their names are
   1065   // different. This is done so that the code using this class is more
   1066   // expressive.
   1067   void SetRequestVersion(const base::StringPiece& version);
   1068   void SetResponseReasonPhrase(const base::StringPiece& reason_phrase);
   1069 
   1070   // The biggest problem with SetFirstLine is that we don't want to use a
   1071   // separate buffer for it.  The second biggest problem with it is that the
   1072   // first biggest problem requires that we store offsets into a buffer instead
   1073   // of pointers into a buffer. Cuteness aside, SetFirstLine doesn't parse
   1074   // the individual fields of the firstline, and so accessors to those fields
   1075   // will not work properly after calling SetFirstLine. If you want those
   1076   // accessors to work, use the Set* functions above this one.
   1077   // SetFirstLine is stuff useful, however, if all you care about is correct
   1078   // serialization with the rest of the header object.
   1079   void SetFirstLine(const base::StringPiece& line);
   1080 
   1081   // Simple accessors to some of the internal state
   1082   bool transfer_encoding_is_chunked() const {
   1083     return transfer_encoding_is_chunked_;
   1084   }
   1085 
   1086   static bool ResponseCodeImpliesNoBody(int code) {
   1087     // From HTTP spec section 6.1.1 all 1xx responses must not have a body,
   1088     // as well as 204 No Content and 304 Not Modified.
   1089     return ((code >= 100) && (code <= 199)) || (code == 204) || (code == 304);
   1090   }
   1091 
   1092   // Note: never check this for requests. Nothing bad will happen if you do,
   1093   // but spec does not allow requests framed by connection close.
   1094   // TODO(vitaliyl): refactor.
   1095   bool is_framed_by_connection_close() const {
   1096     // We declare that response is framed by connection close if it has no
   1097     // content-length, no transfer encoding, and is allowed to have a body by
   1098     // the HTTP spec.
   1099     // parsed_response_code_ is 0 for requests, so ResponseCodeImpliesNoBody
   1100     // will return false.
   1101     return (content_length_status_ == BalsaHeadersEnums::NO_CONTENT_LENGTH) &&
   1102         !transfer_encoding_is_chunked_ &&
   1103         !ResponseCodeImpliesNoBody(parsed_response_code_);
   1104   }
   1105 
   1106   size_t content_length() const { return content_length_; }
   1107   BalsaHeadersEnums::ContentLengthStatus content_length_status() const {
   1108     return content_length_status_;
   1109   }
   1110 
   1111   // SetContentLength and SetChunkEncoding modifies the header object to use
   1112   // content-length and transfer-encoding headers in a consistent manner. They
   1113   // set all internal flags and status so client can get a consistent view from
   1114   // various accessors.
   1115   void SetContentLength(size_t length);
   1116   void SetChunkEncoding(bool chunk_encode);
   1117 
   1118  protected:
   1119   friend class BalsaFrame;
   1120   friend class FlipFrame;
   1121   friend class HTTPMessage;
   1122   friend class BalsaHeadersTokenUtils;
   1123 
   1124   const char* BeginningOfFirstLine() const {
   1125     return GetPtr(firstline_buffer_base_idx_);
   1126   }
   1127 
   1128   char* GetPtr(BalsaBuffer::Blocks::size_type block_idx) {
   1129     return balsa_buffer_.GetPtr(block_idx);
   1130   }
   1131 
   1132   const char* GetPtr(BalsaBuffer::Blocks::size_type block_idx) const {
   1133     return balsa_buffer_.GetPtr(block_idx);
   1134   }
   1135 
   1136   void WriteFromFramer(const char* ptr, size_t size) {
   1137     balsa_buffer_.WriteToContiguousBuffer(base::StringPiece(ptr, size));
   1138   }
   1139 
   1140   void DoneWritingFromFramer() {
   1141     balsa_buffer_.NoMoreWriteToContiguousBuffer();
   1142   }
   1143 
   1144   const char* OriginalHeaderStreamBegin() const {
   1145     return balsa_buffer_.StartOfFirstBlock();
   1146   }
   1147 
   1148   const char* OriginalHeaderStreamEnd() const {
   1149     return balsa_buffer_.EndOfFirstBlock();
   1150   }
   1151 
   1152   size_t GetReadableBytesFromHeaderStream() const {
   1153     return OriginalHeaderStreamEnd() - OriginalHeaderStreamBegin();
   1154   }
   1155 
   1156   void GetReadablePtrFromHeaderStream(const char** p, size_t* s) {
   1157     *p = OriginalHeaderStreamBegin();
   1158     *s = GetReadableBytesFromHeaderStream();
   1159   }
   1160 
   1161   base::StringPiece GetValueFromHeaderLineDescription(
   1162       const HeaderLineDescription& line) const;
   1163 
   1164   void AddAndMakeDescription(const base::StringPiece& key,
   1165                              const base::StringPiece& value,
   1166                              HeaderLineDescription* d);
   1167 
   1168   void AppendOrPrependAndMakeDescription(const base::StringPiece& key,
   1169                                          const base::StringPiece& value,
   1170                                          bool append,
   1171                                          HeaderLineDescription* d);
   1172 
   1173   // Removes all header lines with the given key starting at start.
   1174   void RemoveAllOfHeaderStartingAt(const base::StringPiece& key,
   1175                                    HeaderLines::iterator start);
   1176 
   1177   // If the 'key' does not exist in the headers, calls
   1178   // AppendHeader(key, value).  Otherwise if append is true, appends ',value'
   1179   // to the first existing header with key 'key'.  If append is false, prepends
   1180   // 'value,' to the first existing header with key 'key'.
   1181   void AppendOrPrependToHeader(const base::StringPiece& key,
   1182                                const base::StringPiece& value,
   1183                                bool append);
   1184 
   1185   HeaderLines::const_iterator GetConstHeaderLinesIterator(
   1186       const base::StringPiece& key,
   1187       HeaderLines::const_iterator start) const;
   1188 
   1189   HeaderLines::iterator GetHeaderLinesIteratorNoSkip(
   1190       const base::StringPiece& key,
   1191       HeaderLines::iterator start);
   1192 
   1193   HeaderLines::iterator GetHeaderLinesIterator(
   1194       const base::StringPiece& key,
   1195       HeaderLines::iterator start);
   1196 
   1197   template <typename IteratorType>
   1198   const IteratorType HeaderLinesBeginHelper() const {
   1199     if (header_lines_.empty()) {
   1200       return IteratorType(this, 0);
   1201     }
   1202     const HeaderLines::size_type header_lines_size = header_lines_.size();
   1203     for (HeaderLines::size_type i = 0; i < header_lines_size; ++i) {
   1204       if (header_lines_[i].skip == false) {
   1205         return IteratorType(this, i);
   1206       }
   1207     }
   1208     return IteratorType(this, 0);
   1209   }
   1210 
   1211   template <typename IteratorType>
   1212   const IteratorType HeaderLinesEndHelper() const {
   1213     if (header_lines_.empty()) {
   1214       return IteratorType(this, 0);
   1215     }
   1216     const HeaderLines::size_type header_lines_size = header_lines_.size();
   1217     HeaderLines::size_type i = header_lines_size;
   1218     do {
   1219       --i;
   1220       if (header_lines_[i].skip == false) {
   1221         return IteratorType(this, i + 1);
   1222       }
   1223     } while (i != 0);
   1224     return IteratorType(this, 0);
   1225   }
   1226 
   1227   // At the moment, this function will always return the original headers.
   1228   // In the future, it may not do so after erasing header lines, modifying
   1229   // header lines, or modifying the first line.
   1230   // For this reason, it is strongly suggested that use of this function is
   1231   // only acceptable for the purpose of debugging parse errors seen by the
   1232   // BalsaFrame class.
   1233   base::StringPiece OriginalHeadersForDebugging() const {
   1234     return base::StringPiece(OriginalHeaderStreamBegin(),
   1235                        OriginalHeaderStreamEnd() - OriginalHeaderStreamBegin());
   1236   }
   1237 
   1238   BalsaBuffer balsa_buffer_;
   1239 
   1240   size_t content_length_;
   1241   BalsaHeadersEnums::ContentLengthStatus content_length_status_;
   1242   size_t parsed_response_code_;
   1243   // HTTP firstlines all have the following structure:
   1244   //  LWS         NONWS  LWS    NONWS   LWS    NONWS   NOTCRLF  CRLF
   1245   //  [\t \r\n]+ [^\t ]+ [\t ]+ [^\t ]+ [\t ]+ [^\t ]+ [^\r\n]+ "\r\n"
   1246   //  ws1        nws1    ws2    nws2    ws3    nws3             ws4
   1247   //  |          [-------)      [-------)      [----------------)
   1248   //    REQ:     method         request_uri    version
   1249   //   RESP:     version        statuscode     reason
   1250   //
   1251   //   The first NONWS->LWS component we'll call firstline_a.
   1252   //   The second firstline_b, and the third firstline_c.
   1253   //
   1254   //   firstline_a goes from nws1 to (but not including) ws2
   1255   //   firstline_b goes from nws2 to (but not including) ws3
   1256   //   firstline_c goes from nws3 to (but not including) ws4
   1257   //
   1258   // In the code:
   1259   //    ws1 == whitespace_1_idx_
   1260   //   nws1 == non_whitespace_1_idx_
   1261   //    ws2 == whitespace_2_idx_
   1262   //   nws2 == non_whitespace_2_idx_
   1263   //    ws3 == whitespace_3_idx_
   1264   //   nws3 == non_whitespace_3_idx_
   1265   //    ws4 == whitespace_4_idx_
   1266   BalsaBuffer::Blocks::size_type firstline_buffer_base_idx_;
   1267   size_t whitespace_1_idx_;
   1268   size_t non_whitespace_1_idx_;
   1269   size_t whitespace_2_idx_;
   1270   size_t non_whitespace_2_idx_;
   1271   size_t whitespace_3_idx_;
   1272   size_t non_whitespace_3_idx_;
   1273   size_t whitespace_4_idx_;
   1274   size_t end_of_firstline_idx_;
   1275 
   1276   bool transfer_encoding_is_chunked_;
   1277 
   1278   HeaderLines header_lines_;
   1279 };
   1280 
   1281 }  // namespace net
   1282 
   1283 #endif  // NET_TOOLS_FLIP_SERVER_BALSA_HEADERS_H_
   1284 
   1285