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 3 // found in the LICENSE file. 4 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 6 // constantly adding and subtracting header sizes; this is ugly and error- 7 // prone. 8 9 #include "net/spdy/spdy_framer.h" 10 11 #include "base/lazy_instance.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/metrics/stats_counters.h" 14 #include "base/third_party/valgrind/memcheck.h" 15 #include "net/spdy/spdy_frame_builder.h" 16 #include "net/spdy/spdy_frame_reader.h" 17 #include "net/spdy/spdy_bitmasks.h" 18 #include "third_party/zlib/zlib.h" 19 20 using std::vector; 21 22 namespace net { 23 24 namespace { 25 26 // Compute the id of our dictionary so that we know we're using the 27 // right one when asked for it. 28 uLong CalculateDictionaryId(const char* dictionary, 29 const size_t dictionary_size) { 30 uLong initial_value = adler32(0L, Z_NULL, 0); 31 return adler32(initial_value, 32 reinterpret_cast<const Bytef*>(dictionary), 33 dictionary_size); 34 } 35 36 struct DictionaryIds { 37 DictionaryIds() 38 : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)), 39 v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) 40 {} 41 const uLong v2_dictionary_id; 42 const uLong v3_dictionary_id; 43 }; 44 45 // Adler ID for the SPDY header compressor dictionaries. Note that they are 46 // initialized lazily to avoid static initializers. 47 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; 48 49 // Used to indicate no flags in a SPDY flags field. 50 const uint8 kNoFlags = 0; 51 52 } // namespace 53 54 const SpdyStreamId SpdyFramer::kInvalidStream = -1; 55 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 56 // The size of the control frame buffer. Must be >= the minimum size of the 57 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for 58 // calculation details. 59 const size_t SpdyFramer::kControlFrameBufferSize = 18; 60 61 #ifdef DEBUG_SPDY_STATE_CHANGES 62 #define CHANGE_STATE(newstate) \ 63 do { \ 64 DVLOG(1) << "Changing state from: " \ 65 << StateToString(state_) \ 66 << " to " << StateToString(newstate) << "\n"; \ 67 DCHECK(state_ != SPDY_ERROR); \ 68 DCHECK_EQ(previous_state_, state_); \ 69 previous_state_ = state_; \ 70 state_ = newstate; \ 71 } while (false) 72 #else 73 #define CHANGE_STATE(newstate) \ 74 do { \ 75 DCHECK(state_ != SPDY_ERROR); \ 76 DCHECK_EQ(previous_state_, state_); \ 77 previous_state_ = state_; \ 78 state_ = newstate; \ 79 } while (false) 80 #endif 81 82 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, 83 uint32 wire) { 84 if (version < 3) { 85 ConvertFlagsAndIdForSpdy2(&wire); 86 } 87 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); 88 } 89 90 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) 91 : flags_(flags), id_(id & 0x00ffffff) { 92 DCHECK_GT(1u << 24, id) << "SPDY setting ID too large."; 93 } 94 95 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { 96 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); 97 if (version < 3) { 98 ConvertFlagsAndIdForSpdy2(&wire); 99 } 100 return wire; 101 } 102 103 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. 104 // This method is used to preserve buggy behavior and works on both 105 // little-endian and big-endian hosts. 106 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 107 // as well as vice versa). 108 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { 109 uint8* wire_array = reinterpret_cast<uint8*>(val); 110 std::swap(wire_array[0], wire_array[3]); 111 std::swap(wire_array[1], wire_array[2]); 112 } 113 114 SpdyCredential::SpdyCredential() : slot(0) {} 115 SpdyCredential::~SpdyCredential() {} 116 117 SpdyFramer::SpdyFramer(SpdyMajorVersion version) 118 : current_frame_buffer_(new char[kControlFrameBufferSize]), 119 enable_compression_(true), 120 visitor_(NULL), 121 debug_visitor_(NULL), 122 display_protocol_("SPDY"), 123 spdy_version_(version), 124 syn_frame_processed_(false), 125 probable_http_response_(false) { 126 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 127 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION); 128 Reset(); 129 } 130 131 SpdyFramer::~SpdyFramer() { 132 if (header_compressor_.get()) { 133 deflateEnd(header_compressor_.get()); 134 } 135 if (header_decompressor_.get()) { 136 inflateEnd(header_decompressor_.get()); 137 } 138 } 139 140 void SpdyFramer::Reset() { 141 state_ = SPDY_RESET; 142 previous_state_ = SPDY_RESET; 143 error_code_ = SPDY_NO_ERROR; 144 remaining_data_length_ = 0; 145 remaining_control_header_ = 0; 146 current_frame_buffer_length_ = 0; 147 current_frame_type_ = DATA; 148 current_frame_flags_ = 0; 149 current_frame_length_ = 0; 150 current_frame_stream_id_ = kInvalidStream; 151 settings_scratch_.Reset(); 152 } 153 154 size_t SpdyFramer::GetDataFrameMinimumSize() const { 155 // Size, in bytes, of the data frame header. Future versions of SPDY 156 // will likely vary this, so we allow for the flexibility of a function call 157 // for this value as opposed to a constant. 158 return 8; 159 } 160 161 // Size, in bytes, of the control frame header. 162 size_t SpdyFramer::GetControlFrameHeaderSize() const { 163 switch (protocol_version()) { 164 case SPDY2: 165 case SPDY3: 166 case SPDY4: 167 return 8; 168 } 169 LOG(DFATAL) << "Unhandled SPDY version."; 170 return 0; 171 } 172 173 size_t SpdyFramer::GetSynStreamMinimumSize() const { 174 // Size, in bytes, of a SYN_STREAM frame not including the variable-length 175 // name-value block. 176 if (spdy_version_ < 4) { 177 // Calculated as: 178 // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) 179 return GetControlFrameHeaderSize() + 10; 180 } else { 181 // Calculated as: 182 // frame prefix + 4 (associated stream ID) + 1 (priority) + 1 (slot) 183 return GetControlFrameHeaderSize() + 6; 184 } 185 } 186 187 size_t SpdyFramer::GetSynReplyMinimumSize() const { 188 // Size, in bytes, of a SYN_REPLY frame not including the variable-length 189 // name-value block. 190 size_t size = GetControlFrameHeaderSize(); 191 if (spdy_version_ < 4) { 192 // Calculated as: 193 // control frame header + 4 (stream IDs) 194 size += 4; 195 } 196 197 // In SPDY 2, there were 2 unused bytes before payload. 198 if (protocol_version() < 3) { 199 size += 2; 200 } 201 202 return size; 203 } 204 205 size_t SpdyFramer::GetRstStreamSize() const { 206 // Size, in bytes, of a RST_STREAM frame. 207 if (spdy_version_ < 4) { 208 // Calculated as: 209 // control frame header + 4 (stream id) + 4 (status code) 210 return GetControlFrameHeaderSize() + 8; 211 } else { 212 // Calculated as: 213 // frame prefix + 4 (status code) 214 return GetControlFrameHeaderSize() + 4; 215 } 216 } 217 218 size_t SpdyFramer::GetSettingsMinimumSize() const { 219 // Size, in bytes, of a SETTINGS frame not including the IDs and values 220 // from the variable-length value block. Calculated as: 221 // control frame header + 4 (number of ID/value pairs) 222 return GetControlFrameHeaderSize() + 4; 223 } 224 225 size_t SpdyFramer::GetPingSize() const { 226 // Size, in bytes, of this PING frame. Calculated as: 227 // control frame header + 4 (id) 228 return GetControlFrameHeaderSize() + 4; 229 } 230 231 size_t SpdyFramer::GetGoAwaySize() const { 232 // Size, in bytes, of this GOAWAY frame. Calculated as: 233 // control frame header + 4 (last good stream id) 234 size_t size = GetControlFrameHeaderSize() + 4; 235 236 // SPDY 3+ GOAWAY frames also contain a status. 237 if (protocol_version() >= 3) { 238 size += 4; 239 } 240 241 return size; 242 } 243 244 size_t SpdyFramer::GetHeadersMinimumSize() const { 245 // Size, in bytes, of a HEADERS frame not including the variable-length 246 // name-value block. 247 size_t size = GetControlFrameHeaderSize(); 248 if (spdy_version_ < 4) { 249 // Calculated as: 250 // control frame header + 4 (stream IDs) 251 size += 4; 252 } 253 254 // In SPDY 2, there were 2 unused bytes before payload. 255 if (protocol_version() < 3) { 256 size += 2; 257 } 258 259 return size; 260 } 261 262 size_t SpdyFramer::GetWindowUpdateSize() const { 263 // Size, in bytes, of a WINDOW_UPDATE frame. 264 if (spdy_version_ < 4) { 265 // Calculated as: 266 // control frame header + 4 (stream id) + 4 (delta) 267 return GetControlFrameHeaderSize() + 8; 268 } else { 269 // Calculated as: 270 // frame prefix + 4 (delta) 271 return GetControlFrameHeaderSize() + 4; 272 } 273 } 274 275 size_t SpdyFramer::GetCredentialMinimumSize() const { 276 // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list 277 // and proof. Calculated as: 278 // control frame header + 2 (slot) 279 return GetControlFrameHeaderSize() + 2; 280 } 281 282 size_t SpdyFramer::GetBlockedSize() const { 283 DCHECK_LE(4, protocol_version()); 284 // Size, in bytes, of a BLOCKED frame. 285 // The BLOCKED frame has no payload beyond the control frame header. 286 return GetControlFrameHeaderSize(); 287 } 288 289 size_t SpdyFramer::GetPushPromiseMinimumSize() const { 290 DCHECK_LE(4, protocol_version()); 291 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. 292 // Calculated as frame prefix + 4 (promised stream id). 293 return GetControlFrameHeaderSize() + 4; 294 } 295 296 size_t SpdyFramer::GetFrameMinimumSize() const { 297 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); 298 } 299 300 size_t SpdyFramer::GetFrameMaximumSize() const { 301 return (protocol_version() < 4) ? 0xffffff : 0xffff; 302 } 303 304 size_t SpdyFramer::GetDataFrameMaximumPayload() const { 305 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); 306 } 307 308 const char* SpdyFramer::StateToString(int state) { 309 switch (state) { 310 case SPDY_ERROR: 311 return "ERROR"; 312 case SPDY_AUTO_RESET: 313 return "AUTO_RESET"; 314 case SPDY_RESET: 315 return "RESET"; 316 case SPDY_READING_COMMON_HEADER: 317 return "READING_COMMON_HEADER"; 318 case SPDY_CONTROL_FRAME_PAYLOAD: 319 return "CONTROL_FRAME_PAYLOAD"; 320 case SPDY_IGNORE_REMAINING_PAYLOAD: 321 return "IGNORE_REMAINING_PAYLOAD"; 322 case SPDY_FORWARD_STREAM_FRAME: 323 return "FORWARD_STREAM_FRAME"; 324 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 325 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 326 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 327 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 328 case SPDY_CREDENTIAL_FRAME_PAYLOAD: 329 return "SPDY_CREDENTIAL_FRAME_PAYLOAD"; 330 case SPDY_SETTINGS_FRAME_PAYLOAD: 331 return "SPDY_SETTINGS_FRAME_PAYLOAD"; 332 } 333 return "UNKNOWN_STATE"; 334 } 335 336 void SpdyFramer::set_error(SpdyError error) { 337 DCHECK(visitor_); 338 error_code_ = error; 339 CHANGE_STATE(SPDY_ERROR); 340 visitor_->OnError(this); 341 } 342 343 const char* SpdyFramer::ErrorCodeToString(int error_code) { 344 switch (error_code) { 345 case SPDY_NO_ERROR: 346 return "NO_ERROR"; 347 case SPDY_INVALID_CONTROL_FRAME: 348 return "INVALID_CONTROL_FRAME"; 349 case SPDY_CONTROL_PAYLOAD_TOO_LARGE: 350 return "CONTROL_PAYLOAD_TOO_LARGE"; 351 case SPDY_ZLIB_INIT_FAILURE: 352 return "ZLIB_INIT_FAILURE"; 353 case SPDY_UNSUPPORTED_VERSION: 354 return "UNSUPPORTED_VERSION"; 355 case SPDY_DECOMPRESS_FAILURE: 356 return "DECOMPRESS_FAILURE"; 357 case SPDY_COMPRESS_FAILURE: 358 return "COMPRESS_FAILURE"; 359 case SPDY_INVALID_DATA_FRAME_FLAGS: 360 return "SPDY_INVALID_DATA_FRAME_FLAGS"; 361 case SPDY_INVALID_CONTROL_FRAME_FLAGS: 362 return "SPDY_INVALID_CONTROL_FRAME_FLAGS"; 363 } 364 return "UNKNOWN_ERROR"; 365 } 366 367 const char* SpdyFramer::StatusCodeToString(int status_code) { 368 switch (status_code) { 369 case RST_STREAM_INVALID: 370 return "INVALID"; 371 case RST_STREAM_PROTOCOL_ERROR: 372 return "PROTOCOL_ERROR"; 373 case RST_STREAM_INVALID_STREAM: 374 return "INVALID_STREAM"; 375 case RST_STREAM_REFUSED_STREAM: 376 return "REFUSED_STREAM"; 377 case RST_STREAM_UNSUPPORTED_VERSION: 378 return "UNSUPPORTED_VERSION"; 379 case RST_STREAM_CANCEL: 380 return "CANCEL"; 381 case RST_STREAM_INTERNAL_ERROR: 382 return "INTERNAL_ERROR"; 383 case RST_STREAM_FLOW_CONTROL_ERROR: 384 return "FLOW_CONTROL_ERROR"; 385 case RST_STREAM_STREAM_IN_USE: 386 return "STREAM_IN_USE"; 387 case RST_STREAM_STREAM_ALREADY_CLOSED: 388 return "STREAM_ALREADY_CLOSED"; 389 case RST_STREAM_INVALID_CREDENTIALS: 390 return "INVALID_CREDENTIALS"; 391 case RST_STREAM_FRAME_TOO_LARGE: 392 return "FRAME_TOO_LARGE"; 393 } 394 return "UNKNOWN_STATUS"; 395 } 396 397 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) { 398 switch (type) { 399 case DATA: 400 return "DATA"; 401 case SYN_STREAM: 402 return "SYN_STREAM"; 403 case SYN_REPLY: 404 return "SYN_REPLY"; 405 case RST_STREAM: 406 return "RST_STREAM"; 407 case SETTINGS: 408 return "SETTINGS"; 409 case NOOP: 410 return "NOOP"; 411 case PING: 412 return "PING"; 413 case GOAWAY: 414 return "GOAWAY"; 415 case HEADERS: 416 return "HEADERS"; 417 case WINDOW_UPDATE: 418 return "WINDOW_UPDATE"; 419 case CREDENTIAL: 420 return "CREDENTIAL"; 421 case BLOCKED: 422 return "BLOCKED"; 423 case PUSH_PROMISE: 424 return "PUSH_PROMISE"; 425 } 426 return "UNKNOWN_CONTROL_TYPE"; 427 } 428 429 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { 430 DCHECK(visitor_); 431 DCHECK(data); 432 433 size_t original_len = len; 434 do { 435 previous_state_ = state_; 436 switch (state_) { 437 case SPDY_ERROR: 438 goto bottom; 439 440 case SPDY_AUTO_RESET: 441 case SPDY_RESET: 442 Reset(); 443 if (len > 0) { 444 CHANGE_STATE(SPDY_READING_COMMON_HEADER); 445 } 446 break; 447 448 case SPDY_READING_COMMON_HEADER: { 449 size_t bytes_read = ProcessCommonHeader(data, len); 450 len -= bytes_read; 451 data += bytes_read; 452 break; 453 } 454 455 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: { 456 // Control frames that contain header blocks 457 // (SYN_STREAM, SYN_REPLY, HEADERS, PUSH_PROMISE) 458 // take a different path through the state machine - they 459 // will go: 460 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 461 // 2. SPDY_CONTROL_FRAME_HEADER_BLOCK 462 // 463 // SETTINGS frames take a slightly modified route: 464 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 465 // 2. SPDY_SETTINGS_FRAME_PAYLOAD 466 // 467 // All other control frames will use the alternate route directly to 468 // SPDY_CONTROL_FRAME_PAYLOAD 469 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len); 470 len -= bytes_read; 471 data += bytes_read; 472 break; 473 } 474 475 case SPDY_SETTINGS_FRAME_PAYLOAD: { 476 int bytes_read = ProcessSettingsFramePayload(data, len); 477 len -= bytes_read; 478 data += bytes_read; 479 break; 480 } 481 482 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { 483 int bytes_read = ProcessControlFrameHeaderBlock(data, len); 484 len -= bytes_read; 485 data += bytes_read; 486 break; 487 } 488 489 case SPDY_CREDENTIAL_FRAME_PAYLOAD: { 490 size_t bytes_read = ProcessCredentialFramePayload(data, len); 491 len -= bytes_read; 492 data += bytes_read; 493 break; 494 } 495 496 case SPDY_CONTROL_FRAME_PAYLOAD: { 497 size_t bytes_read = ProcessControlFramePayload(data, len); 498 len -= bytes_read; 499 data += bytes_read; 500 break; 501 } 502 503 case SPDY_IGNORE_REMAINING_PAYLOAD: 504 // control frame has too-large payload 505 // intentional fallthrough 506 case SPDY_FORWARD_STREAM_FRAME: { 507 size_t bytes_read = ProcessDataFramePayload(data, len); 508 len -= bytes_read; 509 data += bytes_read; 510 break; 511 } 512 default: 513 LOG(DFATAL) << "Invalid value for " << display_protocol_ 514 << " framer state: " << state_; 515 // This ensures that we don't infinite-loop if state_ gets an 516 // invalid value somehow, such as due to a SpdyFramer getting deleted 517 // from a callback it calls. 518 goto bottom; 519 } 520 } while (state_ != previous_state_); 521 bottom: 522 DCHECK(len == 0 || state_ == SPDY_ERROR); 523 if (current_frame_buffer_length_ == 0 && 524 remaining_data_length_ == 0 && 525 remaining_control_header_ == 0) { 526 DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR) 527 << "State: " << StateToString(state_); 528 } 529 530 return original_len - len; 531 } 532 533 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { 534 // This should only be called when we're in the SPDY_READING_COMMON_HEADER 535 // state. 536 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); 537 538 size_t original_len = len; 539 540 // Update current frame buffer as needed. 541 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { 542 size_t bytes_desired = 543 GetControlFrameHeaderSize() - current_frame_buffer_length_; 544 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); 545 } 546 547 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { 548 // Not enough information to do anything meaningful. 549 return original_len - len; 550 } 551 552 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader 553 // when processing DATA frames below. 554 scoped_ptr<SpdyFrameReader> reader( 555 new SpdyFrameReader(current_frame_buffer_.get(), 556 current_frame_buffer_length_)); 557 558 uint16 version = 0; 559 bool is_control_frame = false; 560 561 uint16 control_frame_type_field = DATA; 562 // ProcessControlFrameHeader() will set current_frame_type_ to the 563 // correct value if this is a valid control frame. 564 current_frame_type_ = DATA; 565 if (protocol_version() < 4) { 566 bool successful_read = reader->ReadUInt16(&version); 567 DCHECK(successful_read); 568 is_control_frame = (version & kControlFlagMask) != 0; 569 version &= ~kControlFlagMask; // Only valid for control frames. 570 571 if (is_control_frame) { 572 // We check control_frame_type_field's validity in 573 // ProcessControlFrameHeader(). 574 successful_read = reader->ReadUInt16(&control_frame_type_field); 575 } else { 576 reader->Rewind(); 577 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); 578 } 579 DCHECK(successful_read); 580 581 successful_read = reader->ReadUInt8(¤t_frame_flags_); 582 DCHECK(successful_read); 583 584 uint32 length_field = 0; 585 successful_read = reader->ReadUInt24(&length_field); 586 DCHECK(successful_read); 587 remaining_data_length_ = length_field; 588 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); 589 } else { 590 version = protocol_version(); 591 uint16 length_field = 0; 592 bool successful_read = reader->ReadUInt16(&length_field); 593 DCHECK(successful_read); 594 current_frame_length_ = length_field; 595 596 uint8 control_frame_type_field_uint8 = DATA; 597 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); 598 DCHECK(successful_read); 599 // We check control_frame_type_field's validity in 600 // ProcessControlFrameHeader(). 601 control_frame_type_field = control_frame_type_field_uint8; 602 is_control_frame = (control_frame_type_field != DATA); 603 604 successful_read = reader->ReadUInt8(¤t_frame_flags_); 605 DCHECK(successful_read); 606 607 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); 608 DCHECK(successful_read); 609 610 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); 611 } 612 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() 613 : GetDataFrameMinimumSize(), 614 reader->GetBytesConsumed()); 615 DCHECK_EQ(current_frame_length_, 616 remaining_data_length_ + reader->GetBytesConsumed()); 617 618 // This is just a sanity check for help debugging early frame errors. 619 if (remaining_data_length_ > 1000000u) { 620 // The strncmp for 5 is safe because we only hit this point if we 621 // have kMinCommonHeader (8) bytes 622 if (!syn_frame_processed_ && 623 strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) { 624 LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_ 625 << " request"; 626 probable_http_response_ = true; 627 } else { 628 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_ 629 << " session is likely corrupt."; 630 } 631 } 632 633 // if we're here, then we have the common header all received. 634 if (!is_control_frame) { 635 if (current_frame_flags_ & ~DATA_FLAG_FIN) { 636 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 637 } else { 638 visitor_->OnDataFrameHeader(current_frame_stream_id_, 639 remaining_data_length_, 640 current_frame_flags_ & DATA_FLAG_FIN); 641 if (remaining_data_length_ > 0) { 642 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 643 } else { 644 // Empty data frame. 645 if (current_frame_flags_ & DATA_FLAG_FIN) { 646 visitor_->OnStreamFrameData( 647 current_frame_stream_id_, NULL, 0, true); 648 } 649 CHANGE_STATE(SPDY_AUTO_RESET); 650 } 651 } 652 } else if (version != spdy_version_) { 653 // We check version before we check validity: version can never be 654 // 'invalid', it can only be unsupported. 655 DVLOG(1) << "Unsupported SPDY version " << version 656 << " (expected " << spdy_version_ << ")"; 657 set_error(SPDY_UNSUPPORTED_VERSION); 658 } else { 659 ProcessControlFrameHeader(control_frame_type_field); 660 } 661 662 return original_len - len; 663 } 664 665 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { 666 DCHECK_EQ(SPDY_NO_ERROR, error_code_); 667 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); 668 669 if (control_frame_type_field < FIRST_CONTROL_TYPE || 670 control_frame_type_field > LAST_CONTROL_TYPE) { 671 set_error(SPDY_INVALID_CONTROL_FRAME); 672 return; 673 } 674 675 current_frame_type_ = static_cast<SpdyFrameType>(control_frame_type_field); 676 677 if (current_frame_type_ == NOOP) { 678 DVLOG(1) << "NOOP control frame found. Ignoring."; 679 CHANGE_STATE(SPDY_AUTO_RESET); 680 return; 681 } 682 683 // Do some sanity checking on the control frame sizes and flags. 684 switch (current_frame_type_) { 685 case SYN_STREAM: 686 if (current_frame_length_ < GetSynStreamMinimumSize()) { 687 set_error(SPDY_INVALID_CONTROL_FRAME); 688 } else if (current_frame_flags_ & 689 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { 690 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 691 } 692 break; 693 case SYN_REPLY: 694 if (current_frame_length_ < GetSynReplyMinimumSize()) { 695 set_error(SPDY_INVALID_CONTROL_FRAME); 696 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { 697 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 698 } 699 break; 700 case RST_STREAM: 701 if (current_frame_length_ != GetRstStreamSize()) { 702 set_error(SPDY_INVALID_CONTROL_FRAME); 703 } else if (current_frame_flags_ != 0) { 704 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 705 } 706 break; 707 case SETTINGS: 708 // Make sure that we have an integral number of 8-byte key/value pairs, 709 // plus a 4-byte length field. 710 if (current_frame_length_ < GetSettingsMinimumSize() || 711 (current_frame_length_ - GetControlFrameHeaderSize()) % 8 != 4) { 712 DLOG(WARNING) << "Invalid length for SETTINGS frame: " 713 << current_frame_length_; 714 set_error(SPDY_INVALID_CONTROL_FRAME); 715 } else if (current_frame_flags_ & 716 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { 717 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 718 } 719 break; 720 case PING: 721 if (current_frame_length_ != GetPingSize()) { 722 set_error(SPDY_INVALID_CONTROL_FRAME); 723 } else if (current_frame_flags_ != 0) { 724 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 725 } 726 break; 727 case GOAWAY: 728 { 729 if (current_frame_length_ != GetGoAwaySize()) { 730 set_error(SPDY_INVALID_CONTROL_FRAME); 731 } else if (current_frame_flags_ != 0) { 732 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 733 } 734 break; 735 } 736 case HEADERS: 737 if (current_frame_length_ < GetHeadersMinimumSize()) { 738 set_error(SPDY_INVALID_CONTROL_FRAME); 739 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { 740 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 741 } 742 break; 743 case WINDOW_UPDATE: 744 if (current_frame_length_ != GetWindowUpdateSize()) { 745 set_error(SPDY_INVALID_CONTROL_FRAME); 746 } else if (current_frame_flags_ != 0) { 747 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 748 } 749 break; 750 case CREDENTIAL: 751 if (current_frame_length_ < GetCredentialMinimumSize()) { 752 set_error(SPDY_INVALID_CONTROL_FRAME); 753 } else if (current_frame_flags_ != 0) { 754 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 755 } 756 break; 757 case BLOCKED: 758 if (current_frame_length_ != GetBlockedSize()) { 759 set_error(SPDY_INVALID_CONTROL_FRAME); 760 } else if (current_frame_flags_ != 0) { 761 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 762 } 763 break; 764 case PUSH_PROMISE: 765 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 766 set_error(SPDY_INVALID_CONTROL_FRAME); 767 } else if (current_frame_flags_ != 0) { 768 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 769 } 770 break; 771 default: 772 LOG(WARNING) << "Valid " << display_protocol_ 773 << " control frame with unhandled type: " 774 << current_frame_type_; 775 // This branch should be unreachable because of the frame type bounds 776 // check above. However, we DLOG(FATAL) here in an effort to painfully 777 // club the head of the developer who failed to keep this file in sync 778 // with spdy_protocol.h. 779 DLOG(FATAL); 780 set_error(SPDY_INVALID_CONTROL_FRAME); 781 break; 782 } 783 784 if (state_ == SPDY_ERROR) { 785 return; 786 } 787 788 if (current_frame_length_ > GetControlFrameBufferMaxSize()) { 789 DLOG(WARNING) << "Received control frame with way too big of a payload: " 790 << current_frame_length_; 791 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 792 return; 793 } 794 795 if (current_frame_type_ == CREDENTIAL) { 796 CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD); 797 return; 798 } 799 800 // Determine the frame size without variable-length data. 801 int32 frame_size_without_variable_data; 802 switch (current_frame_type_) { 803 case SYN_STREAM: 804 syn_frame_processed_ = true; 805 frame_size_without_variable_data = GetSynStreamMinimumSize(); 806 break; 807 case SYN_REPLY: 808 syn_frame_processed_ = true; 809 frame_size_without_variable_data = GetSynReplyMinimumSize(); 810 break; 811 case SETTINGS: 812 frame_size_without_variable_data = GetSettingsMinimumSize(); 813 break; 814 case HEADERS: 815 frame_size_without_variable_data = GetHeadersMinimumSize(); 816 break; 817 case PUSH_PROMISE: 818 frame_size_without_variable_data = GetPushPromiseMinimumSize(); 819 break; 820 default: 821 frame_size_without_variable_data = -1; 822 break; 823 } 824 825 if ((frame_size_without_variable_data == -1) && 826 (current_frame_length_ > kControlFrameBufferSize)) { 827 // We should already be in an error state. Double-check. 828 DCHECK_EQ(SPDY_ERROR, state_); 829 if (state_ != SPDY_ERROR) { 830 LOG(DFATAL) << display_protocol_ 831 << " control frame buffer too small for fixed-length frame."; 832 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 833 } 834 return; 835 } 836 837 if (frame_size_without_variable_data > 0) { 838 // We have a control frame with a header block. We need to parse the 839 // remainder of the control frame's header before we can parse the header 840 // block. The start of the header block varies with the control type. 841 DCHECK_GE(frame_size_without_variable_data, 842 static_cast<int32>(current_frame_buffer_length_)); 843 remaining_control_header_ = frame_size_without_variable_data - 844 current_frame_buffer_length_; 845 846 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK); 847 return; 848 } 849 850 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); 851 } 852 853 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len, 854 size_t max_bytes) { 855 size_t bytes_to_read = std::min(*len, max_bytes); 856 if (bytes_to_read > 0) { 857 DCHECK_GE(kControlFrameBufferSize, 858 current_frame_buffer_length_ + bytes_to_read); 859 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_, 860 *data, 861 bytes_to_read); 862 current_frame_buffer_length_ += bytes_to_read; 863 *data += bytes_to_read; 864 *len -= bytes_to_read; 865 } 866 return bytes_to_read; 867 } 868 869 size_t SpdyFramer::GetSerializedLength(const int spdy_version, 870 const SpdyHeaderBlock* headers) { 871 const size_t num_name_value_pairs_size 872 = (spdy_version < 3) ? sizeof(uint16) : sizeof(uint32); 873 const size_t length_of_name_size = num_name_value_pairs_size; 874 const size_t length_of_value_size = num_name_value_pairs_size; 875 876 size_t total_length = num_name_value_pairs_size; 877 for (SpdyHeaderBlock::const_iterator it = headers->begin(); 878 it != headers->end(); 879 ++it) { 880 // We add space for the length of the name and the length of the value as 881 // well as the length of the name and the length of the value. 882 total_length += length_of_name_size + it->first.size() + 883 length_of_value_size + it->second.size(); 884 } 885 return total_length; 886 } 887 888 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame, 889 const int spdy_version, 890 const SpdyHeaderBlock* headers) { 891 if (spdy_version < 3) { 892 frame->WriteUInt16(headers->size()); // Number of headers. 893 } else { 894 frame->WriteUInt32(headers->size()); // Number of headers. 895 } 896 SpdyHeaderBlock::const_iterator it; 897 for (it = headers->begin(); it != headers->end(); ++it) { 898 if (spdy_version < 3) { 899 frame->WriteString(it->first); 900 frame->WriteString(it->second); 901 } else { 902 frame->WriteStringPiece32(it->first); 903 frame->WriteStringPiece32(it->second); 904 } 905 } 906 } 907 908 // TODO(phajdan.jr): Clean up after we no longer need 909 // to workaround http://crbug.com/139744. 910 #if !defined(USE_SYSTEM_ZLIB) 911 912 // These constants are used by zlib to differentiate between normal data and 913 // cookie data. Cookie data is handled specially by zlib when compressing. 914 enum ZDataClass { 915 // kZStandardData is compressed normally, save that it will never match 916 // against any other class of data in the window. 917 kZStandardData = Z_CLASS_STANDARD, 918 // kZCookieData is compressed in its own Huffman blocks and only matches in 919 // its entirety and only against other kZCookieData blocks. Any matches must 920 // be preceeded by a kZStandardData byte, or a semicolon to prevent matching 921 // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent 922 // prefix matches. 923 kZCookieData = Z_CLASS_COOKIE, 924 // kZHuffmanOnlyData is only Huffman compressed - no matches are performed 925 // against the window. 926 kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY, 927 }; 928 929 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as 930 // needed when switching between classes of data. 931 static void WriteZ(const base::StringPiece& data, 932 ZDataClass clas, 933 z_stream* out) { 934 int rv; 935 936 // If we are switching from standard to non-standard data then we need to end 937 // the current Huffman context to avoid it leaking between them. 938 if (out->clas == kZStandardData && 939 clas != kZStandardData) { 940 out->avail_in = 0; 941 rv = deflate(out, Z_PARTIAL_FLUSH); 942 DCHECK_EQ(Z_OK, rv); 943 DCHECK_EQ(0u, out->avail_in); 944 DCHECK_LT(0u, out->avail_out); 945 } 946 947 out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data())); 948 out->avail_in = data.size(); 949 out->clas = clas; 950 if (clas == kZStandardData) { 951 rv = deflate(out, Z_NO_FLUSH); 952 } else { 953 rv = deflate(out, Z_PARTIAL_FLUSH); 954 } 955 if (!data.empty()) { 956 // If we didn't provide any data then zlib will return Z_BUF_ERROR. 957 DCHECK_EQ(Z_OK, rv); 958 } 959 DCHECK_EQ(0u, out->avail_in); 960 DCHECK_LT(0u, out->avail_out); 961 } 962 963 // WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|. 964 static void WriteLengthZ(size_t n, 965 unsigned length, 966 ZDataClass clas, 967 z_stream* out) { 968 char buf[4]; 969 DCHECK_LE(length, sizeof(buf)); 970 for (unsigned i = 1; i <= length; i++) { 971 buf[length - i] = n; 972 n >>= 8; 973 } 974 WriteZ(base::StringPiece(buf, length), clas, out); 975 } 976 977 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a 978 // manner that resists the length of the compressed data from compromising 979 // cookie data. 980 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, 981 z_stream* z) const { 982 unsigned length_length = 4; 983 if (spdy_version_ < 3) 984 length_length = 2; 985 986 WriteLengthZ(headers->size(), length_length, kZStandardData, z); 987 988 std::map<std::string, std::string>::const_iterator it; 989 for (it = headers->begin(); it != headers->end(); ++it) { 990 WriteLengthZ(it->first.size(), length_length, kZStandardData, z); 991 WriteZ(it->first, kZStandardData, z); 992 993 if (it->first == "cookie") { 994 // We require the cookie values (save for the last) to end with a 995 // semicolon and (save for the first) to start with a space. This is 996 // typically the format that we are given them in but we reserialize them 997 // to be sure. 998 999 std::vector<base::StringPiece> cookie_values; 1000 size_t cookie_length = 0; 1001 base::StringPiece cookie_data(it->second); 1002 1003 for (;;) { 1004 while (!cookie_data.empty() && 1005 (cookie_data[0] == ' ' || cookie_data[0] == '\t')) { 1006 cookie_data.remove_prefix(1); 1007 } 1008 if (cookie_data.empty()) 1009 break; 1010 1011 size_t i; 1012 for (i = 0; i < cookie_data.size(); i++) { 1013 if (cookie_data[i] == ';') 1014 break; 1015 } 1016 if (i < cookie_data.size()) { 1017 cookie_values.push_back(cookie_data.substr(0, i)); 1018 cookie_length += i + 2 /* semicolon and space */; 1019 cookie_data.remove_prefix(i + 1); 1020 } else { 1021 cookie_values.push_back(cookie_data); 1022 cookie_length += cookie_data.size(); 1023 cookie_data.remove_prefix(i); 1024 } 1025 } 1026 1027 WriteLengthZ(cookie_length, length_length, kZStandardData, z); 1028 for (size_t i = 0; i < cookie_values.size(); i++) { 1029 std::string cookie; 1030 // Since zlib will only back-reference complete cookies, a cookie that 1031 // is currently last (and so doesn't have a trailing semicolon) won't 1032 // match if it's later in a non-final position. The same is true of 1033 // the first cookie. 1034 if (i == 0 && cookie_values.size() == 1) { 1035 cookie = cookie_values[i].as_string(); 1036 } else if (i == 0) { 1037 cookie = cookie_values[i].as_string() + ";"; 1038 } else if (i < cookie_values.size() - 1) { 1039 cookie = " " + cookie_values[i].as_string() + ";"; 1040 } else { 1041 cookie = " " + cookie_values[i].as_string(); 1042 } 1043 WriteZ(cookie, kZCookieData, z); 1044 } 1045 } else if (it->first == "accept" || 1046 it->first == "accept-charset" || 1047 it->first == "accept-encoding" || 1048 it->first == "accept-language" || 1049 it->first == "host" || 1050 it->first == "version" || 1051 it->first == "method" || 1052 it->first == "scheme" || 1053 it->first == ":host" || 1054 it->first == ":version" || 1055 it->first == ":method" || 1056 it->first == ":scheme" || 1057 it->first == "user-agent") { 1058 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); 1059 WriteZ(it->second, kZStandardData, z); 1060 } else { 1061 // Non-whitelisted headers are Huffman compressed in their own block, but 1062 // don't match against the window. 1063 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); 1064 WriteZ(it->second, kZHuffmanOnlyData, z); 1065 } 1066 } 1067 1068 z->avail_in = 0; 1069 int rv = deflate(z, Z_SYNC_FLUSH); 1070 DCHECK_EQ(Z_OK, rv); 1071 z->clas = kZStandardData; 1072 } 1073 #endif // !defined(USE_SYSTEM_ZLIB) 1074 1075 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, 1076 size_t len) { 1077 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_); 1078 size_t original_len = len; 1079 1080 if (remaining_control_header_ > 0) { 1081 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, 1082 remaining_control_header_); 1083 remaining_control_header_ -= bytes_read; 1084 remaining_data_length_ -= bytes_read; 1085 } 1086 1087 if (remaining_control_header_ == 0) { 1088 SpdyFrameReader reader(current_frame_buffer_.get(), 1089 current_frame_buffer_length_); 1090 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1091 1092 switch (current_frame_type_) { 1093 case SYN_STREAM: 1094 { 1095 bool successful_read = true; 1096 if (spdy_version_ < 4) { 1097 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1098 DCHECK(successful_read); 1099 } 1100 if (current_frame_stream_id_ == 0) { 1101 set_error(SPDY_INVALID_CONTROL_FRAME); 1102 break; 1103 } 1104 1105 SpdyStreamId associated_to_stream_id = kInvalidStream; 1106 successful_read = reader.ReadUInt31(&associated_to_stream_id); 1107 DCHECK(successful_read); 1108 1109 SpdyPriority priority = 0; 1110 successful_read = reader.ReadUInt8(&priority); 1111 DCHECK(successful_read); 1112 if (protocol_version() < 3) { 1113 priority = priority >> 6; 1114 } else { 1115 priority = priority >> 5; 1116 } 1117 1118 uint8 slot = 0; 1119 if (protocol_version() < 3) { 1120 // SPDY 2 had an unused byte here. Seek past it. 1121 reader.Seek(1); 1122 } else { 1123 successful_read = reader.ReadUInt8(&slot); 1124 DCHECK(successful_read); 1125 } 1126 1127 DCHECK(reader.IsDoneReading()); 1128 if (debug_visitor_) { 1129 debug_visitor_->OnReceiveCompressedFrame( 1130 current_frame_stream_id_, 1131 current_frame_type_, 1132 current_frame_length_); 1133 } 1134 visitor_->OnSynStream( 1135 current_frame_stream_id_, 1136 associated_to_stream_id, 1137 priority, 1138 slot, 1139 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1140 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); 1141 } 1142 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1143 break; 1144 case SETTINGS: 1145 visitor_->OnSettings(current_frame_flags_ & 1146 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); 1147 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); 1148 break; 1149 case SYN_REPLY: 1150 case HEADERS: 1151 // SYN_REPLY and HEADERS are the same, save for the visitor call. 1152 { 1153 bool successful_read = true; 1154 if (spdy_version_ < 4) { 1155 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1156 DCHECK(successful_read); 1157 } 1158 if (current_frame_stream_id_ == 0) { 1159 set_error(SPDY_INVALID_CONTROL_FRAME); 1160 break; 1161 } 1162 if (protocol_version() < 3) { 1163 // SPDY 2 had two unused bytes here. Seek past them. 1164 reader.Seek(2); 1165 } 1166 DCHECK(reader.IsDoneReading()); 1167 if (debug_visitor_) { 1168 debug_visitor_->OnReceiveCompressedFrame( 1169 current_frame_stream_id_, 1170 current_frame_type_, 1171 current_frame_length_); 1172 } 1173 if (current_frame_type_ == SYN_REPLY) { 1174 visitor_->OnSynReply( 1175 current_frame_stream_id_, 1176 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); 1177 } else { 1178 visitor_->OnHeaders( 1179 current_frame_stream_id_, 1180 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); 1181 } 1182 } 1183 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1184 break; 1185 case PUSH_PROMISE: 1186 { 1187 DCHECK_LE(4, protocol_version()); 1188 if (current_frame_stream_id_ == 0) { 1189 set_error(SPDY_INVALID_CONTROL_FRAME); 1190 break; 1191 } 1192 SpdyStreamId promised_stream_id = kInvalidStream; 1193 bool successful_read = reader.ReadUInt31(&promised_stream_id); 1194 DCHECK(successful_read); 1195 DCHECK(reader.IsDoneReading()); 1196 if (promised_stream_id == 0) { 1197 set_error(SPDY_INVALID_CONTROL_FRAME); 1198 break; 1199 } 1200 if (debug_visitor_) { 1201 debug_visitor_->OnReceiveCompressedFrame( 1202 current_frame_stream_id_, 1203 current_frame_type_, 1204 current_frame_length_); 1205 } 1206 visitor_->OnPushPromise(current_frame_stream_id_, promised_stream_id); 1207 } 1208 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1209 break; 1210 default: 1211 DCHECK(false); 1212 } 1213 } 1214 return original_len - len; 1215 } 1216 1217 // Does not buffer the control payload. Instead, either passes directly to the 1218 // visitor or decompresses and then passes directly to the visitor, via 1219 // IncrementallyDeliverControlFrameHeaderData() or 1220 // IncrementallyDecompressControlFrameHeaderData() respectively. 1221 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, 1222 size_t data_len) { 1223 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); 1224 1225 bool processed_successfully = true; 1226 if (current_frame_type_ != SYN_STREAM && 1227 current_frame_type_ != SYN_REPLY && 1228 current_frame_type_ != HEADERS && 1229 current_frame_type_ != PUSH_PROMISE) { 1230 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; 1231 } 1232 size_t process_bytes = std::min(data_len, remaining_data_length_); 1233 if (process_bytes > 0) { 1234 if (enable_compression_) { 1235 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1236 current_frame_stream_id_, data, process_bytes); 1237 } else { 1238 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1239 current_frame_stream_id_, data, process_bytes); 1240 } 1241 1242 remaining_data_length_ -= process_bytes; 1243 } 1244 1245 // Handle the case that there is no futher data in this frame. 1246 if (remaining_data_length_ == 0 && processed_successfully) { 1247 // The complete header block has been delivered. We send a zero-length 1248 // OnControlFrameHeaderData() to indicate this. 1249 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0); 1250 1251 // If this is a FIN, tell the caller. 1252 if (current_frame_flags_ & CONTROL_FLAG_FIN) { 1253 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 1254 } 1255 1256 CHANGE_STATE(SPDY_AUTO_RESET); 1257 } 1258 1259 // Handle error. 1260 if (!processed_successfully) { 1261 return data_len; 1262 } 1263 1264 // Return amount processed. 1265 return process_bytes; 1266 } 1267 1268 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, 1269 size_t data_len) { 1270 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); 1271 DCHECK_EQ(SETTINGS, current_frame_type_); 1272 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); 1273 size_t processed_bytes = 0; 1274 1275 // Loop over our incoming data. 1276 while (unprocessed_bytes > 0) { 1277 // Process up to one setting at a time. 1278 size_t processing = std::min( 1279 unprocessed_bytes, 1280 static_cast<size_t>(8 - settings_scratch_.setting_buf_len)); 1281 1282 // Check if we have a complete setting in our input. 1283 if (processing == 8) { 1284 // Parse the setting directly out of the input without buffering. 1285 if (!ProcessSetting(data + processed_bytes)) { 1286 set_error(SPDY_INVALID_CONTROL_FRAME); 1287 return processed_bytes; 1288 } 1289 } else { 1290 // Continue updating settings_scratch_.setting_buf. 1291 memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len, 1292 data + processed_bytes, 1293 processing); 1294 settings_scratch_.setting_buf_len += processing; 1295 1296 // Check if we have a complete setting buffered. 1297 if (settings_scratch_.setting_buf_len == 8) { 1298 if (!ProcessSetting(settings_scratch_.setting_buf)) { 1299 set_error(SPDY_INVALID_CONTROL_FRAME); 1300 return processed_bytes; 1301 } 1302 // Reset settings_scratch_.setting_buf for our next setting. 1303 settings_scratch_.setting_buf_len = 0; 1304 } 1305 } 1306 1307 // Iterate. 1308 unprocessed_bytes -= processing; 1309 processed_bytes += processing; 1310 } 1311 1312 // Check if we're done handling this SETTINGS frame. 1313 remaining_data_length_ -= processed_bytes; 1314 if (remaining_data_length_ == 0) { 1315 CHANGE_STATE(SPDY_AUTO_RESET); 1316 } 1317 1318 return processed_bytes; 1319 } 1320 1321 bool SpdyFramer::ProcessSetting(const char* data) { 1322 // Extract fields. 1323 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. 1324 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); 1325 SettingsFlagsAndId id_and_flags = 1326 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire); 1327 uint8 flags = id_and_flags.flags(); 1328 uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); 1329 1330 // Validate id. 1331 switch (id_and_flags.id()) { 1332 case SETTINGS_UPLOAD_BANDWIDTH: 1333 case SETTINGS_DOWNLOAD_BANDWIDTH: 1334 case SETTINGS_ROUND_TRIP_TIME: 1335 case SETTINGS_MAX_CONCURRENT_STREAMS: 1336 case SETTINGS_CURRENT_CWND: 1337 case SETTINGS_DOWNLOAD_RETRANS_RATE: 1338 case SETTINGS_INITIAL_WINDOW_SIZE: 1339 // Valid values. 1340 break; 1341 default: 1342 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id(); 1343 return false; 1344 } 1345 SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id()); 1346 1347 // Detect duplciates. 1348 if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) { 1349 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id 1350 << " in " << display_protocol_ << " SETTINGS frame " 1351 << "(last settikng id was " 1352 << settings_scratch_.last_setting_id << ")."; 1353 return false; 1354 } 1355 settings_scratch_.last_setting_id = id; 1356 1357 // Validate flags. 1358 uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED; 1359 if ((flags & ~(kFlagsMask)) != 0) { 1360 DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": " 1361 << flags; 1362 return false; 1363 } 1364 1365 // Validation succeeded. Pass on to visitor. 1366 visitor_->OnSetting(id, flags, value); 1367 return true; 1368 } 1369 1370 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { 1371 size_t original_len = len; 1372 size_t bytes_read = 1373 UpdateCurrentFrameBuffer(&data, &len, remaining_data_length_); 1374 remaining_data_length_ -= bytes_read; 1375 if (remaining_data_length_ == 0) { 1376 SpdyFrameReader reader(current_frame_buffer_.get(), 1377 current_frame_buffer_length_); 1378 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. 1379 1380 // Use frame-specific handlers. 1381 switch (current_frame_type_) { 1382 case RST_STREAM: { 1383 bool successful_read = true; 1384 if (spdy_version_ < 4) { 1385 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1386 DCHECK(successful_read); 1387 } 1388 SpdyRstStreamStatus status = RST_STREAM_INVALID; 1389 uint32 status_raw = status; 1390 successful_read = reader.ReadUInt32(&status_raw); 1391 DCHECK(successful_read); 1392 if (status_raw > RST_STREAM_INVALID && 1393 status_raw < RST_STREAM_NUM_STATUS_CODES) { 1394 status = static_cast<SpdyRstStreamStatus>(status_raw); 1395 } else { 1396 // TODO(hkhalil): Probably best to OnError here, depending on 1397 // our interpretation of the spec. Keeping with existing liberal 1398 // behavior for now. 1399 } 1400 DCHECK(reader.IsDoneReading()); 1401 visitor_->OnRstStream(current_frame_stream_id_, status); 1402 } 1403 break; 1404 case PING: { 1405 SpdyPingId id = 0; 1406 bool successful_read = reader.ReadUInt32(&id); 1407 DCHECK(successful_read); 1408 DCHECK(reader.IsDoneReading()); 1409 visitor_->OnPing(id); 1410 } 1411 break; 1412 case GOAWAY: { 1413 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1414 DCHECK(successful_read); 1415 SpdyGoAwayStatus status = GOAWAY_OK; 1416 if (spdy_version_ >= 3) { 1417 uint32 status_raw = GOAWAY_OK; 1418 successful_read = reader.ReadUInt32(&status_raw); 1419 DCHECK(successful_read); 1420 if (status_raw >= GOAWAY_OK && 1421 status_raw < static_cast<uint32>(GOAWAY_NUM_STATUS_CODES)) { 1422 status = static_cast<SpdyGoAwayStatus>(status_raw); 1423 } else { 1424 // TODO(hkhalil): Probably best to OnError here, depending on 1425 // our interpretation of the spec. Keeping with existing liberal 1426 // behavior for now. 1427 } 1428 } 1429 DCHECK(reader.IsDoneReading()); 1430 visitor_->OnGoAway(current_frame_stream_id_, status); 1431 } 1432 break; 1433 case WINDOW_UPDATE: { 1434 uint32 delta_window_size = 0; 1435 bool successful_read = true; 1436 if (spdy_version_ < 4) { 1437 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1438 DCHECK(successful_read); 1439 } 1440 successful_read = reader.ReadUInt32(&delta_window_size); 1441 DCHECK(successful_read); 1442 DCHECK(reader.IsDoneReading()); 1443 visitor_->OnWindowUpdate(current_frame_stream_id_, 1444 delta_window_size); 1445 } 1446 break; 1447 case BLOCKED: { 1448 DCHECK_LE(4, protocol_version()); 1449 DCHECK(reader.IsDoneReading()); 1450 visitor_->OnBlocked(current_frame_stream_id_); 1451 } 1452 break; 1453 default: 1454 // Unreachable. 1455 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; 1456 } 1457 1458 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 1459 } 1460 return original_len - len; 1461 } 1462 1463 size_t SpdyFramer::ProcessCredentialFramePayload(const char* data, size_t len) { 1464 if (len > 0) { 1465 // Clamp to the actual remaining payload. 1466 if (len > remaining_data_length_) { 1467 len = remaining_data_length_; 1468 } 1469 bool processed_succesfully = visitor_->OnCredentialFrameData(data, len); 1470 remaining_data_length_ -= len; 1471 if (!processed_succesfully) { 1472 set_error(SPDY_CREDENTIAL_FRAME_CORRUPT); 1473 } else if (remaining_data_length_ == 0) { 1474 visitor_->OnCredentialFrameData(NULL, 0); 1475 CHANGE_STATE(SPDY_AUTO_RESET); 1476 } 1477 } 1478 return len; 1479 } 1480 1481 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 1482 size_t original_len = len; 1483 1484 if (remaining_data_length_ > 0) { 1485 size_t amount_to_forward = std::min(remaining_data_length_, len); 1486 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { 1487 // Only inform the visitor if there is data. 1488 if (amount_to_forward) { 1489 visitor_->OnStreamFrameData( 1490 current_frame_stream_id_, data, amount_to_forward, false); 1491 } 1492 } 1493 data += amount_to_forward; 1494 len -= amount_to_forward; 1495 remaining_data_length_ -= amount_to_forward; 1496 1497 // If the FIN flag is set, and there is no more data in this data 1498 // frame, inform the visitor of EOF via a 0-length data frame. 1499 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) { 1500 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 1501 } 1502 } 1503 1504 if (remaining_data_length_ == 0) { 1505 CHANGE_STATE(SPDY_AUTO_RESET); 1506 } 1507 return original_len - len; 1508 } 1509 1510 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 1511 size_t header_length, 1512 SpdyHeaderBlock* block) const { 1513 SpdyFrameReader reader(header_data, header_length); 1514 1515 // Read number of headers. 1516 uint32 num_headers; 1517 if (spdy_version_ < 3) { 1518 uint16 temp; 1519 if (!reader.ReadUInt16(&temp)) { 1520 DVLOG(1) << "Unable to read number of headers."; 1521 return 0; 1522 } 1523 num_headers = temp; 1524 } else { 1525 if (!reader.ReadUInt32(&num_headers)) { 1526 DVLOG(1) << "Unable to read number of headers."; 1527 return 0; 1528 } 1529 } 1530 1531 // Read each header. 1532 for (uint32 index = 0; index < num_headers; ++index) { 1533 base::StringPiece temp; 1534 1535 // Read header name. 1536 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) 1537 : !reader.ReadStringPiece32(&temp)) { 1538 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " 1539 << num_headers << ")."; 1540 return 0; 1541 } 1542 std::string name = temp.as_string(); 1543 1544 // Read header value. 1545 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) 1546 : !reader.ReadStringPiece32(&temp)) { 1547 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " 1548 << num_headers << ")."; 1549 return 0; 1550 } 1551 std::string value = temp.as_string(); 1552 1553 // Ensure no duplicates. 1554 if (block->find(name) != block->end()) { 1555 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " 1556 << num_headers << ")."; 1557 return 0; 1558 } 1559 1560 // Store header. 1561 (*block)[name] = value; 1562 } 1563 return reader.GetBytesConsumed(); 1564 } 1565 1566 /* static */ 1567 bool SpdyFramer::ParseCredentialData(const char* data, size_t len, 1568 SpdyCredential* credential) { 1569 DCHECK(credential); 1570 1571 SpdyFrameReader parser(data, len); 1572 base::StringPiece temp; 1573 if (!parser.ReadUInt16(&credential->slot)) { 1574 return false; 1575 } 1576 1577 if (!parser.ReadStringPiece32(&temp)) { 1578 return false; 1579 } 1580 credential->proof = temp.as_string(); 1581 1582 while (!parser.IsDoneReading()) { 1583 if (!parser.ReadStringPiece32(&temp)) { 1584 return false; 1585 } 1586 credential->certs.push_back(temp.as_string()); 1587 } 1588 return true; 1589 } 1590 1591 SpdyFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, 1592 const char* data, 1593 uint32 len, SpdyDataFlags flags) const { 1594 DCHECK_EQ(0, flags & (!DATA_FLAG_FIN)); 1595 1596 SpdyDataIR data_ir(stream_id, base::StringPiece(data, len)); 1597 data_ir.set_fin(flags & DATA_FLAG_FIN); 1598 return SerializeData(data_ir); 1599 } 1600 1601 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const { 1602 const size_t kSize = GetDataFrameMinimumSize() + data.data().length(); 1603 1604 SpdyDataFlags flags = DATA_FLAG_NONE; 1605 if (data.fin()) { 1606 flags = DATA_FLAG_FIN; 1607 } 1608 1609 SpdyFrameBuilder builder(kSize); 1610 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 1611 builder.WriteBytes(data.data().data(), data.data().length()); 1612 DCHECK_EQ(kSize, builder.length()); 1613 return builder.take(); 1614 } 1615 1616 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( 1617 const SpdyDataIR& data) const { 1618 const size_t kSize = GetDataFrameMinimumSize(); 1619 1620 SpdyDataFlags flags = DATA_FLAG_NONE; 1621 if (data.fin()) { 1622 flags = DATA_FLAG_FIN; 1623 } 1624 1625 SpdyFrameBuilder builder(kSize); 1626 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 1627 if (protocol_version() < 4) { 1628 builder.OverwriteLength(*this, data.data().length()); 1629 } else { 1630 builder.OverwriteLength(*this, data.data().length() + kSize); 1631 } 1632 DCHECK_EQ(kSize, builder.length()); 1633 return builder.take(); 1634 } 1635 1636 SpdyFrame* SpdyFramer::CreateSynStream( 1637 SpdyStreamId stream_id, 1638 SpdyStreamId associated_stream_id, 1639 SpdyPriority priority, 1640 uint8 credential_slot, 1641 SpdyControlFlags flags, 1642 const SpdyHeaderBlock* headers) { 1643 DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN & ~CONTROL_FLAG_UNIDIRECTIONAL); 1644 1645 SpdySynStreamIR syn_stream(stream_id); 1646 syn_stream.set_associated_to_stream_id(associated_stream_id); 1647 syn_stream.set_priority(priority); 1648 syn_stream.set_slot(credential_slot); 1649 syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0); 1650 syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0); 1651 // TODO(hkhalil): Avoid copy here. 1652 *(syn_stream.GetMutableNameValueBlock()) = *headers; 1653 1654 return SerializeSynStream(syn_stream); 1655 } 1656 1657 SpdySerializedFrame* SpdyFramer::SerializeSynStream( 1658 const SpdySynStreamIR& syn_stream) { 1659 uint8 flags = 0; 1660 if (syn_stream.fin()) { 1661 flags |= CONTROL_FLAG_FIN; 1662 } 1663 if (syn_stream.unidirectional()) { 1664 flags |= CONTROL_FLAG_UNIDIRECTIONAL; 1665 } 1666 1667 // The size of this frame, including variable-length name-value block. 1668 const size_t size = GetSynStreamMinimumSize() 1669 + GetSerializedLength(syn_stream.name_value_block()); 1670 1671 SpdyFrameBuilder builder(size); 1672 if (spdy_version_ < 4) { 1673 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 1674 builder.WriteUInt32(syn_stream.stream_id()); 1675 } else { 1676 builder.WriteFramePrefix(*this, 1677 SYN_STREAM, 1678 flags, 1679 syn_stream.stream_id()); 1680 } 1681 builder.WriteUInt32(syn_stream.associated_to_stream_id()); 1682 uint8 priority = syn_stream.priority(); 1683 if (priority > GetLowestPriority()) { 1684 DLOG(DFATAL) << "Priority out-of-bounds."; 1685 priority = GetLowestPriority(); 1686 } 1687 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); 1688 builder.WriteUInt8(syn_stream.slot()); 1689 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); 1690 SerializeNameValueBlock(&builder, syn_stream); 1691 1692 if (debug_visitor_) { 1693 const size_t payload_len = GetSerializedLength( 1694 protocol_version(), &(syn_stream.name_value_block())); 1695 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), 1696 SYN_STREAM, 1697 payload_len, 1698 builder.length()); 1699 } 1700 1701 return builder.take(); 1702 } 1703 1704 SpdyFrame* SpdyFramer::CreateSynReply( 1705 SpdyStreamId stream_id, 1706 SpdyControlFlags flags, 1707 const SpdyHeaderBlock* headers) { 1708 DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN); 1709 1710 SpdySynReplyIR syn_reply(stream_id); 1711 syn_reply.set_fin(flags & CONTROL_FLAG_FIN); 1712 // TODO(hkhalil): Avoid copy here. 1713 *(syn_reply.GetMutableNameValueBlock()) = *headers; 1714 1715 return SerializeSynReply(syn_reply); 1716 } 1717 1718 SpdySerializedFrame* SpdyFramer::SerializeSynReply( 1719 const SpdySynReplyIR& syn_reply) { 1720 uint8 flags = 0; 1721 if (syn_reply.fin()) { 1722 flags |= CONTROL_FLAG_FIN; 1723 } 1724 1725 // The size of this frame, including variable-length name-value block. 1726 size_t size = GetSynReplyMinimumSize() 1727 + GetSerializedLength(syn_reply.name_value_block()); 1728 1729 SpdyFrameBuilder builder(size); 1730 if (spdy_version_ < 4) { 1731 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 1732 builder.WriteUInt32(syn_reply.stream_id()); 1733 } else { 1734 builder.WriteFramePrefix(*this, 1735 SYN_REPLY, 1736 flags, 1737 syn_reply.stream_id()); 1738 } 1739 if (protocol_version() < 3) { 1740 builder.WriteUInt16(0); // Unused. 1741 } 1742 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); 1743 SerializeNameValueBlock(&builder, syn_reply); 1744 1745 if (debug_visitor_) { 1746 const size_t payload_len = GetSerializedLength( 1747 protocol_version(), &(syn_reply.name_value_block())); 1748 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), 1749 SYN_REPLY, 1750 payload_len, 1751 builder.length()); 1752 } 1753 1754 return builder.take(); 1755 } 1756 1757 SpdyFrame* SpdyFramer::CreateRstStream( 1758 SpdyStreamId stream_id, 1759 SpdyRstStreamStatus status) const { 1760 SpdyRstStreamIR rst_stream(stream_id, status); 1761 return SerializeRstStream(rst_stream); 1762 } 1763 1764 SpdySerializedFrame* SpdyFramer::SerializeRstStream( 1765 const SpdyRstStreamIR& rst_stream) const { 1766 SpdyFrameBuilder builder(GetRstStreamSize()); 1767 if (spdy_version_ < 4) { 1768 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); 1769 builder.WriteUInt32(rst_stream.stream_id()); 1770 } else { 1771 builder.WriteFramePrefix(*this, 1772 RST_STREAM, 1773 0, 1774 rst_stream.stream_id()); 1775 } 1776 builder.WriteUInt32(rst_stream.status()); 1777 DCHECK_EQ(GetRstStreamSize(), builder.length()); 1778 return builder.take(); 1779 } 1780 1781 SpdyFrame* SpdyFramer::CreateSettings( 1782 const SettingsMap& values) const { 1783 SpdySettingsIR settings; 1784 for (SettingsMap::const_iterator it = values.begin(); 1785 it != values.end(); 1786 ++it) { 1787 settings.AddSetting(it->first, 1788 (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0, 1789 (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, 1790 it->second.second); 1791 } 1792 return SerializeSettings(settings); 1793 } 1794 1795 SpdySerializedFrame* SpdyFramer::SerializeSettings( 1796 const SpdySettingsIR& settings) const { 1797 uint8 flags = 0; 1798 if (settings.clear_settings()) { 1799 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; 1800 } 1801 const SpdySettingsIR::ValueMap* values = &(settings.values()); 1802 1803 // Size, in bytes, of this SETTINGS frame. 1804 const size_t size = GetSettingsMinimumSize() + (values->size() * 8); 1805 1806 SpdyFrameBuilder builder(size); 1807 if (spdy_version_ < 4) { 1808 builder.WriteControlFrameHeader(*this, SETTINGS, flags); 1809 } else { 1810 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); 1811 } 1812 builder.WriteUInt32(values->size()); 1813 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); 1814 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); 1815 it != values->end(); 1816 ++it) { 1817 uint8 setting_flags = 0; 1818 if (it->second.persist_value) { 1819 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; 1820 } 1821 if (it->second.persisted) { 1822 setting_flags |= SETTINGS_FLAG_PERSISTED; 1823 } 1824 SettingsFlagsAndId flags_and_id(setting_flags, it->first); 1825 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); 1826 builder.WriteBytes(&id_and_flags_wire, 4); 1827 builder.WriteUInt32(it->second.value); 1828 } 1829 DCHECK_EQ(size, builder.length()); 1830 return builder.take(); 1831 } 1832 1833 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { 1834 DCHECK_LE(4, protocol_version()); 1835 SpdyFrameBuilder builder(GetBlockedSize()); 1836 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id()); 1837 return builder.take(); 1838 } 1839 1840 SpdyFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { 1841 SpdyPingIR ping(unique_id); 1842 return SerializePing(ping); 1843 } 1844 1845 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { 1846 SpdyFrameBuilder builder(GetPingSize()); 1847 if (spdy_version_ < 4) { 1848 builder.WriteControlFrameHeader(*this, PING, kNoFlags); 1849 } else { 1850 builder.WriteFramePrefix(*this, PING, 0, 0); 1851 } 1852 builder.WriteUInt32(ping.id()); 1853 DCHECK_EQ(GetPingSize(), builder.length()); 1854 return builder.take(); 1855 } 1856 1857 SpdyFrame* SpdyFramer::CreateGoAway( 1858 SpdyStreamId last_accepted_stream_id, 1859 SpdyGoAwayStatus status) const { 1860 SpdyGoAwayIR goaway(last_accepted_stream_id, status); 1861 return SerializeGoAway(goaway); 1862 } 1863 1864 SpdySerializedFrame* SpdyFramer::SerializeGoAway( 1865 const SpdyGoAwayIR& goaway) const { 1866 SpdyFrameBuilder builder(GetGoAwaySize()); 1867 if (spdy_version_ < 4) { 1868 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); 1869 } else { 1870 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); 1871 } 1872 builder.WriteUInt32(goaway.last_good_stream_id()); 1873 if (protocol_version() >= 3) { 1874 builder.WriteUInt32(goaway.status()); 1875 } 1876 DCHECK_EQ(GetGoAwaySize(), builder.length()); 1877 return builder.take(); 1878 } 1879 1880 SpdyFrame* SpdyFramer::CreateHeaders( 1881 SpdyStreamId stream_id, 1882 SpdyControlFlags flags, 1883 const SpdyHeaderBlock* header_block) { 1884 // Basically the same as CreateSynReply(). 1885 DCHECK_EQ(0, flags & (!CONTROL_FLAG_FIN)); 1886 1887 SpdyHeadersIR headers(stream_id); 1888 headers.set_fin(flags & CONTROL_FLAG_FIN); 1889 // TODO(hkhalil): Avoid copy here. 1890 *(headers.GetMutableNameValueBlock()) = *header_block; 1891 1892 return SerializeHeaders(headers); 1893 } 1894 1895 SpdySerializedFrame* SpdyFramer::SerializeHeaders( 1896 const SpdyHeadersIR& headers) { 1897 uint8 flags = 0; 1898 if (headers.fin()) { 1899 flags |= CONTROL_FLAG_FIN; 1900 } 1901 1902 // The size of this frame, including variable-length name-value block. 1903 size_t size = GetHeadersMinimumSize() 1904 + GetSerializedLength(headers.name_value_block()); 1905 1906 SpdyFrameBuilder builder(size); 1907 if (spdy_version_ < 4) { 1908 builder.WriteControlFrameHeader(*this, HEADERS, flags); 1909 builder.WriteUInt32(headers.stream_id()); 1910 } else { 1911 builder.WriteFramePrefix(*this, 1912 HEADERS, 1913 flags, 1914 headers.stream_id()); 1915 } 1916 if (protocol_version() < 3) { 1917 builder.WriteUInt16(0); // Unused. 1918 } 1919 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 1920 1921 SerializeNameValueBlock(&builder, headers); 1922 1923 if (debug_visitor_) { 1924 const size_t payload_len = GetSerializedLength( 1925 protocol_version(), &(headers.name_value_block())); 1926 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), 1927 HEADERS, 1928 payload_len, 1929 builder.length()); 1930 } 1931 1932 return builder.take(); 1933 } 1934 1935 SpdyFrame* SpdyFramer::CreateWindowUpdate( 1936 SpdyStreamId stream_id, 1937 uint32 delta_window_size) const { 1938 SpdyWindowUpdateIR window_update(stream_id, delta_window_size); 1939 return SerializeWindowUpdate(window_update); 1940 } 1941 1942 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( 1943 const SpdyWindowUpdateIR& window_update) const { 1944 SpdyFrameBuilder builder(GetWindowUpdateSize()); 1945 if (spdy_version_ < 4) { 1946 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); 1947 builder.WriteUInt32(window_update.stream_id()); 1948 } else { 1949 builder.WriteFramePrefix(*this, 1950 WINDOW_UPDATE, 1951 kNoFlags, 1952 window_update.stream_id()); 1953 } 1954 builder.WriteUInt32(window_update.delta()); 1955 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); 1956 return builder.take(); 1957 } 1958 1959 // TODO(hkhalil): Gut with SpdyCredential removal. 1960 SpdyFrame* SpdyFramer::CreateCredentialFrame( 1961 const SpdyCredential& credential) const { 1962 SpdyCredentialIR credential_ir(credential.slot); 1963 credential_ir.set_proof(credential.proof); 1964 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); 1965 cert != credential.certs.end(); 1966 ++cert) { 1967 credential_ir.AddCertificate(*cert); 1968 } 1969 return SerializeCredential(credential_ir); 1970 } 1971 1972 SpdySerializedFrame* SpdyFramer::SerializeCredential( 1973 const SpdyCredentialIR& credential) const { 1974 size_t size = GetCredentialMinimumSize(); 1975 size += 4 + credential.proof().length(); // Room for proof. 1976 for (SpdyCredentialIR::CertificateList::const_iterator it = 1977 credential.certificates()->begin(); 1978 it != credential.certificates()->end(); 1979 ++it) { 1980 size += 4 + it->length(); // Room for certificate. 1981 } 1982 1983 SpdyFrameBuilder builder(size); 1984 if (spdy_version_ < 4) { 1985 builder.WriteControlFrameHeader(*this, CREDENTIAL, kNoFlags); 1986 } else { 1987 builder.WriteFramePrefix(*this, CREDENTIAL, kNoFlags, 0); 1988 } 1989 builder.WriteUInt16(credential.slot()); 1990 DCHECK_EQ(GetCredentialMinimumSize(), builder.length()); 1991 builder.WriteStringPiece32(credential.proof()); 1992 for (SpdyCredentialIR::CertificateList::const_iterator it = 1993 credential.certificates()->begin(); 1994 it != credential.certificates()->end(); 1995 ++it) { 1996 builder.WriteStringPiece32(*it); 1997 } 1998 DCHECK_EQ(size, builder.length()); 1999 return builder.take(); 2000 } 2001 2002 SpdyFrame* SpdyFramer::CreatePushPromise( 2003 SpdyStreamId stream_id, 2004 SpdyStreamId promised_stream_id, 2005 const SpdyHeaderBlock* header_block) { 2006 SpdyPushPromiseIR push_promise(stream_id, promised_stream_id); 2007 // TODO(hkhalil): Avoid copy here. 2008 *(push_promise.GetMutableNameValueBlock()) = *header_block; 2009 2010 return SerializePushPromise(push_promise); 2011 } 2012 2013 SpdyFrame* SpdyFramer::SerializePushPromise( 2014 const SpdyPushPromiseIR& push_promise) { 2015 DCHECK_LE(4, protocol_version()); 2016 // The size of this frame, including variable-length name-value block. 2017 size_t size = GetPushPromiseMinimumSize() 2018 + GetSerializedLength(push_promise.name_value_block()); 2019 2020 SpdyFrameBuilder builder(size); 2021 builder.WriteFramePrefix(*this, PUSH_PROMISE, kNoFlags, 2022 push_promise.stream_id()); 2023 builder.WriteUInt32(push_promise.promised_stream_id()); 2024 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); 2025 2026 SerializeNameValueBlock(&builder, push_promise); 2027 2028 if (debug_visitor_) { 2029 const size_t payload_len = GetSerializedLength( 2030 protocol_version(), &(push_promise.name_value_block())); 2031 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), 2032 PUSH_PROMISE, payload_len, builder.length()); 2033 } 2034 2035 return builder.take(); 2036 } 2037 2038 namespace { 2039 2040 class FrameSerializationVisitor : public SpdyFrameVisitor { 2041 public: 2042 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} 2043 virtual ~FrameSerializationVisitor() {} 2044 2045 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } 2046 2047 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { 2048 frame_.reset(framer_->SerializeData(data)); 2049 } 2050 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE { 2051 frame_.reset(framer_->SerializeSynStream(syn_stream)); 2052 } 2053 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE { 2054 frame_.reset(framer_->SerializeSynReply(syn_reply)); 2055 } 2056 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE { 2057 frame_.reset(framer_->SerializeRstStream(rst_stream)); 2058 } 2059 virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE { 2060 frame_.reset(framer_->SerializeSettings(settings)); 2061 } 2062 virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE { 2063 frame_.reset(framer_->SerializePing(ping)); 2064 } 2065 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE { 2066 frame_.reset(framer_->SerializeGoAway(goaway)); 2067 } 2068 virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE { 2069 frame_.reset(framer_->SerializeHeaders(headers)); 2070 } 2071 virtual void VisitWindowUpdate( 2072 const SpdyWindowUpdateIR& window_update) OVERRIDE { 2073 frame_.reset(framer_->SerializeWindowUpdate(window_update)); 2074 } 2075 virtual void VisitCredential(const SpdyCredentialIR& credential) OVERRIDE { 2076 frame_.reset(framer_->SerializeCredential(credential)); 2077 } 2078 virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE { 2079 frame_.reset(framer_->SerializeBlocked(blocked)); 2080 } 2081 virtual void VisitPushPromise( 2082 const SpdyPushPromiseIR& push_promise) OVERRIDE { 2083 frame_.reset(framer_->SerializePushPromise(push_promise)); 2084 } 2085 2086 private: 2087 SpdyFramer* framer_; 2088 scoped_ptr<SpdySerializedFrame> frame_; 2089 }; 2090 2091 } // namespace 2092 2093 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { 2094 FrameSerializationVisitor visitor(this); 2095 frame.Visit(&visitor); 2096 return visitor.ReleaseSerializedFrame(); 2097 } 2098 2099 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { 2100 const size_t uncompressed_length = 2101 GetSerializedLength(protocol_version(), &headers); 2102 if (!enable_compression_) { 2103 return uncompressed_length; 2104 } 2105 z_stream* compressor = GetHeaderCompressor(); 2106 // Since we'll be performing lots of flushes when compressing the data, 2107 // zlib's lower bounds may be insufficient. 2108 return 2 * deflateBound(compressor, uncompressed_length); 2109 } 2110 2111 // The following compression setting are based on Brian Olson's analysis. See 2112 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792 2113 // for more details. 2114 #if defined(USE_SYSTEM_ZLIB) 2115 // System zlib is not expected to have workaround for http://crbug.com/139744, 2116 // so disable compression in that case. 2117 // TODO(phajdan.jr): Remove the special case when it's no longer necessary. 2118 static const int kCompressorLevel = 0; 2119 #else // !defined(USE_SYSTEM_ZLIB) 2120 static const int kCompressorLevel = 9; 2121 #endif // !defined(USE_SYSTEM_ZLIB) 2122 static const int kCompressorWindowSizeInBits = 11; 2123 static const int kCompressorMemLevel = 1; 2124 2125 z_stream* SpdyFramer::GetHeaderCompressor() { 2126 if (header_compressor_.get()) 2127 return header_compressor_.get(); // Already initialized. 2128 2129 header_compressor_.reset(new z_stream); 2130 memset(header_compressor_.get(), 0, sizeof(z_stream)); 2131 2132 int success = deflateInit2(header_compressor_.get(), 2133 kCompressorLevel, 2134 Z_DEFLATED, 2135 kCompressorWindowSizeInBits, 2136 kCompressorMemLevel, 2137 Z_DEFAULT_STRATEGY); 2138 if (success == Z_OK) { 2139 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary 2140 : kV3Dictionary; 2141 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize 2142 : kV3DictionarySize; 2143 success = deflateSetDictionary(header_compressor_.get(), 2144 reinterpret_cast<const Bytef*>(dictionary), 2145 dictionary_size); 2146 } 2147 if (success != Z_OK) { 2148 LOG(WARNING) << "deflateSetDictionary failure: " << success; 2149 header_compressor_.reset(NULL); 2150 return NULL; 2151 } 2152 return header_compressor_.get(); 2153 } 2154 2155 z_stream* SpdyFramer::GetHeaderDecompressor() { 2156 if (header_decompressor_.get()) 2157 return header_decompressor_.get(); // Already initialized. 2158 2159 header_decompressor_.reset(new z_stream); 2160 memset(header_decompressor_.get(), 0, sizeof(z_stream)); 2161 2162 int success = inflateInit(header_decompressor_.get()); 2163 if (success != Z_OK) { 2164 LOG(WARNING) << "inflateInit failure: " << success; 2165 header_decompressor_.reset(NULL); 2166 return NULL; 2167 } 2168 return header_decompressor_.get(); 2169 } 2170 2171 // Incrementally decompress the control frame's header block, feeding the 2172 // result to the visitor in chunks. Continue this until the visitor 2173 // indicates that it cannot process any more data, or (more commonly) we 2174 // run out of data to deliver. 2175 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 2176 SpdyStreamId stream_id, 2177 const char* data, 2178 size_t len) { 2179 // Get a decompressor or set error. 2180 z_stream* decomp = GetHeaderDecompressor(); 2181 if (decomp == NULL) { 2182 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; 2183 set_error(SPDY_DECOMPRESS_FAILURE); 2184 return false; 2185 } 2186 2187 bool processed_successfully = true; 2188 char buffer[kHeaderDataChunkMaxSize]; 2189 2190 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data)); 2191 decomp->avail_in = len; 2192 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we 2193 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've 2194 // reached this method successfully, stream_id should be nonzero. 2195 DCHECK_LT(0u, stream_id); 2196 while (decomp->avail_in > 0 && processed_successfully) { 2197 decomp->next_out = reinterpret_cast<Bytef*>(buffer); 2198 decomp->avail_out = arraysize(buffer); 2199 2200 int rv = inflate(decomp, Z_SYNC_FLUSH); 2201 if (rv == Z_NEED_DICT) { 2202 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary 2203 : kV3Dictionary; 2204 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize 2205 : kV3DictionarySize; 2206 const DictionaryIds& ids = g_dictionary_ids.Get(); 2207 const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id 2208 : ids.v3_dictionary_id; 2209 // Need to try again with the right dictionary. 2210 if (decomp->adler == dictionary_id) { 2211 rv = inflateSetDictionary(decomp, 2212 reinterpret_cast<const Bytef*>(dictionary), 2213 dictionary_size); 2214 if (rv == Z_OK) 2215 rv = inflate(decomp, Z_SYNC_FLUSH); 2216 } 2217 } 2218 2219 // Inflate will generate a Z_BUF_ERROR if it runs out of input 2220 // without producing any output. The input is consumed and 2221 // buffered internally by zlib so we can detect this condition by 2222 // checking if avail_in is 0 after the call to inflate. 2223 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0)); 2224 if ((rv == Z_OK) || input_exhausted) { 2225 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; 2226 if (decompressed_len > 0) { 2227 processed_successfully = visitor_->OnControlFrameHeaderData( 2228 stream_id, buffer, decompressed_len); 2229 } 2230 if (!processed_successfully) { 2231 // Assume that the problem was the header block was too large for the 2232 // visitor. 2233 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 2234 } 2235 } else { 2236 DLOG(WARNING) << "inflate failure: " << rv << " " << len; 2237 set_error(SPDY_DECOMPRESS_FAILURE); 2238 processed_successfully = false; 2239 } 2240 } 2241 return processed_successfully; 2242 } 2243 2244 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( 2245 SpdyStreamId stream_id, const char* data, size_t len) { 2246 bool read_successfully = true; 2247 while (read_successfully && len > 0) { 2248 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); 2249 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, 2250 bytes_to_deliver); 2251 data += bytes_to_deliver; 2252 len -= bytes_to_deliver; 2253 if (!read_successfully) { 2254 // Assume that the problem was the header block was too large for the 2255 // visitor. 2256 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 2257 } 2258 } 2259 return read_successfully; 2260 } 2261 2262 void SpdyFramer::SerializeNameValueBlockWithoutCompression( 2263 SpdyFrameBuilder* builder, 2264 const SpdyNameValueBlock& name_value_block) const { 2265 // Serialize number of headers. 2266 if (protocol_version() < 3) { 2267 builder->WriteUInt16(name_value_block.size()); 2268 } else { 2269 builder->WriteUInt32(name_value_block.size()); 2270 } 2271 2272 // Serialize each header. 2273 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin(); 2274 it != name_value_block.end(); 2275 ++it) { 2276 if (protocol_version() < 3) { 2277 builder->WriteString(it->first); 2278 builder->WriteString(it->second); 2279 } else { 2280 builder->WriteStringPiece32(it->first); 2281 builder->WriteStringPiece32(it->second); 2282 } 2283 } 2284 } 2285 2286 void SpdyFramer::SerializeNameValueBlock( 2287 SpdyFrameBuilder* builder, 2288 const SpdyFrameWithNameValueBlockIR& frame) { 2289 if (!enable_compression_) { 2290 return SerializeNameValueBlockWithoutCompression(builder, 2291 frame.name_value_block()); 2292 } 2293 2294 // First build an uncompressed version to be fed into the compressor. 2295 const size_t uncompressed_len = GetSerializedLength( 2296 protocol_version(), &(frame.name_value_block())); 2297 SpdyFrameBuilder uncompressed_builder(uncompressed_len); 2298 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, 2299 frame.name_value_block()); 2300 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take()); 2301 2302 z_stream* compressor = GetHeaderCompressor(); 2303 if (!compressor) { 2304 LOG(DFATAL) << "Could not obtain compressor."; 2305 return; 2306 } 2307 2308 base::StatsCounter compressed_frames("spdy.CompressedFrames"); 2309 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize"); 2310 base::StatsCounter post_compress_bytes("spdy.PostCompressSize"); 2311 2312 // Create an output frame. 2313 // Since we'll be performing lots of flushes when compressing the data, 2314 // zlib's lower bounds may be insufficient. 2315 // 2316 // TODO(akalin): Avoid the duplicate calculation with 2317 // GetSerializedLength(const SpdyHeaderBlock&). 2318 const int compressed_max_size = 2319 2 * deflateBound(compressor, uncompressed_len); 2320 2321 // TODO(phajdan.jr): Clean up after we no longer need 2322 // to workaround http://crbug.com/139744. 2323 #if defined(USE_SYSTEM_ZLIB) 2324 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data()); 2325 compressor->avail_in = uncompressed_len; 2326 #endif // defined(USE_SYSTEM_ZLIB) 2327 compressor->next_out = reinterpret_cast<Bytef*>( 2328 builder->GetWritableBuffer(compressed_max_size)); 2329 compressor->avail_out = compressed_max_size; 2330 2331 // TODO(phajdan.jr): Clean up after we no longer need 2332 // to workaround http://crbug.com/139744. 2333 #if defined(USE_SYSTEM_ZLIB) 2334 int rv = deflate(compressor, Z_SYNC_FLUSH); 2335 if (rv != Z_OK) { // How can we know that it compressed everything? 2336 // This shouldn't happen, right? 2337 LOG(WARNING) << "deflate failure: " << rv; 2338 // TODO(akalin): Upstream this return. 2339 return; 2340 } 2341 #else 2342 WriteHeaderBlockToZ(&frame.name_value_block(), compressor); 2343 #endif // defined(USE_SYSTEM_ZLIB) 2344 2345 int compressed_size = compressed_max_size - compressor->avail_out; 2346 builder->Seek(compressed_size); 2347 builder->RewriteLength(*this); 2348 2349 pre_compress_bytes.Add(uncompressed_len); 2350 post_compress_bytes.Add(compressed_size); 2351 2352 compressed_frames.Increment(); 2353 } 2354 2355 } // namespace net 2356