Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 292543002: Lazily alloc/init the HPACK encoder/decoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nullptr => NULL Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/spdy_framer.h" 5 #include "net/spdy/spdy_framer.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/metrics/stats_counters.h" 9 #include "base/metrics/stats_counters.h"
10 #include "base/third_party/valgrind/memcheck.h" 10 #include "base/third_party/valgrind/memcheck.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 debug_visitor_(NULL), 127 debug_visitor_(NULL),
128 display_protocol_("SPDY"), 128 display_protocol_("SPDY"),
129 spdy_version_(version), 129 spdy_version_(version),
130 syn_frame_processed_(false), 130 syn_frame_processed_(false),
131 probable_http_response_(false), 131 probable_http_response_(false),
132 expect_continuation_(0), 132 expect_continuation_(0),
133 end_stream_when_done_(false) { 133 end_stream_when_done_(false) {
134 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 134 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
135 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION); 135 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
136 Reset(); 136 Reset();
137
138 // SPDY4 and up use HPACK. Allocate instances for these protocol versions.
139 if (spdy_version_ > SPDY3) {
140 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
141 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
142 }
143 } 137 }
144 138
145 SpdyFramer::~SpdyFramer() { 139 SpdyFramer::~SpdyFramer() {
146 if (header_compressor_.get()) { 140 if (header_compressor_.get()) {
147 deflateEnd(header_compressor_.get()); 141 deflateEnd(header_compressor_.get());
148 } 142 }
149 if (header_decompressor_.get()) { 143 if (header_decompressor_.get()) {
150 inflateEnd(header_decompressor_.get()); 144 inflateEnd(header_decompressor_.get());
151 } 145 }
152 } 146 }
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 bool processed_successfully = true; 1468 bool processed_successfully = true;
1475 if (current_frame_type_ != SYN_STREAM && 1469 if (current_frame_type_ != SYN_STREAM &&
1476 current_frame_type_ != SYN_REPLY && 1470 current_frame_type_ != SYN_REPLY &&
1477 current_frame_type_ != HEADERS && 1471 current_frame_type_ != HEADERS &&
1478 current_frame_type_ != PUSH_PROMISE && 1472 current_frame_type_ != PUSH_PROMISE &&
1479 current_frame_type_ != CONTINUATION) { 1473 current_frame_type_ != CONTINUATION) {
1480 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; 1474 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
1481 } 1475 }
1482 size_t process_bytes = std::min(data_len, remaining_data_length_); 1476 size_t process_bytes = std::min(data_len, remaining_data_length_);
1483 if (is_hpack_header_block) { 1477 if (is_hpack_header_block) {
1484 if (!hpack_decoder_->HandleControlFrameHeadersData(current_frame_stream_id_, 1478 if (!GetHpackDecoder()->HandleControlFrameHeadersData(
1485 data, 1479 current_frame_stream_id_, data, process_bytes)) {
1486 process_bytes)) {
1487 // TODO(jgraettinger): Finer-grained HPACK error codes. 1480 // TODO(jgraettinger): Finer-grained HPACK error codes.
1488 set_error(SPDY_DECOMPRESS_FAILURE); 1481 set_error(SPDY_DECOMPRESS_FAILURE);
1489 processed_successfully = false; 1482 processed_successfully = false;
1490 } 1483 }
1491 } else if (process_bytes > 0) { 1484 } else if (process_bytes > 0) {
1492 if (enable_compression_ && protocol_version() <= SPDY3) { 1485 if (enable_compression_ && protocol_version() <= SPDY3) {
1493 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1486 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
1494 current_frame_stream_id_, data, process_bytes); 1487 current_frame_stream_id_, data, process_bytes);
1495 } else { 1488 } else {
1496 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1489 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
1497 current_frame_stream_id_, data, process_bytes); 1490 current_frame_stream_id_, data, process_bytes);
1498 } 1491 }
1499 } 1492 }
1500 remaining_data_length_ -= process_bytes; 1493 remaining_data_length_ -= process_bytes;
1501 1494
1502 // Handle the case that there is no futher data in this frame. 1495 // Handle the case that there is no futher data in this frame.
1503 if (remaining_data_length_ == 0 && processed_successfully) { 1496 if (remaining_data_length_ == 0 && processed_successfully) {
1504 if (expect_continuation_ == 0) { 1497 if (expect_continuation_ == 0) {
1505 if (is_hpack_header_block) { 1498 if (is_hpack_header_block) {
1506 if (!hpack_decoder_->HandleControlFrameHeadersComplete( 1499 if (!GetHpackDecoder()->HandleControlFrameHeadersComplete(
1507 current_frame_stream_id_)) { 1500 current_frame_stream_id_)) {
1508 set_error(SPDY_DECOMPRESS_FAILURE); 1501 set_error(SPDY_DECOMPRESS_FAILURE);
1509 processed_successfully = false; 1502 processed_successfully = false;
1510 } else { 1503 } else {
1511 // TODO(jgraettinger): To be removed with migration to 1504 // TODO(jgraettinger): To be removed with migration to
1512 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 1505 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
1513 // block, delivered via reentrant call to 1506 // block, delivered via reentrant call to
1514 // ProcessControlFrameHeaderBlock(). 1507 // ProcessControlFrameHeaderBlock().
1515 DeliverHpackBlockAsSpdy3Block(); 1508 DeliverHpackBlockAsSpdy3Block();
1516 return process_bytes; 1509 return process_bytes;
1517 } 1510 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 CHANGE_STATE(SPDY_AUTO_RESET); 1585 CHANGE_STATE(SPDY_AUTO_RESET);
1593 } 1586 }
1594 1587
1595 return processed_bytes; 1588 return processed_bytes;
1596 } 1589 }
1597 1590
1598 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { 1591 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
1599 DCHECK_LT(SPDY3, protocol_version()); 1592 DCHECK_LT(SPDY3, protocol_version());
1600 DCHECK_EQ(0u, remaining_data_length_); 1593 DCHECK_EQ(0u, remaining_data_length_);
1601 1594
1602 const SpdyNameValueBlock& block = hpack_decoder_->decoded_block(); 1595 const SpdyNameValueBlock& block = GetHpackDecoder()->decoded_block();
1603 if (block.empty()) { 1596 if (block.empty()) {
1604 // Special-case this to make tests happy. 1597 // Special-case this to make tests happy.
1605 ProcessControlFrameHeaderBlock(NULL, 0, false); 1598 ProcessControlFrameHeaderBlock(NULL, 0, false);
1606 return; 1599 return;
1607 } 1600 }
1608 SpdyFrameBuilder builder( 1601 SpdyFrameBuilder builder(
1609 GetSerializedLength(protocol_version(), &block), 1602 GetSerializedLength(protocol_version(), &block),
1610 SPDY3); 1603 SPDY3);
1611 1604
1612 SerializeNameValueBlockWithoutCompression(&builder, block); 1605 SerializeNameValueBlockWithoutCompression(&builder, block);
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 DLOG(DFATAL) << "Priority out-of-bounds."; 2134 DLOG(DFATAL) << "Priority out-of-bounds.";
2142 priority = GetLowestPriority(); 2135 priority = GetLowestPriority();
2143 } 2136 }
2144 2137
2145 // The size of this frame, including variable-length name-value block. 2138 // The size of this frame, including variable-length name-value block.
2146 size_t size = GetSynStreamMinimumSize(); 2139 size_t size = GetSynStreamMinimumSize();
2147 2140
2148 string hpack_encoding; 2141 string hpack_encoding;
2149 if (protocol_version() > SPDY3) { 2142 if (protocol_version() > SPDY3) {
2150 if (enable_compression_) { 2143 if (enable_compression_) {
2151 hpack_encoder_->EncodeHeaderSet( 2144 GetHpackEncoder()->EncodeHeaderSet(
2152 syn_stream.name_value_block(), &hpack_encoding); 2145 syn_stream.name_value_block(), &hpack_encoding);
2153 } else { 2146 } else {
2154 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2147 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2155 syn_stream.name_value_block(), &hpack_encoding); 2148 syn_stream.name_value_block(), &hpack_encoding);
2156 } 2149 }
2157 size += hpack_encoding.size(); 2150 size += hpack_encoding.size();
2158 } else { 2151 } else {
2159 size += GetSerializedLength(syn_stream.name_value_block()); 2152 size += GetSerializedLength(syn_stream.name_value_block());
2160 } 2153 }
2161 2154
2162 SpdyFrameBuilder builder(size, protocol_version()); 2155 SpdyFrameBuilder builder(size, protocol_version());
2163 if (protocol_version() <= SPDY3) { 2156 if (protocol_version() <= SPDY3) {
2164 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 2157 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 if (protocol_version() > SPDY3) { 2199 if (protocol_version() > SPDY3) {
2207 flags |= HEADERS_FLAG_END_HEADERS; 2200 flags |= HEADERS_FLAG_END_HEADERS;
2208 } 2201 }
2209 2202
2210 // The size of this frame, including variable-length name-value block. 2203 // The size of this frame, including variable-length name-value block.
2211 size_t size = GetSynReplyMinimumSize(); 2204 size_t size = GetSynReplyMinimumSize();
2212 2205
2213 string hpack_encoding; 2206 string hpack_encoding;
2214 if (protocol_version() > SPDY3) { 2207 if (protocol_version() > SPDY3) {
2215 if (enable_compression_) { 2208 if (enable_compression_) {
2216 hpack_encoder_->EncodeHeaderSet( 2209 GetHpackEncoder()->EncodeHeaderSet(
2217 syn_reply.name_value_block(), &hpack_encoding); 2210 syn_reply.name_value_block(), &hpack_encoding);
2218 } else { 2211 } else {
2219 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2212 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2220 syn_reply.name_value_block(), &hpack_encoding); 2213 syn_reply.name_value_block(), &hpack_encoding);
2221 } 2214 }
2222 size += hpack_encoding.size(); 2215 size += hpack_encoding.size();
2223 } else { 2216 } else {
2224 size += GetSerializedLength(syn_reply.name_value_block()); 2217 size += GetSerializedLength(syn_reply.name_value_block());
2225 } 2218 }
2226 2219
2227 SpdyFrameBuilder builder(size, protocol_version()); 2220 SpdyFrameBuilder builder(size, protocol_version());
2228 if (protocol_version() <= SPDY3) { 2221 if (protocol_version() <= SPDY3) {
2229 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 2222 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 if (priority > GetLowestPriority()) { 2419 if (priority > GetLowestPriority()) {
2427 DLOG(DFATAL) << "Priority out-of-bounds."; 2420 DLOG(DFATAL) << "Priority out-of-bounds.";
2428 priority = GetLowestPriority(); 2421 priority = GetLowestPriority();
2429 } 2422 }
2430 size += 4; 2423 size += 4;
2431 } 2424 }
2432 2425
2433 string hpack_encoding; 2426 string hpack_encoding;
2434 if (protocol_version() > SPDY3) { 2427 if (protocol_version() > SPDY3) {
2435 if (enable_compression_) { 2428 if (enable_compression_) {
2436 hpack_encoder_->EncodeHeaderSet( 2429 GetHpackEncoder()->EncodeHeaderSet(
2437 headers.name_value_block(), &hpack_encoding); 2430 headers.name_value_block(), &hpack_encoding);
2438 } else { 2431 } else {
2439 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2432 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2440 headers.name_value_block(), &hpack_encoding); 2433 headers.name_value_block(), &hpack_encoding);
2441 } 2434 }
2442 size += hpack_encoding.size(); 2435 size += hpack_encoding.size();
2443 if (size > GetControlFrameBufferMaxSize()) { 2436 if (size > GetControlFrameBufferMaxSize()) {
2444 size += GetNumberRequiredContinuationFrames(size) * 2437 size += GetNumberRequiredContinuationFrames(size) *
2445 GetContinuationMinimumSize(); 2438 GetContinuationMinimumSize();
2446 flags &= ~HEADERS_FLAG_END_HEADERS; 2439 flags &= ~HEADERS_FLAG_END_HEADERS;
2447 } 2440 }
2448 } else { 2441 } else {
2449 size += GetSerializedLength(headers.name_value_block()); 2442 size += GetSerializedLength(headers.name_value_block());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 DCHECK_LT(SPDY3, protocol_version()); 2512 DCHECK_LT(SPDY3, protocol_version());
2520 uint8 flags = 0; 2513 uint8 flags = 0;
2521 // This will get overwritten if we overflow into a CONTINUATION frame. 2514 // This will get overwritten if we overflow into a CONTINUATION frame.
2522 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2515 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2523 // The size of this frame, including variable-length name-value block. 2516 // The size of this frame, including variable-length name-value block.
2524 size_t size = GetPushPromiseMinimumSize(); 2517 size_t size = GetPushPromiseMinimumSize();
2525 2518
2526 string hpack_encoding; 2519 string hpack_encoding;
2527 if (protocol_version() > SPDY3) { 2520 if (protocol_version() > SPDY3) {
2528 if (enable_compression_) { 2521 if (enable_compression_) {
2529 hpack_encoder_->EncodeHeaderSet( 2522 GetHpackEncoder()->EncodeHeaderSet(
2530 push_promise.name_value_block(), &hpack_encoding); 2523 push_promise.name_value_block(), &hpack_encoding);
2531 } else { 2524 } else {
2532 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2525 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2533 push_promise.name_value_block(), &hpack_encoding); 2526 push_promise.name_value_block(), &hpack_encoding);
2534 } 2527 }
2535 size += hpack_encoding.size(); 2528 size += hpack_encoding.size();
2536 if (size > GetControlFrameBufferMaxSize()) { 2529 if (size > GetControlFrameBufferMaxSize()) {
2537 size += GetNumberRequiredContinuationFrames(size) * 2530 size += GetNumberRequiredContinuationFrames(size) *
2538 GetContinuationMinimumSize(); 2531 GetContinuationMinimumSize();
2539 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2532 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2540 } 2533 }
2541 } else { 2534 } else {
2542 size += GetSerializedLength(push_promise.name_value_block()); 2535 size += GetSerializedLength(push_promise.name_value_block());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2579 CHECK_LT(SPDY3, protocol_version()); 2572 CHECK_LT(SPDY3, protocol_version());
2580 uint8 flags = 0; 2573 uint8 flags = 0;
2581 if (continuation.end_headers()) { 2574 if (continuation.end_headers()) {
2582 flags |= HEADERS_FLAG_END_HEADERS; 2575 flags |= HEADERS_FLAG_END_HEADERS;
2583 } 2576 }
2584 2577
2585 // The size of this frame, including variable-length name-value block. 2578 // The size of this frame, including variable-length name-value block.
2586 size_t size = GetContinuationMinimumSize(); 2579 size_t size = GetContinuationMinimumSize();
2587 string hpack_encoding; 2580 string hpack_encoding;
2588 if (enable_compression_) { 2581 if (enable_compression_) {
2589 hpack_encoder_->EncodeHeaderSet( 2582 GetHpackEncoder()->EncodeHeaderSet(
2590 continuation.name_value_block(), &hpack_encoding); 2583 continuation.name_value_block(), &hpack_encoding);
2591 } else { 2584 } else {
2592 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2585 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2593 continuation.name_value_block(), &hpack_encoding); 2586 continuation.name_value_block(), &hpack_encoding);
2594 } 2587 }
2595 size += hpack_encoding.size(); 2588 size += hpack_encoding.size();
2596 2589
2597 SpdyFrameBuilder builder(size, protocol_version()); 2590 SpdyFrameBuilder builder(size, protocol_version());
2598 builder.BeginNewFrame(*this, CONTINUATION, flags, 2591 builder.BeginNewFrame(*this, CONTINUATION, flags,
2599 continuation.stream_id()); 2592 continuation.stream_id());
2600 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); 2593 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2601 2594
2602 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2595 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 2794
2802 int success = inflateInit(header_decompressor_.get()); 2795 int success = inflateInit(header_decompressor_.get());
2803 if (success != Z_OK) { 2796 if (success != Z_OK) {
2804 LOG(WARNING) << "inflateInit failure: " << success; 2797 LOG(WARNING) << "inflateInit failure: " << success;
2805 header_decompressor_.reset(NULL); 2798 header_decompressor_.reset(NULL);
2806 return NULL; 2799 return NULL;
2807 } 2800 }
2808 return header_decompressor_.get(); 2801 return header_decompressor_.get();
2809 } 2802 }
2810 2803
2804 HpackEncoder* SpdyFramer::GetHpackEncoder() {
2805 DCHECK_LT(SPDY3, spdy_version_);
2806 if (hpack_encoder_.get() == NULL) {
2807 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
2808 }
2809 return hpack_encoder_.get();
2810 }
2811
2812 HpackDecoder* SpdyFramer::GetHpackDecoder() {
2813 DCHECK_LT(SPDY3, spdy_version_);
2814 if (hpack_decoder_.get() == NULL) {
2815 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
2816 }
2817 return hpack_decoder_.get();
2818 }
2819
2811 // Incrementally decompress the control frame's header block, feeding the 2820 // Incrementally decompress the control frame's header block, feeding the
2812 // result to the visitor in chunks. Continue this until the visitor 2821 // result to the visitor in chunks. Continue this until the visitor
2813 // indicates that it cannot process any more data, or (more commonly) we 2822 // indicates that it cannot process any more data, or (more commonly) we
2814 // run out of data to deliver. 2823 // run out of data to deliver.
2815 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 2824 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
2816 SpdyStreamId stream_id, 2825 SpdyStreamId stream_id,
2817 const char* data, 2826 const char* data,
2818 size_t len) { 2827 size_t len) {
2819 // Get a decompressor or set error. 2828 // Get a decompressor or set error.
2820 z_stream* decomp = GetHeaderDecompressor(); 2829 z_stream* decomp = GetHeaderDecompressor();
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2987 builder->Seek(compressed_size); 2996 builder->Seek(compressed_size);
2988 builder->RewriteLength(*this); 2997 builder->RewriteLength(*this);
2989 2998
2990 pre_compress_bytes.Add(uncompressed_len); 2999 pre_compress_bytes.Add(uncompressed_len);
2991 post_compress_bytes.Add(compressed_size); 3000 post_compress_bytes.Add(compressed_size);
2992 3001
2993 compressed_frames.Increment(); 3002 compressed_frames.Increment();
2994 } 3003 }
2995 3004
2996 } // namespace net 3005 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698