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

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

Issue 290003006: Land recent SPDY changes (through 67282679) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on 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') | 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"
11 #include "net/spdy/spdy_frame_builder.h" 11 #include "net/spdy/spdy_frame_builder.h"
12 #include "net/spdy/spdy_frame_reader.h" 12 #include "net/spdy/spdy_frame_reader.h"
13 #include "net/spdy/spdy_bitmasks.h" 13 #include "net/spdy/spdy_bitmasks.h"
14 #include "third_party/zlib/zlib.h" 14 #include "third_party/zlib/zlib.h"
15 15
16 using base::StringPiece;
16 using std::string; 17 using std::string;
17 using std::vector; 18 using std::vector;
18 19
19 namespace net { 20 namespace net {
20 21
21 namespace { 22 namespace {
22 23
23 // Compute the id of our dictionary so that we know we're using the 24 // Compute the id of our dictionary so that we know we're using the
24 // right one when asked for it. 25 // right one when asked for it.
25 uLong CalculateDictionaryId(const char* dictionary, 26 uLong CalculateDictionaryId(const char* dictionary,
(...skipping 17 matching lines...) Expand all
43 // initialized lazily to avoid static initializers. 44 // initialized lazily to avoid static initializers.
44 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; 45 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
45 46
46 // Used to indicate no flags in a SPDY flags field. 47 // Used to indicate no flags in a SPDY flags field.
47 const uint8 kNoFlags = 0; 48 const uint8 kNoFlags = 0;
48 49
49 } // namespace 50 } // namespace
50 51
51 const SpdyStreamId SpdyFramer::kInvalidStream = -1; 52 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
52 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 53 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
53 // The size of the control frame buffer. Must be >= the minimum size of the
54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for 54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
55 // calculation details. 55 // calculation details.
56 const size_t SpdyFramer::kControlFrameBufferSize = 18; 56 const size_t SpdyFramer::kControlFrameBufferSize = 18;
57 57
58 #ifdef DEBUG_SPDY_STATE_CHANGES 58 #ifdef DEBUG_SPDY_STATE_CHANGES
59 #define CHANGE_STATE(newstate) \ 59 #define CHANGE_STATE(newstate) \
60 do { \ 60 do { \
61 DVLOG(1) << "Changing state from: " \ 61 DVLOG(1) << "Changing state from: " \
62 << StateToString(state_) \ 62 << StateToString(state_) \
63 << " to " << StateToString(newstate) << "\n"; \ 63 << " to " << StateToString(newstate) << "\n"; \
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 // This method is used to preserve buggy behavior and works on both 102 // This method is used to preserve buggy behavior and works on both
103 // little-endian and big-endian hosts. 103 // little-endian and big-endian hosts.
104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
105 // as well as vice versa). 105 // as well as vice versa).
106 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { 106 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
107 uint8* wire_array = reinterpret_cast<uint8*>(val); 107 uint8* wire_array = reinterpret_cast<uint8*>(val);
108 std::swap(wire_array[0], wire_array[3]); 108 std::swap(wire_array[0], wire_array[3]);
109 std::swap(wire_array[1], wire_array[2]); 109 std::swap(wire_array[1], wire_array[2]);
110 } 110 }
111 111
112 SpdyAltSvcScratch::SpdyAltSvcScratch() { Reset(); }
113 SpdyAltSvcScratch::~SpdyAltSvcScratch() {}
114
112 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, 115 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
113 size_t len) { 116 size_t len) {
114 return true; 117 return true;
115 } 118 }
116 119
117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( 120 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
118 const char* rst_stream_data, 121 const char* rst_stream_data,
119 size_t len) { 122 size_t len) {
120 return true; 123 return true;
121 } 124 }
122 125
123 SpdyFramer::SpdyFramer(SpdyMajorVersion version) 126 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
124 : current_frame_buffer_(new char[kControlFrameBufferSize]), 127 : current_frame_buffer_(new char[kControlFrameBufferSize]),
125 enable_compression_(true), 128 enable_compression_(true),
126 visitor_(NULL), 129 visitor_(NULL),
127 debug_visitor_(NULL), 130 debug_visitor_(NULL),
128 display_protocol_("SPDY"), 131 display_protocol_("SPDY"),
129 spdy_version_(version), 132 spdy_version_(version),
130 syn_frame_processed_(false), 133 syn_frame_processed_(false),
131 probable_http_response_(false), 134 probable_http_response_(false),
132 expect_continuation_(0), 135 expect_continuation_(0),
133 end_stream_when_done_(false) { 136 end_stream_when_done_(false) {
134 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 137 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
135 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION); 138 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
136 Reset(); 139 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 } 140 }
144 141
145 SpdyFramer::~SpdyFramer() { 142 SpdyFramer::~SpdyFramer() {
146 if (header_compressor_.get()) { 143 if (header_compressor_.get()) {
147 deflateEnd(header_compressor_.get()); 144 deflateEnd(header_compressor_.get());
148 } 145 }
149 if (header_decompressor_.get()) { 146 if (header_decompressor_.get()) {
150 inflateEnd(header_decompressor_.get()); 147 inflateEnd(header_decompressor_.get());
151 } 148 }
152 } 149 }
153 150
154 void SpdyFramer::Reset() { 151 void SpdyFramer::Reset() {
155 state_ = SPDY_RESET; 152 state_ = SPDY_RESET;
156 previous_state_ = SPDY_RESET; 153 previous_state_ = SPDY_RESET;
157 error_code_ = SPDY_NO_ERROR; 154 error_code_ = SPDY_NO_ERROR;
158 remaining_data_length_ = 0; 155 remaining_data_length_ = 0;
159 remaining_control_header_ = 0; 156 remaining_control_header_ = 0;
160 current_frame_buffer_length_ = 0; 157 current_frame_buffer_length_ = 0;
161 current_frame_type_ = DATA; 158 current_frame_type_ = DATA;
162 current_frame_flags_ = 0; 159 current_frame_flags_ = 0;
163 current_frame_length_ = 0; 160 current_frame_length_ = 0;
164 current_frame_stream_id_ = kInvalidStream; 161 current_frame_stream_id_ = kInvalidStream;
165 settings_scratch_.Reset(); 162 settings_scratch_.Reset();
163 altsvc_scratch_.Reset();
166 remaining_padding_payload_length_ = 0; 164 remaining_padding_payload_length_ = 0;
167 remaining_padding_length_fields_ = 0; 165 remaining_padding_length_fields_ = 0;
168 } 166 }
169 167
170 size_t SpdyFramer::GetDataFrameMinimumSize() const { 168 size_t SpdyFramer::GetDataFrameMinimumSize() const {
171 return SpdyConstants::GetDataFrameMinimumSize(); 169 return SpdyConstants::GetDataFrameMinimumSize();
172 } 170 }
173 171
174 // Size, in bytes, of the control frame header. 172 // Size, in bytes, of the control frame header.
175 size_t SpdyFramer::GetControlFrameHeaderSize() const { 173 size_t SpdyFramer::GetControlFrameHeaderSize() const {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 return GetControlFrameHeaderSize(); 298 return GetControlFrameHeaderSize();
301 } 299 }
302 300
303 size_t SpdyFramer::GetPushPromiseMinimumSize() const { 301 size_t SpdyFramer::GetPushPromiseMinimumSize() const {
304 DCHECK_LT(SPDY3, protocol_version()); 302 DCHECK_LT(SPDY3, protocol_version());
305 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. 303 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
306 // Calculated as frame prefix + 4 (promised stream id). 304 // Calculated as frame prefix + 4 (promised stream id).
307 return GetControlFrameHeaderSize() + 4; 305 return GetControlFrameHeaderSize() + 4;
308 } 306 }
309 307
310 size_t SpdyFramer::GetContinuationMinimumSize() const { 308 size_t SpdyFramer::GetContinuationMinimumSize() const {
311 // Size, in bytes, of a CONTINUATION frame not including the variable-length 309 // Size, in bytes, of a CONTINUATION frame not including the variable-length
312 // headers fragments. 310 // headers fragments.
313 return GetControlFrameHeaderSize(); 311 return GetControlFrameHeaderSize();
314 } 312 }
315 313
314 size_t SpdyFramer::GetAltSvcMinimumSize() const {
315 // Size, in bytes, of an ALTSVC frame not including the Protocol-ID, Host, and
316 // (optional) Origin fields, all of which can vary in length.
317 // Note that this gives a lower bound on the frame size rather than a true
318 // minimum; the actual frame should always be larger than this.
319 // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte)
320 // + 1 (pid_len) + 1 (host_len).
321 return GetControlFrameHeaderSize() + 9;
322 }
323
324 size_t SpdyFramer::GetPrioritySize() const {
325 // Size, in bytes, of a PRIORITY frame.
326 // Calculated as frame prefix + 4 (stream dependency) + 1 (weight)
327 return GetControlFrameHeaderSize() + 5;
328 }
329
316 size_t SpdyFramer::GetFrameMinimumSize() const { 330 size_t SpdyFramer::GetFrameMinimumSize() const {
317 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); 331 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
318 } 332 }
319 333
320 size_t SpdyFramer::GetFrameMaximumSize() const { 334 size_t SpdyFramer::GetFrameMaximumSize() const {
321 return SpdyConstants::GetFrameMaximumSize(protocol_version()); 335 return SpdyConstants::GetFrameMaximumSize(protocol_version());
322 } 336 }
323 337
324 size_t SpdyFramer::GetDataFrameMaximumPayload() const { 338 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
325 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); 339 return GetFrameMaximumSize() - GetDataFrameMinimumSize();
(...skipping 26 matching lines...) Expand all
352 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 366 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
353 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 367 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
354 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 368 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
355 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 369 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
356 case SPDY_GOAWAY_FRAME_PAYLOAD: 370 case SPDY_GOAWAY_FRAME_PAYLOAD:
357 return "SPDY_GOAWAY_FRAME_PAYLOAD"; 371 return "SPDY_GOAWAY_FRAME_PAYLOAD";
358 case SPDY_RST_STREAM_FRAME_PAYLOAD: 372 case SPDY_RST_STREAM_FRAME_PAYLOAD:
359 return "SPDY_RST_STREAM_FRAME_PAYLOAD"; 373 return "SPDY_RST_STREAM_FRAME_PAYLOAD";
360 case SPDY_SETTINGS_FRAME_PAYLOAD: 374 case SPDY_SETTINGS_FRAME_PAYLOAD:
361 return "SPDY_SETTINGS_FRAME_PAYLOAD"; 375 return "SPDY_SETTINGS_FRAME_PAYLOAD";
376 case SPDY_ALTSVC_FRAME_PAYLOAD:
377 return "SPDY_ALTSVC_FRAME_PAYLOAD";
362 } 378 }
363 return "UNKNOWN_STATE"; 379 return "UNKNOWN_STATE";
364 } 380 }
365 381
366 void SpdyFramer::set_error(SpdyError error) { 382 void SpdyFramer::set_error(SpdyError error) {
367 DCHECK(visitor_); 383 DCHECK(visitor_);
368 error_code_ = error; 384 error_code_ = error;
369 // These values will usually get reset once we come to the end 385 // These values will usually get reset once we come to the end
370 // of a header block, but if we run into an error that 386 // of a header block, but if we run into an error that
371 // might not happen, so reset them here. 387 // might not happen, so reset them here.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 case WINDOW_UPDATE: 475 case WINDOW_UPDATE:
460 return "WINDOW_UPDATE"; 476 return "WINDOW_UPDATE";
461 case CREDENTIAL: 477 case CREDENTIAL:
462 return "CREDENTIAL"; 478 return "CREDENTIAL";
463 case BLOCKED: 479 case BLOCKED:
464 return "BLOCKED"; 480 return "BLOCKED";
465 case PUSH_PROMISE: 481 case PUSH_PROMISE:
466 return "PUSH_PROMISE"; 482 return "PUSH_PROMISE";
467 case CONTINUATION: 483 case CONTINUATION:
468 return "CONTINUATION"; 484 return "CONTINUATION";
485 case ALTSVC:
486 return "ALTSVC";
487 case PRIORITY:
488 return "PRIORITY";
469 } 489 }
470 return "UNKNOWN_CONTROL_TYPE"; 490 return "UNKNOWN_CONTROL_TYPE";
471 } 491 }
472 492
473 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { 493 size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
474 DCHECK(visitor_); 494 DCHECK(visitor_);
475 DCHECK(data); 495 DCHECK(data);
476 496
477 size_t original_len = len; 497 size_t original_len = len;
478 do { 498 do {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 break; 558 break;
539 } 559 }
540 560
541 case SPDY_GOAWAY_FRAME_PAYLOAD: { 561 case SPDY_GOAWAY_FRAME_PAYLOAD: {
542 size_t bytes_read = ProcessGoAwayFramePayload(data, len); 562 size_t bytes_read = ProcessGoAwayFramePayload(data, len);
543 len -= bytes_read; 563 len -= bytes_read;
544 data += bytes_read; 564 data += bytes_read;
545 break; 565 break;
546 } 566 }
547 567
568 case SPDY_ALTSVC_FRAME_PAYLOAD: {
569 size_t bytes_read = ProcessAltSvcFramePayload(data, len);
570 len -= bytes_read;
571 data += bytes_read;
572 break;
573 }
574
548 case SPDY_CONTROL_FRAME_PAYLOAD: { 575 case SPDY_CONTROL_FRAME_PAYLOAD: {
549 size_t bytes_read = ProcessControlFramePayload(data, len); 576 size_t bytes_read = ProcessControlFramePayload(data, len);
550 len -= bytes_read; 577 len -= bytes_read;
551 data += bytes_read; 578 data += bytes_read;
552 break; 579 break;
553 } 580 }
554 581
555 case SPDY_READ_PADDING_LENGTH: { 582 case SPDY_READ_PADDING_LENGTH: {
556 size_t bytes_read = ProcessFramePaddingLength(data, len); 583 size_t bytes_read = ProcessFramePaddingLength(data, len);
557 len -= bytes_read; 584 len -= bytes_read;
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 size_t min_size = GetHeadersMinimumSize(); 922 size_t min_size = GetHeadersMinimumSize();
896 if (protocol_version() > SPDY3 && 923 if (protocol_version() > SPDY3 &&
897 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { 924 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
898 min_size += 4; 925 min_size += 4;
899 } 926 }
900 if (current_frame_length_ < min_size) { 927 if (current_frame_length_ < min_size) {
901 set_error(SPDY_INVALID_CONTROL_FRAME); 928 set_error(SPDY_INVALID_CONTROL_FRAME);
902 } else if (protocol_version() <= SPDY3 && 929 } else if (protocol_version() <= SPDY3 &&
903 current_frame_flags_ & ~CONTROL_FLAG_FIN) { 930 current_frame_flags_ & ~CONTROL_FLAG_FIN) {
904 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 931 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
905 } else if (protocol_version() > SPDY3 && current_frame_flags_ & 932 } else if (protocol_version() > SPDY3 &&
906 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | 933 current_frame_flags_ &
907 HEADERS_FLAG_END_HEADERS)) { 934 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY |
935 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT |
936 HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) {
908 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 937 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
909 } 938 }
910 } 939 }
911 break; 940 break;
912 case WINDOW_UPDATE: 941 case WINDOW_UPDATE:
913 if (current_frame_length_ != GetWindowUpdateSize()) { 942 if (current_frame_length_ != GetWindowUpdateSize()) {
914 set_error(SPDY_INVALID_CONTROL_FRAME); 943 set_error(SPDY_INVALID_CONTROL_FRAME);
915 } else if (current_frame_flags_ != 0) { 944 } else if (current_frame_flags_ != 0) {
916 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 945 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
917 } 946 }
918 break; 947 break;
919 case BLOCKED: 948 case BLOCKED:
920 if (current_frame_length_ != GetBlockedSize()) { 949 if (current_frame_length_ != GetBlockedSize() ||
950 protocol_version() <= SPDY3) {
951 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4.
921 set_error(SPDY_INVALID_CONTROL_FRAME); 952 set_error(SPDY_INVALID_CONTROL_FRAME);
922 } else if (current_frame_flags_ != 0) { 953 } else if (current_frame_flags_ != 0) {
923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 954 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
924 } 955 }
925 break; 956 break;
926 case PUSH_PROMISE: 957 case PUSH_PROMISE:
927 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 958 if (current_frame_length_ < GetPushPromiseMinimumSize()) {
928 set_error(SPDY_INVALID_CONTROL_FRAME); 959 set_error(SPDY_INVALID_CONTROL_FRAME);
929 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { 960 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
930 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 961 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
931 } else if (protocol_version() > SPDY3 && current_frame_flags_ & 962 } else if (protocol_version() > SPDY3 &&
932 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { 963 current_frame_flags_ &
964 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE |
965 HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) {
933 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 966 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
934 } 967 }
935 break; 968 break;
936 case CONTINUATION: 969 case CONTINUATION:
937 if (current_frame_length_ < GetContinuationMinimumSize() || 970 if (current_frame_length_ < GetContinuationMinimumSize() ||
938 protocol_version() <= SPDY3) { 971 protocol_version() <= SPDY3) {
939 set_error(SPDY_INVALID_CONTROL_FRAME); 972 set_error(SPDY_INVALID_CONTROL_FRAME);
940 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { 973 } else if (current_frame_flags_ &
974 ~(HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PAD_LOW |
975 HEADERS_FLAG_PAD_HIGH)) {
941 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 976 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
942 } 977 }
943 break; 978 break;
979 case ALTSVC:
980 if (current_frame_length_ <= GetAltSvcMinimumSize()) {
981 set_error(SPDY_INVALID_CONTROL_FRAME);
982 } else if (current_frame_flags_ != 0) {
983 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
984 }
985 break;
986 case PRIORITY:
987 if (current_frame_length_ != GetPrioritySize() ||
988 protocol_version() <= SPDY3) {
989 set_error(SPDY_INVALID_CONTROL_FRAME);
990 } else if (current_frame_flags_ != 0) {
991 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
992 }
993 break;
944 default: 994 default:
945 LOG(WARNING) << "Valid " << display_protocol_ 995 LOG(WARNING) << "Valid " << display_protocol_
946 << " control frame with unhandled type: " 996 << " control frame with unhandled type: "
947 << current_frame_type_; 997 << current_frame_type_;
948 // This branch should be unreachable because of the frame type bounds 998 // This branch should be unreachable because of the frame type bounds
949 // check above. However, we DLOG(FATAL) here in an effort to painfully 999 // check above. However, we DLOG(FATAL) here in an effort to painfully
950 // club the head of the developer who failed to keep this file in sync 1000 // club the head of the developer who failed to keep this file in sync
951 // with spdy_protocol.h. 1001 // with spdy_protocol.h.
952 DLOG(FATAL); 1002 DLOG(FATAL);
953 set_error(SPDY_INVALID_CONTROL_FRAME); 1003 set_error(SPDY_INVALID_CONTROL_FRAME);
(...skipping 14 matching lines...) Expand all
968 if (current_frame_type_ == GOAWAY) { 1018 if (current_frame_type_ == GOAWAY) {
969 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD); 1019 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD);
970 return; 1020 return;
971 } 1021 }
972 1022
973 if (current_frame_type_ == RST_STREAM) { 1023 if (current_frame_type_ == RST_STREAM) {
974 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD); 1024 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD);
975 return; 1025 return;
976 } 1026 }
977 1027
1028 if (current_frame_type_ == ALTSVC) {
1029 CHANGE_STATE(SPDY_ALTSVC_FRAME_PAYLOAD);
1030 return;
1031 }
978 // Determine the frame size without variable-length data. 1032 // Determine the frame size without variable-length data.
979 int32 frame_size_without_variable_data; 1033 int32 frame_size_without_variable_data;
980 switch (current_frame_type_) { 1034 switch (current_frame_type_) {
981 case SYN_STREAM: 1035 case SYN_STREAM:
982 syn_frame_processed_ = true; 1036 syn_frame_processed_ = true;
983 frame_size_without_variable_data = GetSynStreamMinimumSize(); 1037 frame_size_without_variable_data = GetSynStreamMinimumSize();
984 break; 1038 break;
985 case SYN_REPLY: 1039 case SYN_REPLY:
986 syn_frame_processed_ = true; 1040 syn_frame_processed_ = true;
987 frame_size_without_variable_data = GetSynReplyMinimumSize(); 1041 frame_size_without_variable_data = GetSynReplyMinimumSize();
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 priority, 1443 priority,
1390 current_frame_flags_ & CONTROL_FLAG_FIN, 1444 current_frame_flags_ & CONTROL_FLAG_FIN,
1391 false); // unidirectional 1445 false); // unidirectional
1392 } else { 1446 } else {
1393 visitor_->OnHeaders( 1447 visitor_->OnHeaders(
1394 current_frame_stream_id_, 1448 current_frame_stream_id_,
1395 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1449 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1396 expect_continuation_ == 0); 1450 expect_continuation_ == 0);
1397 } 1451 }
1398 } 1452 }
1399 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1453 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
1400 break; 1454 break;
1401 case PUSH_PROMISE: 1455 case PUSH_PROMISE:
1402 { 1456 {
1403 DCHECK_LT(SPDY3, protocol_version()); 1457 DCHECK_LT(SPDY3, protocol_version());
1404 if (current_frame_stream_id_ == 0) { 1458 if (current_frame_stream_id_ == 0) {
1405 set_error(SPDY_INVALID_CONTROL_FRAME); 1459 set_error(SPDY_INVALID_CONTROL_FRAME);
1406 break; 1460 break;
1407 } 1461 }
1408 SpdyStreamId promised_stream_id = kInvalidStream; 1462 SpdyStreamId promised_stream_id = kInvalidStream;
1409 bool successful_read = reader.ReadUInt31(&promised_stream_id); 1463 bool successful_read = reader.ReadUInt31(&promised_stream_id);
(...skipping 10 matching lines...) Expand all
1420 debug_visitor_->OnReceiveCompressedFrame( 1474 debug_visitor_->OnReceiveCompressedFrame(
1421 current_frame_stream_id_, 1475 current_frame_stream_id_,
1422 current_frame_type_, 1476 current_frame_type_,
1423 current_frame_length_); 1477 current_frame_length_);
1424 } 1478 }
1425 visitor_->OnPushPromise(current_frame_stream_id_, 1479 visitor_->OnPushPromise(current_frame_stream_id_,
1426 promised_stream_id, 1480 promised_stream_id,
1427 (current_frame_flags_ & 1481 (current_frame_flags_ &
1428 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); 1482 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
1429 } 1483 }
1430 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1484 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
1431 break; 1485 break;
1432 case CONTINUATION: 1486 case CONTINUATION:
1433 { 1487 {
1434 // Check to make sure the stream id of the current frame is 1488 // Check to make sure the stream id of the current frame is
1435 // the same as that of the preceding frame. 1489 // the same as that of the preceding frame.
1436 // If we're at this point we should already know that 1490 // If we're at this point we should already know that
1437 // expect_continuation_ != 0, so this doubles as a check 1491 // expect_continuation_ != 0, so this doubles as a check
1438 // that current_frame_stream_id != 0. 1492 // that current_frame_stream_id != 0.
1439 if (current_frame_stream_id_ != expect_continuation_) { 1493 if (current_frame_stream_id_ != expect_continuation_) {
1440 set_error(SPDY_INVALID_CONTROL_FRAME); 1494 set_error(SPDY_INVALID_CONTROL_FRAME);
1441 break; 1495 break;
1442 } 1496 }
1443 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { 1497 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) {
1444 expect_continuation_ = 0; 1498 expect_continuation_ = 0;
1445 } 1499 }
1446 if (debug_visitor_) { 1500 if (debug_visitor_) {
1447 debug_visitor_->OnReceiveCompressedFrame( 1501 debug_visitor_->OnReceiveCompressedFrame(
1448 current_frame_stream_id_, 1502 current_frame_stream_id_,
1449 current_frame_type_, 1503 current_frame_type_,
1450 current_frame_length_); 1504 current_frame_length_);
1451 } 1505 }
1452 visitor_->OnContinuation(current_frame_stream_id_, 1506 visitor_->OnContinuation(current_frame_stream_id_,
1453 (current_frame_flags_ & 1507 (current_frame_flags_ &
1454 HEADERS_FLAG_END_HEADERS) != 0); 1508 HEADERS_FLAG_END_HEADERS) != 0);
1455 } 1509 }
1456 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1510 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
1457 break; 1511 break;
1458 default: 1512 default:
1459 DCHECK(false); 1513 DCHECK(false);
1460 } 1514 }
1461 } 1515 }
1462 return original_len - len; 1516 return original_len - len;
1463 } 1517 }
1464 1518
1465 // Does not buffer the control payload. Instead, either passes directly to the 1519 // Does not buffer the control payload. Instead, either passes directly to the
1466 // visitor or decompresses and then passes directly to the visitor, via 1520 // visitor or decompresses and then passes directly to the visitor, via
1467 // IncrementallyDeliverControlFrameHeaderData() or 1521 // IncrementallyDeliverControlFrameHeaderData() or
1468 // IncrementallyDecompressControlFrameHeaderData() respectively. 1522 // IncrementallyDecompressControlFrameHeaderData() respectively.
1469 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, 1523 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
1470 size_t data_len, 1524 size_t data_len,
1471 bool is_hpack_header_block) { 1525 bool is_hpack_header_block) {
1472 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); 1526 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
1473 1527
1474 bool processed_successfully = true; 1528 bool processed_successfully = true;
1475 if (current_frame_type_ != SYN_STREAM && 1529 if (current_frame_type_ != SYN_STREAM &&
1476 current_frame_type_ != SYN_REPLY && 1530 current_frame_type_ != SYN_REPLY &&
1477 current_frame_type_ != HEADERS && 1531 current_frame_type_ != HEADERS &&
1478 current_frame_type_ != PUSH_PROMISE && 1532 current_frame_type_ != PUSH_PROMISE &&
1479 current_frame_type_ != CONTINUATION) { 1533 current_frame_type_ != CONTINUATION) {
1480 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; 1534 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
1481 } 1535 }
1482 size_t process_bytes = std::min(data_len, remaining_data_length_); 1536 size_t process_bytes = std::min(
1537 data_len, remaining_data_length_ - remaining_padding_payload_length_);
1483 if (is_hpack_header_block) { 1538 if (is_hpack_header_block) {
1484 if (!hpack_decoder_->HandleControlFrameHeadersData(current_frame_stream_id_, 1539 if (!GetHpackDecoder()->HandleControlFrameHeadersData(
1485 data, 1540 current_frame_stream_id_, data, process_bytes)) {
1486 process_bytes)) {
1487 // TODO(jgraettinger): Finer-grained HPACK error codes. 1541 // TODO(jgraettinger): Finer-grained HPACK error codes.
1488 set_error(SPDY_DECOMPRESS_FAILURE); 1542 set_error(SPDY_DECOMPRESS_FAILURE);
1489 processed_successfully = false; 1543 processed_successfully = false;
1490 } 1544 }
1491 } else if (process_bytes > 0) { 1545 } else if (process_bytes > 0) {
1492 if (enable_compression_ && protocol_version() <= SPDY3) { 1546 if (enable_compression_ && protocol_version() <= SPDY3) {
1493 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1547 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
1494 current_frame_stream_id_, data, process_bytes); 1548 current_frame_stream_id_, data, process_bytes);
1495 } else { 1549 } else {
1496 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1550 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
1497 current_frame_stream_id_, data, process_bytes); 1551 current_frame_stream_id_, data, process_bytes);
1498 } 1552 }
1499 } 1553 }
1500 remaining_data_length_ -= process_bytes; 1554 remaining_data_length_ -= process_bytes;
1501 1555
1502 // Handle the case that there is no futher data in this frame. 1556 // Handle the case that there is no futher data in this frame.
1503 if (remaining_data_length_ == 0 && processed_successfully) { 1557 if (remaining_data_length_ == remaining_padding_payload_length_ &&
1558 processed_successfully) {
1504 if (expect_continuation_ == 0) { 1559 if (expect_continuation_ == 0) {
1505 if (is_hpack_header_block) { 1560 if (is_hpack_header_block) {
1506 if (!hpack_decoder_->HandleControlFrameHeadersComplete( 1561 if (!GetHpackDecoder()->HandleControlFrameHeadersComplete(
1507 current_frame_stream_id_)) { 1562 current_frame_stream_id_)) {
1508 set_error(SPDY_DECOMPRESS_FAILURE); 1563 set_error(SPDY_DECOMPRESS_FAILURE);
1509 processed_successfully = false; 1564 processed_successfully = false;
1510 } else { 1565 } else {
1511 // TODO(jgraettinger): To be removed with migration to 1566 // TODO(jgraettinger): To be removed with migration to
1512 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 1567 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
1513 // block, delivered via reentrant call to 1568 // block, delivered via reentrant call to
1514 // ProcessControlFrameHeaderBlock(). 1569 // ProcessControlFrameHeaderBlock().
1515 DeliverHpackBlockAsSpdy3Block(); 1570 DeliverHpackBlockAsSpdy3Block();
1516 return process_bytes; 1571 return process_bytes;
1517 } 1572 }
1518 } else { 1573 } else {
1519 // The complete header block has been delivered. We send a zero-length 1574 // The complete header block has been delivered. We send a zero-length
1520 // OnControlFrameHeaderData() to indicate this. 1575 // OnControlFrameHeaderData() to indicate this.
1521 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0); 1576 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0);
1522 } 1577 }
1523 // If this is a FIN, tell the caller.
1524 if ((current_frame_flags_ & CONTROL_FLAG_FIN) || end_stream_when_done_) {
1525 end_stream_when_done_ = false;
1526 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1527 }
1528 } 1578 }
1529 if (processed_successfully) 1579 if (processed_successfully) {
1530 CHANGE_STATE(SPDY_AUTO_RESET); 1580 CHANGE_STATE(SPDY_CONSUME_PADDING);
1581 }
1531 } 1582 }
1532 1583
1533 // Handle error. 1584 // Handle error.
1534 if (!processed_successfully) { 1585 if (!processed_successfully) {
1535 return data_len; 1586 return data_len;
1536 } 1587 }
1537 1588
1538 // Return amount processed. 1589 // Return amount processed.
1539 return process_bytes; 1590 return process_bytes;
1540 } 1591 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 if (remaining_data_length_ == 0) { 1641 if (remaining_data_length_ == 0) {
1591 visitor_->OnSettingsEnd(); 1642 visitor_->OnSettingsEnd();
1592 CHANGE_STATE(SPDY_AUTO_RESET); 1643 CHANGE_STATE(SPDY_AUTO_RESET);
1593 } 1644 }
1594 1645
1595 return processed_bytes; 1646 return processed_bytes;
1596 } 1647 }
1597 1648
1598 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { 1649 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
1599 DCHECK_LT(SPDY3, protocol_version()); 1650 DCHECK_LT(SPDY3, protocol_version());
1600 DCHECK_EQ(0u, remaining_data_length_); 1651 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
1601 1652
1602 const SpdyNameValueBlock& block = hpack_decoder_->decoded_block(); 1653 const SpdyNameValueBlock& block = GetHpackDecoder()->decoded_block();
1603 if (block.empty()) { 1654 if (block.empty()) {
1604 // Special-case this to make tests happy. 1655 // Special-case this to make tests happy.
1605 ProcessControlFrameHeaderBlock(NULL, 0, false); 1656 ProcessControlFrameHeaderBlock(NULL, 0, false);
1606 return; 1657 return;
1607 } 1658 }
1608 SpdyFrameBuilder builder( 1659 SpdyFrameBuilder builder(
1609 GetSerializedLength(protocol_version(), &block), 1660 GetSerializedLength(protocol_version(), &block),
1610 SPDY3); 1661 SPDY3);
1611 1662
1612 SerializeNameValueBlockWithoutCompression(&builder, block); 1663 SerializeNameValueBlockWithoutCompression(&builder, block);
1613 scoped_ptr<SpdyFrame> frame(builder.take()); 1664 scoped_ptr<SpdyFrame> frame(builder.take());
1614 1665
1666 // Preserve padding length, and reset it after the re-entrant call.
1667 size_t remaining_padding = remaining_padding_payload_length_;
1668
1669 remaining_padding_payload_length_ = 0;
1615 remaining_data_length_ = frame->size(); 1670 remaining_data_length_ = frame->size();
1671
1616 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); 1672 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
1673
1674 remaining_padding_payload_length_ = remaining_padding;
1675 remaining_data_length_ = remaining_padding;
1617 } 1676 }
1618 1677
1619 bool SpdyFramer::ProcessSetting(const char* data) { 1678 bool SpdyFramer::ProcessSetting(const char* data) {
1620 int id_field; 1679 int id_field;
1621 SpdySettingsIds id; 1680 SpdySettingsIds id;
1622 uint8 flags = 0; 1681 uint8 flags = 0;
1623 uint32 value; 1682 uint32 value;
1624 1683
1625 // Extract fields. 1684 // Extract fields.
1626 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. 1685 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 visitor_->OnWindowUpdate(current_frame_stream_id_, 1769 visitor_->OnWindowUpdate(current_frame_stream_id_,
1711 delta_window_size); 1770 delta_window_size);
1712 } 1771 }
1713 break; 1772 break;
1714 case BLOCKED: { 1773 case BLOCKED: {
1715 DCHECK_LT(SPDY3, protocol_version()); 1774 DCHECK_LT(SPDY3, protocol_version());
1716 DCHECK(reader.IsDoneReading()); 1775 DCHECK(reader.IsDoneReading());
1717 visitor_->OnBlocked(current_frame_stream_id_); 1776 visitor_->OnBlocked(current_frame_stream_id_);
1718 } 1777 }
1719 break; 1778 break;
1779 case PRIORITY: {
1780 DCHECK_LT(SPDY3, protocol_version());
1781 // TODO(hkhalil): Process PRIORITY frames rather than ignore them.
1782 reader.Seek(5);
1783 DCHECK(reader.IsDoneReading());
1784 }
1785 break;
1720 default: 1786 default:
1721 // Unreachable. 1787 // Unreachable.
1722 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; 1788 LOG(FATAL) << "Unhandled control frame " << current_frame_type_;
1723 } 1789 }
1724 1790
1725 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 1791 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
1726 } 1792 }
1727 return original_len - len; 1793 return original_len - len;
1728 } 1794 }
1729 1795
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 if (!processed_successfully) { 1922 if (!processed_successfully) {
1857 set_error(SPDY_RST_STREAM_FRAME_CORRUPT); 1923 set_error(SPDY_RST_STREAM_FRAME_CORRUPT);
1858 } else if (remaining_data_length_ == 0) { 1924 } else if (remaining_data_length_ == 0) {
1859 // Signal that there is not more opaque data. 1925 // Signal that there is not more opaque data.
1860 visitor_->OnRstStreamFrameData(NULL, 0); 1926 visitor_->OnRstStreamFrameData(NULL, 0);
1861 CHANGE_STATE(SPDY_AUTO_RESET); 1927 CHANGE_STATE(SPDY_AUTO_RESET);
1862 } 1928 }
1863 return original_len; 1929 return original_len;
1864 } 1930 }
1865 1931
1932 size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) {
1933 if (len == 0) {
1934 return 0;
1935 }
1936
1937 // Clamp to the actual remaining payload.
1938 len = std::min(len, remaining_data_length_);
1939
1940 size_t processed_bytes = 0;
1941 size_t processing = 0;
1942 size_t bytes_remaining;
1943 char* buffer;
1944 size_t* buffer_len;
1945
1946 while (len > 0) {
1947 if (altsvc_scratch_.pid_len == 0) {
1948 // The size of the frame up to the PID_LEN field.
1949 size_t fixed_len_portion = GetAltSvcMinimumSize() - 1;
1950 bytes_remaining = fixed_len_portion - current_frame_buffer_length_;
1951 processing = std::min(len, bytes_remaining);
1952 // Buffer the new ALTSVC bytes we got.
1953 UpdateCurrentFrameBuffer(&data, &len, processing);
1954
1955 // Do we have enough to parse the length of the protocol id?
1956 if (current_frame_buffer_length_ == fixed_len_portion) {
1957 // Parse out the max age, port, and pid_len.
1958 SpdyFrameReader reader(current_frame_buffer_.get(),
1959 current_frame_buffer_length_);
1960 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1961 bool successful_read = reader.ReadUInt32(&altsvc_scratch_.max_age);
1962 reader.ReadUInt16(&altsvc_scratch_.port);
1963 reader.Seek(1); // Reserved byte.
1964 successful_read = successful_read &&
1965 reader.ReadUInt8(&altsvc_scratch_.pid_len);
1966 DCHECK(successful_read);
1967 // Sanity check length value.
1968 if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len >=
1969 current_frame_length_) {
1970 set_error(SPDY_INVALID_CONTROL_FRAME);
1971 return 0;
1972 }
1973 altsvc_scratch_.protocol_id.reset(
1974 new char[size_t(altsvc_scratch_.pid_len)]);
1975 }
1976 processed_bytes += processing;
1977 continue;
1978 } else if (altsvc_scratch_.pid_buf_len < altsvc_scratch_.pid_len) {
1979 // Buffer protocol id field as in comes in.
1980 buffer = altsvc_scratch_.protocol_id.get();
1981 buffer_len = &altsvc_scratch_.pid_buf_len;
1982 bytes_remaining = altsvc_scratch_.pid_len - altsvc_scratch_.pid_buf_len;
1983 } else if (altsvc_scratch_.host_len == 0) {
1984 // Parse out the host length.
1985 processing = 1;
1986 altsvc_scratch_.host_len = *reinterpret_cast<const uint8*>(data);
1987 // Sanity check length value.
1988 if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len +
1989 altsvc_scratch_.host_len > current_frame_length_) {
1990 set_error(SPDY_INVALID_CONTROL_FRAME);
1991 return 0;
1992 }
1993 altsvc_scratch_.host.reset(new char[altsvc_scratch_.host_len]);
1994 // Once we have host length, we can also determine the origin length
1995 // by process of elimination.
1996 altsvc_scratch_.origin_len = current_frame_length_ -
1997 GetAltSvcMinimumSize() -
1998 altsvc_scratch_.pid_len -
1999 altsvc_scratch_.host_len;
2000 if (altsvc_scratch_.origin_len > 0) {
2001 altsvc_scratch_.origin.reset(new char[altsvc_scratch_.origin_len]);
2002 }
2003 data += processing;
2004 processed_bytes += processing;
2005 len -= processing;
2006 continue;
2007 } else if (altsvc_scratch_.host_buf_len < altsvc_scratch_.host_len) {
2008 // Buffer host field as it comes in.
2009 // TODO(mlavan): check formatting for host and origin
2010 buffer = altsvc_scratch_.host.get();
2011 buffer_len = &altsvc_scratch_.host_buf_len;
2012 bytes_remaining = altsvc_scratch_.host_len - altsvc_scratch_.host_buf_len;
2013 } else {
2014 // Buffer (optional) origin field as it comes in.
2015 if (altsvc_scratch_.origin_len <= 0) {
2016 set_error(SPDY_INVALID_CONTROL_FRAME);
2017 return 0;
2018 }
2019 buffer = altsvc_scratch_.origin.get();
2020 buffer_len = &altsvc_scratch_.origin_buf_len;
2021 bytes_remaining = remaining_data_length_ -
2022 processed_bytes -
2023 altsvc_scratch_.origin_buf_len;
2024 if (len > bytes_remaining) {
2025 // This is our last field; there shouldn't be any more bytes.
2026 set_error(SPDY_INVALID_CONTROL_FRAME);
2027 return 0;
2028 }
2029 }
2030
2031 // Copy data bytes into the appropriate field.
2032 processing = std::min(len, bytes_remaining);
2033 memcpy(buffer + *buffer_len,
2034 data,
2035 processing);
2036 *buffer_len += processing;
2037 data += processing;
2038 processed_bytes += processing;
2039 len -= processing;
2040 }
2041
2042 remaining_data_length_ -= processed_bytes;
2043 if (remaining_data_length_ == 0) {
2044 visitor_->OnAltSvc(current_frame_stream_id_,
2045 altsvc_scratch_.max_age,
2046 altsvc_scratch_.port,
2047 StringPiece(altsvc_scratch_.protocol_id.get(),
2048 altsvc_scratch_.pid_len),
2049 StringPiece(altsvc_scratch_.host.get(),
2050 altsvc_scratch_.host_len),
2051 StringPiece(altsvc_scratch_.origin.get(),
2052 altsvc_scratch_.origin_len));
2053 CHANGE_STATE(SPDY_AUTO_RESET);
2054 }
2055
2056 return processed_bytes;
2057 }
2058
1866 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { 2059 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
1867 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); 2060 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
1868 2061
1869 size_t original_len = len; 2062 size_t original_len = len;
1870 if (remaining_padding_length_fields_ == 0) { 2063 if (remaining_padding_length_fields_ == 0) {
1871 DCHECK_EQ(remaining_padding_payload_length_, 0u); 2064 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1872 bool pad_low = false; 2065 bool pad_low = false;
1873 bool pad_high = false; 2066 bool pad_high = false;
1874 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) { 2067 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) {
1875 pad_low = true; 2068 pad_low = true;
(...skipping 19 matching lines...) Expand all
1895 --len; 2088 --len;
1896 --remaining_padding_length_fields_; 2089 --remaining_padding_length_fields_;
1897 --remaining_data_length_; 2090 --remaining_data_length_;
1898 } 2091 }
1899 2092
1900 if (remaining_padding_length_fields_ == 0) { 2093 if (remaining_padding_length_fields_ == 0) {
1901 if (remaining_padding_payload_length_ > remaining_data_length_) { 2094 if (remaining_padding_payload_length_ > remaining_data_length_) {
1902 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 2095 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1903 return 0; 2096 return 0;
1904 } 2097 }
1905 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 2098 if (current_frame_type_ == DATA) {
2099 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
2100 } else {
2101 DCHECK(current_frame_type_ == HEADERS ||
2102 current_frame_type_ == PUSH_PROMISE ||
2103 current_frame_type_ == CONTINUATION ||
2104 current_frame_type_ == SYN_STREAM ||
2105 current_frame_type_ == SYN_REPLY)
2106 << current_frame_type_;
2107 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
2108 }
1906 } 2109 }
1907 return original_len - len; 2110 return original_len - len;
1908 } 2111 }
1909 2112
1910 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { 2113 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
1911 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); 2114 DCHECK_EQ(SPDY_CONSUME_PADDING, state_);
1912 2115
1913 size_t original_len = len; 2116 size_t original_len = len;
1914 if (remaining_padding_payload_length_ > 0) { 2117 if (remaining_padding_payload_length_ > 0) {
1915 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); 2118 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
1916 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); 2119 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
1917 // The visitor needs to know about padding so it can send window updates. 2120 if (current_frame_type_ == DATA && amount_to_discard > 0) {
1918 // Communicate the padding to the visitor through a NULL data pointer, with 2121 // The visitor needs to know about padding so it can send window updates.
1919 // a nonzero size. 2122 // Communicate the padding to the visitor through a NULL data pointer,
1920 if (amount_to_discard) { 2123 // with a nonzero size.
1921 visitor_->OnStreamFrameData( 2124 visitor_->OnStreamFrameData(
1922 current_frame_stream_id_, NULL, amount_to_discard, false); 2125 current_frame_stream_id_, NULL, amount_to_discard, false);
1923 } 2126 }
1924 data += amount_to_discard; 2127 data += amount_to_discard;
1925 len -= amount_to_discard; 2128 len -= amount_to_discard;
1926 remaining_padding_payload_length_ -= amount_to_discard; 2129 remaining_padding_payload_length_ -= amount_to_discard;
1927 remaining_data_length_ -= amount_to_discard; 2130 remaining_data_length_ -= amount_to_discard;
1928 } 2131 }
1929 2132
1930 if (remaining_data_length_ == 0) { 2133 if (remaining_data_length_ == 0) {
1931 // If the FIN flag is set, and there is no more data in this data frame, 2134 // If the FIN flag is set, or this ends a header block which set FIN,
1932 // inform the visitor of EOF via a 0-length data frame. 2135 // inform the visitor of EOF via a 0-length data frame.
1933 if (current_frame_flags_ & DATA_FLAG_FIN) { 2136 if (expect_continuation_ == 0 &&
2137 ((current_frame_flags_ & CONTROL_FLAG_FIN) != 0 ||
2138 end_stream_when_done_)) {
2139 end_stream_when_done_ = false;
1934 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 2140 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1935 } 2141 }
1936
1937 CHANGE_STATE(SPDY_AUTO_RESET); 2142 CHANGE_STATE(SPDY_AUTO_RESET);
1938 } 2143 }
1939 return original_len - len; 2144 return original_len - len;
1940 } 2145 }
1941 2146
1942 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 2147 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
1943 size_t original_len = len; 2148 size_t original_len = len;
1944 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) { 2149 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
1945 size_t amount_to_forward = std::min( 2150 size_t amount_to_forward = std::min(
1946 remaining_data_length_ - remaining_padding_payload_length_, len); 2151 remaining_data_length_ - remaining_padding_payload_length_, len);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 DLOG(DFATAL) << "Priority out-of-bounds."; 2346 DLOG(DFATAL) << "Priority out-of-bounds.";
2142 priority = GetLowestPriority(); 2347 priority = GetLowestPriority();
2143 } 2348 }
2144 2349
2145 // The size of this frame, including variable-length name-value block. 2350 // The size of this frame, including variable-length name-value block.
2146 size_t size = GetSynStreamMinimumSize(); 2351 size_t size = GetSynStreamMinimumSize();
2147 2352
2148 string hpack_encoding; 2353 string hpack_encoding;
2149 if (protocol_version() > SPDY3) { 2354 if (protocol_version() > SPDY3) {
2150 if (enable_compression_) { 2355 if (enable_compression_) {
2151 hpack_encoder_->EncodeHeaderSet( 2356 GetHpackEncoder()->EncodeHeaderSet(
2152 syn_stream.name_value_block(), &hpack_encoding); 2357 syn_stream.name_value_block(), &hpack_encoding);
2153 } else { 2358 } else {
2154 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2359 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2155 syn_stream.name_value_block(), &hpack_encoding); 2360 syn_stream.name_value_block(), &hpack_encoding);
2156 } 2361 }
2157 size += hpack_encoding.size(); 2362 size += hpack_encoding.size();
2158 } else { 2363 } else {
2159 size += GetSerializedLength(syn_stream.name_value_block()); 2364 size += GetSerializedLength(syn_stream.name_value_block());
2160 } 2365 }
2161 2366
2162 SpdyFrameBuilder builder(size, protocol_version()); 2367 SpdyFrameBuilder builder(size, protocol_version());
2163 if (protocol_version() <= SPDY3) { 2368 if (protocol_version() <= SPDY3) {
2164 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 2369 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 if (protocol_version() > SPDY3) { 2411 if (protocol_version() > SPDY3) {
2207 flags |= HEADERS_FLAG_END_HEADERS; 2412 flags |= HEADERS_FLAG_END_HEADERS;
2208 } 2413 }
2209 2414
2210 // The size of this frame, including variable-length name-value block. 2415 // The size of this frame, including variable-length name-value block.
2211 size_t size = GetSynReplyMinimumSize(); 2416 size_t size = GetSynReplyMinimumSize();
2212 2417
2213 string hpack_encoding; 2418 string hpack_encoding;
2214 if (protocol_version() > SPDY3) { 2419 if (protocol_version() > SPDY3) {
2215 if (enable_compression_) { 2420 if (enable_compression_) {
2216 hpack_encoder_->EncodeHeaderSet( 2421 GetHpackEncoder()->EncodeHeaderSet(
2217 syn_reply.name_value_block(), &hpack_encoding); 2422 syn_reply.name_value_block(), &hpack_encoding);
2218 } else { 2423 } else {
2219 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2424 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2220 syn_reply.name_value_block(), &hpack_encoding); 2425 syn_reply.name_value_block(), &hpack_encoding);
2221 } 2426 }
2222 size += hpack_encoding.size(); 2427 size += hpack_encoding.size();
2223 } else { 2428 } else {
2224 size += GetSerializedLength(syn_reply.name_value_block()); 2429 size += GetSerializedLength(syn_reply.name_value_block());
2225 } 2430 }
2226 2431
2227 SpdyFrameBuilder builder(size, protocol_version()); 2432 SpdyFrameBuilder builder(size, protocol_version());
2228 if (protocol_version() <= SPDY3) { 2433 if (protocol_version() <= SPDY3) {
2229 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 2434 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 if (priority > GetLowestPriority()) { 2631 if (priority > GetLowestPriority()) {
2427 DLOG(DFATAL) << "Priority out-of-bounds."; 2632 DLOG(DFATAL) << "Priority out-of-bounds.";
2428 priority = GetLowestPriority(); 2633 priority = GetLowestPriority();
2429 } 2634 }
2430 size += 4; 2635 size += 4;
2431 } 2636 }
2432 2637
2433 string hpack_encoding; 2638 string hpack_encoding;
2434 if (protocol_version() > SPDY3) { 2639 if (protocol_version() > SPDY3) {
2435 if (enable_compression_) { 2640 if (enable_compression_) {
2436 hpack_encoder_->EncodeHeaderSet( 2641 GetHpackEncoder()->EncodeHeaderSet(
2437 headers.name_value_block(), &hpack_encoding); 2642 headers.name_value_block(), &hpack_encoding);
2438 } else { 2643 } else {
2439 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2644 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2440 headers.name_value_block(), &hpack_encoding); 2645 headers.name_value_block(), &hpack_encoding);
2441 } 2646 }
2442 size += hpack_encoding.size(); 2647 size += hpack_encoding.size();
2443 if (size > GetControlFrameBufferMaxSize()) { 2648 if (size > GetControlFrameBufferMaxSize()) {
2444 size += GetNumberRequiredContinuationFrames(size) * 2649 size += GetNumberRequiredContinuationFrames(size) *
2445 GetContinuationMinimumSize(); 2650 GetContinuationMinimumSize();
2446 flags &= ~HEADERS_FLAG_END_HEADERS; 2651 flags &= ~HEADERS_FLAG_END_HEADERS;
2447 } 2652 }
2448 } else { 2653 } else {
2449 size += GetSerializedLength(headers.name_value_block()); 2654 size += GetSerializedLength(headers.name_value_block());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 DCHECK_LT(SPDY3, protocol_version()); 2724 DCHECK_LT(SPDY3, protocol_version());
2520 uint8 flags = 0; 2725 uint8 flags = 0;
2521 // This will get overwritten if we overflow into a CONTINUATION frame. 2726 // This will get overwritten if we overflow into a CONTINUATION frame.
2522 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2727 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2523 // The size of this frame, including variable-length name-value block. 2728 // The size of this frame, including variable-length name-value block.
2524 size_t size = GetPushPromiseMinimumSize(); 2729 size_t size = GetPushPromiseMinimumSize();
2525 2730
2526 string hpack_encoding; 2731 string hpack_encoding;
2527 if (protocol_version() > SPDY3) { 2732 if (protocol_version() > SPDY3) {
2528 if (enable_compression_) { 2733 if (enable_compression_) {
2529 hpack_encoder_->EncodeHeaderSet( 2734 GetHpackEncoder()->EncodeHeaderSet(
2530 push_promise.name_value_block(), &hpack_encoding); 2735 push_promise.name_value_block(), &hpack_encoding);
2531 } else { 2736 } else {
2532 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2737 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2533 push_promise.name_value_block(), &hpack_encoding); 2738 push_promise.name_value_block(), &hpack_encoding);
2534 } 2739 }
2535 size += hpack_encoding.size(); 2740 size += hpack_encoding.size();
2536 if (size > GetControlFrameBufferMaxSize()) { 2741 if (size > GetControlFrameBufferMaxSize()) {
2537 size += GetNumberRequiredContinuationFrames(size) * 2742 size += GetNumberRequiredContinuationFrames(size) *
2538 GetContinuationMinimumSize(); 2743 GetContinuationMinimumSize();
2539 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2744 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2540 } 2745 }
2541 } else { 2746 } else {
2542 size += GetSerializedLength(push_promise.name_value_block()); 2747 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()); 2784 CHECK_LT(SPDY3, protocol_version());
2580 uint8 flags = 0; 2785 uint8 flags = 0;
2581 if (continuation.end_headers()) { 2786 if (continuation.end_headers()) {
2582 flags |= HEADERS_FLAG_END_HEADERS; 2787 flags |= HEADERS_FLAG_END_HEADERS;
2583 } 2788 }
2584 2789
2585 // The size of this frame, including variable-length name-value block. 2790 // The size of this frame, including variable-length name-value block.
2586 size_t size = GetContinuationMinimumSize(); 2791 size_t size = GetContinuationMinimumSize();
2587 string hpack_encoding; 2792 string hpack_encoding;
2588 if (enable_compression_) { 2793 if (enable_compression_) {
2589 hpack_encoder_->EncodeHeaderSet( 2794 GetHpackEncoder()->EncodeHeaderSet(
2590 continuation.name_value_block(), &hpack_encoding); 2795 continuation.name_value_block(), &hpack_encoding);
2591 } else { 2796 } else {
2592 hpack_encoder_->EncodeHeaderSetWithoutCompression( 2797 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2593 continuation.name_value_block(), &hpack_encoding); 2798 continuation.name_value_block(), &hpack_encoding);
2594 } 2799 }
2595 size += hpack_encoding.size(); 2800 size += hpack_encoding.size();
2596 2801
2597 SpdyFrameBuilder builder(size, protocol_version()); 2802 SpdyFrameBuilder builder(size, protocol_version());
2598 builder.BeginNewFrame(*this, CONTINUATION, flags, 2803 builder.BeginNewFrame(*this, CONTINUATION, flags,
2599 continuation.stream_id()); 2804 continuation.stream_id());
2600 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); 2805 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2601 2806
2602 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2807 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2603 2808
2604 if (debug_visitor_) { 2809 if (debug_visitor_) {
2605 const size_t payload_len = hpack_encoding.size(); 2810 const size_t payload_len = hpack_encoding.size();
2606 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(), 2811 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(),
2607 CONTINUATION, payload_len, builder.length()); 2812 CONTINUATION, payload_len, builder.length());
2608 } 2813 }
2609 2814
2610 return builder.take(); 2815 return builder.take();
2611 } 2816 }
2612 2817
2818 SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc) {
2819 DCHECK_LT(SPDY3, protocol_version());
2820 size_t size = GetAltSvcMinimumSize();
2821 size += altsvc.protocol_id().length();
2822 size += altsvc.host().length();
2823 size += altsvc.origin().length();
2824
2825 SpdyFrameBuilder builder(size, protocol_version());
2826 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc.stream_id());
2827
2828 builder.WriteUInt32(altsvc.max_age());
2829 builder.WriteUInt16(altsvc.port());
2830 builder.WriteUInt8(0); // Reserved.
2831 builder.WriteUInt8(altsvc.protocol_id().length());
2832 builder.WriteBytes(altsvc.protocol_id().data(),
2833 altsvc.protocol_id().length());
2834 builder.WriteUInt8(altsvc.host().length());
2835 builder.WriteBytes(altsvc.host().data(), altsvc.host().length());
2836 builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length());
2837 DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
2838 return builder.take();
2839 }
2840
2613 namespace { 2841 namespace {
2614 2842
2615 class FrameSerializationVisitor : public SpdyFrameVisitor { 2843 class FrameSerializationVisitor : public SpdyFrameVisitor {
2616 public: 2844 public:
2617 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} 2845 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
2618 virtual ~FrameSerializationVisitor() {} 2846 virtual ~FrameSerializationVisitor() {}
2619 2847
2620 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } 2848 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }
2621 2849
2622 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { 2850 virtual void VisitData(const SpdyDataIR& data) OVERRIDE {
(...skipping 28 matching lines...) Expand all
2651 frame_.reset(framer_->SerializeBlocked(blocked)); 2879 frame_.reset(framer_->SerializeBlocked(blocked));
2652 } 2880 }
2653 virtual void VisitPushPromise( 2881 virtual void VisitPushPromise(
2654 const SpdyPushPromiseIR& push_promise) OVERRIDE { 2882 const SpdyPushPromiseIR& push_promise) OVERRIDE {
2655 frame_.reset(framer_->SerializePushPromise(push_promise)); 2883 frame_.reset(framer_->SerializePushPromise(push_promise));
2656 } 2884 }
2657 virtual void VisitContinuation( 2885 virtual void VisitContinuation(
2658 const SpdyContinuationIR& continuation) OVERRIDE { 2886 const SpdyContinuationIR& continuation) OVERRIDE {
2659 frame_.reset(framer_->SerializeContinuation(continuation)); 2887 frame_.reset(framer_->SerializeContinuation(continuation));
2660 } 2888 }
2889 virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) OVERRIDE {
2890 frame_.reset(framer_->SerializeAltSvc(altsvc));
2891 }
2661 2892
2662 private: 2893 private:
2663 SpdyFramer* framer_; 2894 SpdyFramer* framer_;
2664 scoped_ptr<SpdySerializedFrame> frame_; 2895 scoped_ptr<SpdySerializedFrame> frame_;
2665 }; 2896 };
2666 2897
2667 } // namespace 2898 } // namespace
2668 2899
2669 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { 2900 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
2670 FrameSerializationVisitor visitor(this); 2901 FrameSerializationVisitor visitor(this);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 3032
2802 int success = inflateInit(header_decompressor_.get()); 3033 int success = inflateInit(header_decompressor_.get());
2803 if (success != Z_OK) { 3034 if (success != Z_OK) {
2804 LOG(WARNING) << "inflateInit failure: " << success; 3035 LOG(WARNING) << "inflateInit failure: " << success;
2805 header_decompressor_.reset(NULL); 3036 header_decompressor_.reset(NULL);
2806 return NULL; 3037 return NULL;
2807 } 3038 }
2808 return header_decompressor_.get(); 3039 return header_decompressor_.get();
2809 } 3040 }
2810 3041
3042 HpackEncoder* SpdyFramer::GetHpackEncoder() {
3043 DCHECK_LT(SPDY3, spdy_version_);
3044 if (hpack_encoder_.get() == NULL) {
3045 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
3046 }
3047 return hpack_encoder_.get();
3048 }
3049
3050 HpackDecoder* SpdyFramer::GetHpackDecoder() {
3051 DCHECK_LT(SPDY3, spdy_version_);
3052 if (hpack_decoder_.get() == NULL) {
3053 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
3054 }
3055 return hpack_decoder_.get();
3056 }
3057
2811 // Incrementally decompress the control frame's header block, feeding the 3058 // Incrementally decompress the control frame's header block, feeding the
2812 // result to the visitor in chunks. Continue this until the visitor 3059 // result to the visitor in chunks. Continue this until the visitor
2813 // indicates that it cannot process any more data, or (more commonly) we 3060 // indicates that it cannot process any more data, or (more commonly) we
2814 // run out of data to deliver. 3061 // run out of data to deliver.
2815 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 3062 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
2816 SpdyStreamId stream_id, 3063 SpdyStreamId stream_id,
2817 const char* data, 3064 const char* data,
2818 size_t len) { 3065 size_t len) {
2819 // Get a decompressor or set error. 3066 // Get a decompressor or set error.
2820 z_stream* decomp = GetHeaderDecompressor(); 3067 z_stream* decomp = GetHeaderDecompressor();
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2987 builder->Seek(compressed_size); 3234 builder->Seek(compressed_size);
2988 builder->RewriteLength(*this); 3235 builder->RewriteLength(*this);
2989 3236
2990 pre_compress_bytes.Add(uncompressed_len); 3237 pre_compress_bytes.Add(uncompressed_len);
2991 post_compress_bytes.Add(compressed_size); 3238 post_compress_bytes.Add(compressed_size);
2992 3239
2993 compressed_frames.Increment(); 3240 compressed_frames.Increment();
2994 } 3241 }
2995 3242
2996 } // namespace net 3243 } // 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