| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/hpack/hpack_encoder.h" | 5 #include "net/spdy/hpack/hpack_encoder.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "net/spdy/hpack/hpack_constants.h" | 12 #include "net/spdy/hpack/hpack_constants.h" |
| 13 #include "net/spdy/hpack/hpack_header_table.h" | 13 #include "net/spdy/hpack/hpack_header_table.h" |
| 14 #include "net/spdy/hpack/hpack_huffman_table.h" | 14 #include "net/spdy/hpack/hpack_huffman_table.h" |
| 15 #include "net/spdy/hpack/hpack_output_stream.h" | 15 #include "net/spdy/hpack/hpack_output_stream.h" |
| 16 #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" | 16 #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" |
| 17 | 17 |
| 18 namespace net { | 18 namespace net { |
| 19 | 19 |
| 20 using std::string; | |
| 21 | |
| 22 class HpackEncoder::RepresentationIterator { | 20 class HpackEncoder::RepresentationIterator { |
| 23 public: | 21 public: |
| 24 // |pseudo_headers| and |regular_headers| must outlive the iterator. | 22 // |pseudo_headers| and |regular_headers| must outlive the iterator. |
| 25 RepresentationIterator(const Representations& pseudo_headers, | 23 RepresentationIterator(const Representations& pseudo_headers, |
| 26 const Representations& regular_headers) | 24 const Representations& regular_headers) |
| 27 : pseudo_begin_(pseudo_headers.begin()), | 25 : pseudo_begin_(pseudo_headers.begin()), |
| 28 pseudo_end_(pseudo_headers.end()), | 26 pseudo_end_(pseudo_headers.end()), |
| 29 regular_begin_(regular_headers.begin()), | 27 regular_begin_(regular_headers.begin()), |
| 30 regular_end_(regular_headers.end()) {} | 28 regular_end_(regular_headers.end()) {} |
| 31 | 29 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 huffman_table_(table), | 79 huffman_table_(table), |
| 82 min_table_size_setting_received_(std::numeric_limits<size_t>::max()), | 80 min_table_size_setting_received_(std::numeric_limits<size_t>::max()), |
| 83 listener_(NoOpListener), | 81 listener_(NoOpListener), |
| 84 should_index_(DefaultPolicy), | 82 should_index_(DefaultPolicy), |
| 85 enable_compression_(true), | 83 enable_compression_(true), |
| 86 should_emit_table_size_(false) {} | 84 should_emit_table_size_(false) {} |
| 87 | 85 |
| 88 HpackEncoder::~HpackEncoder() {} | 86 HpackEncoder::~HpackEncoder() {} |
| 89 | 87 |
| 90 void HpackEncoder::EncodeHeaderSet(const Representations& representations, | 88 void HpackEncoder::EncodeHeaderSet(const Representations& representations, |
| 91 string* output) { | 89 SpdyString* output) { |
| 92 RepresentationIterator iter(representations); | 90 RepresentationIterator iter(representations); |
| 93 EncodeRepresentations(&iter, output); | 91 EncodeRepresentations(&iter, output); |
| 94 } | 92 } |
| 95 | 93 |
| 96 bool HpackEncoder::EncodeHeaderSet(const SpdyHeaderBlock& header_set, | 94 bool HpackEncoder::EncodeHeaderSet(const SpdyHeaderBlock& header_set, |
| 97 string* output) { | 95 SpdyString* output) { |
| 98 // Separate header set into pseudo-headers and regular headers. | 96 // Separate header set into pseudo-headers and regular headers. |
| 99 Representations pseudo_headers; | 97 Representations pseudo_headers; |
| 100 Representations regular_headers; | 98 Representations regular_headers; |
| 101 bool found_cookie = false; | 99 bool found_cookie = false; |
| 102 for (const auto& header : header_set) { | 100 for (const auto& header : header_set) { |
| 103 if (!found_cookie && header.first == "cookie") { | 101 if (!found_cookie && header.first == "cookie") { |
| 104 // Note that there can only be one "cookie" header, because header_set is | 102 // Note that there can only be one "cookie" header, because header_set is |
| 105 // a map. | 103 // a map. |
| 106 found_cookie = true; | 104 found_cookie = true; |
| 107 CookieToCrumbs(header, ®ular_headers); | 105 CookieToCrumbs(header, ®ular_headers); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 132 should_emit_table_size_ = true; | 130 should_emit_table_size_ = true; |
| 133 } | 131 } |
| 134 | 132 |
| 135 size_t HpackEncoder::EstimateMemoryUsage() const { | 133 size_t HpackEncoder::EstimateMemoryUsage() const { |
| 136 // |huffman_table_| is a singleton. It's accounted for in spdy_session_pool.cc | 134 // |huffman_table_| is a singleton. It's accounted for in spdy_session_pool.cc |
| 137 return SpdyEstimateMemoryUsage(header_table_) + | 135 return SpdyEstimateMemoryUsage(header_table_) + |
| 138 SpdyEstimateMemoryUsage(output_stream_); | 136 SpdyEstimateMemoryUsage(output_stream_); |
| 139 } | 137 } |
| 140 | 138 |
| 141 void HpackEncoder::EncodeRepresentations(RepresentationIterator* iter, | 139 void HpackEncoder::EncodeRepresentations(RepresentationIterator* iter, |
| 142 string* output) { | 140 SpdyString* output) { |
| 143 MaybeEmitTableSize(); | 141 MaybeEmitTableSize(); |
| 144 while (iter->HasNext()) { | 142 while (iter->HasNext()) { |
| 145 const auto header = iter->Next(); | 143 const auto header = iter->Next(); |
| 146 listener_(header.first, header.second); | 144 listener_(header.first, header.second); |
| 147 if (enable_compression_) { | 145 if (enable_compression_) { |
| 148 const HpackEntry* entry = | 146 const HpackEntry* entry = |
| 149 header_table_.GetByNameAndValue(header.first, header.second); | 147 header_table_.GetByNameAndValue(header.first, header.second); |
| 150 if (entry != nullptr) { | 148 if (entry != nullptr) { |
| 151 EmitIndex(entry); | 149 EmitIndex(entry); |
| 152 } else if (should_index_(header.first, header.second)) { | 150 } else if (should_index_(header.first, header.second)) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 289 |
| 292 // Encoderator is neither copyable nor movable. | 290 // Encoderator is neither copyable nor movable. |
| 293 Encoderator(const Encoderator&) = delete; | 291 Encoderator(const Encoderator&) = delete; |
| 294 Encoderator& operator=(const Encoderator&) = delete; | 292 Encoderator& operator=(const Encoderator&) = delete; |
| 295 | 293 |
| 296 // Returns true iff more remains to encode. | 294 // Returns true iff more remains to encode. |
| 297 bool HasNext() const override { return has_next_; } | 295 bool HasNext() const override { return has_next_; } |
| 298 | 296 |
| 299 // Encodes up to max_encoded_bytes of the current header block into the | 297 // Encodes up to max_encoded_bytes of the current header block into the |
| 300 // given output string. | 298 // given output string. |
| 301 void Next(size_t max_encoded_bytes, string* output) override; | 299 void Next(size_t max_encoded_bytes, SpdyString* output) override; |
| 302 | 300 |
| 303 private: | 301 private: |
| 304 HpackEncoder* encoder_; | 302 HpackEncoder* encoder_; |
| 305 std::unique_ptr<RepresentationIterator> header_it_; | 303 std::unique_ptr<RepresentationIterator> header_it_; |
| 306 Representations pseudo_headers_; | 304 Representations pseudo_headers_; |
| 307 Representations regular_headers_; | 305 Representations regular_headers_; |
| 308 bool has_next_; | 306 bool has_next_; |
| 309 }; | 307 }; |
| 310 | 308 |
| 311 HpackEncoder::Encoderator::Encoderator(const SpdyHeaderBlock& header_set, | 309 HpackEncoder::Encoderator::Encoderator(const SpdyHeaderBlock& header_set, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 328 use_compression ? DecomposeRepresentation(header, ®ular_headers_) | 326 use_compression ? DecomposeRepresentation(header, ®ular_headers_) |
| 329 : GatherRepresentation(header, ®ular_headers_); | 327 : GatherRepresentation(header, ®ular_headers_); |
| 330 } | 328 } |
| 331 } | 329 } |
| 332 header_it_ = base::MakeUnique<RepresentationIterator>(pseudo_headers_, | 330 header_it_ = base::MakeUnique<RepresentationIterator>(pseudo_headers_, |
| 333 regular_headers_); | 331 regular_headers_); |
| 334 | 332 |
| 335 encoder_->MaybeEmitTableSize(); | 333 encoder_->MaybeEmitTableSize(); |
| 336 } | 334 } |
| 337 | 335 |
| 338 void HpackEncoder::Encoderator::Next(size_t max_encoded_bytes, string* output) { | 336 void HpackEncoder::Encoderator::Next(size_t max_encoded_bytes, |
| 337 SpdyString* output) { |
| 339 SPDY_BUG_IF(!has_next_) | 338 SPDY_BUG_IF(!has_next_) |
| 340 << "Encoderator::Next called with nothing left to encode."; | 339 << "Encoderator::Next called with nothing left to encode."; |
| 341 const bool use_compression = encoder_->enable_compression_; | 340 const bool use_compression = encoder_->enable_compression_; |
| 342 | 341 |
| 343 // Encode up to max_encoded_bytes of headers. | 342 // Encode up to max_encoded_bytes of headers. |
| 344 while (header_it_->HasNext() && | 343 while (header_it_->HasNext() && |
| 345 encoder_->output_stream_.size() <= max_encoded_bytes) { | 344 encoder_->output_stream_.size() <= max_encoded_bytes) { |
| 346 const Representation header = header_it_->Next(); | 345 const Representation header = header_it_->Next(); |
| 347 encoder_->listener_(header.first, header.second); | 346 encoder_->listener_(header.first, header.second); |
| 348 if (use_compression) { | 347 if (use_compression) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 363 has_next_ = encoder_->output_stream_.size() > max_encoded_bytes; | 362 has_next_ = encoder_->output_stream_.size() > max_encoded_bytes; |
| 364 encoder_->output_stream_.BoundedTakeString(max_encoded_bytes, output); | 363 encoder_->output_stream_.BoundedTakeString(max_encoded_bytes, output); |
| 365 } | 364 } |
| 366 | 365 |
| 367 std::unique_ptr<HpackEncoder::ProgressiveEncoder> HpackEncoder::EncodeHeaderSet( | 366 std::unique_ptr<HpackEncoder::ProgressiveEncoder> HpackEncoder::EncodeHeaderSet( |
| 368 const SpdyHeaderBlock& header_set) { | 367 const SpdyHeaderBlock& header_set) { |
| 369 return base::MakeUnique<Encoderator>(header_set, this); | 368 return base::MakeUnique<Encoderator>(header_set, this); |
| 370 } | 369 } |
| 371 | 370 |
| 372 } // namespace net | 371 } // namespace net |
| OLD | NEW |