15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/balsa_headers.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ext/hash_set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/port.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/balsa_enums.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/buffer_interface.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/simple_buffer.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/tcmalloc/chromium/src/base/googleinit.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #include "util/gtl/iterator_adaptors-inl.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #include "util/gtl/map-util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kContentLength[] = "Content-Length"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTransferEncoding[] = "Transfer-Encoding"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSpaceChar = ' '; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__gnu_cxx::hash_set<base::StringPiece, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::StringPieceCaseHash, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::StringPieceCaseEqual> g_multivalued_headers; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitMultivaluedHeaders() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("accept"); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("accept-charset"); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("accept-encoding"); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("accept-language"); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("accept-ranges"); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("allow"); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("cache-control"); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("connection"); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("content-encoding"); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("content-language"); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("expect"); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("if-match"); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("if-none-match"); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("pragma"); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("proxy-authenticate"); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("te"); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("trailer"); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("transfer-encoding"); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("upgrade"); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("vary"); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("via"); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("warning"); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("www-authenticate"); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not mentioned in RFC 2616, but it can have multiple values. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_multivalued_headers.insert("set-cookie"); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_MODULE_INITIALIZER(multivalued_headers, InitMultivaluedHeaders()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kFastToBufferSize = 32; // I think 22 is adequate, but anyway.. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t BalsaBuffer::kDefaultBlocksize; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::iterator_base::iterator_base() : headers_(NULL), idx_(0) { } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::iterator_base::iterator_base(const iterator_base& it) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : headers_(it.headers_), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx_(it.idx_) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& BalsaHeaders::iterator_base::operator<<(std::ostream& os) const { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "[" << this->headers_ << ", " << this->idx_ << "]"; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return os; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::iterator_base::iterator_base(const BalsaHeaders* headers, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::size_type index) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : headers_(headers), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx_(index) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaBuffer::~BalsaBuffer() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupBlocksStartingFrom(0); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the total amount of memory used by the buffer blocks. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t BalsaBuffer::GetTotalBufferBlockSize() const { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t buffer_size = 0; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Blocks::const_iterator iter = blocks_.begin(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != blocks_.end(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size += iter->buffer_size; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer_size; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaBuffer::WriteToContiguousBuffer(const base::StringPiece& sp) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sp.empty()) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(can_write_to_contiguous_buffer_); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(blocks_.size(), 1u); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocks_[0].buffer == NULL && sp.size() <= blocksize_) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[0] = AllocBlock(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(blocks_[0].start_of_unused_bytes(), sp.data(), sp.size()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocks_[0].bytes_free < sp.size()) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the first block isn't big enough, resize it. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t old_storage_size_used = blocks_[0].bytes_used(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t new_storage_size = old_storage_size_used + sp.size(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* new_storage = new char[new_storage_size]; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* old_storage = blocks_[0].buffer; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_storage_size_used) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(new_storage, old_storage, old_storage_size_used); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(new_storage + old_storage_size_used, sp.data(), sp.size()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[0].buffer = new_storage; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[0].bytes_free = sp.size(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[0].buffer_size = new_storage_size; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] old_storage; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(blocks_[0].start_of_unused_bytes(), sp.data(), sp.size()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[0].bytes_free -= sp.size(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::StringPiece BalsaBuffer::Write(const base::StringPiece& sp, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Blocks::size_type* block_buffer_idx) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sp.empty()) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sp; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* storage = Reserve(sp.size(), block_buffer_idx); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(storage, sp.data(), sp.size()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPiece(storage, sp.size()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* BalsaBuffer::Reserve(size_t size, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Blocks::size_type* block_buffer_idx) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should always be a 'first_block', even if it 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contains nothing. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(blocks_.size(), 1u); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferBlock* block = NULL; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Blocks::size_type block_idx = can_write_to_contiguous_buffer_ ? 1 : 0; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; block_idx < blocks_.size(); ++block_idx) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocks_[block_idx].bytes_free >= size) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block = &blocks_[block_idx]; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (block == NULL) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocksize_ < size) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.push_back(AllocCustomBlock(size)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.push_back(AllocBlock()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block = &blocks_.back(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* storage = block->start_of_unused_bytes(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block->bytes_free -= size; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (block_buffer_idx) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *block_buffer_idx = block_idx; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return storage; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaBuffer::Clear() { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocks_.empty()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocksize_ == blocks_[0].buffer_size) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupBlocksStartingFrom(1); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[0].bytes_free = blocks_[0].buffer_size; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupBlocksStartingFrom(0); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.push_back(AllocBlock()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(blocks_.size(), 1u); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) can_write_to_contiguous_buffer_ = true; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaBuffer::Swap(BalsaBuffer* b) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.swap(b->blocks_); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(can_write_to_contiguous_buffer_, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->can_write_to_contiguous_buffer_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(blocksize_, b->blocksize_); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaBuffer::CopyFrom(const BalsaBuffer& b) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupBlocksStartingFrom(0); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.resize(b.blocks_.size()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Blocks::size_type i = 0; i < blocks_.size(); ++i) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_[i] = CopyBlock(b.blocks_[i]); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocksize_ = b.blocksize_; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) can_write_to_contiguous_buffer_ = b.can_write_to_contiguous_buffer_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaBuffer::BalsaBuffer() 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : blocksize_(kDefaultBlocksize), can_write_to_contiguous_buffer_(true) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.push_back(AllocBlock()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaBuffer::BalsaBuffer(size_t blocksize) : 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocksize_(blocksize), can_write_to_contiguous_buffer_(true) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.push_back(AllocBlock()); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaBuffer::BufferBlock BalsaBuffer::AllocBlock() { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AllocCustomBlock(blocksize_); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaBuffer::BufferBlock BalsaBuffer::AllocCustomBlock(size_t blocksize) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BufferBlock(new char[blocksize], blocksize, blocksize); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaBuffer::BufferBlock BalsaBuffer::CopyBlock(const BufferBlock& b) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferBlock block = b; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b.buffer == NULL) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return block; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block.buffer = new char[b.buffer_size]; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(block.buffer, b.buffer, b.bytes_used()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return block; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaBuffer::CleanupBlocksStartingFrom(Blocks::size_type start_idx) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Blocks::size_type i = start_idx; i < blocks_.size(); ++i) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] blocks_[i].buffer; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocks_.resize(start_idx); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::const_header_lines_key_iterator::const_header_lines_key_iterator( 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const const_header_lines_key_iterator& other) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : iterator_base(other), 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_(other.key_) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::const_header_lines_key_iterator::const_header_lines_key_iterator( 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BalsaHeaders* headers, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::size_type index, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : iterator_base(headers, index), 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_(key) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::const_header_lines_key_iterator::const_header_lines_key_iterator( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BalsaHeaders* headers, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::size_type index) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : iterator_base(headers, index) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::BalsaHeaders() 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : balsa_buffer_(4096), 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_(0), 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_(BalsaHeadersEnums::NO_CONTENT_LENGTH), 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_response_code_(0), 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline_buffer_base_idx_(0), 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_1_idx_(0), 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_(0), 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_2_idx_(0), 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_2_idx_(0), 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_3_idx_(0), 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_(0), 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_(0), 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_of_firstline_idx_(0), 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_encoding_is_chunked_(false) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::~BalsaHeaders() {} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::Clear() { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) balsa_buffer_.Clear(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_encoding_is_chunked_ = false; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ = 0; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_ = BalsaHeadersEnums::NO_CONTENT_LENGTH; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_response_code_ = 0; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline_buffer_base_idx_ = 0; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_1_idx_ = 0; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_ = 0; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_2_idx_ = 0; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_2_idx_ = 0; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_3_idx_ = 0; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_ = 0; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_ = 0; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_of_firstline_idx_ = 0; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_lines_.clear(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::Swap(BalsaHeaders* other) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protect against swapping with self. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == other) return; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) balsa_buffer_.Swap(&other->balsa_buffer_); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool tmp_bool = transfer_encoding_is_chunked_; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_encoding_is_chunked_ = other->transfer_encoding_is_chunked_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->transfer_encoding_is_chunked_ = tmp_bool; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t tmp_size_t = content_length_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ = other->content_length_; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->content_length_ = tmp_size_t; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeadersEnums::ContentLengthStatus tmp_status = 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_ = other->content_length_status_; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->content_length_status_ = tmp_status; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = parsed_response_code_; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_response_code_ = other->parsed_response_code_; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->parsed_response_code_ = tmp_size_t; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaBuffer::Blocks::size_type tmp_blk_idx = firstline_buffer_base_idx_; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline_buffer_base_idx_ = other->firstline_buffer_base_idx_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->firstline_buffer_base_idx_ = tmp_blk_idx; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = whitespace_1_idx_; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_1_idx_ = other->whitespace_1_idx_; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->whitespace_1_idx_ = tmp_size_t; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = non_whitespace_1_idx_; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_ = other->non_whitespace_1_idx_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->non_whitespace_1_idx_ = tmp_size_t; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = whitespace_2_idx_; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_2_idx_ = other->whitespace_2_idx_; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->whitespace_2_idx_ = tmp_size_t; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = non_whitespace_2_idx_; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_2_idx_ = other->non_whitespace_2_idx_; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->non_whitespace_2_idx_ = tmp_size_t; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = whitespace_3_idx_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_3_idx_ = other->whitespace_3_idx_; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->whitespace_3_idx_ = tmp_size_t; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = non_whitespace_3_idx_; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_ = other->non_whitespace_3_idx_; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->non_whitespace_3_idx_ = tmp_size_t; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = whitespace_4_idx_; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_ = other->whitespace_4_idx_; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->whitespace_4_idx_ = tmp_size_t; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_size_t = end_of_firstline_idx_; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_of_firstline_idx_ = other->end_of_firstline_idx_; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->end_of_firstline_idx_ = tmp_size_t; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swap(header_lines_, other->header_lines_); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::CopyFrom(const BalsaHeaders& other) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protect against copying with self. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == &other) return; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) balsa_buffer_.CopyFrom(other.balsa_buffer_); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_encoding_is_chunked_ = other.transfer_encoding_is_chunked_; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ = other.content_length_; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_ = other.content_length_status_; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_response_code_ = other.parsed_response_code_; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline_buffer_base_idx_ = other.firstline_buffer_base_idx_; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_1_idx_ = other.whitespace_1_idx_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_ = other.non_whitespace_1_idx_; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_2_idx_ = other.whitespace_2_idx_; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_2_idx_ = other.non_whitespace_2_idx_; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_3_idx_ = other.whitespace_3_idx_; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_ = other.non_whitespace_3_idx_; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_ = other.whitespace_4_idx_; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_of_firstline_idx_ = other.end_of_firstline_idx_; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_lines_ = other.header_lines_; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::AddAndMakeDescription(const base::StringPiece& key, 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLineDescription* d) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(d != NULL); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // + 2 to size for ": " 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t line_size = key.size() + 2 + value.size(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaBuffer::Blocks::size_type block_buffer_idx = 0; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* storage = balsa_buffer_.Reserve(line_size, &block_buffer_idx); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t base_idx = storage - GetPtr(block_buffer_idx); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* cur_loc = storage; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, key.data(), key.size()); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur_loc += key.size(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ':'; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ' '; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, value.data(), value.size()); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *d = HeaderLineDescription(base_idx, 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_idx + key.size(), 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_idx + key.size() + 2, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_idx + key.size() + 2 + value.size(), 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_buffer_idx); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::AppendOrPrependAndMakeDescription( 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool append, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLineDescription* d) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Figure out how much space we need to reserve for the new header size. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t old_value_size = d->last_char_idx - d->value_begin_idx; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_value_size == 0) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAndMakeDescription(key, value, d); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece old_value(GetPtr(d->buffer_base_idx) + d->value_begin_idx, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_value_size); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaBuffer::Blocks::size_type block_buffer_idx = 0; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // + 3 because we potentially need to add ": ", and "," to the line. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t new_size = key.size() + 3 + old_value_size + value.size(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* storage = balsa_buffer_.Reserve(new_size, &block_buffer_idx); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t base_idx = storage - GetPtr(block_buffer_idx); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece first_value = old_value; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece second_value = value; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!append) { // !append == prepend 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_value = value; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) second_value = old_value; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* cur_loc = storage; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, key.data(), key.size()); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur_loc += key.size(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ':'; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ' '; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, first_value.data(), first_value.size()); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur_loc += first_value.size(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ','; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, second_value.data(), second_value.size()); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *d = HeaderLineDescription(base_idx, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_idx + key.size(), 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_idx + key.size() + 2, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_idx + new_size, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_buffer_idx); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Removes all keys value pairs with key 'key' starting at 'start'. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::RemoveAllOfHeaderStartingAt(const base::StringPiece& key, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::iterator start) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (start != header_lines_.end()) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start->skip = true; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++start; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = GetHeaderLinesIterator(key, start); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::HackHeader(const base::StringPiece& key, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See TODO in balsa_headers.h 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator end = header_lines_.end(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator begin = header_lines_.begin(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::iterator i = GetHeaderLinesIteratorNoSkip(key, begin); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != end) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, remove all of the header lines including this one. We want to 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove before replacing, in case our replacement ends up being appended 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at the end (and thus would be removed by this call) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeaderStartingAt(key, i); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now add the replacement, at this location. 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAndMakeDescription(key, value, &(*i)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendHeader(key, value); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::HackAppendToHeader(const base::StringPiece& key, 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& append_value) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See TODO in balsa_headers.h 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator end = header_lines_.end(); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator begin = header_lines_.begin(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::iterator i = GetHeaderLinesIterator(key, begin); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == end) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HackHeader(key, append_value); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendOrPrependAndMakeDescription(key, append_value, true, &(*i)); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::ReplaceOrAppendHeader(const base::StringPiece& key, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator end = header_lines_.end(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator begin = header_lines_.begin(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::iterator i = GetHeaderLinesIterator(key, begin); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != end) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, remove all of the header lines including this one. We want to 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove before replacing, in case our replacement ends up being appended 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at the end (and thus would be removed by this call) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeaderStartingAt(key, i); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now, take the first instance and replace it. This will remove the 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'skipped' tag if the replacement is done in-place. 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAndMakeDescription(key, value, &(*i)); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendHeader(key, value); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::AppendHeader(const base::StringPiece& key, 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLineDescription hld; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAndMakeDescription(key, value, &hld); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_lines_.push_back(hld); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::AppendToHeader(const base::StringPiece& key, 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendOrPrependToHeader(key, value, true); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::PrependToHeader(const base::StringPiece& key, 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendOrPrependToHeader(key, value, false); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::StringPiece BalsaHeaders::GetValueFromHeaderLineDescription( 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLineDescription& line) const { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(line.last_char_idx, line.value_begin_idx); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPiece(GetPtr(line.buffer_base_idx) + line.value_begin_idx, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line.last_char_idx - line.value_begin_idx); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::StringPiece BalsaHeaders::GetHeader( 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key) const { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsMultivaluedHeader(key)) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Header '" << key << "' may consist of multiple lines. Do not " 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "use BalsaHeaders::GetHeader() or you may be missing some of its " 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "values."; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::const_iterator end = header_lines_.end(); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::const_iterator begin = header_lines_.begin(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::const_iterator i = GetConstHeaderLinesIterator(key, begin); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == end) { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPiece(NULL, 0); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetValueFromHeaderLineDescription(*i); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::const_header_lines_iterator BalsaHeaders::GetHeaderPosition( 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key) const { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::const_iterator end = header_lines_.end(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::const_iterator begin = header_lines_.begin(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::const_iterator i = GetConstHeaderLinesIterator(key, begin); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == end) { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return header_lines_end(); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_header_lines_iterator(this, (i - begin)); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::const_header_lines_key_iterator BalsaHeaders::GetIteratorForKey( 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key) const { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::const_iterator i = 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetConstHeaderLinesIterator(key, header_lines_.begin()); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == header_lines_.end()) { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return header_lines_key_end(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::const_iterator begin = header_lines_.begin(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_header_lines_key_iterator(this, (i - begin), key); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::AppendOrPrependToHeader(const base::StringPiece& key, 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& value, 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool append) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::iterator i = GetHeaderLinesIterator(key, header_lines_.begin()); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == header_lines_.end()) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The header did not exist already. Instead of appending to an existing 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // header simply append the key/value pair to the headers. 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendHeader(key, value); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLineDescription hld = *i; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendOrPrependAndMakeDescription(key, value, append, &hld); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invalidate the old header line and add the new one. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->skip = true; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_lines_.push_back(hld); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::HeaderLines::const_iterator 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::GetConstHeaderLinesIterator( 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key, 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders::HeaderLines::const_iterator start) const { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::const_iterator end = header_lines_.end(); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HeaderLines::const_iterator i = start; i != end; ++i) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLineDescription& line = *i; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line.skip) { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t key_len = line.key_end_idx - line.first_char_idx; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_len != key.size()) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strncasecmp(GetPtr(line.buffer_base_idx) + line.first_char_idx, 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.data(), key_len) == 0) { 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(line.last_char_idx, line.value_begin_idx); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return end; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::HeaderLines::iterator BalsaHeaders::GetHeaderLinesIteratorNoSkip( 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key, 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders::HeaderLines::iterator start) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator end = header_lines_.end(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HeaderLines::iterator i = start; i != end; ++i) { 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLineDescription& line = *i; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t key_len = line.key_end_idx - line.first_char_idx; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_len != key.size()) { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strncasecmp(GetPtr(line.buffer_base_idx) + line.first_char_idx, 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.data(), key_len) == 0) { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(line.last_char_idx, line.value_begin_idx); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return end; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BalsaHeaders::HeaderLines::iterator BalsaHeaders::GetHeaderLinesIterator( 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders::HeaderLines::iterator start) { 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::iterator end = header_lines_.end(); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HeaderLines::iterator i = start; i != end; ++i) { 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLineDescription& line = *i; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line.skip) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t key_len = line.key_end_idx - line.first_char_idx; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_len != key.size()) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strncasecmp(GetPtr(line.buffer_base_idx) + line.first_char_idx, 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.data(), key_len) == 0) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(line.last_char_idx, line.value_begin_idx); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return end; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::GetAllOfHeader( 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& key, std::vector<base::StringPiece>* out) const { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_header_lines_key_iterator it = GetIteratorForKey(key); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != header_lines_end(); ++it) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->push_back(it->second); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BalsaHeaders::HasNonEmptyHeader(const base::StringPiece& key) const { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_header_lines_key_iterator it = GetIteratorForKey(key); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != header_lines_key_end(); ++it) { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->second.empty()) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::GetAllOfHeaderAsString(const base::StringPiece& key, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out) const { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_header_lines_iterator it = header_lines_begin(); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_header_lines_iterator end = header_lines_end(); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; it != end; ++it) { 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key == it->first) { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!out->empty()) { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append(","); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->append(std::string(it->second.data(), it->second.size())); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BalsaHeaders::IsMultivaluedHeader(const base::StringPiece& header) { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_multivalued_headers.find(header) != g_multivalued_headers.end(); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::RemoveAllOfHeader(const base::StringPiece& key) { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLines::iterator it = GetHeaderLinesIterator(key, header_lines_.begin()); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeaderStartingAt(key, it); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::RemoveAllHeadersWithPrefix(const base::StringPiece& key) { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HeaderLines::size_type i = 0; i < header_lines_.size(); ++i) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_lines_[i].skip) { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeaderLineDescription& line = header_lines_[i]; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t key_len = line.key_end_idx - line.first_char_idx; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_len < key.size()) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the key given to us is longer than this header, don't consider it. 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strncasecmp(GetPtr(line.buffer_base_idx) + line.first_char_idx, 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.data(), key.size())) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line.skip = true; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t BalsaHeaders::GetMemoryUsedLowerBound() const { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (sizeof(*this) + 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) balsa_buffer_.GetTotalBufferBlockSize() + 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_lines_.capacity() * sizeof(HeaderLineDescription)); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t BalsaHeaders::GetSizeForWriteBuffer() const { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First add the space required for the first line + CRLF 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t write_buf_size = whitespace_4_idx_ - non_whitespace_1_idx_ + 2; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then add the space needed for each header line to write out + CRLF. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLines::size_type end = header_lines_.size(); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HeaderLines::size_type i = 0; i < end; ++i) { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeaderLineDescription& line = header_lines_[i]; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!line.skip) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the key size and ": ". 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_buf_size += line.key_end_idx - line.first_char_idx + 2; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the value size and the CRLF 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_buf_size += line.last_char_idx - line.value_begin_idx + 2; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally tag on the terminal CRLF. 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return write_buf_size + 2; 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::DumpToString(std::string* str) const { 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece firstline = first_line(); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int buffer_length = 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginalHeaderStreamEnd() - OriginalHeaderStreamBegin(); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First check whether the header object is empty. 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (firstline.empty() && buffer_length == 0) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str->append("\n<empty header>\n"); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then check whether the header is in a partially parsed state. If so, just 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dump the raw data. 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (balsa_buffer_.can_write_to_contiguous_buffer()) { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(str, "\n<incomplete header len: %d>\n%.*s\n", 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_length, buffer_length, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginalHeaderStreamBegin()); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the header is complete, then just dump them with the logical key value 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pair. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str->reserve(str->size() + GetSizeForWriteBuffer()); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(str, "\n %.*s\n", 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(firstline.size()), 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline.data()); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BalsaHeaders::const_header_lines_iterator i = header_lines_begin(); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i != header_lines_end(); ++i) { 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(str, " %.*s: %.*s\n", 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(i->first.size()), i->first.data(), 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(i->second.size()), i->second.data()); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetFirstLine(const base::StringPiece& line) { 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece new_line = balsa_buffer_.Write(line, 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &firstline_buffer_base_idx_); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_1_idx_ = new_line.data() - GetPtr(firstline_buffer_base_idx_); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_ = whitespace_1_idx_; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_ = whitespace_1_idx_ + line.size(); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_2_idx_ = whitespace_4_idx_; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_2_idx_ = whitespace_4_idx_; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_3_idx_ = whitespace_4_idx_; 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_ = whitespace_4_idx_; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_of_firstline_idx_ = whitespace_4_idx_; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetContentLength(size_t length) { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the content-length is already the one we want, don't do anything. 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_length_status_ == BalsaHeadersEnums::VALID_CONTENT_LENGTH && 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ == length) { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece content_length(kContentLength, 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kContentLength) - 1); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If header state indicates that there is either a content length or 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transfer encoding header, remove them before adding the new content 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // length. There is always the possibility that client can manually add 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either header directly and cause content_length_status_ or 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transfer_encoding_is_chunked_ to be inconsistent with the actual header. 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the interest of efficiency, however, we will assume that clients will 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use the header object correctly and thus we will not scan the all headers 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // each time this function is called. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_length_status_ != BalsaHeadersEnums::NO_CONTENT_LENGTH) { 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeader(content_length); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (transfer_encoding_is_chunked_) { 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece transfer_encoding(kTransferEncoding, 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kTransferEncoding) - 1); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeader(transfer_encoding); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_encoding_is_chunked_ = false; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_ = BalsaHeadersEnums::VALID_CONTENT_LENGTH; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ = length; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FastUInt64ToBuffer is supposed to use a maximum of kFastToBufferSize bytes. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[kFastToBufferSize]; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len_converted = snprintf(buffer, sizeof(buffer), "%zd", length); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(len_converted, 0); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece length_str(buffer, len_converted); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendHeader(content_length, length_str); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetChunkEncoding(bool chunk_encode) { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transfer_encoding_is_chunked_ == chunk_encode) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_length_status_ != BalsaHeadersEnums::NO_CONTENT_LENGTH && 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chunk_encode) { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Want to change to chunk encoding, but have content length. Arguably we 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can leave this step out, since transfer-encoding overrides 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content-length. 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece content_length(kContentLength, 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kContentLength) - 1); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeader(content_length); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_status_ = BalsaHeadersEnums::NO_CONTENT_LENGTH; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_ = 0; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece transfer_encoding(kTransferEncoding, 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(kTransferEncoding) - 1); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chunk_encode) { 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kChunked[] = "chunked"; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece chunked(kChunked, sizeof(kChunked) - 1); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendHeader(transfer_encoding, chunked); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllOfHeader(transfer_encoding); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_encoding_is_chunked_ = chunk_encode; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the comment about this function in the header file for a 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// warning about its usage. 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetFirstlineFromStringPieces( 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& firstline_a, 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& firstline_b, 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& firstline_c) { 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t line_size = (firstline_a.size() + 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline_b.size() + 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstline_c.size() + 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* storage = balsa_buffer_.Reserve(line_size, &firstline_buffer_base_idx_); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* cur_loc = storage; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, firstline_a.data(), firstline_a.size()); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur_loc += firstline_a.size(); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ' '; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, firstline_b.data(), firstline_b.size()); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur_loc += firstline_b.size(); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cur_loc = ' '; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_loc; 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(cur_loc, firstline_c.data(), firstline_c.size()); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_1_idx_ = storage - GetPtr(firstline_buffer_base_idx_); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_ = whitespace_1_idx_; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_2_idx_ = non_whitespace_1_idx_ + firstline_a.size(); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_2_idx_ = whitespace_2_idx_ + 1; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_3_idx_ = non_whitespace_2_idx_ + firstline_b.size(); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_ = whitespace_3_idx_ + 1; 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_ = non_whitespace_3_idx_ + firstline_c.size(); 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_of_firstline_idx_ = whitespace_4_idx_; 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetRequestMethod(const base::StringPiece& method) { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the first of the three parts of the firstline. 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (method.size() <= (whitespace_2_idx_ - non_whitespace_1_idx_)) { 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_1_idx_ = whitespace_2_idx_ - method.size(); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* stream_begin = GetPtr(firstline_buffer_base_idx_); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(stream_begin + non_whitespace_1_idx_, 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method.data(), 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method.size()); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The new method is too large to fit in the space available for the old 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one, so we have to reformat the firstline. 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetFirstlineFromStringPieces(method, request_uri(), request_version()); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetResponseVersion(const base::StringPiece& version) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: There is no difference between request_method() and 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response_Version(). Thus, a function to set one is equivalent to a 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function to set the other. We maintain two functions for this as it is 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // much more descriptive, and makes code more understandable. 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRequestMethod(version); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetRequestUri(const base::StringPiece& uri) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetFirstlineFromStringPieces(request_method(), uri, request_version()); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetResponseCode(const base::StringPiece& code) { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: There is no difference between request_uri() and response_code(). 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thus, a function to set one is equivalent to a function to set the other. 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We maintain two functions for this as it is much more descriptive, and 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // makes code more understandable. 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRequestUri(code); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetParsedResponseCodeAndUpdateFirstline( 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t parsed_response_code) { 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[kFastToBufferSize]; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len_converted = snprintf(buffer, sizeof(buffer), 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%zd", parsed_response_code); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GT(len_converted, 0); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetResponseCode(base::StringPiece(buffer, len_converted)); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetRequestVersion(const base::StringPiece& version) { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the last of the three parts of the firstline. 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since whitespace_3_idx and non_whitespace_3_idx may point to the same 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // place, we ensure below that any available space includes space for a 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // litteral space (' ') character between the second component and the third 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // component. If the space between whitespace_3_idx_ and 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // end_of_firstline_idx_ is >= to version.size() + 1 (for the space), then we 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can update the firstline in-place. 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* stream_begin = GetPtr(firstline_buffer_base_idx_); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version.size() + 1 <= end_of_firstline_idx_ - whitespace_3_idx_) { 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(stream_begin + whitespace_3_idx_) = kSpaceChar; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_whitespace_3_idx_ = whitespace_3_idx_ + 1; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whitespace_4_idx_ = non_whitespace_3_idx_ + version.size(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(stream_begin + non_whitespace_3_idx_, 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version.data(), 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version.size()); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The new version is to large to fit in the space available for the old 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one, so we have to reformat the firstline. 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetFirstlineFromStringPieces(request_method(), request_uri(), version); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BalsaHeaders::SetResponseReasonPhrase(const base::StringPiece& reason) { 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: There is no difference between request_version() and 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response_reason_phrase(). Thus, a function to set one is equivalent to a 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function to set the other. We maintain two functions for this as it is 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // much more descriptive, and makes code more understandable. 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRequestVersion(reason); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 966