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