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