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