summaryrefslogtreecommitdiffstats
path: root/net/spdy
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-01 23:02:18 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-01 23:02:18 +0000
commitb9c4b6e28a0e311342387903b82a2f43f02810d5 (patch)
treeaa467acc2c443ea731ad79b04e1b39693c0906ee /net/spdy
parent456e9b09d076bc129e4360ef75b547de383e62bf (diff)
downloadchromium_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.cc15
-rw-r--r--net/spdy/spdy_framer.h5
-rw-r--r--net/spdy/spdy_protocol.h57
-rw-r--r--net/spdy/spdy_protocol_test.cc20
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) {