diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/spdy/buffered_spdy_framer.cc | 2 | ||||
-rw-r--r-- | net/spdy/buffered_spdy_framer.h | 4 | ||||
-rw-r--r-- | net/spdy/buffered_spdy_framer_spdy2_unittest.cc | 2 | ||||
-rw-r--r-- | net/spdy/buffered_spdy_framer_spdy3_unittest.cc | 2 | ||||
-rw-r--r-- | net/spdy/spdy_framer.cc | 29 | ||||
-rw-r--r-- | net/spdy/spdy_framer.h | 4 | ||||
-rw-r--r-- | net/spdy/spdy_framer_test.cc | 37 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.h | 43 | ||||
-rw-r--r-- | net/spdy/spdy_protocol_test.cc | 31 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 2 |
10 files changed, 66 insertions, 90 deletions
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc index 18744a6..2df8afa 100644 --- a/net/spdy/buffered_spdy_framer.cc +++ b/net/spdy/buffered_spdy_framer.cc @@ -237,7 +237,7 @@ SpdyFrame* BufferedSpdyFramer::CreateSynReply( return spdy_framer_.CreateSynReply(stream_id, flags, compressed, headers); } -SpdyRstStreamControlFrame* BufferedSpdyFramer::CreateRstStream( +SpdyFrame* BufferedSpdyFramer::CreateRstStream( SpdyStreamId stream_id, SpdyRstStreamStatus status) const { return spdy_framer_.CreateRstStream(stream_id, status); diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h index 9524675..32c6d44 100644 --- a/net/spdy/buffered_spdy_framer.h +++ b/net/spdy/buffered_spdy_framer.h @@ -158,8 +158,8 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers); - SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, - SpdyRstStreamStatus status) const; + SpdyFrame* CreateRstStream(SpdyStreamId stream_id, + SpdyRstStreamStatus status) const; SpdySettingsControlFrame* CreateSettings(const SettingsMap& values) const; SpdyFrame* CreatePingFrame(uint32 unique_id) const; SpdyFrame* CreateGoAway( diff --git a/net/spdy/buffered_spdy_framer_spdy2_unittest.cc b/net/spdy/buffered_spdy_framer_spdy2_unittest.cc index 99bf952..4d6c5a3 100644 --- a/net/spdy/buffered_spdy_framer_spdy2_unittest.cc +++ b/net/spdy/buffered_spdy_framer_spdy2_unittest.cc @@ -106,7 +106,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { LOG(FATAL) << "Unexpected OnDataFrameHeader call."; } - void OnRstStream(const SpdyRstStreamControlFrame& frame) {} + void OnRstStream(const SpdyFrame& frame) {} void OnGoAway(const SpdyFrame& frame) {} void OnPing(const SpdyFrame& frame) {} virtual void OnWindowUpdate(SpdyStreamId stream_id, diff --git a/net/spdy/buffered_spdy_framer_spdy3_unittest.cc b/net/spdy/buffered_spdy_framer_spdy3_unittest.cc index b2fb39b..935a7f5 100644 --- a/net/spdy/buffered_spdy_framer_spdy3_unittest.cc +++ b/net/spdy/buffered_spdy_framer_spdy3_unittest.cc @@ -104,7 +104,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { LOG(FATAL) << "Unexpected OnDataFrameHeader call."; } - void OnRstStream(const SpdyRstStreamControlFrame& frame) {} + void OnRstStream(const SpdyFrame& frame) {} void OnGoAway(const SpdyFrame& frame) {} void OnPing(const SpdyFrame& frame) {} virtual void OnWindowUpdate(SpdyStreamId stream_id, diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index b9826f5..8fc2335 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc @@ -1208,10 +1208,26 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { } break; case RST_STREAM: { - SpdyRstStreamControlFrame* rst_stream_frame = - reinterpret_cast<SpdyRstStreamControlFrame*>(&control_frame); - visitor_->OnRstStream(rst_stream_frame->stream_id(), - rst_stream_frame->status()); + SpdyFrameReader reader(current_frame_buffer_.get(), + current_frame_len_); + reader.Seek(GetControlFrameMinimumSize()); // Skip frame header. + SpdyStreamId stream_id = kInvalidStream; + bool successful_read = reader.ReadUInt32(&stream_id); + DCHECK(successful_read); + SpdyRstStreamStatus status = RST_STREAM_INVALID; + uint32 status_raw = status; + successful_read = reader.ReadUInt32(&status_raw); + DCHECK(successful_read); + if (status_raw > RST_STREAM_INVALID && + status_raw < RST_STREAM_NUM_STATUS_CODES) { + status = static_cast<SpdyRstStreamStatus>(status_raw); + } else { + // TODO(hkhalil): Probably best to OnError here, depending on + // our interpretation of the spec. Keeping with existing liberal + // behavior for now. + } + DCHECK(reader.IsDoneReading()); + visitor_->OnRstStream(stream_id, status); } break; case GOAWAY: { @@ -1511,12 +1527,11 @@ SpdySerializedFrame* SpdyFramer::SerializeSynReply( return builder.take(); } -SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream( +SpdyFrame* SpdyFramer::CreateRstStream( SpdyStreamId stream_id, SpdyRstStreamStatus status) const { SpdyRstStreamIR rst_stream(stream_id, status); - return reinterpret_cast<SpdyRstStreamControlFrame*>( - SerializeRstStream(rst_stream)); + return SerializeRstStream(rst_stream); } SpdySerializedFrame* SpdyFramer::SerializeRstStream( diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h index 257eea7..77df747 100644 --- a/net/spdy/spdy_framer.h +++ b/net/spdy/spdy_framer.h @@ -380,8 +380,8 @@ class NET_EXPORT_PRIVATE SpdyFramer { const SpdyHeaderBlock* headers); SpdySerializedFrame* SerializeSynReply(const SpdySynReplyIR& syn_reply); - SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, - SpdyRstStreamStatus status) const; + SpdyFrame* CreateRstStream(SpdyStreamId stream_id, + SpdyRstStreamStatus status) const; SpdySerializedFrame* SerializeRstStream( const SpdyRstStreamIR& rst_stream) const; diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index ceea1d3..7abdf97 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc @@ -2015,7 +2015,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, }; - scoped_ptr<SpdyRstStreamControlFrame> frame( + scoped_ptr<SpdyFrame> frame( framer.CreateRstStream(1, RST_STREAM_PROTOCOL_ERROR)); CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); } @@ -3559,6 +3559,41 @@ TEST_P(SpdyFramerTest, SettingsFlagsAndId) { EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(spdy_version_)); } +// Test handling of a RST_STREAM with out-of-bounds status codes. +TEST_P(SpdyFramerTest, RstStreamStatusBounds) { + DCHECK_GE(0xff, RST_STREAM_NUM_STATUS_CODES); + + const unsigned char kRstStreamInvalid[] = { + 0x80, spdy_version_, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, RST_STREAM_INVALID + }; + + const unsigned char kRstStreamNumStatusCodes[] = { + 0x80, spdy_version_, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, RST_STREAM_NUM_STATUS_CODES + }; + + testing::StrictMock<net::test::MockVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID)); + framer.ProcessInput(reinterpret_cast<const char*>(kRstStreamInvalid), + arraysize(kRstStreamInvalid)); + EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()); + + EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID)); + framer.ProcessInput(reinterpret_cast<const char*>(kRstStreamNumStatusCodes), + arraysize(kRstStreamNumStatusCodes)); + EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()); +} + // Tests handling of a GOAWAY frame with out-of-bounds stream ID. TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) { const unsigned char kV2FrameData[] = { diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h index dd7e753..78f75b9 100644 --- a/net/spdy/spdy_protocol.h +++ b/net/spdy/spdy_protocol.h @@ -491,12 +491,6 @@ struct SpdySynStreamControlFrameBlock : SpdyFrameBlock { uint8 credential_slot_; }; -// A RST_STREAM Control Frame structure. -struct SpdyRstStreamControlFrameBlock : SpdyFrameBlock { - SpdyStreamId stream_id_; - uint32 status_; -}; - // A SETTINGS Control Frame structure. struct SpdySettingsControlFrameBlock : SpdyFrameBlock { uint32 num_entries_; @@ -1038,43 +1032,6 @@ class SpdySynStreamControlFrame : public SpdyControlFrame { DISALLOW_COPY_AND_ASSIGN(SpdySynStreamControlFrame); }; -// A RST_STREAM frame. -class SpdyRstStreamControlFrame : public SpdyControlFrame { - public: - SpdyRstStreamControlFrame() : SpdyControlFrame(size()) {} - SpdyRstStreamControlFrame(char* data, bool owns_buffer) - : SpdyControlFrame(data, owns_buffer) {} - - SpdyStreamId stream_id() const { - return ntohl(block()->stream_id_) & kStreamIdMask; - } - - SpdyRstStreamStatus status() const { - SpdyRstStreamStatus status = - static_cast<SpdyRstStreamStatus>(ntohl(block()->status_)); - if (status < RST_STREAM_INVALID || status >= RST_STREAM_NUM_STATUS_CODES) { - status = RST_STREAM_INVALID; - } - return status; - } - void set_status(SpdyRstStreamStatus status) { - mutable_block()->status_ = htonl(static_cast<uint32>(status)); - } - - // Returns the size of the SpdyRstStreamControlFrameBlock structure. - // Note: this is not the size of the SpdyRstStreamControlFrame class. - static size_t size() { return sizeof(SpdyRstStreamControlFrameBlock); } - - private: - const struct SpdyRstStreamControlFrameBlock* block() const { - return static_cast<SpdyRstStreamControlFrameBlock*>(frame_); - } - struct SpdyRstStreamControlFrameBlock* mutable_block() { - return static_cast<SpdyRstStreamControlFrameBlock*>(frame_); - } - DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamControlFrame); -}; - class SpdySettingsControlFrame : public SpdyControlFrame { public: SpdySettingsControlFrame() : SpdyControlFrame(size()) {} diff --git a/net/spdy/spdy_protocol_test.cc b/net/spdy/spdy_protocol_test.cc index aa4b345..9c1de18 100644 --- a/net/spdy/spdy_protocol_test.cc +++ b/net/spdy/spdy_protocol_test.cc @@ -44,7 +44,6 @@ TEST_P(SpdyProtocolTest, ProtocolConstants) { EXPECT_EQ(8u, SpdyDataFrame::size()); EXPECT_EQ(8u, SpdyControlFrame::kHeaderSize); EXPECT_EQ(18u, SpdySynStreamControlFrame::size()); - EXPECT_EQ(16u, SpdyRstStreamControlFrame::size()); EXPECT_EQ(12u, SpdySettingsControlFrame::size()); EXPECT_EQ(12u, SpdyHeadersControlFrame::size()); EXPECT_EQ(4u, sizeof(FlagsAndLength)); @@ -102,17 +101,6 @@ TEST_P(SpdyProtocolTest, ControlFrameStructs) { EXPECT_EQ(123u, syn_frame->stream_id()); EXPECT_EQ(999u, syn_frame->associated_stream_id()); - scoped_ptr<SpdyRstStreamControlFrame> rst_frame( - framer.CreateRstStream(123, net::RST_STREAM_PROTOCOL_ERROR)); - EXPECT_EQ(framer.protocol_version(), rst_frame->version()); - EXPECT_TRUE(rst_frame->is_control_frame()); - EXPECT_EQ(RST_STREAM, rst_frame->type()); - EXPECT_EQ(123u, rst_frame->stream_id()); - EXPECT_EQ(net::RST_STREAM_PROTOCOL_ERROR, rst_frame->status()); - rst_frame->set_status(net::RST_STREAM_INVALID_STREAM); - EXPECT_EQ(net::RST_STREAM_INVALID_STREAM, rst_frame->status()); - EXPECT_EQ(0, rst_frame->flags()); - scoped_ptr<SpdyHeadersControlFrame> headers_frame( framer.CreateHeaders(123, CONTROL_FLAG_NONE, false, &headers)); EXPECT_EQ(framer.protocol_version(), headers_frame->version()); @@ -326,23 +314,4 @@ TEST_P(SpdyProtocolDeathTest, TestSpdyControlFrameType) { } } -TEST_P(SpdyProtocolDeathTest, TestRstStreamStatusBounds) { - SpdyFramer framer(spdy_version_); - scoped_ptr<SpdyRstStreamControlFrame> rst_frame; - - rst_frame.reset(framer.CreateRstStream( - 123, RST_STREAM_PROTOCOL_ERROR)); - EXPECT_EQ(RST_STREAM_PROTOCOL_ERROR, rst_frame->status()); - - rst_frame->set_status(RST_STREAM_INVALID); - EXPECT_EQ(RST_STREAM_INVALID, rst_frame->status()); - - rst_frame->set_status(static_cast<SpdyRstStreamStatus>( - RST_STREAM_INVALID - 1)); - EXPECT_EQ(RST_STREAM_INVALID, rst_frame->status()); - - rst_frame->set_status(RST_STREAM_NUM_STATUS_CODES); - EXPECT_EQ(RST_STREAM_INVALID, rst_frame->status()); -} - } // namespace net diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 4fbd37c..d777c05 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -745,7 +745,7 @@ void SpdySession::ResetStream(SpdyStreamId stream_id, base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); DCHECK(buffered_spdy_framer_.get()); - scoped_ptr<SpdyRstStreamControlFrame> rst_frame( + scoped_ptr<SpdyFrame> rst_frame( buffered_spdy_framer_->CreateRstStream(stream_id, status)); // Default to lowest priority unless we know otherwise. |