| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/spdy_framer.h" | 5 #include "net/spdy/spdy_framer.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cctype> | 10 #include <cctype> |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 #else | 109 #else |
| 110 #define CHANGE_STATE(newstate) \ | 110 #define CHANGE_STATE(newstate) \ |
| 111 do { \ | 111 do { \ |
| 112 DCHECK(state_ != SPDY_ERROR); \ | 112 DCHECK(state_ != SPDY_ERROR); \ |
| 113 DCHECK_EQ(previous_state_, state_); \ | 113 DCHECK_EQ(previous_state_, state_); \ |
| 114 previous_state_ = state_; \ | 114 previous_state_ = state_; \ |
| 115 state_ = newstate; \ | 115 state_ = newstate; \ |
| 116 } while (false) | 116 } while (false) |
| 117 #endif | 117 #endif |
| 118 | 118 |
| 119 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(SpdyMajorVersion version, | 119 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(uint32_t wire) { |
| 120 uint32_t wire) { | |
| 121 return SettingsFlagsAndId(base::NetToHost32(wire) >> 24, | 120 return SettingsFlagsAndId(base::NetToHost32(wire) >> 24, |
| 122 base::NetToHost32(wire) & 0x00ffffff); | 121 base::NetToHost32(wire) & 0x00ffffff); |
| 123 } | 122 } |
| 124 | 123 |
| 125 SettingsFlagsAndId::SettingsFlagsAndId(uint8_t flags, uint32_t id) | 124 SettingsFlagsAndId::SettingsFlagsAndId(uint8_t flags, uint32_t id) |
| 126 : flags_(flags), id_(id & 0x00ffffff) { | 125 : flags_(flags), id_(id & 0x00ffffff) { |
| 127 SPDY_BUG_IF(id > (1u << 24)) << "HTTP2 setting ID too large: " << id; | 126 SPDY_BUG_IF(id > (1u << 24)) << "HTTP2 setting ID too large: " << id; |
| 128 } | 127 } |
| 129 | 128 |
| 130 uint32_t SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version) const { | 129 uint32_t SettingsFlagsAndId::GetWireFormat() const { |
| 131 return base::HostToNet32(id_ & 0x00ffffff) | base::HostToNet32(flags_ << 24); | 130 return base::HostToNet32(id_ & 0x00ffffff) | base::HostToNet32(flags_ << 24); |
| 132 } | 131 } |
| 133 | 132 |
| 134 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, | 133 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, |
| 135 size_t len) { | 134 size_t len) { |
| 136 return true; | 135 return true; |
| 137 } | 136 } |
| 138 | 137 |
| 139 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( | 138 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( |
| 140 const char* rst_stream_data, | 139 const char* rst_stream_data, |
| 141 size_t len) { | 140 size_t len) { |
| 142 return true; | 141 return true; |
| 143 } | 142 } |
| 144 | 143 |
| 145 SpdyFramer::SpdyFramer(SpdyMajorVersion version, | 144 SpdyFramer::SpdyFramer(SpdyFramer::DecoderAdapterFactoryFn adapter_factory) |
| 146 SpdyFramer::DecoderAdapterFactoryFn adapter_factory) | |
| 147 : current_frame_buffer_(kControlFrameBufferSize), | 145 : current_frame_buffer_(kControlFrameBufferSize), |
| 148 expect_continuation_(0), | 146 expect_continuation_(0), |
| 149 visitor_(NULL), | 147 visitor_(NULL), |
| 150 debug_visitor_(NULL), | 148 debug_visitor_(NULL), |
| 151 header_handler_(nullptr), | 149 header_handler_(nullptr), |
| 152 protocol_version_(version), | |
| 153 enable_compression_(true), | 150 enable_compression_(true), |
| 154 probable_http_response_(false), | 151 probable_http_response_(false), |
| 155 end_stream_when_done_(false) { | 152 end_stream_when_done_(false) { |
| 156 DCHECK(protocol_version_ == HTTP2); | |
| 157 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it | 153 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it |
| 158 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. | 154 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. |
| 159 // Therefore this assertion is unnecessarily strict. | 155 // Therefore this assertion is unnecessarily strict. |
| 160 static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, | 156 static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, |
| 161 "Our send limit should be at most our receive limit"); | 157 "Our send limit should be at most our receive limit"); |
| 162 Reset(); | 158 Reset(); |
| 163 | 159 |
| 164 if (version == HTTP2 && adapter_factory != nullptr) { | 160 if (adapter_factory != nullptr) { |
| 165 decoder_adapter_ = adapter_factory(this); | 161 decoder_adapter_ = adapter_factory(this); |
| 166 } | 162 } |
| 167 } | 163 } |
| 168 | 164 |
| 169 SpdyFramer::SpdyFramer(SpdyMajorVersion version) | 165 SpdyFramer::SpdyFramer() : SpdyFramer(&DecoderAdapterFactory) {} |
| 170 : SpdyFramer(version, &DecoderAdapterFactory) {} | |
| 171 | 166 |
| 172 SpdyFramer::~SpdyFramer() { | 167 SpdyFramer::~SpdyFramer() { |
| 173 } | 168 } |
| 174 | 169 |
| 175 void SpdyFramer::Reset() { | 170 void SpdyFramer::Reset() { |
| 176 if (decoder_adapter_ != nullptr) { | 171 if (decoder_adapter_ != nullptr) { |
| 177 decoder_adapter_->Reset(); | 172 decoder_adapter_->Reset(); |
| 178 } | 173 } |
| 179 state_ = SPDY_READY_FOR_FRAME; | 174 state_ = SPDY_READY_FOR_FRAME; |
| 180 previous_state_ = SPDY_READY_FOR_FRAME; | 175 previous_state_ = SPDY_READY_FOR_FRAME; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 } | 223 } |
| 229 | 224 |
| 230 SpdyFramer::SpdyState SpdyFramer::state() const { | 225 SpdyFramer::SpdyState SpdyFramer::state() const { |
| 231 if (decoder_adapter_ != nullptr) { | 226 if (decoder_adapter_ != nullptr) { |
| 232 return decoder_adapter_->state(); | 227 return decoder_adapter_->state(); |
| 233 } | 228 } |
| 234 return state_; | 229 return state_; |
| 235 } | 230 } |
| 236 | 231 |
| 237 size_t SpdyFramer::GetDataFrameMinimumSize() const { | 232 size_t SpdyFramer::GetDataFrameMinimumSize() const { |
| 238 return SpdyConstants::GetDataFrameMinimumSize(protocol_version_); | 233 return SpdyConstants::kDataFrameMinimumSize; |
| 239 } | 234 } |
| 240 | 235 |
| 241 // Size, in bytes, of the control frame header. | 236 // Size, in bytes, of the control frame header. |
| 242 size_t SpdyFramer::GetFrameHeaderSize() const { | 237 size_t SpdyFramer::GetFrameHeaderSize() const { |
| 243 return SpdyConstants::GetFrameHeaderSize(protocol_version_); | 238 return SpdyConstants::kFrameHeaderSize; |
| 244 } | 239 } |
| 245 | 240 |
| 246 // TODO(jamessynge): Rename this to GetRstStreamSize as the frame is fixed size. | 241 // TODO(jamessynge): Rename this to GetRstStreamSize as the frame is fixed size. |
| 247 size_t SpdyFramer::GetRstStreamMinimumSize() const { | 242 size_t SpdyFramer::GetRstStreamMinimumSize() const { |
| 248 // Size, in bytes, of a RST_STREAM frame. | 243 // Size, in bytes, of a RST_STREAM frame. |
| 249 // Calculated as: | 244 // Calculated as: |
| 250 // frame prefix + 4 (status code) | 245 // frame prefix + 4 (status code) |
| 251 return GetFrameHeaderSize() + 4; | 246 return GetFrameHeaderSize() + 4; |
| 252 } | 247 } |
| 253 | 248 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 277 } | 272 } |
| 278 | 273 |
| 279 size_t SpdyFramer::GetWindowUpdateSize() const { | 274 size_t SpdyFramer::GetWindowUpdateSize() const { |
| 280 // Size, in bytes, of a WINDOW_UPDATE frame. | 275 // Size, in bytes, of a WINDOW_UPDATE frame. |
| 281 // Calculated as: | 276 // Calculated as: |
| 282 // frame prefix + 4 (delta) | 277 // frame prefix + 4 (delta) |
| 283 return GetFrameHeaderSize() + 4; | 278 return GetFrameHeaderSize() + 4; |
| 284 } | 279 } |
| 285 | 280 |
| 286 size_t SpdyFramer::GetBlockedSize() const { | 281 size_t SpdyFramer::GetBlockedSize() const { |
| 287 DCHECK_EQ(HTTP2, protocol_version_); | |
| 288 // Size, in bytes, of a BLOCKED frame. | 282 // Size, in bytes, of a BLOCKED frame. |
| 289 // The BLOCKED frame has no payload beyond the control frame header. | 283 // The BLOCKED frame has no payload beyond the control frame header. |
| 290 return GetFrameHeaderSize(); | 284 return GetFrameHeaderSize(); |
| 291 } | 285 } |
| 292 | 286 |
| 293 size_t SpdyFramer::GetPushPromiseMinimumSize() const { | 287 size_t SpdyFramer::GetPushPromiseMinimumSize() const { |
| 294 DCHECK_EQ(HTTP2, protocol_version_); | |
| 295 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. | 288 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. |
| 296 // Calculated as frame prefix + 4 (promised stream id) | 289 // Calculated as frame prefix + 4 (promised stream id) |
| 297 return GetFrameHeaderSize() + 4; | 290 return GetFrameHeaderSize() + 4; |
| 298 } | 291 } |
| 299 | 292 |
| 300 size_t SpdyFramer::GetContinuationMinimumSize() const { | 293 size_t SpdyFramer::GetContinuationMinimumSize() const { |
| 301 // Size, in bytes, of a CONTINUATION frame not including the variable-length | 294 // Size, in bytes, of a CONTINUATION frame not including the variable-length |
| 302 // headers fragments. | 295 // headers fragments. |
| 303 return GetFrameHeaderSize(); | 296 return GetFrameHeaderSize(); |
| 304 } | 297 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 316 // Size, in bytes, of a PRIORITY frame. | 309 // Size, in bytes, of a PRIORITY frame. |
| 317 return GetFrameHeaderSize() + kPriorityDependencyPayloadSize + | 310 return GetFrameHeaderSize() + kPriorityDependencyPayloadSize + |
| 318 kPriorityWeightPayloadSize; | 311 kPriorityWeightPayloadSize; |
| 319 } | 312 } |
| 320 | 313 |
| 321 size_t SpdyFramer::GetFrameMinimumSize() const { | 314 size_t SpdyFramer::GetFrameMinimumSize() const { |
| 322 return GetFrameHeaderSize(); | 315 return GetFrameHeaderSize(); |
| 323 } | 316 } |
| 324 | 317 |
| 325 size_t SpdyFramer::GetFrameMaximumSize() const { | 318 size_t SpdyFramer::GetFrameMaximumSize() const { |
| 326 if (protocol_version_ == HTTP2) { | 319 return send_frame_size_limit_ + SpdyConstants::kFrameHeaderSize; |
| 327 return send_frame_size_limit_ + | |
| 328 SpdyConstants::GetFrameHeaderSize(protocol_version_); | |
| 329 } else { | |
| 330 return SpdyConstants::GetMaxFrameSizeLimit(protocol_version_); | |
| 331 } | |
| 332 } | 320 } |
| 333 | 321 |
| 334 size_t SpdyFramer::GetDataFrameMaximumPayload() const { | 322 size_t SpdyFramer::GetDataFrameMaximumPayload() const { |
| 335 if (protocol_version_ == HTTP2) { | 323 return std::min(kMaxDataPayloadSendSize, |
| 336 return std::min(kMaxDataPayloadSendSize, | 324 GetFrameMaximumSize() - GetDataFrameMinimumSize()); |
| 337 GetFrameMaximumSize() - GetDataFrameMinimumSize()); | |
| 338 } else { | |
| 339 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); | |
| 340 } | |
| 341 } | 325 } |
| 342 | 326 |
| 343 const char* SpdyFramer::StateToString(int state) { | 327 const char* SpdyFramer::StateToString(int state) { |
| 344 switch (state) { | 328 switch (state) { |
| 345 case SPDY_ERROR: | 329 case SPDY_ERROR: |
| 346 return "ERROR"; | 330 return "ERROR"; |
| 347 case SPDY_FRAME_COMPLETE: | 331 case SPDY_FRAME_COMPLETE: |
| 348 return "FRAME_COMPLETE"; | 332 return "FRAME_COMPLETE"; |
| 349 case SPDY_READY_FOR_FRAME: | 333 case SPDY_READY_FOR_FRAME: |
| 350 return "READY_FOR_FRAME"; | 334 return "READY_FOR_FRAME"; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 } | 534 } |
| 551 | 535 |
| 552 case SPDY_SETTINGS_FRAME_PAYLOAD: { | 536 case SPDY_SETTINGS_FRAME_PAYLOAD: { |
| 553 int bytes_read = ProcessSettingsFramePayload(data, len); | 537 int bytes_read = ProcessSettingsFramePayload(data, len); |
| 554 len -= bytes_read; | 538 len -= bytes_read; |
| 555 data += bytes_read; | 539 data += bytes_read; |
| 556 break; | 540 break; |
| 557 } | 541 } |
| 558 | 542 |
| 559 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { | 543 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { |
| 560 int bytes_read = ProcessControlFrameHeaderBlock( | 544 int bytes_read = ProcessControlFrameHeaderBlock(data, len); |
| 561 data, len, protocol_version_ == HTTP2); | |
| 562 len -= bytes_read; | 545 len -= bytes_read; |
| 563 data += bytes_read; | 546 data += bytes_read; |
| 564 break; | 547 break; |
| 565 } | 548 } |
| 566 | 549 |
| 567 case SPDY_RST_STREAM_FRAME_PAYLOAD: { | 550 case SPDY_RST_STREAM_FRAME_PAYLOAD: { |
| 568 size_t bytes_read = ProcessRstStreamFramePayload(data, len); | 551 size_t bytes_read = ProcessRstStreamFramePayload(data, len); |
| 569 len -= bytes_read; | 552 len -= bytes_read; |
| 570 data += bytes_read; | 553 data += bytes_read; |
| 571 break; | 554 break; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 : buffer(8), last_setting_id(-1) {} | 642 : buffer(8), last_setting_id(-1) {} |
| 660 | 643 |
| 661 void SpdyFramer::SpdySettingsScratch::Reset() { | 644 void SpdyFramer::SpdySettingsScratch::Reset() { |
| 662 buffer.Rewind(); | 645 buffer.Rewind(); |
| 663 last_setting_id = -1; | 646 last_setting_id = -1; |
| 664 } | 647 } |
| 665 | 648 |
| 666 SpdyFrameType SpdyFramer::ValidateFrameHeader(bool is_control_frame, | 649 SpdyFrameType SpdyFramer::ValidateFrameHeader(bool is_control_frame, |
| 667 int frame_type_field, | 650 int frame_type_field, |
| 668 size_t payload_length_field) { | 651 size_t payload_length_field) { |
| 669 if (!SpdyConstants::IsValidFrameType(protocol_version_, frame_type_field)) { | 652 if (!SpdyConstants::IsValidFrameType(frame_type_field)) { |
| 670 // In HTTP2 we ignore unknown frame types for extensibility, as long as | 653 // We ignore unknown frame types for extensibility, as long as |
| 671 // the rest of the control frame header is valid. | 654 // the rest of the control frame header is valid. |
| 672 // We rely on the visitor to check validity of current_frame_stream_id_. | 655 // We rely on the visitor to check validity of current_frame_stream_id_. |
| 673 bool valid_stream = | 656 bool valid_stream = |
| 674 visitor_->OnUnknownFrame(current_frame_stream_id_, frame_type_field); | 657 visitor_->OnUnknownFrame(current_frame_stream_id_, frame_type_field); |
| 675 if (expect_continuation_) { | 658 if (expect_continuation_) { |
| 676 // Report an unexpected frame error and close the connection | 659 // Report an unexpected frame error and close the connection |
| 677 // if we expect a continuation and receive an unknown frame. | 660 // if we expect a continuation and receive an unknown frame. |
| 678 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " | 661 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
| 679 << "frame, but instead received an unknown frame of type " | 662 << "frame, but instead received an unknown frame of type " |
| 680 << frame_type_field; | 663 << frame_type_field; |
| 681 set_error(SPDY_UNEXPECTED_FRAME); | 664 set_error(SPDY_UNEXPECTED_FRAME); |
| 682 } else if (!valid_stream) { | 665 } else if (!valid_stream) { |
| 683 // Report an invalid frame error and close the stream if the | 666 // Report an invalid frame error and close the stream if the |
| 684 // stream_id is not valid. | 667 // stream_id is not valid. |
| 685 DLOG(WARNING) << "Unknown control frame type " << frame_type_field | 668 DLOG(WARNING) << "Unknown control frame type " << frame_type_field |
| 686 << " received on invalid stream " | 669 << " received on invalid stream " |
| 687 << current_frame_stream_id_; | 670 << current_frame_stream_id_; |
| 688 set_error(SPDY_INVALID_CONTROL_FRAME); | 671 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 689 } else { | 672 } else { |
| 690 DVLOG(1) << "Ignoring unknown frame type."; | 673 DVLOG(1) << "Ignoring unknown frame type."; |
| 691 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 674 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 692 } | 675 } |
| 693 return DATA; | 676 return DATA; |
| 694 } | 677 } |
| 695 | 678 |
| 696 SpdyFrameType frame_type = | 679 SpdyFrameType frame_type = SpdyConstants::ParseFrameType(frame_type_field); |
| 697 SpdyConstants::ParseFrameType(protocol_version_, frame_type_field); | |
| 698 | 680 |
| 699 if (protocol_version_ == HTTP2) { | 681 if (!SpdyConstants::IsValidHTTP2FrameStreamId(current_frame_stream_id_, |
| 700 if (!SpdyConstants::IsValidHTTP2FrameStreamId(current_frame_stream_id_, | 682 frame_type)) { |
| 701 frame_type)) { | 683 DLOG(ERROR) << "The framer received an invalid streamID of " |
| 702 DLOG(ERROR) << "The framer received an invalid streamID of " | 684 << current_frame_stream_id_ << " for a frame of type " |
| 703 << current_frame_stream_id_ << " for a frame of type " | 685 << FrameTypeToString(frame_type); |
| 704 << FrameTypeToString(frame_type); | 686 set_error(SPDY_INVALID_STREAM_ID); |
| 705 set_error(SPDY_INVALID_STREAM_ID); | 687 return frame_type; |
| 706 return frame_type; | |
| 707 } | |
| 708 | |
| 709 // Ensure that we see a CONTINUATION frame iff we expect to. | |
| 710 if ((frame_type == CONTINUATION) != (expect_continuation_ != 0)) { | |
| 711 if (expect_continuation_ != 0) { | |
| 712 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " | |
| 713 << "frame, but instead received a frame of type " | |
| 714 << FrameTypeToString(frame_type); | |
| 715 } else { | |
| 716 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; | |
| 717 } | |
| 718 set_error(SPDY_UNEXPECTED_FRAME); | |
| 719 return frame_type; | |
| 720 } | |
| 721 } | 688 } |
| 722 | 689 |
| 723 if (protocol_version_ == HTTP2 && | 690 // Ensure that we see a CONTINUATION frame iff we expect to. |
| 724 payload_length_field > recv_frame_size_limit_) { | 691 if ((frame_type == CONTINUATION) != (expect_continuation_ != 0)) { |
| 692 if (expect_continuation_ != 0) { |
| 693 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
| 694 << "frame, but instead received a frame of type " |
| 695 << FrameTypeToString(frame_type); |
| 696 } else { |
| 697 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; |
| 698 } |
| 699 set_error(SPDY_UNEXPECTED_FRAME); |
| 700 return frame_type; |
| 701 } |
| 702 |
| 703 if (payload_length_field > recv_frame_size_limit_) { |
| 725 set_error(SPDY_OVERSIZED_PAYLOAD); | 704 set_error(SPDY_OVERSIZED_PAYLOAD); |
| 726 } | 705 } |
| 727 | 706 |
| 728 return frame_type; | 707 return frame_type; |
| 729 } | 708 } |
| 730 | 709 |
| 731 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { | 710 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { |
| 732 // This should only be called when we're in the SPDY_READING_COMMON_HEADER | 711 // This should only be called when we're in the SPDY_READING_COMMON_HEADER |
| 733 // state. | 712 // state. |
| 734 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); | 713 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); |
| 735 | 714 |
| 736 size_t original_len = len; | 715 size_t original_len = len; |
| 737 | 716 |
| 738 // Update current frame buffer as needed. | 717 // Update current frame buffer as needed. |
| 739 if (current_frame_buffer_.len() < GetFrameHeaderSize()) { | 718 if (current_frame_buffer_.len() < GetFrameHeaderSize()) { |
| 740 size_t bytes_desired = GetFrameHeaderSize() - current_frame_buffer_.len(); | 719 size_t bytes_desired = GetFrameHeaderSize() - current_frame_buffer_.len(); |
| 741 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); | 720 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); |
| 742 } | 721 } |
| 743 | 722 |
| 744 if (current_frame_buffer_.len() < GetFrameHeaderSize()) { | 723 if (current_frame_buffer_.len() < GetFrameHeaderSize()) { |
| 745 // Not enough information to do anything meaningful. | 724 // Not enough information to do anything meaningful. |
| 746 return original_len - len; | 725 return original_len - len; |
| 747 } | 726 } |
| 748 | 727 |
| 749 SpdyFrameReader reader(current_frame_buffer_.data(), | 728 SpdyFrameReader reader(current_frame_buffer_.data(), |
| 750 current_frame_buffer_.len()); | 729 current_frame_buffer_.len()); |
| 751 bool is_control_frame = false; | 730 bool is_control_frame = false; |
| 752 | 731 |
| 753 int control_frame_type_field = | 732 int control_frame_type_field = SpdyConstants::kDataFrameType; |
| 754 SpdyConstants::DataFrameType(protocol_version_); | |
| 755 // ProcessControlFrameHeader() will set current_frame_type_ to the | 733 // ProcessControlFrameHeader() will set current_frame_type_ to the |
| 756 // correct value if this is a valid control frame. | 734 // correct value if this is a valid control frame. |
| 757 current_frame_type_ = DATA; | 735 current_frame_type_ = DATA; |
| 758 uint32_t length_field = 0; | 736 uint32_t length_field = 0; |
| 759 bool successful_read = reader.ReadUInt24(&length_field); | 737 bool successful_read = reader.ReadUInt24(&length_field); |
| 760 DCHECK(successful_read); | 738 DCHECK(successful_read); |
| 761 | 739 |
| 762 uint8_t control_frame_type_field_uint8; | 740 uint8_t control_frame_type_field_uint8; |
| 763 successful_read = reader.ReadUInt8(&control_frame_type_field_uint8); | 741 successful_read = reader.ReadUInt8(&control_frame_type_field_uint8); |
| 764 DCHECK(successful_read); | 742 DCHECK(successful_read); |
| 765 // We check control_frame_type_field's validity in | 743 // We check control_frame_type_field's validity in |
| 766 // ProcessControlFrameHeader(). | 744 // ProcessControlFrameHeader(). |
| 767 control_frame_type_field = control_frame_type_field_uint8; | 745 control_frame_type_field = control_frame_type_field_uint8; |
| 768 is_control_frame = control_frame_type_field != | 746 is_control_frame = control_frame_type_field != SpdyConstants::kDataFrameType; |
| 769 SpdyConstants::SerializeFrameType(protocol_version_, DATA); | |
| 770 | 747 |
| 771 current_frame_length_ = length_field + GetFrameHeaderSize(); | 748 current_frame_length_ = length_field + GetFrameHeaderSize(); |
| 772 | 749 |
| 773 successful_read = reader.ReadUInt8(¤t_frame_flags_); | 750 successful_read = reader.ReadUInt8(¤t_frame_flags_); |
| 774 DCHECK(successful_read); | 751 DCHECK(successful_read); |
| 775 | 752 |
| 776 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 753 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 777 DCHECK(successful_read); | 754 DCHECK(successful_read); |
| 778 | 755 |
| 779 remaining_data_length_ = current_frame_length_ - reader.GetBytesConsumed(); | 756 remaining_data_length_ = current_frame_length_ - reader.GetBytesConsumed(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 case SETTINGS: | 823 case SETTINGS: |
| 847 { | 824 { |
| 848 // Make sure that we have an integral number of 8-byte key/value pairs, | 825 // Make sure that we have an integral number of 8-byte key/value pairs, |
| 849 // Size of each key/value pair in bytes. | 826 // Size of each key/value pair in bytes. |
| 850 int setting_size = 6; | 827 int setting_size = 6; |
| 851 if (current_frame_length_ < GetSettingsMinimumSize() || | 828 if (current_frame_length_ < GetSettingsMinimumSize() || |
| 852 (current_frame_length_ - GetFrameHeaderSize()) % setting_size != 0) { | 829 (current_frame_length_ - GetFrameHeaderSize()) % setting_size != 0) { |
| 853 DLOG(WARNING) << "Invalid length for SETTINGS frame: " | 830 DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
| 854 << current_frame_length_; | 831 << current_frame_length_; |
| 855 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 832 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
| 856 } else if (protocol_version_ == HTTP2 && | 833 } else if (current_frame_flags_ & SETTINGS_FLAG_ACK && |
| 857 current_frame_flags_ & SETTINGS_FLAG_ACK && | |
| 858 current_frame_length_ > GetSettingsMinimumSize()) { | 834 current_frame_length_ > GetSettingsMinimumSize()) { |
| 859 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 835 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
| 860 } else if (protocol_version_ == HTTP2 && | 836 } else if (current_frame_flags_ & ~SETTINGS_FLAG_ACK) { |
| 861 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { | |
| 862 VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex | 837 VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex |
| 863 << static_cast<int>(current_frame_flags_); | 838 << static_cast<int>(current_frame_flags_); |
| 864 current_frame_flags_ &= SETTINGS_FLAG_ACK; | 839 current_frame_flags_ &= SETTINGS_FLAG_ACK; |
| 865 } | 840 } |
| 866 break; | 841 break; |
| 867 } | 842 } |
| 868 case PING: | 843 case PING: |
| 869 if (current_frame_length_ != GetPingSize()) { | 844 if (current_frame_length_ != GetPingSize()) { |
| 870 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 845 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
| 871 } else { | 846 } else { |
| 872 if (protocol_version_ == HTTP2 && | 847 if (current_frame_flags_ & ~PING_FLAG_ACK) { |
| 873 current_frame_flags_ & ~PING_FLAG_ACK) { | |
| 874 VLOG(1) << "Undefined frame flags for PING frame: " << hex | 848 VLOG(1) << "Undefined frame flags for PING frame: " << hex |
| 875 << static_cast<int>(current_frame_flags_); | 849 << static_cast<int>(current_frame_flags_); |
| 876 current_frame_flags_ &= PING_FLAG_ACK; | 850 current_frame_flags_ &= PING_FLAG_ACK; |
| 877 } | 851 } |
| 878 } | 852 } |
| 879 break; | 853 break; |
| 880 case GOAWAY: | 854 case GOAWAY: |
| 881 { | 855 { |
| 882 // For HTTP/2, optional opaque data may be appended to the | 856 // For HTTP/2, optional opaque data may be appended to the |
| 883 // GOAWAY frame, thus there is only a minimal length restriction. | 857 // GOAWAY frame, thus there is only a minimal length restriction. |
| 884 if (protocol_version_ == HTTP2 && | 858 if (current_frame_length_ < GetGoAwayMinimumSize()) { |
| 885 current_frame_length_ < GetGoAwayMinimumSize()) { | |
| 886 set_error(SPDY_INVALID_CONTROL_FRAME); | 859 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 887 } else if (current_frame_flags_ != 0) { | 860 } else if (current_frame_flags_ != 0) { |
| 888 VLOG(1) << "Undefined frame flags for GOAWAY frame: " << hex | 861 VLOG(1) << "Undefined frame flags for GOAWAY frame: " << hex |
| 889 << static_cast<int>(current_frame_flags_); | 862 << static_cast<int>(current_frame_flags_); |
| 890 current_frame_flags_ = 0; | 863 current_frame_flags_ = 0; |
| 891 } | 864 } |
| 892 break; | 865 break; |
| 893 } | 866 } |
| 894 case HEADERS: | 867 case HEADERS: |
| 895 { | 868 { |
| 896 size_t min_size = GetHeadersMinimumSize(); | 869 size_t min_size = GetHeadersMinimumSize(); |
| 897 if (protocol_version_ == HTTP2 && | 870 if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
| 898 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { | |
| 899 min_size += 4; | 871 min_size += 4; |
| 900 } | 872 } |
| 901 if (current_frame_length_ < min_size) { | 873 if (current_frame_length_ < min_size) { |
| 902 // TODO(mlavan): check here for HEADERS with no payload? | 874 // TODO(mlavan): check here for HEADERS with no payload? |
| 903 // (not allowed in HTTP2) | 875 // (not allowed in HTTP2) |
| 904 set_error(SPDY_INVALID_CONTROL_FRAME); | 876 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 905 } else if (protocol_version_ == HTTP2 && | 877 } else if (current_frame_flags_ & |
| 906 current_frame_flags_ & | 878 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
| 907 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 879 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED)) { |
| 908 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED)) { | |
| 909 VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex | 880 VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex |
| 910 << static_cast<int>(current_frame_flags_); | 881 << static_cast<int>(current_frame_flags_); |
| 911 current_frame_flags_ &= | 882 current_frame_flags_ &= |
| 912 (CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 883 (CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
| 913 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED); | 884 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED); |
| 914 } | 885 } |
| 915 } | 886 } |
| 916 break; | 887 break; |
| 917 case WINDOW_UPDATE: | 888 case WINDOW_UPDATE: |
| 918 if (current_frame_length_ != GetWindowUpdateSize()) { | 889 if (current_frame_length_ != GetWindowUpdateSize()) { |
| 919 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 890 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
| 920 } else if (current_frame_flags_ != 0) { | 891 } else if (current_frame_flags_ != 0) { |
| 921 VLOG(1) << "Undefined frame flags for WINDOW_UPDATE frame: " << hex | 892 VLOG(1) << "Undefined frame flags for WINDOW_UPDATE frame: " << hex |
| 922 << static_cast<int>(current_frame_flags_); | 893 << static_cast<int>(current_frame_flags_); |
| 923 current_frame_flags_ = 0; | 894 current_frame_flags_ = 0; |
| 924 } | 895 } |
| 925 break; | 896 break; |
| 926 case BLOCKED: | 897 case BLOCKED: |
| 927 if (current_frame_length_ != GetBlockedSize()) { | 898 if (current_frame_length_ != GetBlockedSize()) { |
| 928 set_error(SPDY_INVALID_CONTROL_FRAME); | 899 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 929 } else if (current_frame_flags_ != 0) { | 900 } else if (current_frame_flags_ != 0) { |
| 930 VLOG(1) << "Undefined frame flags for BLOCKED frame: " << hex | 901 VLOG(1) << "Undefined frame flags for BLOCKED frame: " << hex |
| 931 << static_cast<int>(current_frame_flags_); | 902 << static_cast<int>(current_frame_flags_); |
| 932 current_frame_flags_ = 0; | 903 current_frame_flags_ = 0; |
| 933 } | 904 } |
| 934 break; | 905 break; |
| 935 case PUSH_PROMISE: | 906 case PUSH_PROMISE: |
| 936 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 907 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
| 937 set_error(SPDY_INVALID_CONTROL_FRAME); | 908 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 938 } else if (protocol_version_ == HTTP2 && | 909 } else if (current_frame_flags_ & |
| 939 current_frame_flags_ & | 910 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED)) { |
| 940 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | | |
| 941 HEADERS_FLAG_PADDED)) { | |
| 942 VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex | 911 VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex |
| 943 << static_cast<int>(current_frame_flags_); | 912 << static_cast<int>(current_frame_flags_); |
| 944 current_frame_flags_ &= | 913 current_frame_flags_ &= |
| 945 (PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED); | 914 (PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED); |
| 946 } | 915 } |
| 947 break; | 916 break; |
| 948 case CONTINUATION: | 917 case CONTINUATION: |
| 949 if (current_frame_length_ < GetContinuationMinimumSize()) { | 918 if (current_frame_length_ < GetContinuationMinimumSize()) { |
| 950 set_error(SPDY_INVALID_CONTROL_FRAME); | 919 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 951 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { | 920 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 return; | 972 return; |
| 1004 } | 973 } |
| 1005 // Determine the frame size without variable-length data. | 974 // Determine the frame size without variable-length data. |
| 1006 int32_t frame_size_without_variable_data; | 975 int32_t frame_size_without_variable_data; |
| 1007 switch (current_frame_type_) { | 976 switch (current_frame_type_) { |
| 1008 case SETTINGS: | 977 case SETTINGS: |
| 1009 frame_size_without_variable_data = GetSettingsMinimumSize(); | 978 frame_size_without_variable_data = GetSettingsMinimumSize(); |
| 1010 break; | 979 break; |
| 1011 case HEADERS: | 980 case HEADERS: |
| 1012 frame_size_without_variable_data = GetHeadersMinimumSize(); | 981 frame_size_without_variable_data = GetHeadersMinimumSize(); |
| 1013 if (protocol_version_ == HTTP2) { | 982 if (current_frame_flags_ & HEADERS_FLAG_PADDED) { |
| 1014 if (current_frame_flags_ & HEADERS_FLAG_PADDED) { | 983 frame_size_without_variable_data += kPadLengthFieldSize; |
| 1015 frame_size_without_variable_data += kPadLengthFieldSize; | 984 } |
| 1016 } | 985 if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
| 1017 if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) { | |
| 1018 frame_size_without_variable_data += | 986 frame_size_without_variable_data += |
| 1019 kPriorityDependencyPayloadSize + | 987 kPriorityDependencyPayloadSize + kPriorityWeightPayloadSize; |
| 1020 kPriorityWeightPayloadSize; | |
| 1021 } | |
| 1022 } | 988 } |
| 1023 break; | 989 break; |
| 1024 case PUSH_PROMISE: | 990 case PUSH_PROMISE: |
| 1025 frame_size_without_variable_data = GetPushPromiseMinimumSize(); | 991 frame_size_without_variable_data = GetPushPromiseMinimumSize(); |
| 1026 if (protocol_version_ == HTTP2 && | 992 if (current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) { |
| 1027 current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) { | |
| 1028 frame_size_without_variable_data += kPadLengthFieldSize; | 993 frame_size_without_variable_data += kPadLengthFieldSize; |
| 1029 } | 994 } |
| 1030 break; | 995 break; |
| 1031 case CONTINUATION: | 996 case CONTINUATION: |
| 1032 frame_size_without_variable_data = GetContinuationMinimumSize(); | 997 frame_size_without_variable_data = GetContinuationMinimumSize(); |
| 1033 break; | 998 break; |
| 1034 default: | 999 default: |
| 1035 frame_size_without_variable_data = -1; | 1000 frame_size_without_variable_data = -1; |
| 1036 break; | 1001 break; |
| 1037 } | 1002 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 size_t bytes_to_read = std::min(*len, max_bytes); | 1037 size_t bytes_to_read = std::min(*len, max_bytes); |
| 1073 if (bytes_to_read > 0) { | 1038 if (bytes_to_read > 0) { |
| 1074 current_frame_buffer_.CopyFrom(*data, bytes_to_read); | 1039 current_frame_buffer_.CopyFrom(*data, bytes_to_read); |
| 1075 *data += bytes_to_read; | 1040 *data += bytes_to_read; |
| 1076 *len -= bytes_to_read; | 1041 *len -= bytes_to_read; |
| 1077 } | 1042 } |
| 1078 return bytes_to_read; | 1043 return bytes_to_read; |
| 1079 } | 1044 } |
| 1080 | 1045 |
| 1081 size_t SpdyFramer::GetSerializedLength( | 1046 size_t SpdyFramer::GetSerializedLength( |
| 1082 const SpdyMajorVersion spdy_version, | |
| 1083 const SpdyHeaderBlock* headers) { | 1047 const SpdyHeaderBlock* headers) { |
| 1084 const size_t num_name_value_pairs_size = sizeof(uint32_t); | 1048 const size_t num_name_value_pairs_size = sizeof(uint32_t); |
| 1085 const size_t length_of_name_size = num_name_value_pairs_size; | 1049 const size_t length_of_name_size = num_name_value_pairs_size; |
| 1086 const size_t length_of_value_size = num_name_value_pairs_size; | 1050 const size_t length_of_value_size = num_name_value_pairs_size; |
| 1087 | 1051 |
| 1088 size_t total_length = num_name_value_pairs_size; | 1052 size_t total_length = num_name_value_pairs_size; |
| 1089 for (const auto& header : *headers) { | 1053 for (const auto& header : *headers) { |
| 1090 // We add space for the length of the name and the length of the value as | 1054 // We add space for the length of the name and the length of the value as |
| 1091 // well as the length of the name and the length of the value. | 1055 // well as the length of the name and the length of the value. |
| 1092 total_length += length_of_name_size + header.first.size() + | 1056 total_length += length_of_name_size + header.first.size() + |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1113 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. | 1077 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. |
| 1114 | 1078 |
| 1115 switch (current_frame_type_) { | 1079 switch (current_frame_type_) { |
| 1116 case HEADERS: | 1080 case HEADERS: |
| 1117 { | 1081 { |
| 1118 bool successful_read = true; | 1082 bool successful_read = true; |
| 1119 if (current_frame_stream_id_ == 0) { | 1083 if (current_frame_stream_id_ == 0) { |
| 1120 set_error(SPDY_INVALID_CONTROL_FRAME); | 1084 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1121 return original_len - len; | 1085 return original_len - len; |
| 1122 } | 1086 } |
| 1123 if (protocol_version_ == HTTP2 && | 1087 if (!(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && |
| 1124 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && | |
| 1125 current_frame_type_ == HEADERS) { | 1088 current_frame_type_ == HEADERS) { |
| 1126 expect_continuation_ = current_frame_stream_id_; | 1089 expect_continuation_ = current_frame_stream_id_; |
| 1127 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; | 1090 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; |
| 1128 } | 1091 } |
| 1129 if (protocol_version_ == HTTP2 && | 1092 if (current_frame_flags_ & HEADERS_FLAG_PADDED) { |
| 1130 current_frame_flags_ & HEADERS_FLAG_PADDED) { | |
| 1131 uint8_t pad_payload_len = 0; | 1093 uint8_t pad_payload_len = 0; |
| 1132 DCHECK_EQ(remaining_padding_payload_length_, 0u); | 1094 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
| 1133 successful_read = reader.ReadUInt8(&pad_payload_len); | 1095 successful_read = reader.ReadUInt8(&pad_payload_len); |
| 1134 DCHECK(successful_read); | 1096 DCHECK(successful_read); |
| 1135 remaining_padding_payload_length_ = pad_payload_len; | 1097 remaining_padding_payload_length_ = pad_payload_len; |
| 1136 } | 1098 } |
| 1137 const bool has_priority = | 1099 const bool has_priority = |
| 1138 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; | 1100 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; |
| 1139 int weight = 0; | 1101 int weight = 0; |
| 1140 uint32_t parent_stream_id = 0; | 1102 uint32_t parent_stream_id = 0; |
| 1141 bool exclusive = false; | 1103 bool exclusive = false; |
| 1142 if (protocol_version_ == HTTP2 && has_priority) { | 1104 if (has_priority) { |
| 1143 uint32_t stream_dependency; | 1105 uint32_t stream_dependency; |
| 1144 successful_read = reader.ReadUInt32(&stream_dependency); | 1106 successful_read = reader.ReadUInt32(&stream_dependency); |
| 1145 DCHECK(successful_read); | 1107 DCHECK(successful_read); |
| 1146 UnpackStreamDependencyValues(stream_dependency, &exclusive, | 1108 UnpackStreamDependencyValues(stream_dependency, &exclusive, |
| 1147 &parent_stream_id); | 1109 &parent_stream_id); |
| 1148 | 1110 |
| 1149 uint8_t serialized_weight = 0; | 1111 uint8_t serialized_weight = 0; |
| 1150 successful_read = reader.ReadUInt8(&serialized_weight); | 1112 successful_read = reader.ReadUInt8(&serialized_weight); |
| 1151 if (successful_read) { | 1113 if (successful_read) { |
| 1152 // Per RFC 7540 section 6.3, serialized weight value is actual | 1114 // Per RFC 7540 section 6.3, serialized weight value is actual |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1163 visitor_->OnHeaders( | 1125 visitor_->OnHeaders( |
| 1164 current_frame_stream_id_, | 1126 current_frame_stream_id_, |
| 1165 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0, weight, | 1127 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0, weight, |
| 1166 parent_stream_id, exclusive, | 1128 parent_stream_id, exclusive, |
| 1167 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | 1129 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
| 1168 expect_continuation_ == 0); | 1130 expect_continuation_ == 0); |
| 1169 } | 1131 } |
| 1170 break; | 1132 break; |
| 1171 case PUSH_PROMISE: | 1133 case PUSH_PROMISE: |
| 1172 { | 1134 { |
| 1173 DCHECK_EQ(HTTP2, protocol_version_); | |
| 1174 if (current_frame_stream_id_ == 0) { | 1135 if (current_frame_stream_id_ == 0) { |
| 1175 set_error(SPDY_INVALID_CONTROL_FRAME); | 1136 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1176 return original_len - len; | 1137 return original_len - len; |
| 1177 } | 1138 } |
| 1178 bool successful_read = true; | 1139 bool successful_read = true; |
| 1179 if (protocol_version_ == HTTP2 && | 1140 if (current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) { |
| 1180 current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) { | |
| 1181 DCHECK_EQ(remaining_padding_payload_length_, 0u); | 1141 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
| 1182 uint8_t pad_payload_len = 0; | 1142 uint8_t pad_payload_len = 0; |
| 1183 successful_read = reader.ReadUInt8(&pad_payload_len); | 1143 successful_read = reader.ReadUInt8(&pad_payload_len); |
| 1184 DCHECK(successful_read); | 1144 DCHECK(successful_read); |
| 1185 remaining_padding_payload_length_ = pad_payload_len; | 1145 remaining_padding_payload_length_ = pad_payload_len; |
| 1186 } | 1146 } |
| 1187 } | 1147 } |
| 1188 { | 1148 { |
| 1189 SpdyStreamId promised_stream_id = kInvalidStream; | 1149 SpdyStreamId promised_stream_id = kInvalidStream; |
| 1190 bool successful_read = reader.ReadUInt31(&promised_stream_id); | 1150 bool successful_read = reader.ReadUInt31(&promised_stream_id); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 } | 1214 } |
| 1255 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1215 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
| 1256 } | 1216 } |
| 1257 return original_len - len; | 1217 return original_len - len; |
| 1258 } | 1218 } |
| 1259 | 1219 |
| 1260 // Does not buffer the control payload. Instead, either passes directly to the | 1220 // Does not buffer the control payload. Instead, either passes directly to the |
| 1261 // visitor or decompresses and then passes directly to the visitor, via | 1221 // visitor or decompresses and then passes directly to the visitor, via |
| 1262 // IncrementallyDeliverControlFrameHeaderData() | 1222 // IncrementallyDeliverControlFrameHeaderData() |
| 1263 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, | 1223 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, |
| 1264 size_t data_len, | 1224 size_t data_len) { |
| 1265 bool is_hpack_header_block) { | |
| 1266 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); | 1225 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); |
| 1267 | 1226 |
| 1268 bool processed_successfully = true; | 1227 bool processed_successfully = true; |
| 1269 if (current_frame_type_ != HEADERS && current_frame_type_ != PUSH_PROMISE && | 1228 if (current_frame_type_ != HEADERS && current_frame_type_ != PUSH_PROMISE && |
| 1270 current_frame_type_ != CONTINUATION) { | 1229 current_frame_type_ != CONTINUATION) { |
| 1271 SPDY_BUG << "Unhandled frame type in ProcessControlFrameHeaderBlock."; | 1230 SPDY_BUG << "Unhandled frame type in ProcessControlFrameHeaderBlock."; |
| 1272 } | 1231 } |
| 1273 | 1232 |
| 1274 if (remaining_padding_payload_length_ > remaining_data_length_) { | 1233 if (remaining_padding_payload_length_ > remaining_data_length_) { |
| 1275 set_error(SPDY_INVALID_PADDING); | 1234 set_error(SPDY_INVALID_PADDING); |
| 1276 return data_len; | 1235 return data_len; |
| 1277 } | 1236 } |
| 1278 | 1237 |
| 1279 size_t process_bytes = std::min( | 1238 size_t process_bytes = std::min( |
| 1280 data_len, remaining_data_length_ - remaining_padding_payload_length_); | 1239 data_len, remaining_data_length_ - remaining_padding_payload_length_); |
| 1281 if (is_hpack_header_block) { | 1240 if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, process_bytes)) { |
| 1282 if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, | 1241 // TODO(jgraettinger): Finer-grained HPACK error codes. |
| 1283 process_bytes)) { | 1242 set_error(SPDY_DECOMPRESS_FAILURE); |
| 1284 // TODO(jgraettinger): Finer-grained HPACK error codes. | 1243 processed_successfully = false; |
| 1285 set_error(SPDY_DECOMPRESS_FAILURE); | |
| 1286 processed_successfully = false; | |
| 1287 } | |
| 1288 } else if (process_bytes > 0) { | |
| 1289 processed_successfully = IncrementallyDeliverControlFrameHeaderData( | |
| 1290 current_frame_stream_id_, data, process_bytes); | |
| 1291 } | 1244 } |
| 1292 remaining_data_length_ -= process_bytes; | 1245 remaining_data_length_ -= process_bytes; |
| 1293 | 1246 |
| 1294 // Handle the case that there is no futher data in this frame. | 1247 // Handle the case that there is no futher data in this frame. |
| 1295 if (remaining_data_length_ == remaining_padding_payload_length_ && | 1248 if (remaining_data_length_ == remaining_padding_payload_length_ && |
| 1296 processed_successfully) { | 1249 processed_successfully) { |
| 1297 if (expect_continuation_ == 0) { | 1250 if (expect_continuation_ == 0) { |
| 1298 if (is_hpack_header_block) { | 1251 size_t compressed_len = 0; |
| 1299 size_t compressed_len = 0; | 1252 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( |
| 1300 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( | 1253 &compressed_len)) { |
| 1301 &compressed_len)) { | |
| 1302 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); | |
| 1303 if (state_ == SPDY_ERROR) { | |
| 1304 return data_len; | |
| 1305 } | |
| 1306 } else { | |
| 1307 set_error(SPDY_DECOMPRESS_FAILURE); | |
| 1308 processed_successfully = false; | |
| 1309 } | |
| 1310 } else { | |
| 1311 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); | 1254 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); |
| 1312 if (state_ == SPDY_ERROR) { | 1255 if (state_ == SPDY_ERROR) { |
| 1313 return data_len; | 1256 return data_len; |
| 1314 } | 1257 } |
| 1258 } else { |
| 1259 set_error(SPDY_DECOMPRESS_FAILURE); |
| 1260 processed_successfully = false; |
| 1315 } | 1261 } |
| 1316 } | 1262 } |
| 1317 if (processed_successfully) { | 1263 if (processed_successfully) { |
| 1318 CHANGE_STATE(SPDY_CONSUME_PADDING); | 1264 CHANGE_STATE(SPDY_CONSUME_PADDING); |
| 1319 } | 1265 } |
| 1320 } | 1266 } |
| 1321 | 1267 |
| 1322 // Handle error. | 1268 // Handle error. |
| 1323 if (!processed_successfully) { | 1269 if (!processed_successfully) { |
| 1324 return data_len; | 1270 return data_len; |
| 1325 } | 1271 } |
| 1326 | 1272 |
| 1327 // Return amount processed. | 1273 // Return amount processed. |
| 1328 return process_bytes; | 1274 return process_bytes; |
| 1329 } | 1275 } |
| 1330 | 1276 |
| 1331 size_t SpdyFramer::ProcessSettingsFrameHeader(const char* data, size_t len) { | 1277 size_t SpdyFramer::ProcessSettingsFrameHeader(const char* data, size_t len) { |
| 1332 // TODO(birenroy): Remove this state when removing SPDY3. I think it only | 1278 // TODO(birenroy): Remove this state when removing SPDY3. I think it only |
| 1333 // exists to read the number of settings in the frame for SPDY3. This value | 1279 // exists to read the number of settings in the frame for SPDY3. This value |
| 1334 // is never parsed or used. | 1280 // is never parsed or used. |
| 1335 size_t bytes_read = 0; | 1281 size_t bytes_read = 0; |
| 1336 if (remaining_control_header_ > 0) { | 1282 if (remaining_control_header_ > 0) { |
| 1337 bytes_read = | 1283 bytes_read = |
| 1338 UpdateCurrentFrameBuffer(&data, &len, remaining_control_header_); | 1284 UpdateCurrentFrameBuffer(&data, &len, remaining_control_header_); |
| 1339 remaining_control_header_ -= bytes_read; | 1285 remaining_control_header_ -= bytes_read; |
| 1340 remaining_data_length_ -= bytes_read; | 1286 remaining_data_length_ -= bytes_read; |
| 1341 } | 1287 } |
| 1342 if (remaining_control_header_ == 0) { | 1288 if (remaining_control_header_ == 0) { |
| 1343 if (protocol_version_ == HTTP2 && | 1289 if (current_frame_flags_ & SETTINGS_FLAG_ACK) { |
| 1344 current_frame_flags_ & SETTINGS_FLAG_ACK) { | |
| 1345 visitor_->OnSettingsAck(); | 1290 visitor_->OnSettingsAck(); |
| 1346 CHANGE_STATE(SPDY_FRAME_COMPLETE); | 1291 CHANGE_STATE(SPDY_FRAME_COMPLETE); |
| 1347 } else { | 1292 } else { |
| 1348 visitor_->OnSettings(current_frame_flags_ & | 1293 visitor_->OnSettings(current_frame_flags_ & |
| 1349 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); | 1294 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); |
| 1350 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); | 1295 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); |
| 1351 } | 1296 } |
| 1352 } | 1297 } |
| 1353 return bytes_read; | 1298 return bytes_read; |
| 1354 } | 1299 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 SpdySettingsIds id; | 1355 SpdySettingsIds id; |
| 1411 uint8_t flags = 0; | 1356 uint8_t flags = 0; |
| 1412 uint32_t value; | 1357 uint32_t value; |
| 1413 | 1358 |
| 1414 // Extract fields. | 1359 // Extract fields. |
| 1415 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. | 1360 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. |
| 1416 id_field = base::NetToHost16(*(reinterpret_cast<const uint16_t*>(data))); | 1361 id_field = base::NetToHost16(*(reinterpret_cast<const uint16_t*>(data))); |
| 1417 value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 2))); | 1362 value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 2))); |
| 1418 | 1363 |
| 1419 // Validate id. | 1364 // Validate id. |
| 1420 if (!SpdyConstants::IsValidSettingId(protocol_version_, id_field)) { | 1365 if (!SpdyConstants::IsValidSettingId(id_field)) { |
| 1421 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; | 1366 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
| 1422 // In HTTP2 we ignore unknown settings for extensibility. | 1367 // Ignore unknown settings for extensibility. |
| 1423 return true; | 1368 return true; |
| 1424 } | 1369 } |
| 1425 id = SpdyConstants::ParseSettingId(protocol_version_, id_field); | 1370 id = SpdyConstants::ParseSettingId(id_field); |
| 1426 | 1371 |
| 1427 // Validation succeeded. Pass on to visitor. | 1372 // Validation succeeded. Pass on to visitor. |
| 1428 visitor_->OnSetting(id, flags, value); | 1373 visitor_->OnSetting(id, flags, value); |
| 1429 return true; | 1374 return true; |
| 1430 } | 1375 } |
| 1431 | 1376 |
| 1432 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { | 1377 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { |
| 1433 size_t original_len = len; | 1378 size_t original_len = len; |
| 1434 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, | 1379 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, |
| 1435 remaining_data_length_); | 1380 remaining_data_length_); |
| 1436 remaining_data_length_ -= bytes_read; | 1381 remaining_data_length_ -= bytes_read; |
| 1437 if (remaining_data_length_ == 0) { | 1382 if (remaining_data_length_ == 0) { |
| 1438 SpdyFrameReader reader(current_frame_buffer_.data(), | 1383 SpdyFrameReader reader(current_frame_buffer_.data(), |
| 1439 current_frame_buffer_.len()); | 1384 current_frame_buffer_.len()); |
| 1440 reader.Seek(GetFrameHeaderSize()); // Skip frame header. | 1385 reader.Seek(GetFrameHeaderSize()); // Skip frame header. |
| 1441 | 1386 |
| 1442 // Use frame-specific handlers. | 1387 // Use frame-specific handlers. |
| 1443 switch (current_frame_type_) { | 1388 switch (current_frame_type_) { |
| 1444 case PING: { | 1389 case PING: { |
| 1445 SpdyPingId id = 0; | 1390 SpdyPingId id = 0; |
| 1446 bool is_ack = protocol_version_ == HTTP2 && | 1391 bool is_ack = current_frame_flags_ & PING_FLAG_ACK; |
| 1447 (current_frame_flags_ & PING_FLAG_ACK); | |
| 1448 bool successful_read = true; | 1392 bool successful_read = true; |
| 1449 successful_read = reader.ReadUInt64(&id); | 1393 successful_read = reader.ReadUInt64(&id); |
| 1450 DCHECK(successful_read); | 1394 DCHECK(successful_read); |
| 1451 DCHECK(reader.IsDoneReading()); | 1395 DCHECK(reader.IsDoneReading()); |
| 1452 visitor_->OnPing(id, is_ack); | 1396 visitor_->OnPing(id, is_ack); |
| 1453 } | 1397 } |
| 1454 break; | 1398 break; |
| 1455 case WINDOW_UPDATE: { | 1399 case WINDOW_UPDATE: { |
| 1456 uint32_t delta_window_size = 0; | 1400 uint32_t delta_window_size = 0; |
| 1457 bool successful_read = true; | 1401 bool successful_read = true; |
| 1458 successful_read = reader.ReadUInt32(&delta_window_size); | 1402 successful_read = reader.ReadUInt32(&delta_window_size); |
| 1459 DCHECK(successful_read); | 1403 DCHECK(successful_read); |
| 1460 DCHECK(reader.IsDoneReading()); | 1404 DCHECK(reader.IsDoneReading()); |
| 1461 visitor_->OnWindowUpdate(current_frame_stream_id_, | 1405 visitor_->OnWindowUpdate(current_frame_stream_id_, |
| 1462 delta_window_size); | 1406 delta_window_size); |
| 1463 } | 1407 } |
| 1464 break; | 1408 break; |
| 1465 case BLOCKED: { | 1409 case BLOCKED: { |
| 1466 DCHECK_EQ(HTTP2, protocol_version_); | |
| 1467 DCHECK(reader.IsDoneReading()); | 1410 DCHECK(reader.IsDoneReading()); |
| 1468 visitor_->OnBlocked(current_frame_stream_id_); | 1411 visitor_->OnBlocked(current_frame_stream_id_); |
| 1469 } | 1412 } |
| 1470 break; | 1413 break; |
| 1471 case PRIORITY: { | 1414 case PRIORITY: { |
| 1472 DCHECK_EQ(HTTP2, protocol_version_); | |
| 1473 uint32_t stream_dependency; | 1415 uint32_t stream_dependency; |
| 1474 uint32_t parent_stream_id; | 1416 uint32_t parent_stream_id; |
| 1475 bool exclusive; | 1417 bool exclusive; |
| 1476 uint8_t serialized_weight; | 1418 uint8_t serialized_weight; |
| 1477 bool successful_read = reader.ReadUInt32(&stream_dependency); | 1419 bool successful_read = reader.ReadUInt32(&stream_dependency); |
| 1478 DCHECK(successful_read); | 1420 DCHECK(successful_read); |
| 1479 UnpackStreamDependencyValues(stream_dependency, &exclusive, | 1421 UnpackStreamDependencyValues(stream_dependency, &exclusive, |
| 1480 &parent_stream_id); | 1422 &parent_stream_id); |
| 1481 | 1423 |
| 1482 successful_read = reader.ReadUInt8(&serialized_weight); | 1424 successful_read = reader.ReadUInt8(&serialized_weight); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 current_frame_buffer_.len()); | 1466 current_frame_buffer_.len()); |
| 1525 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. | 1467 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. |
| 1526 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1468 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 1527 DCHECK(successful_read); | 1469 DCHECK(successful_read); |
| 1528 | 1470 |
| 1529 // Parse status code. | 1471 // Parse status code. |
| 1530 SpdyGoAwayStatus status = GOAWAY_OK; | 1472 SpdyGoAwayStatus status = GOAWAY_OK; |
| 1531 uint32_t status_raw = GOAWAY_OK; | 1473 uint32_t status_raw = GOAWAY_OK; |
| 1532 successful_read = reader.ReadUInt32(&status_raw); | 1474 successful_read = reader.ReadUInt32(&status_raw); |
| 1533 DCHECK(successful_read); | 1475 DCHECK(successful_read); |
| 1534 if (SpdyConstants::IsValidGoAwayStatus(protocol_version_, status_raw)) { | 1476 if (SpdyConstants::IsValidGoAwayStatus(status_raw)) { |
| 1535 status = | 1477 status = SpdyConstants::ParseGoAwayStatus(status_raw); |
| 1536 SpdyConstants::ParseGoAwayStatus(protocol_version_, status_raw); | |
| 1537 } else { | 1478 } else { |
| 1538 if (protocol_version_ == HTTP2) { | 1479 // Treat unrecognized status codes as INTERNAL_ERROR as |
| 1539 // Treat unrecognized status codes as INTERNAL_ERROR as | 1480 // recommended by the HTTP/2 spec. |
| 1540 // recommended by the HTTP/2 spec. | 1481 status = GOAWAY_INTERNAL_ERROR; |
| 1541 status = GOAWAY_INTERNAL_ERROR; | |
| 1542 } | |
| 1543 } | 1482 } |
| 1544 // Finished parsing the GOAWAY header, call frame handler. | 1483 // Finished parsing the GOAWAY header, call frame handler. |
| 1545 visitor_->OnGoAway(current_frame_stream_id_, status); | 1484 visitor_->OnGoAway(current_frame_stream_id_, status); |
| 1546 } | 1485 } |
| 1547 } | 1486 } |
| 1548 | 1487 |
| 1549 // Handle remaining data as opaque. | 1488 // Handle remaining data as opaque. |
| 1550 bool processed_successfully = true; | 1489 bool processed_successfully = true; |
| 1551 if (len > 0) { | 1490 if (len > 0) { |
| 1552 processed_successfully = visitor_->OnGoAwayFrameData(data, len); | 1491 processed_successfully = visitor_->OnGoAwayFrameData(data, len); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 if (current_frame_buffer_.len() == header_size) { | 1524 if (current_frame_buffer_.len() == header_size) { |
| 1586 // Parse out the last good stream id. | 1525 // Parse out the last good stream id. |
| 1587 SpdyFrameReader reader(current_frame_buffer_.data(), | 1526 SpdyFrameReader reader(current_frame_buffer_.data(), |
| 1588 current_frame_buffer_.len()); | 1527 current_frame_buffer_.len()); |
| 1589 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. | 1528 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. |
| 1590 | 1529 |
| 1591 SpdyRstStreamStatus status = RST_STREAM_NO_ERROR; | 1530 SpdyRstStreamStatus status = RST_STREAM_NO_ERROR; |
| 1592 uint32_t status_raw = status; | 1531 uint32_t status_raw = status; |
| 1593 bool successful_read = reader.ReadUInt32(&status_raw); | 1532 bool successful_read = reader.ReadUInt32(&status_raw); |
| 1594 DCHECK(successful_read); | 1533 DCHECK(successful_read); |
| 1595 if (SpdyConstants::IsValidRstStreamStatus(protocol_version_, | 1534 if (SpdyConstants::IsValidRstStreamStatus(status_raw)) { |
| 1596 status_raw)) { | 1535 status = SpdyConstants::ParseRstStreamStatus(status_raw); |
| 1597 status = | |
| 1598 SpdyConstants::ParseRstStreamStatus(protocol_version_, status_raw); | |
| 1599 } else { | 1536 } else { |
| 1600 if (protocol_version_ == HTTP2) { | 1537 // Treat unrecognized status codes as INTERNAL_ERROR as |
| 1601 // Treat unrecognized status codes as INTERNAL_ERROR as | 1538 // recommended by the HTTP/2 spec. |
| 1602 // recommended by the HTTP/2 spec. | 1539 status = RST_STREAM_INTERNAL_ERROR; |
| 1603 status = RST_STREAM_INTERNAL_ERROR; | |
| 1604 } | |
| 1605 } | 1540 } |
| 1606 // Finished parsing the RST_STREAM header, call frame handler. | 1541 // Finished parsing the RST_STREAM header, call frame handler. |
| 1607 visitor_->OnRstStream(current_frame_stream_id_, status); | 1542 visitor_->OnRstStream(current_frame_stream_id_, status); |
| 1608 } | 1543 } |
| 1609 } | 1544 } |
| 1610 | 1545 |
| 1611 // Handle remaining data as opaque. | 1546 // Handle remaining data as opaque. |
| 1612 // TODO(jamessynge): Remove support for variable length/opaque trailer. | 1547 // TODO(jamessynge): Remove support for variable length/opaque trailer. |
| 1613 bool processed_successfully = true; | 1548 bool processed_successfully = true; |
| 1614 if (len > 0) { | 1549 if (len > 0) { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 | 1723 |
| 1789 // Read header name. | 1724 // Read header name. |
| 1790 if (!reader.ReadStringPiece32(&temp)) { | 1725 if (!reader.ReadStringPiece32(&temp)) { |
| 1791 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " | 1726 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " |
| 1792 << num_headers << ")."; | 1727 << num_headers << ")."; |
| 1793 return false; | 1728 return false; |
| 1794 } | 1729 } |
| 1795 const char* begin = temp.data(); | 1730 const char* begin = temp.data(); |
| 1796 const char* end = begin; | 1731 const char* end = begin; |
| 1797 std::advance(end, temp.size()); | 1732 std::advance(end, temp.size()); |
| 1798 if (protocol_version_ == HTTP2 && std::any_of(begin, end, isupper)) { | 1733 if (std::any_of(begin, end, isupper)) { |
| 1799 DVLOG(1) << "Malformed header: Header name " << temp | 1734 DVLOG(1) << "Malformed header: Header name " << temp |
| 1800 << " contains upper-case characters."; | 1735 << " contains upper-case characters."; |
| 1801 return false; | 1736 return false; |
| 1802 } | 1737 } |
| 1803 std::string name = temp.as_string(); | 1738 std::string name = temp.as_string(); |
| 1804 | 1739 |
| 1805 // Read header value. | 1740 // Read header value. |
| 1806 if (!reader.ReadStringPiece32(&temp)) { | 1741 if (!reader.ReadStringPiece32(&temp)) { |
| 1807 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " | 1742 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " |
| 1808 << num_headers << ")."; | 1743 << num_headers << ")."; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 | 1795 |
| 1861 if (framer_->debug_visitor_ != nullptr) { | 1796 if (framer_->debug_visitor_ != nullptr) { |
| 1862 debug_total_size_ += size_without_block; | 1797 debug_total_size_ += size_without_block; |
| 1863 debug_total_size_ += encoding->size(); | 1798 debug_total_size_ += encoding->size(); |
| 1864 if (!has_next_frame_) { | 1799 if (!has_next_frame_) { |
| 1865 // TODO(birenroy) are these (here and below) still necessary? | 1800 // TODO(birenroy) are these (here and below) still necessary? |
| 1866 // HTTP2 uses HPACK for header compression. However, continue to | 1801 // HTTP2 uses HPACK for header compression. However, continue to |
| 1867 // use GetSerializedLength() for an apples-to-apples comparision of | 1802 // use GetSerializedLength() for an apples-to-apples comparision of |
| 1868 // compression performance between HPACK and SPDY w/ deflate. | 1803 // compression performance between HPACK and SPDY w/ deflate. |
| 1869 size_t debug_payload_len = | 1804 size_t debug_payload_len = |
| 1870 framer_->GetSerializedLength(HTTP2, &headers_ir_->header_block()); | 1805 framer_->GetSerializedLength(&headers_ir_->header_block()); |
| 1871 framer_->debug_visitor_->OnSendCompressedFrame(headers_ir_->stream_id(), | 1806 framer_->debug_visitor_->OnSendCompressedFrame(headers_ir_->stream_id(), |
| 1872 HEADERS, debug_payload_len, | 1807 HEADERS, debug_payload_len, |
| 1873 debug_total_size_); | 1808 debug_total_size_); |
| 1874 } | 1809 } |
| 1875 } | 1810 } |
| 1876 | 1811 |
| 1877 if (is_first_frame_) { | 1812 if (is_first_frame_) { |
| 1878 is_first_frame_ = false; | 1813 is_first_frame_ = false; |
| 1879 headers_ir_->set_end_headers(!has_next_frame_); | 1814 headers_ir_->set_end_headers(!has_next_frame_); |
| 1880 return framer_->SerializeHeadersGivenEncoding(*headers_ir_, *encoding); | 1815 return framer_->SerializeHeadersGivenEncoding(*headers_ir_, *encoding); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1894 | 1829 |
| 1895 int num_padding_fields = 0; | 1830 int num_padding_fields = 0; |
| 1896 if (data_ir.padded()) { | 1831 if (data_ir.padded()) { |
| 1897 flags |= DATA_FLAG_PADDED; | 1832 flags |= DATA_FLAG_PADDED; |
| 1898 ++num_padding_fields; | 1833 ++num_padding_fields; |
| 1899 } | 1834 } |
| 1900 | 1835 |
| 1901 const size_t size_with_padding = num_padding_fields + data_ir.data_len() + | 1836 const size_t size_with_padding = num_padding_fields + data_ir.data_len() + |
| 1902 data_ir.padding_payload_len() + | 1837 data_ir.padding_payload_len() + |
| 1903 GetDataFrameMinimumSize(); | 1838 GetDataFrameMinimumSize(); |
| 1904 SpdyFrameBuilder builder(size_with_padding, protocol_version_); | 1839 SpdyFrameBuilder builder(size_with_padding); |
| 1905 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); | 1840 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); |
| 1906 if (data_ir.padded()) { | 1841 if (data_ir.padded()) { |
| 1907 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 1842 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
| 1908 } | 1843 } |
| 1909 builder.WriteBytes(data_ir.data(), data_ir.data_len()); | 1844 builder.WriteBytes(data_ir.data(), data_ir.data_len()); |
| 1910 if (data_ir.padding_payload_len() > 0) { | 1845 if (data_ir.padding_payload_len() > 0) { |
| 1911 string padding(data_ir.padding_payload_len(), 0); | 1846 string padding(data_ir.padding_payload_len(), 0); |
| 1912 builder.WriteBytes(padding.data(), padding.length()); | 1847 builder.WriteBytes(padding.data(), padding.length()); |
| 1913 } | 1848 } |
| 1914 DCHECK_EQ(size_with_padding, builder.length()); | 1849 DCHECK_EQ(size_with_padding, builder.length()); |
| 1915 return builder.take(); | 1850 return builder.take(); |
| 1916 } | 1851 } |
| 1917 | 1852 |
| 1918 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 1853 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( |
| 1919 const SpdyDataIR& data_ir) const { | 1854 const SpdyDataIR& data_ir) const { |
| 1920 uint8_t flags = DATA_FLAG_NONE; | 1855 uint8_t flags = DATA_FLAG_NONE; |
| 1921 if (data_ir.fin()) { | 1856 if (data_ir.fin()) { |
| 1922 flags = DATA_FLAG_FIN; | 1857 flags = DATA_FLAG_FIN; |
| 1923 } | 1858 } |
| 1924 | 1859 |
| 1925 size_t frame_size = GetDataFrameMinimumSize(); | 1860 size_t frame_size = GetDataFrameMinimumSize(); |
| 1926 size_t num_padding_fields = 0; | 1861 size_t num_padding_fields = 0; |
| 1927 if (protocol_version_ == HTTP2) { | 1862 if (data_ir.padded()) { |
| 1928 if (data_ir.padded()) { | 1863 flags |= DATA_FLAG_PADDED; |
| 1929 flags |= DATA_FLAG_PADDED; | 1864 ++num_padding_fields; |
| 1930 ++num_padding_fields; | |
| 1931 } | |
| 1932 frame_size += num_padding_fields; | 1865 frame_size += num_padding_fields; |
| 1933 } | 1866 } |
| 1934 | 1867 |
| 1935 SpdyFrameBuilder builder(frame_size, protocol_version_); | 1868 SpdyFrameBuilder builder(frame_size); |
| 1936 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); | 1869 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); |
| 1937 if (protocol_version_ == HTTP2) { | 1870 if (data_ir.padded()) { |
| 1938 if (data_ir.padded()) { | 1871 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
| 1939 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | |
| 1940 } | |
| 1941 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() + | |
| 1942 data_ir.padding_payload_len()); | |
| 1943 } else { | |
| 1944 builder.OverwriteLength(*this, data_ir.data_len()); | |
| 1945 } | 1872 } |
| 1873 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() + |
| 1874 data_ir.padding_payload_len()); |
| 1946 DCHECK_EQ(frame_size, builder.length()); | 1875 DCHECK_EQ(frame_size, builder.length()); |
| 1947 return builder.take(); | 1876 return builder.take(); |
| 1948 } | 1877 } |
| 1949 | 1878 |
| 1950 SpdySerializedFrame SpdyFramer::SerializeRstStream( | 1879 SpdySerializedFrame SpdyFramer::SerializeRstStream( |
| 1951 const SpdyRstStreamIR& rst_stream) const { | 1880 const SpdyRstStreamIR& rst_stream) const { |
| 1952 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM | 1881 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM |
| 1953 // payloads, but will not emit them. This is used for draft HTTP/2, | 1882 // payloads, but will not emit them. This is used for draft HTTP/2, |
| 1954 // which doesn't currently include RST_STREAM payloads. GFE flags have been | 1883 // which doesn't currently include RST_STREAM payloads. GFE flags have been |
| 1955 // commented but left in place to simplify future patching. | 1884 // commented but left in place to simplify future patching. |
| 1956 // Compute the output buffer size, taking opaque data into account. | 1885 // Compute the output buffer size, taking opaque data into account. |
| 1957 size_t expected_length = GetRstStreamMinimumSize(); | 1886 size_t expected_length = GetRstStreamMinimumSize(); |
| 1958 SpdyFrameBuilder builder(expected_length, protocol_version_); | 1887 SpdyFrameBuilder builder(expected_length); |
| 1959 | 1888 |
| 1960 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); | 1889 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); |
| 1961 | 1890 |
| 1962 builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus( | 1891 builder.WriteUInt32( |
| 1963 protocol_version_, rst_stream.status())); | 1892 SpdyConstants::SerializeRstStreamStatus(rst_stream.status())); |
| 1964 | 1893 |
| 1965 DCHECK_EQ(expected_length, builder.length()); | 1894 DCHECK_EQ(expected_length, builder.length()); |
| 1966 return builder.take(); | 1895 return builder.take(); |
| 1967 } | 1896 } |
| 1968 | 1897 |
| 1969 SpdySerializedFrame SpdyFramer::SerializeSettings( | 1898 SpdySerializedFrame SpdyFramer::SerializeSettings( |
| 1970 const SpdySettingsIR& settings) const { | 1899 const SpdySettingsIR& settings) const { |
| 1971 uint8_t flags = 0; | 1900 uint8_t flags = 0; |
| 1972 | 1901 |
| 1973 if (settings.is_ack()) { | 1902 if (settings.is_ack()) { |
| 1974 flags |= SETTINGS_FLAG_ACK; | 1903 flags |= SETTINGS_FLAG_ACK; |
| 1975 } | 1904 } |
| 1976 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 1905 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
| 1977 | 1906 |
| 1978 int setting_size = 6; | 1907 int setting_size = 6; |
| 1979 // Size, in bytes, of this SETTINGS frame. | 1908 // Size, in bytes, of this SETTINGS frame. |
| 1980 const size_t size = GetSettingsMinimumSize() + | 1909 const size_t size = GetSettingsMinimumSize() + |
| 1981 (values->size() * setting_size); | 1910 (values->size() * setting_size); |
| 1982 SpdyFrameBuilder builder(size, protocol_version_); | 1911 SpdyFrameBuilder builder(size); |
| 1983 builder.BeginNewFrame(*this, SETTINGS, flags, 0); | 1912 builder.BeginNewFrame(*this, SETTINGS, flags, 0); |
| 1984 | 1913 |
| 1985 // If this is an ACK, payload should be empty. | 1914 // If this is an ACK, payload should be empty. |
| 1986 if (protocol_version_ == HTTP2 && settings.is_ack()) { | 1915 if (settings.is_ack()) { |
| 1987 return builder.take(); | 1916 return builder.take(); |
| 1988 } | 1917 } |
| 1989 | 1918 |
| 1990 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); | 1919 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); |
| 1991 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); | 1920 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); |
| 1992 it != values->end(); | 1921 it != values->end(); |
| 1993 ++it) { | 1922 ++it) { |
| 1994 int setting_id = | 1923 int setting_id = SpdyConstants::SerializeSettingId(it->first); |
| 1995 SpdyConstants::SerializeSettingId(protocol_version_, it->first); | |
| 1996 DCHECK_GE(setting_id, 0); | 1924 DCHECK_GE(setting_id, 0); |
| 1997 builder.WriteUInt16(static_cast<uint16_t>(setting_id)); | 1925 builder.WriteUInt16(static_cast<uint16_t>(setting_id)); |
| 1998 builder.WriteUInt32(it->second.value); | 1926 builder.WriteUInt32(it->second.value); |
| 1999 } | 1927 } |
| 2000 DCHECK_EQ(size, builder.length()); | 1928 DCHECK_EQ(size, builder.length()); |
| 2001 return builder.take(); | 1929 return builder.take(); |
| 2002 } | 1930 } |
| 2003 | 1931 |
| 2004 SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 1932 SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
| 2005 SpdyFrameBuilder builder(GetPingSize(), protocol_version_); | 1933 SpdyFrameBuilder builder(GetPingSize()); |
| 2006 uint8_t flags = 0; | 1934 uint8_t flags = 0; |
| 2007 if (ping.is_ack()) { | 1935 if (ping.is_ack()) { |
| 2008 flags |= PING_FLAG_ACK; | 1936 flags |= PING_FLAG_ACK; |
| 2009 } | 1937 } |
| 2010 builder.BeginNewFrame(*this, PING, flags, 0); | 1938 builder.BeginNewFrame(*this, PING, flags, 0); |
| 2011 builder.WriteUInt64(ping.id()); | 1939 builder.WriteUInt64(ping.id()); |
| 2012 DCHECK_EQ(GetPingSize(), builder.length()); | 1940 DCHECK_EQ(GetPingSize(), builder.length()); |
| 2013 return builder.take(); | 1941 return builder.take(); |
| 2014 } | 1942 } |
| 2015 | 1943 |
| 2016 SpdySerializedFrame SpdyFramer::SerializeGoAway( | 1944 SpdySerializedFrame SpdyFramer::SerializeGoAway( |
| 2017 const SpdyGoAwayIR& goaway) const { | 1945 const SpdyGoAwayIR& goaway) const { |
| 2018 // Compute the output buffer size, take opaque data into account. | 1946 // Compute the output buffer size, take opaque data into account. |
| 2019 size_t expected_length = GetGoAwayMinimumSize(); | 1947 size_t expected_length = GetGoAwayMinimumSize(); |
| 2020 if (protocol_version_ == HTTP2) { | 1948 expected_length += goaway.description().size(); |
| 2021 expected_length += goaway.description().size(); | 1949 SpdyFrameBuilder builder(expected_length); |
| 2022 } | |
| 2023 SpdyFrameBuilder builder(expected_length, protocol_version_); | |
| 2024 | 1950 |
| 2025 // Serialize the GOAWAY frame. | 1951 // Serialize the GOAWAY frame. |
| 2026 builder.BeginNewFrame(*this, GOAWAY, 0, 0); | 1952 builder.BeginNewFrame(*this, GOAWAY, 0, 0); |
| 2027 | 1953 |
| 2028 // GOAWAY frames specify the last good stream id. | 1954 // GOAWAY frames specify the last good stream id. |
| 2029 builder.WriteUInt32(goaway.last_good_stream_id()); | 1955 builder.WriteUInt32(goaway.last_good_stream_id()); |
| 2030 | 1956 |
| 2031 // GOAWAY frames also specify the error status code. | 1957 // GOAWAY frames also specify the error status code. |
| 2032 builder.WriteUInt32( | 1958 builder.WriteUInt32(SpdyConstants::SerializeGoAwayStatus(goaway.status())); |
| 2033 SpdyConstants::SerializeGoAwayStatus(protocol_version_, goaway.status())); | |
| 2034 | 1959 |
| 2035 // In HTTP2, GOAWAY frames may also specify opaque data. | 1960 // GOAWAY frames may also specify opaque data. |
| 2036 if ((protocol_version_ == HTTP2) && (goaway.description().size() > 0)) { | 1961 if (!goaway.description().empty()) { |
| 2037 builder.WriteBytes(goaway.description().data(), | 1962 builder.WriteBytes(goaway.description().data(), |
| 2038 goaway.description().size()); | 1963 goaway.description().size()); |
| 2039 } | 1964 } |
| 2040 | 1965 |
| 2041 DCHECK_EQ(expected_length, builder.length()); | 1966 DCHECK_EQ(expected_length, builder.length()); |
| 2042 return builder.take(); | 1967 return builder.take(); |
| 2043 } | 1968 } |
| 2044 | 1969 |
| 2045 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { | 1970 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { |
| 2046 uint8_t flags = 0; | 1971 uint8_t flags = 0; |
| 2047 if (headers.fin()) { | 1972 if (headers.fin()) { |
| 2048 flags |= CONTROL_FLAG_FIN; | 1973 flags |= CONTROL_FLAG_FIN; |
| 2049 } | 1974 } |
| 2050 if (protocol_version_ == HTTP2) { | 1975 // This will get overwritten if we overflow into a CONTINUATION frame. |
| 2051 // This will get overwritten if we overflow into a CONTINUATION frame. | 1976 flags |= HEADERS_FLAG_END_HEADERS; |
| 2052 flags |= HEADERS_FLAG_END_HEADERS; | 1977 if (headers.has_priority()) { |
| 2053 if (headers.has_priority()) { | 1978 flags |= HEADERS_FLAG_PRIORITY; |
| 2054 flags |= HEADERS_FLAG_PRIORITY; | 1979 } |
| 2055 } | 1980 if (headers.padded()) { |
| 2056 if (headers.padded()) { | 1981 flags |= HEADERS_FLAG_PADDED; |
| 2057 flags |= HEADERS_FLAG_PADDED; | |
| 2058 } | |
| 2059 } | 1982 } |
| 2060 | 1983 |
| 2061 // The size of this frame, including padding (if there is any) and | 1984 // The size of this frame, including padding (if there is any) and |
| 2062 // variable-length header block. | 1985 // variable-length header block. |
| 2063 size_t size = GetHeadersMinimumSize(); | 1986 size_t size = GetHeadersMinimumSize(); |
| 2064 | 1987 |
| 2065 if (protocol_version_ == HTTP2 && headers.padded()) { | 1988 if (headers.padded()) { |
| 2066 size += kPadLengthFieldSize; | 1989 size += kPadLengthFieldSize; |
| 2067 size += headers.padding_payload_len(); | 1990 size += headers.padding_payload_len(); |
| 2068 } | 1991 } |
| 2069 | 1992 |
| 2070 int weight = 0; | 1993 int weight = 0; |
| 2071 if (headers.has_priority()) { | 1994 if (headers.has_priority()) { |
| 2072 weight = ClampHttp2Weight(headers.weight()); | 1995 weight = ClampHttp2Weight(headers.weight()); |
| 2073 size += 5; | 1996 size += 5; |
| 2074 } | 1997 } |
| 2075 | 1998 |
| 2076 string hpack_encoding; | 1999 string hpack_encoding; |
| 2077 if (enable_compression_) { | 2000 if (enable_compression_) { |
| 2078 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding); | 2001 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding); |
| 2079 } else { | 2002 } else { |
| 2080 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(headers.header_block(), | 2003 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(headers.header_block(), |
| 2081 &hpack_encoding); | 2004 &hpack_encoding); |
| 2082 } | 2005 } |
| 2083 size += hpack_encoding.size(); | 2006 size += hpack_encoding.size(); |
| 2084 if (size > kMaxControlFrameSize) { | 2007 if (size > kMaxControlFrameSize) { |
| 2085 size += GetNumberRequiredContinuationFrames(size) * | 2008 size += GetNumberRequiredContinuationFrames(size) * |
| 2086 GetContinuationMinimumSize(); | 2009 GetContinuationMinimumSize(); |
| 2087 flags &= ~HEADERS_FLAG_END_HEADERS; | 2010 flags &= ~HEADERS_FLAG_END_HEADERS; |
| 2088 } | 2011 } |
| 2089 | 2012 |
| 2090 SpdyFrameBuilder builder(size, protocol_version_); | 2013 SpdyFrameBuilder builder(size); |
| 2091 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); | 2014 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); |
| 2092 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2015 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
| 2093 | 2016 |
| 2094 int padding_payload_len = 0; | 2017 int padding_payload_len = 0; |
| 2095 if (headers.padded()) { | 2018 if (headers.padded()) { |
| 2096 builder.WriteUInt8(headers.padding_payload_len()); | 2019 builder.WriteUInt8(headers.padding_payload_len()); |
| 2097 padding_payload_len = headers.padding_payload_len(); | 2020 padding_payload_len = headers.padding_payload_len(); |
| 2098 } | 2021 } |
| 2099 if (headers.has_priority()) { | 2022 if (headers.has_priority()) { |
| 2100 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), | 2023 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), |
| 2101 headers.parent_stream_id())); | 2024 headers.parent_stream_id())); |
| 2102 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. | 2025 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. |
| 2103 builder.WriteUInt8(weight - 1); | 2026 builder.WriteUInt8(weight - 1); |
| 2104 } | 2027 } |
| 2105 WritePayloadWithContinuation(&builder, hpack_encoding, headers.stream_id(), | 2028 WritePayloadWithContinuation(&builder, hpack_encoding, headers.stream_id(), |
| 2106 HEADERS, padding_payload_len); | 2029 HEADERS, padding_payload_len); |
| 2107 | 2030 |
| 2108 if (debug_visitor_) { | 2031 if (debug_visitor_) { |
| 2109 // HTTP2 uses HPACK for header compression. However, continue to | 2032 // HTTP2 uses HPACK for header compression. However, continue to |
| 2110 // use GetSerializedLength() for an apples-to-apples comparision of | 2033 // use GetSerializedLength() for an apples-to-apples comparision of |
| 2111 // compression performance between HPACK and SPDY w/ deflate. | 2034 // compression performance between HPACK and SPDY w/ deflate. |
| 2112 const size_t payload_len = | 2035 const size_t payload_len = GetSerializedLength(&(headers.header_block())); |
| 2113 GetSerializedLength(protocol_version_, &(headers.header_block())); | |
| 2114 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), | 2036 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), |
| 2115 HEADERS, | 2037 HEADERS, |
| 2116 payload_len, | 2038 payload_len, |
| 2117 builder.length()); | 2039 builder.length()); |
| 2118 } | 2040 } |
| 2119 | 2041 |
| 2120 return builder.take(); | 2042 return builder.take(); |
| 2121 } | 2043 } |
| 2122 | 2044 |
| 2123 SpdySerializedFrame SpdyFramer::SerializeWindowUpdate( | 2045 SpdySerializedFrame SpdyFramer::SerializeWindowUpdate( |
| 2124 const SpdyWindowUpdateIR& window_update) const { | 2046 const SpdyWindowUpdateIR& window_update) const { |
| 2125 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version_); | 2047 SpdyFrameBuilder builder(GetWindowUpdateSize()); |
| 2126 builder.BeginNewFrame(*this, WINDOW_UPDATE, kNoFlags, | 2048 builder.BeginNewFrame(*this, WINDOW_UPDATE, kNoFlags, |
| 2127 window_update.stream_id()); | 2049 window_update.stream_id()); |
| 2128 builder.WriteUInt32(window_update.delta()); | 2050 builder.WriteUInt32(window_update.delta()); |
| 2129 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 2051 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
| 2130 return builder.take(); | 2052 return builder.take(); |
| 2131 } | 2053 } |
| 2132 | 2054 |
| 2133 SpdySerializedFrame SpdyFramer::SerializeBlocked( | 2055 SpdySerializedFrame SpdyFramer::SerializeBlocked( |
| 2134 const SpdyBlockedIR& blocked) const { | 2056 const SpdyBlockedIR& blocked) const { |
| 2135 DCHECK_EQ(HTTP2, protocol_version_); | 2057 SpdyFrameBuilder builder(GetBlockedSize()); |
| 2136 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version_); | |
| 2137 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); | 2058 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); |
| 2138 return builder.take(); | 2059 return builder.take(); |
| 2139 } | 2060 } |
| 2140 | 2061 |
| 2141 SpdySerializedFrame SpdyFramer::SerializePushPromise( | 2062 SpdySerializedFrame SpdyFramer::SerializePushPromise( |
| 2142 const SpdyPushPromiseIR& push_promise) { | 2063 const SpdyPushPromiseIR& push_promise) { |
| 2143 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2144 uint8_t flags = 0; | 2064 uint8_t flags = 0; |
| 2145 // This will get overwritten if we overflow into a CONTINUATION frame. | 2065 // This will get overwritten if we overflow into a CONTINUATION frame. |
| 2146 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2066 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
| 2147 // The size of this frame, including variable-length name-value block. | 2067 // The size of this frame, including variable-length name-value block. |
| 2148 size_t size = GetPushPromiseMinimumSize(); | 2068 size_t size = GetPushPromiseMinimumSize(); |
| 2149 | 2069 |
| 2150 if (push_promise.padded()) { | 2070 if (push_promise.padded()) { |
| 2151 flags |= PUSH_PROMISE_FLAG_PADDED; | 2071 flags |= PUSH_PROMISE_FLAG_PADDED; |
| 2152 size += kPadLengthFieldSize; | 2072 size += kPadLengthFieldSize; |
| 2153 size += push_promise.padding_payload_len(); | 2073 size += push_promise.padding_payload_len(); |
| 2154 } | 2074 } |
| 2155 | 2075 |
| 2156 string hpack_encoding; | 2076 string hpack_encoding; |
| 2157 if (enable_compression_) { | 2077 if (enable_compression_) { |
| 2158 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), | 2078 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), |
| 2159 &hpack_encoding); | 2079 &hpack_encoding); |
| 2160 } else { | 2080 } else { |
| 2161 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( | 2081 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( |
| 2162 push_promise.header_block(), &hpack_encoding); | 2082 push_promise.header_block(), &hpack_encoding); |
| 2163 } | 2083 } |
| 2164 size += hpack_encoding.size(); | 2084 size += hpack_encoding.size(); |
| 2165 if (size > kMaxControlFrameSize) { | 2085 if (size > kMaxControlFrameSize) { |
| 2166 size += GetNumberRequiredContinuationFrames(size) * | 2086 size += GetNumberRequiredContinuationFrames(size) * |
| 2167 GetContinuationMinimumSize(); | 2087 GetContinuationMinimumSize(); |
| 2168 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2088 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
| 2169 } | 2089 } |
| 2170 | 2090 |
| 2171 SpdyFrameBuilder builder(size, protocol_version_); | 2091 SpdyFrameBuilder builder(size); |
| 2172 builder.BeginNewFrame(*this, | 2092 builder.BeginNewFrame(*this, |
| 2173 PUSH_PROMISE, | 2093 PUSH_PROMISE, |
| 2174 flags, | 2094 flags, |
| 2175 push_promise.stream_id()); | 2095 push_promise.stream_id()); |
| 2176 int padding_payload_len = 0; | 2096 int padding_payload_len = 0; |
| 2177 if (push_promise.padded()) { | 2097 if (push_promise.padded()) { |
| 2178 builder.WriteUInt8(push_promise.padding_payload_len()); | 2098 builder.WriteUInt8(push_promise.padding_payload_len()); |
| 2179 builder.WriteUInt32(push_promise.promised_stream_id()); | 2099 builder.WriteUInt32(push_promise.promised_stream_id()); |
| 2180 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, | 2100 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, |
| 2181 builder.length()); | 2101 builder.length()); |
| 2182 | 2102 |
| 2183 padding_payload_len = push_promise.padding_payload_len(); | 2103 padding_payload_len = push_promise.padding_payload_len(); |
| 2184 } else { | 2104 } else { |
| 2185 builder.WriteUInt32(push_promise.promised_stream_id()); | 2105 builder.WriteUInt32(push_promise.promised_stream_id()); |
| 2186 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); | 2106 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); |
| 2187 } | 2107 } |
| 2188 | 2108 |
| 2189 WritePayloadWithContinuation(&builder, | 2109 WritePayloadWithContinuation(&builder, |
| 2190 hpack_encoding, | 2110 hpack_encoding, |
| 2191 push_promise.stream_id(), | 2111 push_promise.stream_id(), |
| 2192 PUSH_PROMISE, | 2112 PUSH_PROMISE, |
| 2193 padding_payload_len); | 2113 padding_payload_len); |
| 2194 | 2114 |
| 2195 if (debug_visitor_) { | 2115 if (debug_visitor_) { |
| 2196 // HTTP2 uses HPACK for header compression. However, continue to | 2116 // HTTP2 uses HPACK for header compression. However, continue to |
| 2197 // use GetSerializedLength() for an apples-to-apples comparision of | 2117 // use GetSerializedLength() for an apples-to-apples comparision of |
| 2198 // compression performance between HPACK and SPDY w/ deflate. | 2118 // compression performance between HPACK and SPDY w/ deflate. |
| 2199 const size_t payload_len = | 2119 const size_t payload_len = |
| 2200 GetSerializedLength(protocol_version_, &(push_promise.header_block())); | 2120 GetSerializedLength(&(push_promise.header_block())); |
| 2201 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), | 2121 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), |
| 2202 PUSH_PROMISE, | 2122 PUSH_PROMISE, |
| 2203 payload_len, | 2123 payload_len, |
| 2204 builder.length()); | 2124 builder.length()); |
| 2205 } | 2125 } |
| 2206 | 2126 |
| 2207 return builder.take(); | 2127 return builder.take(); |
| 2208 } | 2128 } |
| 2209 | 2129 |
| 2210 SpdySerializedFrame SpdyFramer::SerializeHeadersGivenEncoding( | 2130 SpdySerializedFrame SpdyFramer::SerializeHeadersGivenEncoding( |
| 2211 const SpdyHeadersIR& headers, | 2131 const SpdyHeadersIR& headers, |
| 2212 const string& encoding) const { | 2132 const string& encoding) const { |
| 2213 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2214 | |
| 2215 size_t frame_size = GetHeaderFrameSizeSansBlock(headers) + encoding.size(); | 2133 size_t frame_size = GetHeaderFrameSizeSansBlock(headers) + encoding.size(); |
| 2216 SpdyFrameBuilder builder(frame_size, protocol_version_); | 2134 SpdyFrameBuilder builder(frame_size); |
| 2217 builder.BeginNewFrame(*this, HEADERS, SerializeHeaderFrameFlags(headers), | 2135 builder.BeginNewFrame(*this, HEADERS, SerializeHeaderFrameFlags(headers), |
| 2218 headers.stream_id()); | 2136 headers.stream_id()); |
| 2219 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); | 2137 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); |
| 2220 | 2138 |
| 2221 if (headers.padded()) { | 2139 if (headers.padded()) { |
| 2222 builder.WriteUInt8(headers.padding_payload_len()); | 2140 builder.WriteUInt8(headers.padding_payload_len()); |
| 2223 } | 2141 } |
| 2224 | 2142 |
| 2225 if (headers.has_priority()) { | 2143 if (headers.has_priority()) { |
| 2226 int weight = ClampHttp2Weight(headers.weight()); | 2144 int weight = ClampHttp2Weight(headers.weight()); |
| 2227 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), | 2145 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), |
| 2228 headers.parent_stream_id())); | 2146 headers.parent_stream_id())); |
| 2229 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. | 2147 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. |
| 2230 builder.WriteUInt8(weight - 1); | 2148 builder.WriteUInt8(weight - 1); |
| 2231 } | 2149 } |
| 2232 | 2150 |
| 2233 builder.WriteBytes(&encoding[0], encoding.size()); | 2151 builder.WriteBytes(&encoding[0], encoding.size()); |
| 2234 | 2152 |
| 2235 if (headers.padding_payload_len() > 0) { | 2153 if (headers.padding_payload_len() > 0) { |
| 2236 string padding(headers.padding_payload_len(), 0); | 2154 string padding(headers.padding_payload_len(), 0); |
| 2237 builder.WriteBytes(padding.data(), padding.length()); | 2155 builder.WriteBytes(padding.data(), padding.length()); |
| 2238 } | 2156 } |
| 2239 return builder.take(); | 2157 return builder.take(); |
| 2240 } | 2158 } |
| 2241 | 2159 |
| 2242 SpdySerializedFrame SpdyFramer::SerializeContinuation( | 2160 SpdySerializedFrame SpdyFramer::SerializeContinuation( |
| 2243 const SpdyContinuationIR& continuation) const { | 2161 const SpdyContinuationIR& continuation) const { |
| 2244 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2245 | |
| 2246 const string& encoding = continuation.encoding(); | 2162 const string& encoding = continuation.encoding(); |
| 2247 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); | 2163 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); |
| 2248 SpdyFrameBuilder builder(frame_size, protocol_version_); | 2164 SpdyFrameBuilder builder(frame_size); |
| 2249 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; | 2165 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; |
| 2250 builder.BeginNewFrame(*this, CONTINUATION, flags, continuation.stream_id()); | 2166 builder.BeginNewFrame(*this, CONTINUATION, flags, continuation.stream_id()); |
| 2251 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); | 2167 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); |
| 2252 | 2168 |
| 2253 builder.WriteBytes(&encoding[0], encoding.size()); | 2169 builder.WriteBytes(&encoding[0], encoding.size()); |
| 2254 return builder.take(); | 2170 return builder.take(); |
| 2255 } | 2171 } |
| 2256 | 2172 |
| 2257 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { | 2173 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { |
| 2258 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2259 | |
| 2260 size_t size = GetAltSvcMinimumSize(); | 2174 size_t size = GetAltSvcMinimumSize(); |
| 2261 size += altsvc_ir.origin().length(); | 2175 size += altsvc_ir.origin().length(); |
| 2262 string value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue( | 2176 string value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue( |
| 2263 altsvc_ir.altsvc_vector()); | 2177 altsvc_ir.altsvc_vector()); |
| 2264 size += value.length(); | 2178 size += value.length(); |
| 2265 | 2179 |
| 2266 SpdyFrameBuilder builder(size, protocol_version_); | 2180 SpdyFrameBuilder builder(size); |
| 2267 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id()); | 2181 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id()); |
| 2268 | 2182 |
| 2269 builder.WriteUInt16(altsvc_ir.origin().length()); | 2183 builder.WriteUInt16(altsvc_ir.origin().length()); |
| 2270 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length()); | 2184 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length()); |
| 2271 builder.WriteBytes(value.data(), value.length()); | 2185 builder.WriteBytes(value.data(), value.length()); |
| 2272 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); | 2186 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); |
| 2273 return builder.take(); | 2187 return builder.take(); |
| 2274 } | 2188 } |
| 2275 | 2189 |
| 2276 SpdySerializedFrame SpdyFramer::SerializePriority( | 2190 SpdySerializedFrame SpdyFramer::SerializePriority( |
| 2277 const SpdyPriorityIR& priority) const { | 2191 const SpdyPriorityIR& priority) const { |
| 2278 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2279 size_t size = GetPrioritySize(); | 2192 size_t size = GetPrioritySize(); |
| 2280 | 2193 |
| 2281 SpdyFrameBuilder builder(size, protocol_version_); | 2194 SpdyFrameBuilder builder(size); |
| 2282 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id()); | 2195 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id()); |
| 2283 | 2196 |
| 2284 builder.WriteUInt32(PackStreamDependencyValues(priority.exclusive(), | 2197 builder.WriteUInt32(PackStreamDependencyValues(priority.exclusive(), |
| 2285 priority.parent_stream_id())); | 2198 priority.parent_stream_id())); |
| 2286 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. | 2199 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. |
| 2287 builder.WriteUInt8(priority.weight() - 1); | 2200 builder.WriteUInt8(priority.weight() - 1); |
| 2288 DCHECK_EQ(GetPrioritySize(), builder.length()); | 2201 DCHECK_EQ(GetPrioritySize(), builder.length()); |
| 2289 return builder.take(); | 2202 return builder.take(); |
| 2290 } | 2203 } |
| 2291 | 2204 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2343 | 2256 |
| 2344 } // namespace | 2257 } // namespace |
| 2345 | 2258 |
| 2346 SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { | 2259 SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { |
| 2347 FrameSerializationVisitor visitor(this); | 2260 FrameSerializationVisitor visitor(this); |
| 2348 frame.Visit(&visitor); | 2261 frame.Visit(&visitor); |
| 2349 return visitor.ReleaseSerializedFrame(); | 2262 return visitor.ReleaseSerializedFrame(); |
| 2350 } | 2263 } |
| 2351 | 2264 |
| 2352 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { | 2265 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { |
| 2353 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2354 DCHECK_GT(size, kMaxControlFrameSize); | 2266 DCHECK_GT(size, kMaxControlFrameSize); |
| 2355 size_t overflow = size - kMaxControlFrameSize; | 2267 size_t overflow = size - kMaxControlFrameSize; |
| 2356 size_t payload_size = kMaxControlFrameSize - GetContinuationMinimumSize(); | 2268 size_t payload_size = kMaxControlFrameSize - GetContinuationMinimumSize(); |
| 2357 // This is ceiling(overflow/payload_size) using integer arithmetics. | 2269 // This is ceiling(overflow/payload_size) using integer arithmetics. |
| 2358 return (overflow - 1) / payload_size + 1; | 2270 return (overflow - 1) / payload_size + 1; |
| 2359 } | 2271 } |
| 2360 | 2272 |
| 2361 size_t SpdyFramer::GetHeaderFrameSizeSansBlock( | 2273 size_t SpdyFramer::GetHeaderFrameSizeSansBlock( |
| 2362 const SpdyHeadersIR& header_ir) const { | 2274 const SpdyHeadersIR& header_ir) const { |
| 2363 size_t min_size = GetFrameHeaderSize(); | 2275 size_t min_size = GetFrameHeaderSize(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2437 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id); | 2349 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id); |
| 2438 // Write payload fragment. | 2350 // Write payload fragment. |
| 2439 builder->WriteBytes( | 2351 builder->WriteBytes( |
| 2440 &hpack_encoding[hpack_encoding.size() - bytes_remaining], | 2352 &hpack_encoding[hpack_encoding.size() - bytes_remaining], |
| 2441 bytes_to_write); | 2353 bytes_to_write); |
| 2442 bytes_remaining -= bytes_to_write; | 2354 bytes_remaining -= bytes_to_write; |
| 2443 } | 2355 } |
| 2444 } | 2356 } |
| 2445 | 2357 |
| 2446 HpackEncoder* SpdyFramer::GetHpackEncoder() { | 2358 HpackEncoder* SpdyFramer::GetHpackEncoder() { |
| 2447 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2448 if (hpack_encoder_.get() == nullptr) { | 2359 if (hpack_encoder_.get() == nullptr) { |
| 2449 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable())); | 2360 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable())); |
| 2450 } | 2361 } |
| 2451 return hpack_encoder_.get(); | 2362 return hpack_encoder_.get(); |
| 2452 } | 2363 } |
| 2453 | 2364 |
| 2454 HpackDecoderInterface* SpdyFramer::GetHpackDecoder() { | 2365 HpackDecoderInterface* SpdyFramer::GetHpackDecoder() { |
| 2455 DCHECK_EQ(HTTP2, protocol_version_); | |
| 2456 if (hpack_decoder_.get() == nullptr) { | 2366 if (hpack_decoder_.get() == nullptr) { |
| 2457 hpack_decoder_.reset(new HpackDecoder()); | 2367 hpack_decoder_.reset(new HpackDecoder()); |
| 2458 } | 2368 } |
| 2459 return hpack_decoder_.get(); | 2369 return hpack_decoder_.get(); |
| 2460 } | 2370 } |
| 2461 | 2371 |
| 2462 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( | 2372 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( |
| 2463 SpdyStreamId stream_id, const char* data, size_t len) { | 2373 SpdyStreamId stream_id, const char* data, size_t len) { |
| 2464 bool read_successfully = true; | 2374 bool read_successfully = true; |
| 2465 while (read_successfully && len > 0) { | 2375 while (read_successfully && len > 0) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2517 builder->WriteUInt32(header_block.size()); | 2427 builder->WriteUInt32(header_block.size()); |
| 2518 | 2428 |
| 2519 // Serialize each header. | 2429 // Serialize each header. |
| 2520 for (const auto& header : header_block) { | 2430 for (const auto& header : header_block) { |
| 2521 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); | 2431 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); |
| 2522 builder->WriteStringPiece32(header.second); | 2432 builder->WriteStringPiece32(header.second); |
| 2523 } | 2433 } |
| 2524 } | 2434 } |
| 2525 | 2435 |
| 2526 } // namespace net | 2436 } // namespace net |
| OLD | NEW |