1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 6 // constantly adding and subtracting header sizes; this is ugly and error- 7 // prone. 8 9 #include "net/spdy/spdy_framer.h" 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/metrics/stats_counters.h" 13 #ifndef ANDROID 14 #include "base/third_party/valgrind/memcheck.h" 15 #endif 16 #include "net/spdy/spdy_frame_builder.h" 17 #include "net/spdy/spdy_bitmasks.h" 18 19 #if defined(USE_SYSTEM_ZLIB) 20 #include <zlib.h> 21 #else 22 #include "third_party/zlib/zlib.h" 23 #endif 24 25 namespace { 26 27 // The following compression setting are based on Brian Olson's analysis. See 28 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792 29 // for more details. 30 #ifdef ANDROID 31 const int kCompressorLevel = 0; 32 #else 33 const int kCompressorLevel = 9; 34 #endif 35 const int kCompressorWindowSizeInBits = 11; 36 const int kCompressorMemLevel = 1; 37 38 // Adler ID for the SPDY header compressor dictionary. 39 uLong dictionary_id = 0; 40 41 } // namespace 42 43 namespace spdy { 44 45 // This is just a hacked dictionary to use for shrinking HTTP-like headers. 46 // TODO(mbelshe): Use a scientific methodology for computing the dictionary. 47 const char SpdyFramer::kDictionary[] = 48 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" 49 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi" 50 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser" 51 "-agent10010120020120220320420520630030130230330430530630740040140240340440" 52 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta" 53 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic" 54 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran" 55 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati" 56 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo" 57 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe" 58 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic" 59 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1" 60 ".1statusversionurl"; 61 const int SpdyFramer::kDictionarySize = arraysize(kDictionary); 62 63 // By default is compression on or off. 64 bool SpdyFramer::compression_default_ = true; 65 int SpdyFramer::spdy_version_ = kSpdyProtocolVersion; 66 67 // The initial size of the control frame buffer; this is used internally 68 // as we parse through control frames. (It is exposed here for unit test 69 // purposes.) 70 size_t SpdyFramer::kControlFrameBufferInitialSize = 8 * 1024; 71 72 // The maximum size of the control frame buffer that we support. 73 // TODO(mbelshe): We should make this stream-based so there are no limits. 74 size_t SpdyFramer::kControlFrameBufferMaxSize = 16 * 1024; 75 76 const SpdyStreamId SpdyFramer::kInvalidStream = -1; 77 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 78 79 #ifdef DEBUG_SPDY_STATE_CHANGES 80 #define CHANGE_STATE(newstate) \ 81 { \ 82 do { \ 83 LOG(INFO) << "Changing state from: " \ 84 << StateToString(state_) \ 85 << " to " << StateToString(newstate) << "\n"; \ 86 state_ = newstate; \ 87 } while (false); \ 88 } 89 #else 90 #define CHANGE_STATE(newstate) (state_ = newstate) 91 #endif 92 93 int DecompressHeaderBlockInZStream(z_stream* decompressor) { 94 int rv = inflate(decompressor, Z_SYNC_FLUSH); 95 if (rv == Z_NEED_DICT) { 96 // Need to try again with the right dictionary. 97 if (decompressor->adler == dictionary_id) { 98 rv = inflateSetDictionary(decompressor, 99 (const Bytef*)SpdyFramer::kDictionary, 100 SpdyFramer::kDictionarySize); 101 if (rv == Z_OK) 102 rv = inflate(decompressor, Z_SYNC_FLUSH); 103 } 104 } 105 return rv; 106 } 107 108 // Retrieve serialized length of SpdyHeaderBlock. 109 size_t GetSerializedLength(const SpdyHeaderBlock* headers) { 110 size_t total_length = SpdyControlFrame::kNumNameValuePairsSize; 111 SpdyHeaderBlock::const_iterator it; 112 for (it = headers->begin(); it != headers->end(); ++it) { 113 // We add space for the length of the name and the length of the value as 114 // well as the length of the name and the length of the value. 115 total_length += SpdyControlFrame::kLengthOfNameSize + 116 it->first.size() + 117 SpdyControlFrame::kLengthOfValueSize + 118 it->second.size(); 119 } 120 return total_length; 121 } 122 123 // Serializes a SpdyHeaderBlock. 124 void WriteHeaderBlock(SpdyFrameBuilder* frame, const SpdyHeaderBlock* headers) { 125 frame->WriteUInt16(headers->size()); // Number of headers. 126 SpdyHeaderBlock::const_iterator it; 127 for (it = headers->begin(); it != headers->end(); ++it) { 128 bool wrote_header; 129 wrote_header = frame->WriteString(it->first); 130 wrote_header &= frame->WriteString(it->second); 131 DCHECK(wrote_header); 132 } 133 } 134 135 // Creates a FlagsAndLength. 136 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) { 137 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 138 FlagsAndLength flags_length; 139 flags_length.length_ = htonl(static_cast<uint32>(length)); 140 DCHECK_EQ(0, flags & ~kControlFlagsMask); 141 flags_length.flags_[0] = flags; 142 return flags_length; 143 } 144 145 SpdyFramer::SpdyFramer() 146 : state_(SPDY_RESET), 147 error_code_(SPDY_NO_ERROR), 148 remaining_data_(0), 149 remaining_control_payload_(0), 150 remaining_control_header_(0), 151 current_frame_buffer_(NULL), 152 current_frame_len_(0), 153 current_frame_capacity_(0), 154 validate_control_frame_sizes_(true), 155 enable_compression_(compression_default_), 156 visitor_(NULL) { 157 } 158 159 SpdyFramer::~SpdyFramer() { 160 if (header_compressor_.get()) { 161 deflateEnd(header_compressor_.get()); 162 } 163 if (header_decompressor_.get()) { 164 inflateEnd(header_decompressor_.get()); 165 } 166 CleanupStreamCompressorsAndDecompressors(); 167 delete [] current_frame_buffer_; 168 } 169 170 const char* SpdyFramer::StatusCodeToString(int status_code) { 171 switch (status_code) { 172 case INVALID: 173 return "INVALID"; 174 case PROTOCOL_ERROR: 175 return "PROTOCOL_ERROR"; 176 case INVALID_STREAM: 177 return "INVALID_STREAM"; 178 case REFUSED_STREAM: 179 return "REFUSED_STREAM"; 180 case UNSUPPORTED_VERSION: 181 return "UNSUPPORTED_VERSION"; 182 case CANCEL: 183 return "CANCEL"; 184 case INTERNAL_ERROR: 185 return "INTERNAL_ERROR"; 186 case FLOW_CONTROL_ERROR: 187 return "FLOW_CONTROL_ERROR"; 188 } 189 return "UNKNOWN_STATUS"; 190 } 191 192 const char* SpdyFramer::ControlTypeToString(SpdyControlType type) { 193 switch (type) { 194 case SYN_STREAM: 195 return "SYN_STREAM"; 196 case SYN_REPLY: 197 return "SYN_REPLY"; 198 case RST_STREAM: 199 return "RST_STREAM"; 200 case SETTINGS: 201 return "SETTINGS"; 202 case NOOP: 203 return "NOOP"; 204 case PING: 205 return "PING"; 206 case GOAWAY: 207 return "GOAWAY"; 208 case HEADERS: 209 return "HEADERS"; 210 case WINDOW_UPDATE: 211 return "WINDOW_UPDATE"; 212 case NUM_CONTROL_FRAME_TYPES: 213 break; 214 } 215 return "UNKNOWN_CONTROL_TYPE"; 216 } 217 218 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { 219 DCHECK(visitor_); 220 DCHECK(data); 221 222 size_t original_len = len; 223 while (len != 0) { 224 switch (state_) { 225 case SPDY_ERROR: 226 case SPDY_DONE: 227 goto bottom; 228 229 case SPDY_AUTO_RESET: 230 case SPDY_RESET: 231 Reset(); 232 CHANGE_STATE(SPDY_READING_COMMON_HEADER); 233 continue; 234 235 case SPDY_READING_COMMON_HEADER: { 236 size_t bytes_read = ProcessCommonHeader(data, len); 237 len -= bytes_read; 238 data += bytes_read; 239 continue; 240 } 241 242 // Arguably, this case is not necessary, as no bytes are consumed here. 243 // I felt it was a nice partitioning, however (which probably indicates 244 // that it should be refactored into its own function!) 245 // TODO(hkhalil): Remove -- while loop above prevents proper handling of 246 // zero-length control frames. 247 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: 248 ProcessControlFrameHeader(); 249 continue; 250 251 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: { 252 // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY, 253 // HEADERS) take a different path through the state machine - they 254 // will go: 255 // 1. SPDY_INTERPRET_CONTROL_FRAME_COMMON HEADER 256 // 2. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 257 // 3. SPDY_CONTROL_FRAME_HEADER_BLOCK 258 // 259 // All other control frames will use the alternate route: 260 // 1. SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER 261 // 2. SPDY_CONTROL_FRAME_PAYLOAD 262 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len); 263 len -= bytes_read; 264 data += bytes_read; 265 continue; 266 } 267 268 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { 269 int bytes_read = ProcessControlFrameHeaderBlock(data, len); 270 len -= bytes_read; 271 data += bytes_read; 272 continue; 273 } 274 275 case SPDY_CONTROL_FRAME_PAYLOAD: { 276 size_t bytes_read = ProcessControlFramePayload(data, len); 277 len -= bytes_read; 278 data += bytes_read; 279 } 280 // intentional fallthrough 281 case SPDY_IGNORE_REMAINING_PAYLOAD: 282 // control frame has too-large payload 283 // intentional fallthrough 284 case SPDY_FORWARD_STREAM_FRAME: { 285 size_t bytes_read = ProcessDataFramePayload(data, len); 286 len -= bytes_read; 287 data += bytes_read; 288 continue; 289 } 290 default: 291 break; 292 } 293 } 294 bottom: 295 return original_len - len; 296 } 297 298 void SpdyFramer::Reset() { 299 state_ = SPDY_RESET; 300 error_code_ = SPDY_NO_ERROR; 301 remaining_data_ = 0; 302 remaining_control_payload_ = 0; 303 remaining_control_header_ = 0; 304 current_frame_len_ = 0; 305 if (current_frame_capacity_ != kControlFrameBufferInitialSize) { 306 delete [] current_frame_buffer_; 307 current_frame_buffer_ = 0; 308 current_frame_capacity_ = 0; 309 ExpandControlFrameBuffer(kControlFrameBufferInitialSize); 310 } 311 } 312 313 bool SpdyFramer::ParseHeaderBlock(const SpdyFrame* frame, 314 SpdyHeaderBlock* block) { 315 SpdyControlFrame control_frame(frame->data(), false); 316 uint32 type = control_frame.type(); 317 if (type != SYN_STREAM && type != SYN_REPLY && type != HEADERS) 318 return false; 319 320 // Find the header data within the control frame. 321 scoped_ptr<SpdyFrame> decompressed_frame(DecompressFrame(*frame)); 322 if (!decompressed_frame.get()) 323 return false; 324 325 const char *header_data = NULL; 326 int header_length = 0; 327 328 switch (type) { 329 case SYN_STREAM: 330 { 331 SpdySynStreamControlFrame syn_frame(decompressed_frame->data(), false); 332 header_data = syn_frame.header_block(); 333 header_length = syn_frame.header_block_len(); 334 } 335 break; 336 case SYN_REPLY: 337 { 338 SpdySynReplyControlFrame syn_frame(decompressed_frame->data(), false); 339 header_data = syn_frame.header_block(); 340 header_length = syn_frame.header_block_len(); 341 } 342 break; 343 case HEADERS: 344 { 345 SpdyHeadersControlFrame header_frame(decompressed_frame->data(), false); 346 header_data = header_frame.header_block(); 347 header_length = header_frame.header_block_len(); 348 } 349 break; 350 } 351 352 SpdyFrameBuilder builder(header_data, header_length); 353 void* iter = NULL; 354 uint16 num_headers; 355 if (builder.ReadUInt16(&iter, &num_headers)) { 356 int index; 357 for (index = 0; index < num_headers; ++index) { 358 std::string name; 359 std::string value; 360 if (!builder.ReadString(&iter, &name)) 361 break; 362 if (!builder.ReadString(&iter, &value)) 363 break; 364 if (!name.size() || !value.size()) 365 return false; 366 if (block->find(name) == block->end()) { 367 (*block)[name] = value; 368 } else { 369 return false; 370 } 371 } 372 return index == num_headers && 373 iter == header_data + header_length; 374 } 375 return false; 376 } 377 378 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len, 379 size_t max_bytes) { 380 size_t bytes_to_read = std::min(*len, max_bytes); 381 DCHECK_GE(current_frame_capacity_, current_frame_len_ + bytes_to_read); 382 memcpy(¤t_frame_buffer_[current_frame_len_], *data, bytes_to_read); 383 current_frame_len_ += bytes_to_read; 384 *data += bytes_to_read; 385 *len -= bytes_to_read; 386 return bytes_to_read; 387 } 388 389 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, 390 size_t len) { 391 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_); 392 DCHECK_GT(remaining_control_header_, 0u); 393 size_t original_len = len; 394 395 if (remaining_control_header_) { 396 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, 397 remaining_control_header_); 398 remaining_control_header_ -= bytes_read; 399 if (remaining_control_header_ == 0) { 400 SpdyControlFrame control_frame(current_frame_buffer_, false); 401 DCHECK(control_frame.type() == SYN_STREAM || 402 control_frame.type() == SYN_REPLY || 403 control_frame.type() == HEADERS); 404 visitor_->OnControl(&control_frame); 405 406 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 407 } 408 } 409 return original_len - len; 410 } 411 412 // Does not buffer the control payload. Instead, either passes directly to the 413 // visitor or decompresses and then passes directly to the visitor, via 414 // IncrementallyDeliverControlFrameHeaderData() or 415 // IncrementallyDecompressControlFrameHeaderData() respectively. 416 size_t SpdyFramer::NewProcessControlFrameHeaderBlock(const char* data, 417 size_t data_len) { 418 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); 419 SpdyControlFrame control_frame(current_frame_buffer_, false); 420 bool processed_successfully = true; 421 DCHECK(control_frame.type() == SYN_STREAM || 422 control_frame.type() == SYN_REPLY || 423 control_frame.type() == HEADERS); 424 size_t process_bytes = std::min(data_len, remaining_control_payload_); 425 DCHECK_GT(process_bytes, 0u); 426 427 if (enable_compression_) { 428 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 429 &control_frame, data, process_bytes); 430 } else { 431 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 432 &control_frame, data, process_bytes); 433 } 434 remaining_control_payload_ -= process_bytes; 435 436 // Handle the case that there is no futher data in this frame. 437 if (remaining_control_payload_ == 0 && processed_successfully) { 438 // The complete header block has been delivered. We send a zero-length 439 // OnControlFrameHeaderData() to indicate this. 440 visitor_->OnControlFrameHeaderData( 441 GetControlFrameStreamId(&control_frame), NULL, 0); 442 443 // If this is a FIN, tell the caller. 444 if (control_frame.flags() & CONTROL_FLAG_FIN) { 445 visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame), 446 NULL, 0); 447 } 448 449 CHANGE_STATE(SPDY_RESET); 450 } 451 452 // Handle error. 453 if (!processed_successfully) { 454 return data_len; 455 } 456 457 // Return amount processed. 458 return process_bytes; 459 } 460 461 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, 462 size_t data_len) { 463 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); 464 size_t original_data_len = data_len; 465 SpdyControlFrame control_frame(current_frame_buffer_, false); 466 bool read_successfully = true; 467 DCHECK(control_frame.type() == SYN_STREAM || 468 control_frame.type() == SYN_REPLY || 469 control_frame.type() == HEADERS); 470 471 if (enable_compression_) { 472 // Note that the header block is held in the frame's payload, and is not 473 // part of the frame's headers. 474 if (remaining_control_payload_ > 0) { 475 size_t bytes_read = UpdateCurrentFrameBuffer( 476 &data, 477 &data_len, 478 remaining_control_payload_); 479 remaining_control_payload_ -= bytes_read; 480 if (remaining_control_payload_ == 0) { 481 read_successfully = IncrementallyDecompressControlFrameHeaderData( 482 &control_frame); 483 } 484 } 485 } else { 486 size_t bytes_to_send = std::min(data_len, remaining_control_payload_); 487 DCHECK_GT(bytes_to_send, 0u); 488 read_successfully = IncrementallyDeliverControlFrameHeaderData( 489 &control_frame, data, bytes_to_send); 490 data_len -= bytes_to_send; 491 remaining_control_payload_ -= bytes_to_send; 492 } 493 if (remaining_control_payload_ == 0 && read_successfully) { 494 // The complete header block has been delivered. 495 visitor_->OnControlFrameHeaderData(GetControlFrameStreamId(&control_frame), 496 NULL, 0); 497 498 // If this is a FIN, tell the caller. 499 if (control_frame.flags() & CONTROL_FLAG_FIN) { 500 visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame), 501 NULL, 0); 502 } 503 504 CHANGE_STATE(SPDY_RESET); 505 } 506 if (!read_successfully) { 507 return original_data_len; 508 } 509 return original_data_len - data_len; 510 } 511 512 /* static */ 513 bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 514 size_t header_length, 515 SpdyHeaderBlock* block) { 516 SpdyFrameBuilder builder(header_data, header_length); 517 void* iter = NULL; 518 uint16 num_headers; 519 if (builder.ReadUInt16(&iter, &num_headers)) { 520 for (int index = 0; index < num_headers; ++index) { 521 std::string name; 522 std::string value; 523 if (!builder.ReadString(&iter, &name)) 524 return false; 525 if (!builder.ReadString(&iter, &value)) 526 return false; 527 if (block->find(name) == block->end()) { 528 (*block)[name] = value; 529 } else { 530 return false; 531 } 532 } 533 return true; 534 } 535 return false; 536 } 537 538 SpdySynStreamControlFrame* SpdyFramer::CreateSynStream( 539 SpdyStreamId stream_id, SpdyStreamId associated_stream_id, int priority, 540 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { 541 SpdyFrameBuilder frame; 542 543 DCHECK_GT(stream_id, static_cast<SpdyStreamId>(0)); 544 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 545 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); 546 547 frame.WriteUInt16(kControlFlagMask | spdy_version_); 548 frame.WriteUInt16(SYN_STREAM); 549 frame.WriteUInt32(0); // Placeholder for the length and flags 550 frame.WriteUInt32(stream_id); 551 frame.WriteUInt32(associated_stream_id); 552 frame.WriteUInt16(ntohs(priority) << 6); // Priority. 553 554 frame.WriteUInt16(headers->size()); // Number of headers. 555 SpdyHeaderBlock::const_iterator it; 556 for (it = headers->begin(); it != headers->end(); ++it) { 557 bool wrote_header; 558 wrote_header = frame.WriteString(it->first); 559 wrote_header &= frame.WriteString(it->second); 560 DCHECK(wrote_header); 561 } 562 563 // Write the length and flags. 564 size_t length = frame.length() - SpdyFrame::size(); 565 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 566 FlagsAndLength flags_length; 567 flags_length.length_ = htonl(static_cast<uint32>(length)); 568 DCHECK_EQ(0, flags & ~kControlFlagsMask); 569 flags_length.flags_[0] = flags; 570 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length)); 571 572 scoped_ptr<SpdySynStreamControlFrame> syn_frame( 573 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take())); 574 if (compressed) { 575 return reinterpret_cast<SpdySynStreamControlFrame*>( 576 CompressControlFrame(*syn_frame.get())); 577 } 578 return syn_frame.release(); 579 } 580 581 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(SpdyStreamId stream_id, 582 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { 583 DCHECK_GT(stream_id, 0u); 584 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 585 586 SpdyFrameBuilder frame; 587 588 frame.WriteUInt16(kControlFlagMask | spdy_version_); 589 frame.WriteUInt16(SYN_REPLY); 590 frame.WriteUInt32(0); // Placeholder for the length and flags. 591 frame.WriteUInt32(stream_id); 592 frame.WriteUInt16(0); // Unused 593 594 frame.WriteUInt16(headers->size()); // Number of headers. 595 SpdyHeaderBlock::const_iterator it; 596 for (it = headers->begin(); it != headers->end(); ++it) { 597 bool wrote_header; 598 wrote_header = frame.WriteString(it->first); 599 wrote_header &= frame.WriteString(it->second); 600 DCHECK(wrote_header); 601 } 602 603 // Write the length and flags. 604 size_t length = frame.length() - SpdyFrame::size(); 605 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 606 FlagsAndLength flags_length; 607 flags_length.length_ = htonl(static_cast<uint32>(length)); 608 DCHECK_EQ(0, flags & ~kControlFlagsMask); 609 flags_length.flags_[0] = flags; 610 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length)); 611 612 scoped_ptr<SpdySynReplyControlFrame> reply_frame( 613 reinterpret_cast<SpdySynReplyControlFrame*>(frame.take())); 614 if (compressed) { 615 return reinterpret_cast<SpdySynReplyControlFrame*>( 616 CompressControlFrame(*reply_frame.get())); 617 } 618 return reply_frame.release(); 619 } 620 621 /* static */ 622 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(SpdyStreamId stream_id, 623 SpdyStatusCodes status) { 624 DCHECK_GT(stream_id, 0u); 625 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 626 DCHECK_NE(status, INVALID); 627 DCHECK_LT(status, NUM_STATUS_CODES); 628 629 SpdyFrameBuilder frame; 630 frame.WriteUInt16(kControlFlagMask | spdy_version_); 631 frame.WriteUInt16(RST_STREAM); 632 frame.WriteUInt32(8); 633 frame.WriteUInt32(stream_id); 634 frame.WriteUInt32(status); 635 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); 636 } 637 638 /* static */ 639 SpdySettingsControlFrame* SpdyFramer::CreateSettings( 640 const SpdySettings& values) { 641 SpdyFrameBuilder frame; 642 frame.WriteUInt16(kControlFlagMask | spdy_version_); 643 frame.WriteUInt16(SETTINGS); 644 size_t settings_size = SpdySettingsControlFrame::size() - SpdyFrame::size() + 645 8 * values.size(); 646 frame.WriteUInt32(settings_size); 647 frame.WriteUInt32(values.size()); 648 SpdySettings::const_iterator it = values.begin(); 649 while (it != values.end()) { 650 frame.WriteUInt32(it->first.id_); 651 frame.WriteUInt32(it->second); 652 ++it; 653 } 654 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); 655 } 656 657 /* static */ 658 SpdyNoOpControlFrame* SpdyFramer::CreateNopFrame() { 659 SpdyFrameBuilder frame; 660 frame.WriteUInt16(kControlFlagMask | spdy_version_); 661 frame.WriteUInt16(NOOP); 662 frame.WriteUInt32(0); 663 return reinterpret_cast<SpdyNoOpControlFrame*>(frame.take()); 664 } 665 666 /* static */ 667 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) { 668 SpdyFrameBuilder frame; 669 frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion); 670 frame.WriteUInt16(PING); 671 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::size(); 672 frame.WriteUInt32(ping_size); 673 frame.WriteUInt32(unique_id); 674 return reinterpret_cast<SpdyPingControlFrame*>(frame.take()); 675 } 676 677 /* static */ 678 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( 679 SpdyStreamId last_accepted_stream_id) { 680 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); 681 682 SpdyFrameBuilder frame; 683 frame.WriteUInt16(kControlFlagMask | spdy_version_); 684 frame.WriteUInt16(GOAWAY); 685 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::size(); 686 frame.WriteUInt32(go_away_size); 687 frame.WriteUInt32(last_accepted_stream_id); 688 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); 689 } 690 691 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(SpdyStreamId stream_id, 692 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { 693 // Basically the same as CreateSynReply(). 694 DCHECK_GT(stream_id, 0u); 695 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 696 697 SpdyFrameBuilder frame; 698 frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion); 699 frame.WriteUInt16(HEADERS); 700 frame.WriteUInt32(0); // Placeholder for the length and flags. 701 frame.WriteUInt32(stream_id); 702 frame.WriteUInt16(0); // Unused 703 704 frame.WriteUInt16(headers->size()); // Number of headers. 705 SpdyHeaderBlock::const_iterator it; 706 for (it = headers->begin(); it != headers->end(); ++it) { 707 bool wrote_header; 708 wrote_header = frame.WriteString(it->first); 709 wrote_header &= frame.WriteString(it->second); 710 DCHECK(wrote_header); 711 } 712 713 // Write the length and flags. 714 size_t length = frame.length() - SpdyFrame::size(); 715 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 716 FlagsAndLength flags_length; 717 flags_length.length_ = htonl(static_cast<uint32>(length)); 718 DCHECK_EQ(0, flags & ~kControlFlagsMask); 719 flags_length.flags_[0] = flags; 720 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length)); 721 722 scoped_ptr<SpdyHeadersControlFrame> headers_frame( 723 reinterpret_cast<SpdyHeadersControlFrame*>(frame.take())); 724 if (compressed) { 725 return reinterpret_cast<SpdyHeadersControlFrame*>( 726 CompressControlFrame(*headers_frame.get())); 727 } 728 return headers_frame.release(); 729 } 730 731 /* static */ 732 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( 733 SpdyStreamId stream_id, 734 uint32 delta_window_size) { 735 DCHECK_GT(stream_id, 0u); 736 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 737 DCHECK_GT(delta_window_size, 0u); 738 DCHECK_LE(delta_window_size, spdy::kSpdyStreamMaximumWindowSize); 739 740 SpdyFrameBuilder frame; 741 frame.WriteUInt16(kControlFlagMask | spdy_version_); 742 frame.WriteUInt16(WINDOW_UPDATE); 743 size_t window_update_size = SpdyWindowUpdateControlFrame::size() - 744 SpdyFrame::size(); 745 frame.WriteUInt32(window_update_size); 746 frame.WriteUInt32(stream_id); 747 frame.WriteUInt32(delta_window_size); 748 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); 749 } 750 751 /* static */ 752 bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame, 753 SpdySettings* settings) { 754 DCHECK_EQ(frame->type(), SETTINGS); 755 DCHECK(settings); 756 757 SpdyFrameBuilder parser(frame->header_block(), frame->header_block_len()); 758 void* iter = NULL; 759 for (size_t index = 0; index < frame->num_entries(); ++index) { 760 uint32 id; 761 uint32 value; 762 if (!parser.ReadUInt32(&iter, &id)) 763 return false; 764 if (!parser.ReadUInt32(&iter, &value)) 765 return false; 766 settings->insert(settings->end(), std::make_pair(id, value)); 767 } 768 return true; 769 } 770 771 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, 772 const char* data, 773 uint32 len, SpdyDataFlags flags) { 774 SpdyFrameBuilder frame; 775 776 DCHECK_GT(stream_id, 0u); 777 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 778 frame.WriteUInt32(stream_id); 779 780 DCHECK_EQ(0u, len & ~static_cast<size_t>(kLengthMask)); 781 FlagsAndLength flags_length; 782 flags_length.length_ = htonl(len); 783 DCHECK_EQ(0, flags & ~kDataFlagsMask); 784 flags_length.flags_[0] = flags; 785 frame.WriteBytes(&flags_length, sizeof(flags_length)); 786 787 frame.WriteBytes(data, len); 788 scoped_ptr<SpdyFrame> data_frame(frame.take()); 789 SpdyDataFrame* rv; 790 if (flags & DATA_FLAG_COMPRESSED) { 791 rv = reinterpret_cast<SpdyDataFrame*>(CompressFrame(*data_frame.get())); 792 } else { 793 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release()); 794 } 795 796 if (flags & DATA_FLAG_FIN) { 797 CleanupCompressorForStream(stream_id); 798 } 799 800 return rv; 801 } 802 803 SpdyFrame* SpdyFramer::CompressFrame(const SpdyFrame& frame) { 804 if (frame.is_control_frame()) { 805 return CompressControlFrame( 806 reinterpret_cast<const SpdyControlFrame&>(frame)); 807 } 808 return CompressDataFrame(reinterpret_cast<const SpdyDataFrame&>(frame)); 809 } 810 811 SpdyFrame* SpdyFramer::DecompressFrame(const SpdyFrame& frame) { 812 if (frame.is_control_frame()) { 813 return DecompressControlFrame( 814 reinterpret_cast<const SpdyControlFrame&>(frame)); 815 } 816 return DecompressDataFrame(reinterpret_cast<const SpdyDataFrame&>(frame)); 817 } 818 819 SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame& frame) { 820 int size = SpdyFrame::size() + frame.length(); 821 SpdyFrame* new_frame = new SpdyFrame(size); 822 memcpy(new_frame->data(), frame.data(), size); 823 return new_frame; 824 } 825 826 bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const { 827 // The important frames to compress are those which contain large 828 // amounts of compressible data - namely the headers in the SYN_STREAM 829 // and SYN_REPLY. 830 // TODO(mbelshe): Reconcile this with the spec when the spec is 831 // explicit about which frames compress and which do not. 832 if (frame.is_control_frame()) { 833 const SpdyControlFrame& control_frame = 834 reinterpret_cast<const SpdyControlFrame&>(frame); 835 return control_frame.type() == SYN_STREAM || 836 control_frame.type() == SYN_REPLY; 837 } 838 839 const SpdyDataFrame& data_frame = 840 reinterpret_cast<const SpdyDataFrame&>(frame); 841 return (data_frame.flags() & DATA_FLAG_COMPRESSED) != 0; 842 } 843 844 const char* SpdyFramer::StateToString(int state) { 845 switch (state) { 846 case SPDY_ERROR: 847 return "ERROR"; 848 case SPDY_DONE: 849 return "DONE"; 850 case SPDY_AUTO_RESET: 851 return "AUTO_RESET"; 852 case SPDY_RESET: 853 return "RESET"; 854 case SPDY_READING_COMMON_HEADER: 855 return "READING_COMMON_HEADER"; 856 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: 857 return "INTERPRET_CONTROL_FRAME_COMMON_HEADER"; 858 case SPDY_CONTROL_FRAME_PAYLOAD: 859 return "CONTROL_FRAME_PAYLOAD"; 860 case SPDY_IGNORE_REMAINING_PAYLOAD: 861 return "IGNORE_REMAINING_PAYLOAD"; 862 case SPDY_FORWARD_STREAM_FRAME: 863 return "FORWARD_STREAM_FRAME"; 864 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 865 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 866 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 867 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 868 } 869 return "UNKNOWN_STATE"; 870 } 871 872 const char* SpdyFramer::ErrorCodeToString(int error_code) { 873 switch (error_code) { 874 case SPDY_NO_ERROR: 875 return "NO_ERROR"; 876 case SPDY_INVALID_CONTROL_FRAME: 877 return "INVALID_CONTROL_FRAME"; 878 case SPDY_CONTROL_PAYLOAD_TOO_LARGE: 879 return "CONTROL_PAYLOAD_TOO_LARGE"; 880 case SPDY_ZLIB_INIT_FAILURE: 881 return "ZLIB_INIT_FAILURE"; 882 case SPDY_UNSUPPORTED_VERSION: 883 return "UNSUPPORTED_VERSION"; 884 case SPDY_DECOMPRESS_FAILURE: 885 return "DECOMPRESS_FAILURE"; 886 case SPDY_COMPRESS_FAILURE: 887 return "COMPRESS_FAILURE"; 888 } 889 return "UNKNOWN_ERROR"; 890 } 891 892 void SpdyFramer::set_enable_compression(bool value) { 893 enable_compression_ = value; 894 } 895 896 void SpdyFramer::set_enable_compression_default(bool value) { 897 compression_default_ = value; 898 } 899 900 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { 901 // This should only be called when we're in the SPDY_READING_COMMON_HEADER 902 // state. 903 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); 904 905 size_t original_len = len; 906 SpdyFrame current_frame(current_frame_buffer_, false); 907 908 do { 909 if (current_frame_len_ < SpdyFrame::size()) { 910 size_t bytes_desired = SpdyFrame::size() - current_frame_len_; 911 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); 912 // Check for an empty data frame. 913 if (current_frame_len_ == SpdyFrame::size() && 914 !current_frame.is_control_frame() && 915 current_frame.length() == 0) { 916 if (current_frame.flags() & CONTROL_FLAG_FIN) { 917 SpdyDataFrame data_frame(current_frame_buffer_, false); 918 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0); 919 } 920 CHANGE_STATE(SPDY_AUTO_RESET); 921 } 922 break; 923 } 924 remaining_data_ = current_frame.length(); 925 926 // This is just a sanity check for help debugging early frame errors. 927 if (remaining_data_ > 1000000u) { 928 LOG(WARNING) << 929 "Unexpectedly large frame. Spdy session is likely corrupt."; 930 } 931 932 // if we're here, then we have the common header all received. 933 if (!current_frame.is_control_frame()) 934 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 935 else 936 CHANGE_STATE(SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER); 937 } while (false); 938 939 return original_len - len; 940 } 941 942 void SpdyFramer::ProcessControlFrameHeader() { 943 DCHECK_EQ(SPDY_NO_ERROR, error_code_); 944 DCHECK_LE(SpdyFrame::size(), current_frame_len_); 945 SpdyControlFrame current_control_frame(current_frame_buffer_, false); 946 947 // We check version before we check validity: version can never be 'invalid', 948 // it can only be unsupported. 949 if (current_control_frame.version() != spdy_version_) { 950 set_error(SPDY_UNSUPPORTED_VERSION); 951 return; 952 } 953 954 // Next up, check to see if we have valid data. This should be after version 955 // checking (otherwise if the the type were out of bounds due to a version 956 // upgrade we would misclassify the error) and before checking the type 957 // (type can definitely be out of bounds) 958 if (!current_control_frame.AppearsToBeAValidControlFrame()) { 959 set_error(SPDY_INVALID_CONTROL_FRAME); 960 return; 961 } 962 963 // Do some sanity checking on the control frame sizes. 964 switch (current_control_frame.type()) { 965 case SYN_STREAM: 966 if (current_control_frame.length() < 967 SpdySynStreamControlFrame::size() - SpdyControlFrame::size()) 968 set_error(SPDY_INVALID_CONTROL_FRAME); 969 break; 970 case SYN_REPLY: 971 if (current_control_frame.length() < 972 SpdySynReplyControlFrame::size() - SpdyControlFrame::size()) 973 set_error(SPDY_INVALID_CONTROL_FRAME); 974 break; 975 case RST_STREAM: 976 if (current_control_frame.length() != 977 SpdyRstStreamControlFrame::size() - SpdyFrame::size()) 978 set_error(SPDY_INVALID_CONTROL_FRAME); 979 break; 980 case SETTINGS: 981 if (current_control_frame.length() < 982 SpdySettingsControlFrame::size() - SpdyControlFrame::size()) 983 set_error(SPDY_INVALID_CONTROL_FRAME); 984 break; 985 // TODO(hkhalil): Remove NOOP. 986 case NOOP: 987 // NOOP. Swallow it. 988 DLOG(INFO) << "Attempted frame size validation for NOOP. Resetting."; 989 CHANGE_STATE(SPDY_AUTO_RESET); 990 return; 991 case GOAWAY: 992 if (current_control_frame.length() != 993 SpdyGoAwayControlFrame::size() - SpdyFrame::size()) 994 set_error(SPDY_INVALID_CONTROL_FRAME); 995 break; 996 case HEADERS: 997 if (current_control_frame.length() < 998 SpdyHeadersControlFrame::size() - SpdyControlFrame::size()) 999 set_error(SPDY_INVALID_CONTROL_FRAME); 1000 break; 1001 case WINDOW_UPDATE: 1002 if (current_control_frame.length() != 1003 SpdyWindowUpdateControlFrame::size() - SpdyControlFrame::size()) 1004 set_error(SPDY_INVALID_CONTROL_FRAME); 1005 break; 1006 case PING: 1007 if (current_control_frame.length() != 1008 SpdyPingControlFrame::size() - SpdyControlFrame::size()) 1009 set_error(SPDY_INVALID_CONTROL_FRAME); 1010 break; 1011 default: 1012 LOG(WARNING) << "Valid spdy control frame with unhandled type: " 1013 << current_control_frame.type(); 1014 DCHECK(false); 1015 set_error(SPDY_INVALID_CONTROL_FRAME); 1016 break; 1017 } 1018 1019 remaining_control_payload_ = current_control_frame.length(); 1020 if (remaining_control_payload_ > kControlFrameBufferMaxSize) { 1021 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1022 return; 1023 } 1024 1025 ExpandControlFrameBuffer(remaining_control_payload_); 1026 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); 1027 } 1028 1029 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { 1030 size_t original_len = len; 1031 do { 1032 if (remaining_control_payload_) { 1033 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, 1034 remaining_control_payload_); 1035 remaining_control_payload_ -= bytes_read; 1036 remaining_data_ -= bytes_read; 1037 if (remaining_control_payload_) 1038 break; 1039 } 1040 SpdyControlFrame control_frame(current_frame_buffer_, false); 1041 visitor_->OnControl(&control_frame); 1042 1043 // If this is a FIN, tell the caller. 1044 if (control_frame.type() == SYN_REPLY && 1045 control_frame.flags() & CONTROL_FLAG_FIN) { 1046 visitor_->OnStreamFrameData(reinterpret_cast<SpdySynReplyControlFrame*>( 1047 &control_frame)->stream_id(), 1048 NULL, 0); 1049 } 1050 1051 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 1052 } while (false); 1053 return original_len - len; 1054 } 1055 1056 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 1057 size_t original_len = len; 1058 1059 SpdyDataFrame current_data_frame(current_frame_buffer_, false); 1060 if (remaining_data_) { 1061 size_t amount_to_forward = std::min(remaining_data_, len); 1062 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { 1063 if (current_data_frame.flags() & DATA_FLAG_COMPRESSED) { 1064 z_stream* decompressor = 1065 GetStreamDecompressor(current_data_frame.stream_id()); 1066 if (!decompressor) 1067 return 0; 1068 1069 size_t decompressed_max_size = amount_to_forward * 100; 1070 scoped_array<char> decompressed(new char[decompressed_max_size]); 1071 decompressor->next_in = reinterpret_cast<Bytef*>( 1072 const_cast<char*>(data)); 1073 decompressor->avail_in = amount_to_forward; 1074 decompressor->next_out = 1075 reinterpret_cast<Bytef*>(decompressed.get()); 1076 decompressor->avail_out = decompressed_max_size; 1077 1078 int rv = inflate(decompressor, Z_SYNC_FLUSH); 1079 if (rv != Z_OK) { 1080 LOG(WARNING) << "inflate failure: " << rv; 1081 set_error(SPDY_DECOMPRESS_FAILURE); 1082 return 0; 1083 } 1084 size_t decompressed_size = decompressed_max_size - 1085 decompressor->avail_out; 1086 1087 // Only inform the visitor if there is data. 1088 if (decompressed_size) 1089 visitor_->OnStreamFrameData(current_data_frame.stream_id(), 1090 decompressed.get(), 1091 decompressed_size); 1092 amount_to_forward -= decompressor->avail_in; 1093 } else { 1094 // The data frame was not compressed. 1095 // Only inform the visitor if there is data. 1096 if (amount_to_forward) 1097 visitor_->OnStreamFrameData(current_data_frame.stream_id(), 1098 data, amount_to_forward); 1099 } 1100 } 1101 data += amount_to_forward; 1102 len -= amount_to_forward; 1103 remaining_data_ -= amount_to_forward; 1104 1105 // If the FIN flag is set, and there is no more data in this data 1106 // frame, inform the visitor of EOF via a 0-length data frame. 1107 if (!remaining_data_ && 1108 current_data_frame.flags() & DATA_FLAG_FIN) { 1109 visitor_->OnStreamFrameData(current_data_frame.stream_id(), NULL, 0); 1110 CleanupDecompressorForStream(current_data_frame.stream_id()); 1111 } 1112 } else { 1113 CHANGE_STATE(SPDY_AUTO_RESET); 1114 } 1115 return original_len - len; 1116 } 1117 1118 z_stream* SpdyFramer::GetHeaderCompressor() { 1119 if (header_compressor_.get()) 1120 return header_compressor_.get(); // Already initialized. 1121 1122 header_compressor_.reset(new z_stream); 1123 memset(header_compressor_.get(), 0, sizeof(z_stream)); 1124 1125 int success = deflateInit2(header_compressor_.get(), 1126 kCompressorLevel, 1127 Z_DEFLATED, 1128 kCompressorWindowSizeInBits, 1129 kCompressorMemLevel, 1130 Z_DEFAULT_STRATEGY); 1131 if (success == Z_OK) 1132 success = deflateSetDictionary(header_compressor_.get(), 1133 reinterpret_cast<const Bytef*>(kDictionary), 1134 kDictionarySize); 1135 if (success != Z_OK) { 1136 LOG(WARNING) << "deflateSetDictionary failure: " << success; 1137 header_compressor_.reset(NULL); 1138 return NULL; 1139 } 1140 return header_compressor_.get(); 1141 } 1142 1143 z_stream* SpdyFramer::GetHeaderDecompressor() { 1144 if (header_decompressor_.get()) 1145 return header_decompressor_.get(); // Already initialized. 1146 1147 header_decompressor_.reset(new z_stream); 1148 memset(header_decompressor_.get(), 0, sizeof(z_stream)); 1149 1150 // Compute the id of our dictionary so that we know we're using the 1151 // right one when asked for it. 1152 if (dictionary_id == 0) { 1153 dictionary_id = adler32(0L, Z_NULL, 0); 1154 dictionary_id = adler32(dictionary_id, 1155 reinterpret_cast<const Bytef*>(kDictionary), 1156 kDictionarySize); 1157 } 1158 1159 int success = inflateInit(header_decompressor_.get()); 1160 if (success != Z_OK) { 1161 LOG(WARNING) << "inflateInit failure: " << success; 1162 header_decompressor_.reset(NULL); 1163 return NULL; 1164 } 1165 return header_decompressor_.get(); 1166 } 1167 1168 z_stream* SpdyFramer::GetStreamCompressor(SpdyStreamId stream_id) { 1169 CompressorMap::iterator it = stream_compressors_.find(stream_id); 1170 if (it != stream_compressors_.end()) 1171 return it->second; // Already initialized. 1172 1173 scoped_ptr<z_stream> compressor(new z_stream); 1174 memset(compressor.get(), 0, sizeof(z_stream)); 1175 1176 int success = deflateInit2(compressor.get(), 1177 kCompressorLevel, 1178 Z_DEFLATED, 1179 kCompressorWindowSizeInBits, 1180 kCompressorMemLevel, 1181 Z_DEFAULT_STRATEGY); 1182 if (success != Z_OK) { 1183 LOG(WARNING) << "deflateInit failure: " << success; 1184 return NULL; 1185 } 1186 return stream_compressors_[stream_id] = compressor.release(); 1187 } 1188 1189 z_stream* SpdyFramer::GetStreamDecompressor(SpdyStreamId stream_id) { 1190 CompressorMap::iterator it = stream_decompressors_.find(stream_id); 1191 if (it != stream_decompressors_.end()) 1192 return it->second; // Already initialized. 1193 1194 scoped_ptr<z_stream> decompressor(new z_stream); 1195 memset(decompressor.get(), 0, sizeof(z_stream)); 1196 1197 int success = inflateInit(decompressor.get()); 1198 if (success != Z_OK) { 1199 LOG(WARNING) << "inflateInit failure: " << success; 1200 return NULL; 1201 } 1202 return stream_decompressors_[stream_id] = decompressor.release(); 1203 } 1204 1205 SpdyControlFrame* SpdyFramer::CompressControlFrame( 1206 const SpdyControlFrame& frame) { 1207 z_stream* compressor = GetHeaderCompressor(); 1208 if (!compressor) 1209 return NULL; 1210 return reinterpret_cast<SpdyControlFrame*>( 1211 CompressFrameWithZStream(frame, compressor)); 1212 } 1213 1214 SpdyDataFrame* SpdyFramer::CompressDataFrame(const SpdyDataFrame& frame) { 1215 z_stream* compressor = GetStreamCompressor(frame.stream_id()); 1216 if (!compressor) 1217 return NULL; 1218 return reinterpret_cast<SpdyDataFrame*>( 1219 CompressFrameWithZStream(frame, compressor)); 1220 } 1221 1222 SpdyControlFrame* SpdyFramer::DecompressControlFrame( 1223 const SpdyControlFrame& frame) { 1224 z_stream* decompressor = GetHeaderDecompressor(); 1225 if (!decompressor) 1226 return NULL; 1227 return reinterpret_cast<SpdyControlFrame*>( 1228 DecompressFrameWithZStream(frame, decompressor)); 1229 } 1230 1231 // Incrementally decompress the control frame's header block, feeding the 1232 // result to the visitor in chunks. Continue this until the visitor 1233 // indicates that it cannot process any more data, or (more commonly) we 1234 // run out of data to deliver. 1235 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 1236 const SpdyControlFrame* control_frame) { 1237 z_stream* decomp = GetHeaderDecompressor(); 1238 int payload_length; 1239 int header_length; 1240 const char* payload; 1241 bool read_successfully = true; 1242 bool more = true; 1243 char buffer[kHeaderDataChunkMaxSize]; 1244 1245 if (!GetFrameBoundaries( 1246 *control_frame, &payload_length, &header_length, &payload)) { 1247 DLOG(ERROR) << "Control frame of type " 1248 << SpdyFramer::ControlTypeToString(control_frame->type()) 1249 <<" doesn't have headers"; 1250 return false; 1251 } 1252 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); 1253 decomp->avail_in = payload_length; 1254 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); 1255 DCHECK_LT(0u, stream_id); 1256 while (more && read_successfully) { 1257 decomp->next_out = reinterpret_cast<Bytef*>(buffer); 1258 decomp->avail_out = arraysize(buffer); 1259 int rv = DecompressHeaderBlockInZStream(decomp); 1260 if (rv != Z_OK) { 1261 set_error(SPDY_DECOMPRESS_FAILURE); 1262 DLOG(WARNING) << "inflate failure: " << rv; 1263 more = read_successfully = false; 1264 } else { 1265 DCHECK_GT(arraysize(buffer), decomp->avail_out); 1266 size_t len = arraysize(buffer) - decomp->avail_out; 1267 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, buffer, 1268 len); 1269 if (!read_successfully) { 1270 // Assume that the problem was the header block was too large for the 1271 // visitor. 1272 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1273 } 1274 more = decomp->avail_in > 0; 1275 } 1276 } 1277 return read_successfully; 1278 } 1279 1280 // Incrementally decompress the control frame's header block, feeding the 1281 // result to the visitor in chunks. Continue this until the visitor 1282 // indicates that it cannot process any more data, or (more commonly) we 1283 // run out of data to deliver. 1284 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 1285 const SpdyControlFrame* control_frame, 1286 const char* data, 1287 size_t len) { 1288 // Get a decompressor or set error. 1289 z_stream* decomp = GetHeaderDecompressor(); 1290 if (decomp == NULL) { 1291 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; 1292 set_error(SPDY_DECOMPRESS_FAILURE); 1293 return false; 1294 } 1295 1296 bool processed_successfully = true; 1297 char buffer[kHeaderDataChunkMaxSize]; 1298 1299 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data)); 1300 decomp->avail_in = len; 1301 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); 1302 DCHECK_LT(0u, stream_id); 1303 while (decomp->avail_in > 0 && processed_successfully) { 1304 decomp->next_out = reinterpret_cast<Bytef*>(buffer); 1305 decomp->avail_out = arraysize(buffer); 1306 int rv = DecompressHeaderBlockInZStream(decomp); 1307 if (rv != Z_OK) { 1308 set_error(SPDY_DECOMPRESS_FAILURE); 1309 DLOG(WARNING) << "inflate failure: " << rv; 1310 processed_successfully = false; 1311 } else { 1312 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; 1313 if (decompressed_len > 0) { 1314 processed_successfully = visitor_->OnControlFrameHeaderData( 1315 stream_id, buffer, decompressed_len); 1316 } 1317 if (!processed_successfully) { 1318 // Assume that the problem was the header block was too large for the 1319 // visitor. 1320 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1321 } 1322 } 1323 } 1324 return processed_successfully; 1325 } 1326 1327 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( 1328 const SpdyControlFrame* control_frame, const char* data, size_t len) { 1329 bool read_successfully = true; 1330 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); 1331 DCHECK_LT(0u, stream_id); 1332 while (read_successfully && len > 0) { 1333 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); 1334 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, 1335 bytes_to_deliver); 1336 data += bytes_to_deliver; 1337 len -= bytes_to_deliver; 1338 if (!read_successfully) { 1339 // Assume that the problem was the header block was too large for the 1340 // visitor. 1341 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1342 } 1343 } 1344 return read_successfully; 1345 } 1346 1347 size_t SpdyFramer::GetMinimumControlFrameSize(SpdyControlType type) { 1348 switch (type) { 1349 case SYN_STREAM: 1350 return SpdySynStreamControlFrame::size(); 1351 case SYN_REPLY: 1352 return SpdySynReplyControlFrame::size(); 1353 case RST_STREAM: 1354 return SpdyRstStreamControlFrame::size(); 1355 case SETTINGS: 1356 return SpdySettingsControlFrame::size(); 1357 case NOOP: 1358 return SpdyNoOpControlFrame::size(); 1359 case PING: 1360 return SpdyPingControlFrame::size(); 1361 case GOAWAY: 1362 return SpdyGoAwayControlFrame::size(); 1363 case HEADERS: 1364 return SpdyHeadersControlFrame::size(); 1365 case WINDOW_UPDATE: 1366 return SpdyWindowUpdateControlFrame::size(); 1367 case NUM_CONTROL_FRAME_TYPES: 1368 break; 1369 } 1370 LOG(ERROR) << "Unknown SPDY control frame type " << type; 1371 return 0x7FFFFFFF; // Max signed 32bit int 1372 } 1373 1374 /* static */ 1375 SpdyStreamId SpdyFramer::GetControlFrameStreamId( 1376 const SpdyControlFrame* control_frame) { 1377 SpdyStreamId stream_id = kInvalidStream; 1378 if (control_frame != NULL) { 1379 switch (control_frame->type()) { 1380 case SYN_STREAM: 1381 stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>( 1382 control_frame)->stream_id(); 1383 break; 1384 case SYN_REPLY: 1385 stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>( 1386 control_frame)->stream_id(); 1387 break; 1388 case HEADERS: 1389 stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>( 1390 control_frame)->stream_id(); 1391 break; 1392 case RST_STREAM: 1393 stream_id = reinterpret_cast<const SpdyRstStreamControlFrame*>( 1394 control_frame)->stream_id(); 1395 break; 1396 case WINDOW_UPDATE: 1397 stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame*>( 1398 control_frame)->stream_id(); 1399 break; 1400 // All of the following types are not part of a particular stream. 1401 // They all fall through to the invalid control frame type case. 1402 // (The default case isn't used so that the compile will break if a new 1403 // control frame type is added but not included here.) 1404 case SETTINGS: 1405 case NOOP: 1406 case PING: 1407 case GOAWAY: 1408 case NUM_CONTROL_FRAME_TYPES: // makes compiler happy 1409 break; 1410 } 1411 } 1412 return stream_id; 1413 } 1414 1415 void SpdyFramer::set_validate_control_frame_sizes(bool value) { 1416 validate_control_frame_sizes_ = value; 1417 } 1418 1419 SpdyDataFrame* SpdyFramer::DecompressDataFrame(const SpdyDataFrame& frame) { 1420 z_stream* decompressor = GetStreamDecompressor(frame.stream_id()); 1421 if (!decompressor) 1422 return NULL; 1423 return reinterpret_cast<SpdyDataFrame*>( 1424 DecompressFrameWithZStream(frame, decompressor)); 1425 } 1426 1427 SpdyFrame* SpdyFramer::CompressFrameWithZStream(const SpdyFrame& frame, 1428 z_stream* compressor) { 1429 int payload_length; 1430 int header_length; 1431 const char* payload; 1432 1433 base::StatsCounter compressed_frames("spdy.CompressedFrames"); 1434 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize"); 1435 base::StatsCounter post_compress_bytes("spdy.PostCompressSize"); 1436 1437 if (!enable_compression_) 1438 return DuplicateFrame(frame); 1439 1440 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload)) 1441 return NULL; 1442 1443 // Create an output frame. 1444 int compressed_max_size = deflateBound(compressor, payload_length); 1445 int new_frame_size = header_length + compressed_max_size; 1446 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); 1447 memcpy(new_frame->data(), frame.data(), frame.length() + SpdyFrame::size()); 1448 1449 compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); 1450 compressor->avail_in = payload_length; 1451 compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + 1452 header_length; 1453 compressor->avail_out = compressed_max_size; 1454 1455 // Data packets have a 'compressed' flag. 1456 if (!new_frame->is_control_frame()) { 1457 SpdyDataFrame* data_frame = 1458 reinterpret_cast<SpdyDataFrame*>(new_frame.get()); 1459 data_frame->set_flags(data_frame->flags() | DATA_FLAG_COMPRESSED); 1460 } 1461 1462 #ifndef ANDROID 1463 // Make sure that all the data we pass to zlib is defined. 1464 // This way, all Valgrind reports on the compressed data are zlib's fault. 1465 (void)VALGRIND_CHECK_MEM_IS_DEFINED(compressor->next_in, 1466 compressor->avail_in); 1467 #endif 1468 1469 int rv = deflate(compressor, Z_SYNC_FLUSH); 1470 if (rv != Z_OK) { // How can we know that it compressed everything? 1471 // This shouldn't happen, right? 1472 LOG(WARNING) << "deflate failure: " << rv; 1473 return NULL; 1474 } 1475 1476 int compressed_size = compressed_max_size - compressor->avail_out; 1477 1478 #ifndef ANDROID 1479 // We trust zlib. Also, we can't do anything about it. 1480 // See http://www.zlib.net/zlib_faq.html#faq36 1481 (void)VALGRIND_MAKE_MEM_DEFINED(new_frame->data() + header_length, 1482 compressed_size); 1483 #endif 1484 1485 new_frame->set_length(header_length + compressed_size - SpdyFrame::size()); 1486 1487 pre_compress_bytes.Add(payload_length); 1488 post_compress_bytes.Add(new_frame->length()); 1489 1490 compressed_frames.Increment(); 1491 1492 return new_frame.release(); 1493 } 1494 1495 SpdyFrame* SpdyFramer::DecompressFrameWithZStream(const SpdyFrame& frame, 1496 z_stream* decompressor) { 1497 int payload_length; 1498 int header_length; 1499 const char* payload; 1500 1501 base::StatsCounter decompressed_frames("spdy.DecompressedFrames"); 1502 base::StatsCounter pre_decompress_bytes("spdy.PreDeCompressSize"); 1503 base::StatsCounter post_decompress_bytes("spdy.PostDeCompressSize"); 1504 1505 if (!enable_compression_) 1506 return DuplicateFrame(frame); 1507 1508 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload)) 1509 return NULL; 1510 1511 if (!frame.is_control_frame()) { 1512 const SpdyDataFrame& data_frame = 1513 reinterpret_cast<const SpdyDataFrame&>(frame); 1514 if ((data_frame.flags() & DATA_FLAG_COMPRESSED) == 0) 1515 return DuplicateFrame(frame); 1516 } 1517 1518 // Create an output frame. Assume it does not need to be longer than 1519 // the input data. 1520 size_t decompressed_max_size = kControlFrameBufferInitialSize; 1521 int new_frame_size = header_length + decompressed_max_size; 1522 if (frame.length() > decompressed_max_size) 1523 return NULL; 1524 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); 1525 memcpy(new_frame->data(), frame.data(), frame.length() + SpdyFrame::size()); 1526 1527 decompressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); 1528 decompressor->avail_in = payload_length; 1529 decompressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + 1530 header_length; 1531 decompressor->avail_out = decompressed_max_size; 1532 1533 int rv = inflate(decompressor, Z_SYNC_FLUSH); 1534 if (rv == Z_NEED_DICT) { 1535 // Need to try again with the right dictionary. 1536 if (decompressor->adler == dictionary_id) { 1537 rv = inflateSetDictionary(decompressor, (const Bytef*)kDictionary, 1538 kDictionarySize); 1539 if (rv == Z_OK) 1540 rv = inflate(decompressor, Z_SYNC_FLUSH); 1541 } 1542 } 1543 if (rv != Z_OK) { // How can we know that it decompressed everything? 1544 LOG(WARNING) << "inflate failure: " << rv; 1545 return NULL; 1546 } 1547 1548 // Unset the compressed flag for data frames. 1549 if (!new_frame->is_control_frame()) { 1550 SpdyDataFrame* data_frame = 1551 reinterpret_cast<SpdyDataFrame*>(new_frame.get()); 1552 data_frame->set_flags(data_frame->flags() & ~DATA_FLAG_COMPRESSED); 1553 } 1554 1555 int decompressed_size = decompressed_max_size - decompressor->avail_out; 1556 new_frame->set_length(header_length + decompressed_size - SpdyFrame::size()); 1557 1558 // If there is data left, then the frame didn't fully decompress. This 1559 // means that there is stranded data at the end of this frame buffer which 1560 // will be ignored. 1561 DCHECK_EQ(decompressor->avail_in, 0u); 1562 1563 pre_decompress_bytes.Add(frame.length()); 1564 post_decompress_bytes.Add(new_frame->length()); 1565 1566 decompressed_frames.Increment(); 1567 1568 return new_frame.release(); 1569 } 1570 1571 void SpdyFramer::CleanupCompressorForStream(SpdyStreamId id) { 1572 CompressorMap::iterator it = stream_compressors_.find(id); 1573 if (it != stream_compressors_.end()) { 1574 z_stream* compressor = it->second; 1575 deflateEnd(compressor); 1576 delete compressor; 1577 stream_compressors_.erase(it); 1578 } 1579 } 1580 1581 void SpdyFramer::CleanupDecompressorForStream(SpdyStreamId id) { 1582 CompressorMap::iterator it = stream_decompressors_.find(id); 1583 if (it != stream_decompressors_.end()) { 1584 z_stream* decompressor = it->second; 1585 inflateEnd(decompressor); 1586 delete decompressor; 1587 stream_decompressors_.erase(it); 1588 } 1589 } 1590 1591 void SpdyFramer::CleanupStreamCompressorsAndDecompressors() { 1592 CompressorMap::iterator it; 1593 1594 it = stream_compressors_.begin(); 1595 while (it != stream_compressors_.end()) { 1596 z_stream* compressor = it->second; 1597 deflateEnd(compressor); 1598 delete compressor; 1599 ++it; 1600 } 1601 stream_compressors_.clear(); 1602 1603 it = stream_decompressors_.begin(); 1604 while (it != stream_decompressors_.end()) { 1605 z_stream* decompressor = it->second; 1606 inflateEnd(decompressor); 1607 delete decompressor; 1608 ++it; 1609 } 1610 stream_decompressors_.clear(); 1611 } 1612 1613 size_t SpdyFramer::BytesSafeToRead() const { 1614 switch (state_) { 1615 case SPDY_ERROR: 1616 case SPDY_DONE: 1617 case SPDY_AUTO_RESET: 1618 case SPDY_RESET: 1619 return 0; 1620 case SPDY_READING_COMMON_HEADER: 1621 DCHECK_LT(current_frame_len_, SpdyFrame::size()); 1622 return SpdyFrame::size() - current_frame_len_; 1623 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: 1624 return 0; 1625 // TODO(rtenneti): Add support for SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 1626 // and SPDY_CONTROL_FRAME_HEADER_BLOCK. 1627 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 1628 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 1629 return 0; 1630 case SPDY_CONTROL_FRAME_PAYLOAD: 1631 case SPDY_IGNORE_REMAINING_PAYLOAD: 1632 case SPDY_FORWARD_STREAM_FRAME: 1633 return remaining_data_; 1634 } 1635 // We should never get to here. 1636 return 0; 1637 } 1638 1639 void SpdyFramer::set_error(SpdyError error) { 1640 DCHECK(visitor_); 1641 error_code_ = error; 1642 CHANGE_STATE(SPDY_ERROR); 1643 visitor_->OnError(this); 1644 } 1645 1646 void SpdyFramer::ExpandControlFrameBuffer(size_t size) { 1647 size_t alloc_size = size + SpdyFrame::size(); 1648 DCHECK_LE(alloc_size, kControlFrameBufferMaxSize); 1649 if (alloc_size <= current_frame_capacity_) 1650 return; 1651 char* new_buffer = new char[alloc_size]; 1652 memcpy(new_buffer, current_frame_buffer_, current_frame_len_); 1653 delete [] current_frame_buffer_; 1654 current_frame_capacity_ = alloc_size; 1655 current_frame_buffer_ = new_buffer; 1656 } 1657 1658 bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame, 1659 int* payload_length, 1660 int* header_length, 1661 const char** payload) const { 1662 size_t frame_size; 1663 if (frame.is_control_frame()) { 1664 const SpdyControlFrame& control_frame = 1665 reinterpret_cast<const SpdyControlFrame&>(frame); 1666 switch (control_frame.type()) { 1667 case SYN_STREAM: 1668 { 1669 const SpdySynStreamControlFrame& syn_frame = 1670 reinterpret_cast<const SpdySynStreamControlFrame&>(frame); 1671 frame_size = SpdySynStreamControlFrame::size(); 1672 *payload_length = syn_frame.header_block_len(); 1673 *header_length = frame_size; 1674 *payload = frame.data() + *header_length; 1675 } 1676 break; 1677 case SYN_REPLY: 1678 { 1679 const SpdySynReplyControlFrame& syn_frame = 1680 reinterpret_cast<const SpdySynReplyControlFrame&>(frame); 1681 frame_size = SpdySynReplyControlFrame::size(); 1682 *payload_length = syn_frame.header_block_len(); 1683 *header_length = frame_size; 1684 *payload = frame.data() + *header_length; 1685 } 1686 break; 1687 case HEADERS: 1688 { 1689 const SpdyHeadersControlFrame& headers_frame = 1690 reinterpret_cast<const SpdyHeadersControlFrame&>(frame); 1691 frame_size = SpdyHeadersControlFrame::size(); 1692 *payload_length = headers_frame.header_block_len(); 1693 *header_length = frame_size; 1694 *payload = frame.data() + *header_length; 1695 } 1696 break; 1697 default: 1698 // TODO(mbelshe): set an error? 1699 return false; // We can't compress this frame! 1700 } 1701 } else { 1702 frame_size = SpdyFrame::size(); 1703 *header_length = frame_size; 1704 *payload_length = frame.length(); 1705 *payload = frame.data() + SpdyFrame::size(); 1706 } 1707 return true; 1708 } 1709 1710 } // namespace spdy 1711