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