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