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

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

Issue 265763011: Land recent SPDY changes (through 66310528) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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') | net/spdy/spdy_framer_test.cc » ('j') | 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 116
117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( 117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
118 const char* rst_stream_data, 118 const char* rst_stream_data,
119 size_t len) { 119 size_t len) {
120 return true; 120 return true;
121 } 121 }
122 122
123 SpdyFramer::SpdyFramer(SpdyMajorVersion version) 123 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
124 : current_frame_buffer_(new char[kControlFrameBufferSize]), 124 : current_frame_buffer_(new char[kControlFrameBufferSize]),
125 enable_compression_(true), 125 enable_compression_(true),
126 hpack_encoder_(ObtainHpackHuffmanTable()),
127 hpack_decoder_(ObtainHpackHuffmanTable()),
128 visitor_(NULL), 126 visitor_(NULL),
129 debug_visitor_(NULL), 127 debug_visitor_(NULL),
130 display_protocol_("SPDY"), 128 display_protocol_("SPDY"),
131 spdy_version_(version), 129 spdy_version_(version),
132 syn_frame_processed_(false), 130 syn_frame_processed_(false),
133 probable_http_response_(false), 131 probable_http_response_(false),
134 expect_continuation_(0), 132 expect_continuation_(0),
135 end_stream_when_done_(false) { 133 end_stream_when_done_(false) {
136 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 134 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
137 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION); 135 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
138 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 }
139 } 143 }
140 144
141 SpdyFramer::~SpdyFramer() { 145 SpdyFramer::~SpdyFramer() {
142 if (header_compressor_.get()) { 146 if (header_compressor_.get()) {
143 deflateEnd(header_compressor_.get()); 147 deflateEnd(header_compressor_.get());
144 } 148 }
145 if (header_decompressor_.get()) { 149 if (header_decompressor_.get()) {
146 inflateEnd(header_decompressor_.get()); 150 inflateEnd(header_decompressor_.get());
147 } 151 }
148 } 152 }
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 bool processed_successfully = true; 1474 bool processed_successfully = true;
1471 if (current_frame_type_ != SYN_STREAM && 1475 if (current_frame_type_ != SYN_STREAM &&
1472 current_frame_type_ != SYN_REPLY && 1476 current_frame_type_ != SYN_REPLY &&
1473 current_frame_type_ != HEADERS && 1477 current_frame_type_ != HEADERS &&
1474 current_frame_type_ != PUSH_PROMISE && 1478 current_frame_type_ != PUSH_PROMISE &&
1475 current_frame_type_ != CONTINUATION) { 1479 current_frame_type_ != CONTINUATION) {
1476 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; 1480 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
1477 } 1481 }
1478 size_t process_bytes = std::min(data_len, remaining_data_length_); 1482 size_t process_bytes = std::min(data_len, remaining_data_length_);
1479 if (is_hpack_header_block) { 1483 if (is_hpack_header_block) {
1480 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_, 1484 if (!hpack_decoder_->HandleControlFrameHeadersData(current_frame_stream_id_,
1481 data, 1485 data,
1482 process_bytes)) { 1486 process_bytes)) {
1483 // TODO(jgraettinger): Finer-grained HPACK error codes. 1487 // TODO(jgraettinger): Finer-grained HPACK error codes.
1484 set_error(SPDY_DECOMPRESS_FAILURE); 1488 set_error(SPDY_DECOMPRESS_FAILURE);
1485 processed_successfully = false; 1489 processed_successfully = false;
1486 } 1490 }
1487 } else if (process_bytes > 0) { 1491 } else if (process_bytes > 0) {
1488 if (enable_compression_ && protocol_version() <= SPDY3) { 1492 if (enable_compression_ && protocol_version() <= SPDY3) {
1489 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1493 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
1490 current_frame_stream_id_, data, process_bytes); 1494 current_frame_stream_id_, data, process_bytes);
1491 } else { 1495 } else {
1492 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1496 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
1493 current_frame_stream_id_, data, process_bytes); 1497 current_frame_stream_id_, data, process_bytes);
1494 } 1498 }
1495 } 1499 }
1496 remaining_data_length_ -= process_bytes; 1500 remaining_data_length_ -= process_bytes;
1497 1501
1498 // Handle the case that there is no futher data in this frame. 1502 // Handle the case that there is no futher data in this frame.
1499 if (remaining_data_length_ == 0 && processed_successfully) { 1503 if (remaining_data_length_ == 0 && processed_successfully) {
1500 if (expect_continuation_ == 0) { 1504 if (expect_continuation_ == 0) {
1501 if (is_hpack_header_block) { 1505 if (is_hpack_header_block) {
1502 if (!hpack_decoder_.HandleControlFrameHeadersComplete( 1506 if (!hpack_decoder_->HandleControlFrameHeadersComplete(
1503 current_frame_stream_id_)) { 1507 current_frame_stream_id_)) {
1504 set_error(SPDY_DECOMPRESS_FAILURE); 1508 set_error(SPDY_DECOMPRESS_FAILURE);
1505 processed_successfully = false; 1509 processed_successfully = false;
1506 } else { 1510 } else {
1507 // TODO(jgraettinger): To be removed with migration to 1511 // TODO(jgraettinger): To be removed with migration to
1508 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 1512 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
1509 // block, delivered via reentrant call to 1513 // block, delivered via reentrant call to
1510 // ProcessControlFrameHeaderBlock(). 1514 // ProcessControlFrameHeaderBlock().
1511 DeliverHpackBlockAsSpdy3Block(); 1515 DeliverHpackBlockAsSpdy3Block();
1512 return process_bytes; 1516 return process_bytes;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 CHANGE_STATE(SPDY_AUTO_RESET); 1592 CHANGE_STATE(SPDY_AUTO_RESET);
1589 } 1593 }
1590 1594
1591 return processed_bytes; 1595 return processed_bytes;
1592 } 1596 }
1593 1597
1594 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { 1598 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
1595 DCHECK_LT(SPDY3, protocol_version()); 1599 DCHECK_LT(SPDY3, protocol_version());
1596 DCHECK_EQ(0u, remaining_data_length_); 1600 DCHECK_EQ(0u, remaining_data_length_);
1597 1601
1598 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); 1602 const SpdyNameValueBlock& block = hpack_decoder_->decoded_block();
1599 if (block.empty()) { 1603 if (block.empty()) {
1600 // Special-case this to make tests happy. 1604 // Special-case this to make tests happy.
1601 ProcessControlFrameHeaderBlock(NULL, 0, false); 1605 ProcessControlFrameHeaderBlock(NULL, 0, false);
1602 return; 1606 return;
1603 } 1607 }
1604 SpdyFrameBuilder builder( 1608 SpdyFrameBuilder builder(
1605 GetSerializedLength(protocol_version(), &block), 1609 GetSerializedLength(protocol_version(), &block),
1606 SPDY3); 1610 SPDY3);
1607 1611
1608 SerializeNameValueBlockWithoutCompression(&builder, block); 1612 SerializeNameValueBlockWithoutCompression(&builder, block);
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 DLOG(DFATAL) << "Priority out-of-bounds."; 2141 DLOG(DFATAL) << "Priority out-of-bounds.";
2138 priority = GetLowestPriority(); 2142 priority = GetLowestPriority();
2139 } 2143 }
2140 2144
2141 // The size of this frame, including variable-length name-value block. 2145 // The size of this frame, including variable-length name-value block.
2142 size_t size = GetSynStreamMinimumSize(); 2146 size_t size = GetSynStreamMinimumSize();
2143 2147
2144 string hpack_encoding; 2148 string hpack_encoding;
2145 if (protocol_version() > SPDY3) { 2149 if (protocol_version() > SPDY3) {
2146 if (enable_compression_) { 2150 if (enable_compression_) {
2147 hpack_encoder_.EncodeHeaderSet( 2151 hpack_encoder_->EncodeHeaderSet(
2148 syn_stream.name_value_block(), &hpack_encoding); 2152 syn_stream.name_value_block(), &hpack_encoding);
2149 } else { 2153 } else {
2150 hpack_encoder_.EncodeHeaderSetWithoutCompression( 2154 hpack_encoder_->EncodeHeaderSetWithoutCompression(
2151 syn_stream.name_value_block(), &hpack_encoding); 2155 syn_stream.name_value_block(), &hpack_encoding);
2152 } 2156 }
2153 size += hpack_encoding.size(); 2157 size += hpack_encoding.size();
2154 } else { 2158 } else {
2155 size += GetSerializedLength(syn_stream.name_value_block()); 2159 size += GetSerializedLength(syn_stream.name_value_block());
2156 } 2160 }
2157 2161
2158 SpdyFrameBuilder builder(size, protocol_version()); 2162 SpdyFrameBuilder builder(size, protocol_version());
2159 if (protocol_version() <= SPDY3) { 2163 if (protocol_version() <= SPDY3) {
2160 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 2164 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 if (protocol_version() > SPDY3) { 2206 if (protocol_version() > SPDY3) {
2203 flags |= HEADERS_FLAG_END_HEADERS; 2207 flags |= HEADERS_FLAG_END_HEADERS;
2204 } 2208 }
2205 2209
2206 // The size of this frame, including variable-length name-value block. 2210 // The size of this frame, including variable-length name-value block.
2207 size_t size = GetSynReplyMinimumSize(); 2211 size_t size = GetSynReplyMinimumSize();
2208 2212
2209 string hpack_encoding; 2213 string hpack_encoding;
2210 if (protocol_version() > SPDY3) { 2214 if (protocol_version() > SPDY3) {
2211 if (enable_compression_) { 2215 if (enable_compression_) {
2212 hpack_encoder_.EncodeHeaderSet( 2216 hpack_encoder_->EncodeHeaderSet(
2213 syn_reply.name_value_block(), &hpack_encoding); 2217 syn_reply.name_value_block(), &hpack_encoding);
2214 } else { 2218 } else {
2215 hpack_encoder_.EncodeHeaderSetWithoutCompression( 2219 hpack_encoder_->EncodeHeaderSetWithoutCompression(
2216 syn_reply.name_value_block(), &hpack_encoding); 2220 syn_reply.name_value_block(), &hpack_encoding);
2217 } 2221 }
2218 size += hpack_encoding.size(); 2222 size += hpack_encoding.size();
2219 } else { 2223 } else {
2220 size += GetSerializedLength(syn_reply.name_value_block()); 2224 size += GetSerializedLength(syn_reply.name_value_block());
2221 } 2225 }
2222 2226
2223 SpdyFrameBuilder builder(size, protocol_version()); 2227 SpdyFrameBuilder builder(size, protocol_version());
2224 if (protocol_version() <= SPDY3) { 2228 if (protocol_version() <= SPDY3) {
2225 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 2229 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2400 return builder.take(); 2404 return builder.take();
2401 } 2405 }
2402 2406
2403 SpdySerializedFrame* SpdyFramer::SerializeHeaders( 2407 SpdySerializedFrame* SpdyFramer::SerializeHeaders(
2404 const SpdyHeadersIR& headers) { 2408 const SpdyHeadersIR& headers) {
2405 uint8 flags = 0; 2409 uint8 flags = 0;
2406 if (headers.fin()) { 2410 if (headers.fin()) {
2407 flags |= CONTROL_FLAG_FIN; 2411 flags |= CONTROL_FLAG_FIN;
2408 } 2412 }
2409 if (protocol_version() > SPDY3) { 2413 if (protocol_version() > SPDY3) {
2410 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will 2414 // This will get overwritten if we overflow into a CONTINUATION frame.
2411 // get overwritten below, so we should probably just get rid of the 2415 flags |= HEADERS_FLAG_END_HEADERS;
2412 // end_headers field.
2413 if (headers.end_headers()) {
2414 flags |= HEADERS_FLAG_END_HEADERS;
2415 }
2416 if (headers.has_priority()) { 2416 if (headers.has_priority()) {
2417 flags |= HEADERS_FLAG_PRIORITY; 2417 flags |= HEADERS_FLAG_PRIORITY;
2418 } 2418 }
2419 } 2419 }
2420 2420
2421 // The size of this frame, including variable-length name-value block. 2421 // The size of this frame, including variable-length name-value block.
2422 size_t size = GetHeadersMinimumSize(); 2422 size_t size = GetHeadersMinimumSize();
2423 2423
2424 uint32 priority = headers.priority(); 2424 uint32 priority = headers.priority();
2425 if (headers.has_priority()) { 2425 if (headers.has_priority()) {
2426 if (priority > GetLowestPriority()) { 2426 if (priority > GetLowestPriority()) {
2427 DLOG(DFATAL) << "Priority out-of-bounds."; 2427 DLOG(DFATAL) << "Priority out-of-bounds.";
2428 priority = GetLowestPriority(); 2428 priority = GetLowestPriority();
2429 } 2429 }
2430 size += 4; 2430 size += 4;
2431 } 2431 }
2432 2432
2433 string hpack_encoding; 2433 string hpack_encoding;
2434 if (protocol_version() > SPDY3) { 2434 if (protocol_version() > SPDY3) {
2435 if (enable_compression_) { 2435 if (enable_compression_) {
2436 hpack_encoder_.EncodeHeaderSet( 2436 hpack_encoder_->EncodeHeaderSet(
2437 headers.name_value_block(), &hpack_encoding); 2437 headers.name_value_block(), &hpack_encoding);
2438 } else { 2438 } else {
2439 hpack_encoder_.EncodeHeaderSetWithoutCompression( 2439 hpack_encoder_->EncodeHeaderSetWithoutCompression(
2440 headers.name_value_block(), &hpack_encoding); 2440 headers.name_value_block(), &hpack_encoding);
2441 } 2441 }
2442 size += hpack_encoding.size(); 2442 size += hpack_encoding.size();
2443 if (size > GetControlFrameBufferMaxSize()) { 2443 if (size > GetControlFrameBufferMaxSize()) {
2444 size += GetNumberRequiredContinuationFrames(size) * 2444 size += GetNumberRequiredContinuationFrames(size) *
2445 GetContinuationMinimumSize(); 2445 GetContinuationMinimumSize();
2446 flags &= ~HEADERS_FLAG_END_HEADERS; 2446 flags &= ~HEADERS_FLAG_END_HEADERS;
2447 } 2447 }
2448 } else { 2448 } else {
2449 size += GetSerializedLength(headers.name_value_block()); 2449 size += GetSerializedLength(headers.name_value_block());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 DCHECK_LT(SPDY3, protocol_version()); 2511 DCHECK_LT(SPDY3, protocol_version());
2512 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version()); 2512 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version());
2513 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); 2513 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
2514 return builder.take(); 2514 return builder.take();
2515 } 2515 }
2516 2516
2517 SpdyFrame* SpdyFramer::SerializePushPromise( 2517 SpdyFrame* SpdyFramer::SerializePushPromise(
2518 const SpdyPushPromiseIR& push_promise) { 2518 const SpdyPushPromiseIR& push_promise) {
2519 DCHECK_LT(SPDY3, protocol_version()); 2519 DCHECK_LT(SPDY3, protocol_version());
2520 uint8 flags = 0; 2520 uint8 flags = 0;
2521 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will 2521 // This will get overwritten if we overflow into a CONTINUATION frame.
2522 // get overwritten below, so we should probably just get rid of the 2522 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2523 // end_push_promise field.
2524 if (push_promise.end_push_promise()) {
2525 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2526 }
2527 // The size of this frame, including variable-length name-value block. 2523 // The size of this frame, including variable-length name-value block.
2528 size_t size = GetPushPromiseMinimumSize(); 2524 size_t size = GetPushPromiseMinimumSize();
2529 2525
2530 string hpack_encoding; 2526 string hpack_encoding;
2531 if (protocol_version() > SPDY3) { 2527 if (protocol_version() > SPDY3) {
2532 if (enable_compression_) { 2528 if (enable_compression_) {
2533 hpack_encoder_.EncodeHeaderSet( 2529 hpack_encoder_->EncodeHeaderSet(
2534 push_promise.name_value_block(), &hpack_encoding); 2530 push_promise.name_value_block(), &hpack_encoding);
2535 } else { 2531 } else {
2536 hpack_encoder_.EncodeHeaderSetWithoutCompression( 2532 hpack_encoder_->EncodeHeaderSetWithoutCompression(
2537 push_promise.name_value_block(), &hpack_encoding); 2533 push_promise.name_value_block(), &hpack_encoding);
2538 } 2534 }
2539 size += hpack_encoding.size(); 2535 size += hpack_encoding.size();
2540 if (size > GetControlFrameBufferMaxSize()) { 2536 if (size > GetControlFrameBufferMaxSize()) {
2541 size += GetNumberRequiredContinuationFrames(size) * 2537 size += GetNumberRequiredContinuationFrames(size) *
2542 GetContinuationMinimumSize(); 2538 GetContinuationMinimumSize();
2543 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2539 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2544 } 2540 }
2545 } else { 2541 } else {
2546 size += GetSerializedLength(push_promise.name_value_block()); 2542 size += GetSerializedLength(push_promise.name_value_block());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 CHECK_LT(SPDY3, protocol_version()); 2579 CHECK_LT(SPDY3, protocol_version());
2584 uint8 flags = 0; 2580 uint8 flags = 0;
2585 if (continuation.end_headers()) { 2581 if (continuation.end_headers()) {
2586 flags |= HEADERS_FLAG_END_HEADERS; 2582 flags |= HEADERS_FLAG_END_HEADERS;
2587 } 2583 }
2588 2584
2589 // The size of this frame, including variable-length name-value block. 2585 // The size of this frame, including variable-length name-value block.
2590 size_t size = GetContinuationMinimumSize(); 2586 size_t size = GetContinuationMinimumSize();
2591 string hpack_encoding; 2587 string hpack_encoding;
2592 if (enable_compression_) { 2588 if (enable_compression_) {
2593 hpack_encoder_.EncodeHeaderSet( 2589 hpack_encoder_->EncodeHeaderSet(
2594 continuation.name_value_block(), &hpack_encoding); 2590 continuation.name_value_block(), &hpack_encoding);
2595 } else { 2591 } else {
2596 hpack_encoder_.EncodeHeaderSetWithoutCompression( 2592 hpack_encoder_->EncodeHeaderSetWithoutCompression(
2597 continuation.name_value_block(), &hpack_encoding); 2593 continuation.name_value_block(), &hpack_encoding);
2598 } 2594 }
2599 size += hpack_encoding.size(); 2595 size += hpack_encoding.size();
2600 2596
2601 SpdyFrameBuilder builder(size, protocol_version()); 2597 SpdyFrameBuilder builder(size, protocol_version());
2602 builder.BeginNewFrame(*this, CONTINUATION, flags, 2598 builder.BeginNewFrame(*this, CONTINUATION, flags,
2603 continuation.stream_id()); 2599 continuation.stream_id());
2604 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); 2600 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2605 2601
2606 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2602 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 builder->Seek(compressed_size); 2987 builder->Seek(compressed_size);
2992 builder->RewriteLength(*this); 2988 builder->RewriteLength(*this);
2993 2989
2994 pre_compress_bytes.Add(uncompressed_len); 2990 pre_compress_bytes.Add(uncompressed_len);
2995 post_compress_bytes.Add(compressed_size); 2991 post_compress_bytes.Add(compressed_size);
2996 2992
2997 compressed_frames.Increment(); 2993 compressed_frames.Increment();
2998 } 2994 }
2999 2995
3000 } // namespace net 2996 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698