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