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