diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 23:02:18 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 23:02:18 +0000 |
commit | b9c4b6e28a0e311342387903b82a2f43f02810d5 (patch) | |
tree | aa467acc2c443ea731ad79b04e1b39693c0906ee /net/spdy | |
parent | 456e9b09d076bc129e4360ef75b547de383e62bf (diff) | |
download | chromium_src-b9c4b6e28a0e311342387903b82a2f43f02810d5.zip chromium_src-b9c4b6e28a0e311342387903b82a2f43f02810d5.tar.gz chromium_src-b9c4b6e28a0e311342387903b82a2f43f02810d5.tar.bz2 |
SPDY: Add support for WINDOW_UPDATE frame.
This provides the really basic serialization/deserialization of the frame, and does introduce a behavior change.
BUG=48100
TEST=net_unittests --gtest_filter="SpdyProtocolTest.ControlFrameStructs"
Review URL: http://codereview.chromium.org/2886009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51447 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/spdy')
-rw-r--r-- | net/spdy/spdy_framer.cc | 15 | ||||
-rw-r--r-- | net/spdy/spdy_framer.h | 5 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.h | 57 | ||||
-rw-r--r-- | net/spdy/spdy_protocol_test.cc | 20 |
4 files changed, 96 insertions, 1 deletions
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index 9aea310..0a1c2b7 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc @@ -570,6 +570,21 @@ SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( } /* static */ +SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( + SpdyStreamId stream_id, + uint32 delta_window_size) { + SpdyFrameBuilder frame; + frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion); + frame.WriteUInt16(WINDOW_UPDATE); + size_t window_update_size = SpdyWindowUpdateControlFrame::size() - + SpdyFrame::size(); + frame.WriteUInt32(window_update_size); + frame.WriteUInt32(stream_id); + frame.WriteUInt32(delta_window_size); + return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); +} + +/* static */ SpdySettingsControlFrame* SpdyFramer::CreateSettings( const SpdySettings& values) { SpdyFrameBuilder frame; diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h index 540da6d..c905dec 100644 --- a/net/spdy/spdy_framer.h +++ b/net/spdy/spdy_framer.h @@ -163,6 +163,11 @@ class SpdyFramer { static SpdyGoAwayControlFrame* CreateGoAway( SpdyStreamId last_accepted_stream_id); + // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE + // frame is used to implement per stream flow control in SPDY. + static SpdyWindowUpdateControlFrame* CreateWindowUpdate( + SpdyStreamId stream_id, uint32 delta_window_size); + // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is // used to communicate name/value pairs relevant to the communication channel. // TODO(mbelshe): add the name/value pairs!! diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h index a7a5ab7..5bdc2b3 100644 --- a/net/spdy/spdy_protocol.h +++ b/net/spdy/spdy_protocol.h @@ -103,6 +103,18 @@ // +----------------------------------+ // |X| Last-accepted-stream-id | // +----------------------------------+ +// +// Control Frame: WINDOW_UPDATE +// +----------------------------------+ +// |1|000000000000001|0000000000001001| +// +----------------------------------+ +// | flags (8) | Length (24 bits) | = 8 +// +----------------------------------+ +// |X| Stream-ID (31 bits) | +// +----------------------------------+ +// | Delta-Window-Size (32 bits) | +// +----------------------------------+ + namespace spdy { @@ -123,6 +135,7 @@ enum SpdyControlType { PING, GOAWAY, HEADERS, + WINDOW_UPDATE, NUM_CONTROL_FRAME_TYPES }; @@ -258,6 +271,12 @@ struct SpdySettingsControlFrameBlock : SpdyFrameBlock { // Variable data here. }; +// A WINDOW_UPDATE Control Frame structure +struct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock { + SpdyStreamId stream_id_; + uint32 delta_window_size_; +}; + #pragma pack(pop) // ------------------------------------------------------------------------- @@ -594,6 +613,44 @@ class SpdySettingsControlFrame : public SpdyControlFrame { DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame); }; +// A WINDOW_UPDATE frame. +class SpdyWindowUpdateControlFrame : public SpdyControlFrame { + public: + SpdyWindowUpdateControlFrame() : SpdyControlFrame(size()) {} + SpdyWindowUpdateControlFrame(char* data, bool owns_buffer) + : SpdyControlFrame(data, owns_buffer) {} + + SpdyStreamId stream_id() const { + return ntohl(block()->stream_id_) & kStreamIdMask; + } + + void set_stream_id(SpdyStreamId id) { + mutable_block()->stream_id_ = htonl(id & kStreamIdMask); + } + + uint32 delta_window_size() const { + return ntohl(block()->delta_window_size_); + } + + void set_delta_window_size(uint32 delta_window_size) { + mutable_block()->delta_window_size_ = htonl(delta_window_size); + } + + // Returns the size of the SpdyWindowUpdateControlFrameBlock structure. + // Note: this is not the size of the SpdyWindowUpdateControlFrame class. + static size_t size() { return sizeof(SpdyWindowUpdateControlFrameBlock); } + + private: + const struct SpdyWindowUpdateControlFrameBlock* block() const { + return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); + } + struct SpdyWindowUpdateControlFrameBlock* mutable_block() { + return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); + } + + DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame); +}; + } // namespace spdy #endif // NET_SPDY_SPDY_PROTOCOL_H_ diff --git a/net/spdy/spdy_protocol_test.cc b/net/spdy/spdy_protocol_test.cc index 4a14575..4aff242 100644 --- a/net/spdy/spdy_protocol_test.cc +++ b/net/spdy/spdy_protocol_test.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,10 +12,14 @@ using spdy::CONTROL_FLAG_FIN; using spdy::CONTROL_FLAG_NONE; using spdy::GOAWAY; +using spdy::HEADERS; +using spdy::NOOP; +using spdy::PING; using spdy::RST_STREAM; using spdy::SETTINGS; using spdy::SYN_REPLY; using spdy::SYN_STREAM; +using spdy::WINDOW_UPDATE; using spdy::FlagsAndLength; using spdy::SpdyControlFrame; using spdy::SpdyControlType; @@ -29,6 +33,7 @@ using spdy::SpdySettings; using spdy::SpdySettingsControlFrame; using spdy::SpdySynReplyControlFrame; using spdy::SpdySynStreamControlFrame; +using spdy::SpdyWindowUpdateControlFrame; using spdy::SettingsFlagsAndId; using spdy::kLengthMask; using spdy::kSpdyProtocolVersion; @@ -46,12 +51,17 @@ TEST(SpdyProtocolTest, ProtocolConstants) { EXPECT_EQ(16u, SpdyRstStreamControlFrame::size()); EXPECT_EQ(12u, SpdyGoAwayControlFrame::size()); EXPECT_EQ(12u, SpdySettingsControlFrame::size()); + EXPECT_EQ(16u, SpdyWindowUpdateControlFrame::size()); EXPECT_EQ(4u, sizeof(FlagsAndLength)); EXPECT_EQ(1, SYN_STREAM); EXPECT_EQ(2, SYN_REPLY); EXPECT_EQ(3, RST_STREAM); EXPECT_EQ(4, SETTINGS); + EXPECT_EQ(5, NOOP); + EXPECT_EQ(6, PING); EXPECT_EQ(7, GOAWAY); + EXPECT_EQ(8, HEADERS); + EXPECT_EQ(9, WINDOW_UPDATE); } // Test some of the protocol helper functions @@ -120,6 +130,14 @@ TEST(SpdyProtocolTest, ControlFrameStructs) { EXPECT_TRUE(goaway_frame->is_control_frame()); EXPECT_EQ(GOAWAY, goaway_frame->type()); EXPECT_EQ(123u, goaway_frame->last_accepted_stream_id()); + + scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( + framer.CreateWindowUpdate(123, 456)); + EXPECT_EQ(kSpdyProtocolVersion, window_update_frame->version()); + EXPECT_TRUE(window_update_frame->is_control_frame()); + EXPECT_EQ(WINDOW_UPDATE, window_update_frame->type()); + EXPECT_EQ(123u, window_update_frame->stream_id()); + EXPECT_EQ(456u, window_update_frame->delta_window_size()); } TEST(SpdyProtocolTest, TestDataFrame) { |