summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorjgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-25 05:42:05 +0000
committerjgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-25 05:42:05 +0000
commit53669f6067d653bd701a145e0bde26edfa074605 (patch)
tree6e0cb51106b8ee6a1a421ac24f51794474527b07 /net
parent1214b853e84214f7e908a61272eefebe82b7303d (diff)
downloadchromium_src-53669f6067d653bd701a145e0bde26edfa074605.zip
chromium_src-53669f6067d653bd701a145e0bde26edfa074605.tar.gz
chromium_src-53669f6067d653bd701a145e0bde26edfa074605.tar.bz2
Implements the ACK flag for SPDY4/HTTP2 PING frames
This lands server change 61378132 by birenroy. Also update SpdySession, BufferedSpdyFramer, etc to accept and pass the |is_ack| flag. BUG=345769 Review URL: https://codereview.chromium.org/169283012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253088 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/quic/quic_headers_stream.cc2
-rw-r--r--net/quic/quic_headers_stream_test.cc2
-rw-r--r--net/quic/quic_spdy_decompressor.cc2
-rw-r--r--net/spdy/buffered_spdy_framer.cc8
-rw-r--r--net/spdy/buffered_spdy_framer.h6
-rw-r--r--net/spdy/buffered_spdy_framer_unittest.cc2
-rw-r--r--net/spdy/mock_spdy_framer_visitor.h2
-rw-r--r--net/spdy/spdy_framer.cc13
-rw-r--r--net/spdy/spdy_framer.h2
-rw-r--r--net/spdy/spdy_framer_test.cc43
-rw-r--r--net/spdy/spdy_protocol.h11
-rw-r--r--net/spdy/spdy_session.cc21
-rw-r--r--net/spdy/spdy_session.h4
-rw-r--r--net/spdy/spdy_session_unittest.cc14
-rw-r--r--net/spdy/spdy_test_util_common.cc5
-rw-r--r--net/spdy/spdy_test_util_common.h2
-rw-r--r--net/tools/flip_server/spdy_interface.h2
-rw-r--r--net/tools/flip_server/spdy_interface_test.cc6
18 files changed, 95 insertions, 52 deletions
diff --git a/net/quic/quic_headers_stream.cc b/net/quic/quic_headers_stream.cc
index 41e6f7a..f1ec1bf 100644
--- a/net/quic/quic_headers_stream.cc
+++ b/net/quic/quic_headers_stream.cc
@@ -101,7 +101,7 @@ class QuicHeadersStream::SpdyFramerVisitor
CloseConnection("SPDY SETTINGS frame recevied.");
}
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE {
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {
CloseConnection("SPDY PING frame recevied.");
}
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
index 4d97a7a..47cc054 100644
--- a/net/quic/quic_headers_stream_test.cc
+++ b/net/quic/quic_headers_stream_test.cc
@@ -47,7 +47,7 @@ class MockVisitor : public SpdyFramerVisitorInterface {
SpdyRstStreamStatus status));
MOCK_METHOD1(OnSettings, void(bool clear_persisted));
MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
- MOCK_METHOD1(OnPing, void(SpdyPingId unique_id));
+ MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status));
MOCK_METHOD2(OnHeaders, void(SpdyStreamId stream_id, bool fin));
diff --git a/net/quic/quic_spdy_decompressor.cc b/net/quic/quic_spdy_decompressor.cc
index fb899ca..63ea194 100644
--- a/net/quic/quic_spdy_decompressor.cc
+++ b/net/quic/quic_spdy_decompressor.cc
@@ -44,7 +44,7 @@ class SpdyFramerVisitor : public SpdyFramerVisitorInterface {
virtual void OnSetting(SpdySettingsIds id,
uint8 flags,
uint32 value) OVERRIDE {}
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE {}
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status) OVERRIDE {}
virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE {}
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
index 7d419ba..3ac24d0 100644
--- a/net/spdy/buffered_spdy_framer.cc
+++ b/net/spdy/buffered_spdy_framer.cc
@@ -186,8 +186,8 @@ void BufferedSpdyFramer::OnSetting(SpdySettingsIds id,
visitor_->OnSetting(id, flags, value);
}
-void BufferedSpdyFramer::OnPing(SpdyPingId unique_id) {
- visitor_->OnPing(unique_id);
+void BufferedSpdyFramer::OnPing(SpdyPingId unique_id, bool is_ack) {
+ visitor_->OnPing(unique_id, is_ack);
}
void BufferedSpdyFramer::OnRstStream(SpdyStreamId stream_id,
@@ -295,8 +295,10 @@ SpdyFrame* BufferedSpdyFramer::CreateSettings(
}
// TODO(jgraettinger): Eliminate uses of this method (prefer SpdyPingIR).
-SpdyFrame* BufferedSpdyFramer::CreatePingFrame(uint32 unique_id) const {
+SpdyFrame* BufferedSpdyFramer::CreatePingFrame(uint32 unique_id,
+ bool is_ack) const {
SpdyPingIR ping_ir(unique_id);
+ ping_ir.set_is_ack(is_ack);
return spdy_framer_.SerializePing(ping_ir);
}
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h
index 3fd30cd..5f9c0eb 100644
--- a/net/spdy/buffered_spdy_framer.h
+++ b/net/spdy/buffered_spdy_framer.h
@@ -78,7 +78,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
// Called when a PING frame has been parsed.
- virtual void OnPing(SpdyPingId unique_id) = 0;
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
// Called when a RST_STREAM frame has been parsed.
virtual void OnRstStream(SpdyStreamId stream_id,
@@ -140,7 +140,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
virtual void OnSettings(bool clear_persisted) OVERRIDE;
virtual void OnSetting(
SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE;
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE;
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE;
virtual void OnRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) OVERRIDE;
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
@@ -172,7 +172,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
SpdyFrame* CreateRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) const;
SpdyFrame* CreateSettings(const SettingsMap& values) const;
- SpdyFrame* CreatePingFrame(uint32 unique_id) const;
+ SpdyFrame* CreatePingFrame(uint32 unique_id, bool is_ack) const;
SpdyFrame* CreateGoAway(
SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status) const;
diff --git a/net/spdy/buffered_spdy_framer_unittest.cc b/net/spdy/buffered_spdy_framer_unittest.cc
index 78f94e9..2dcba2c 100644
--- a/net/spdy/buffered_spdy_framer_unittest.cc
+++ b/net/spdy/buffered_spdy_framer_unittest.cc
@@ -87,7 +87,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
setting_count_++;
}
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE {}
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
virtual void OnRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) OVERRIDE {
diff --git a/net/spdy/mock_spdy_framer_visitor.h b/net/spdy/mock_spdy_framer_visitor.h
index 1c2526f..f7cabeb 100644
--- a/net/spdy/mock_spdy_framer_visitor.h
+++ b/net/spdy/mock_spdy_framer_visitor.h
@@ -37,7 +37,7 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface {
SpdyRstStreamStatus status));
MOCK_METHOD1(OnSettings, void(bool clear_persisted));
MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
- MOCK_METHOD1(OnPing, void(SpdyPingId unique_id));
+ MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status));
MOCK_METHOD2(OnHeaders, void(SpdyStreamId stream_id, bool fin));
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 4024010..f2ec0f3 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -755,7 +755,8 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
case PING:
if (current_frame_length_ != GetPingSize()) {
set_error(SPDY_INVALID_CONTROL_FRAME);
- } else if (current_frame_flags_ != 0) {
+ } else if ((protocol_version() < 4 && current_frame_flags_ != 0) ||
+ (current_frame_flags_ & ~PING_FLAG_ACK)) {
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
}
break;
@@ -1481,6 +1482,8 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
break;
case PING: {
SpdyPingId id = 0;
+ bool is_ack =
+ spdy_version_ >= 4 && (current_frame_flags_ & PING_FLAG_ACK);
bool successful_read = true;
if (spdy_version_ < 4) {
uint32 id32 = 0;
@@ -1491,7 +1494,7 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
}
DCHECK(successful_read);
DCHECK(reader.IsDoneReading());
- visitor_->OnPing(id);
+ visitor_->OnPing(id, is_ack);
}
break;
case WINDOW_UPDATE: {
@@ -1954,7 +1957,11 @@ SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
builder.WriteControlFrameHeader(*this, PING, kNoFlags);
builder.WriteUInt32(static_cast<uint32>(ping.id()));
} else {
- builder.WriteFramePrefix(*this, PING, 0, 0);
+ uint8 flags = 0;
+ if (ping.is_ack()) {
+ flags |= PING_FLAG_ACK;
+ }
+ builder.WriteFramePrefix(*this, PING, flags, 0);
builder.WriteUInt64(ping.id());
}
DCHECK_EQ(GetPingSize(), builder.length());
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 40c58b1..6cd889a 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -185,7 +185,7 @@ class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
// Called when a PING frame has been parsed.
- virtual void OnPing(SpdyPingId unique_id) = 0;
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
// Called when a GOAWAY frame has been parsed.
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 1b46bf4..606c2cc 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -151,7 +151,7 @@ class SpdyFramerTestUtil {
uint32 value) OVERRIDE {
LOG(FATAL);
}
- virtual void OnPing(uint64 unique_id) OVERRIDE {
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {
LOG(FATAL);
}
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
@@ -343,7 +343,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
setting_count_++;
}
- virtual void OnPing(uint64 unique_id) OVERRIDE {
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {
DLOG(FATAL);
}
@@ -2355,10 +2355,27 @@ TEST_P(SpdyFramerTest, CreatePingFrame) {
0x12, 0x34, 0x56, 0x78,
0x9a, 0xbc, 0xde, 0xff,
};
+ const unsigned char kV4FrameDataWithAck[] = {
+ 0x00, 0x10, 0x06, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x12, 0x34, 0x56, 0x78,
+ 0x9a, 0xbc, 0xde, 0xff,
+ };
scoped_ptr<SpdyFrame> frame;
if (IsSpdy4()) {
- frame.reset(framer.SerializePing(SpdyPingIR(0x123456789abcdeffull)));
+ const SpdyPingId kPingId = 0x123456789abcdeffULL;
+ SpdyPingIR ping_ir(kPingId);
+ // Tests SpdyPingIR when the ping is not an ack.
+ ASSERT_FALSE(ping_ir.is_ack());
+ frame.reset(framer.SerializePing(ping_ir));
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
+
+ // Tests SpdyPingIR when the ping is an ack.
+ ping_ir.set_is_ack(true);
+ frame.reset(framer.SerializePing(ping_ir));
+ CompareFrame(kDescription, *frame,
+ kV4FrameDataWithAck, arraysize(kV4FrameDataWithAck));
+
} else {
frame.reset(framer.SerializePing(SpdyPingIR(0x12345678ull)));
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
@@ -3900,22 +3917,26 @@ TEST_P(SpdyFramerTest, PingFrameFlags) {
scoped_ptr<SpdyFrame> frame(framer.SerializePing(SpdyPingIR(42)));
SetFrameFlags(frame.get(), flags, spdy_version_);
- if (flags != 0) {
- EXPECT_CALL(visitor, OnError(_));
+ if (spdy_version_ >= SPDY4 &&
+ flags == PING_FLAG_ACK) {
+ EXPECT_CALL(visitor, OnPing(42, true));
+ } else if (flags == 0) {
+ EXPECT_CALL(visitor, OnPing(42, false));
} else {
- EXPECT_CALL(visitor, OnPing(42));
+ EXPECT_CALL(visitor, OnError(_));
}
framer.ProcessInput(frame->data(), frame->size());
- if (flags != 0) {
+ if ((spdy_version_ >= SPDY4 && flags == PING_FLAG_ACK) ||
+ flags == 0) {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
+ } else {
EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
framer.error_code())
<< SpdyFramer::ErrorCodeToString(framer.error_code());
- } else {
- EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
- EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
- << SpdyFramer::ErrorCodeToString(framer.error_code());
}
}
}
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
index 110b7eb..5cad819 100644
--- a/net/spdy/spdy_protocol.h
+++ b/net/spdy/spdy_protocol.h
@@ -301,6 +301,10 @@ enum SpdyControlFlags {
CONTROL_FLAG_UNIDIRECTIONAL = 2
};
+enum SpdyPingFlags {
+ PING_FLAG_ACK = 0x1,
+};
+
enum SpdyHeadersFlags {
HEADERS_FLAG_PRIORITY = 0x08
};
@@ -609,13 +613,18 @@ class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
class NET_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
public:
- explicit SpdyPingIR(SpdyPingId id) : id_(id) {}
+ explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
SpdyPingId id() const { return id_; }
+ // ACK logic is valid only for SPDY versions 4 and above.
+ bool is_ack() const { return is_ack_; }
+ void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
+
virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
private:
SpdyPingId id_;
+ bool is_ack_;
DISALLOW_COPY_AND_ASSIGN(SpdyPingIR);
};
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index ec6b353..a6f29c5 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -206,11 +206,13 @@ base::Value* NetLogSpdyRstCallback(SpdyStreamId stream_id,
}
base::Value* NetLogSpdyPingCallback(SpdyPingId unique_id,
+ bool is_ack,
const char* type,
NetLog::LogLevel /* log_level */) {
base::DictionaryValue* dict = new base::DictionaryValue();
dict->SetInteger("unique_id", unique_id);
dict->SetString("type", type);
+ dict->SetBoolean("is_ack", is_ack);
return dict;
}
@@ -2390,7 +2392,7 @@ void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
MaybeFinishGoingAway();
}
-void SpdySession::OnPing(SpdyPingId unique_id) {
+void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) {
CHECK(in_io_loop_);
if (availability_state_ == STATE_CLOSED)
@@ -2398,11 +2400,12 @@ void SpdySession::OnPing(SpdyPingId unique_id) {
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_PING,
- base::Bind(&NetLogSpdyPingCallback, unique_id, "received"));
+ base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received"));
// Send response to a PING from server.
- if (unique_id % 2 == 0) {
- WritePingFrame(unique_id);
+ if ((protocol_ >= kProtoSPDY4a2 && !is_ack) ||
+ (protocol_ < kProtoSPDY4a2 && unique_id % 2 == 0)) {
+ WritePingFrame(unique_id, true);
return;
}
@@ -2647,7 +2650,7 @@ void SpdySession::SendPrefacePingIfNoneInFlight() {
}
void SpdySession::SendPrefacePing() {
- WritePingFrame(next_ping_id_);
+ WritePingFrame(next_ping_id_, false);
}
void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id,
@@ -2673,18 +2676,18 @@ void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id,
EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass());
}
-void SpdySession::WritePingFrame(uint32 unique_id) {
+void SpdySession::WritePingFrame(uint32 unique_id, bool is_ack) {
DCHECK(buffered_spdy_framer_.get());
scoped_ptr<SpdyFrame> ping_frame(
- buffered_spdy_framer_->CreatePingFrame(unique_id));
+ buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack));
EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass());
if (net_log().IsLoggingAllEvents()) {
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_PING,
- base::Bind(&NetLogSpdyPingCallback, unique_id, "sent"));
+ base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent"));
}
- if (unique_id % 2 != 0) {
+ if (!is_ack) {
next_ping_id_ += 2;
++pings_in_flight_;
PlanToCheckPingStatus();
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 73f8cd4..d20afb4 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -668,7 +668,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
RequestPriority priority);
// Send the PING frame.
- void WritePingFrame(uint32 unique_id);
+ void WritePingFrame(uint32 unique_id, bool is_ack);
// Post a CheckPingStatus call after delay. Don't post if there is already
// CheckPingStatus running.
@@ -784,7 +784,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE;
virtual void OnStreamError(SpdyStreamId stream_id,
const std::string& description) OVERRIDE;
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE;
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE;
virtual void OnRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) OVERRIDE;
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index b833f51..463da52 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -774,12 +774,12 @@ TEST_P(SpdySessionTest, ClientPing) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true));
MockRead reads[] = {
CreateMockRead(*read_ping, 1),
MockRead(ASYNC, 0, 0, 2) // EOF
};
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
MockWrite writes[] = {
CreateMockWrite(*write_ping, 0),
};
@@ -829,12 +829,12 @@ TEST_P(SpdySessionTest, ServerPing) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2));
+ scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false));
MockRead reads[] = {
CreateMockRead(*read_ping),
MockRead(SYNCHRONOUS, 0, 0) // EOF
};
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true));
MockWrite writes[] = {
CreateMockWrite(*write_ping),
};
@@ -873,7 +873,7 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
session_deps_.time_func = TheNearFuture;
MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
MockWrite writes[] = {
@@ -1006,7 +1006,7 @@ TEST_P(SpdySessionTest, FailedPing) {
MockRead reads[] = {
MockRead(ASYNC, 0, 0, 0) // EOF
};
- scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
+ scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
@@ -1027,7 +1027,7 @@ TEST_P(SpdySessionTest, FailedPing) {
session->set_hung_interval(base::TimeDelta::FromSeconds(0));
// Send a PING frame.
- session->WritePingFrame(1);
+ session->WritePingFrame(1, false);
EXPECT_LT(0, session->pings_in_flight());
EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
EXPECT_TRUE(session->check_ping_status_pending());
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index b68759b..66a6f8c3 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -237,7 +237,7 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
virtual void OnSettings(bool clear_persisted) OVERRIDE {}
virtual void OnSetting(
SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE {}
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE {}
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
virtual void OnRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) OVERRIDE {}
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
@@ -868,8 +868,9 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySettings(
return CreateFramer()->SerializeSettings(settings_ir);
}
-SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id) const {
+SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id, bool is_ack) const {
SpdyPingIR ping_ir(ping_id);
+ ping_ir.set_is_ack(is_ack);
return CreateFramer()->SerializePing(ping_ir);
}
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index 543c16f..42b595b 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -365,7 +365,7 @@ class SpdyTestUtil {
// Construct a SPDY PING frame.
// Returns the constructed frame. The caller takes ownership of the frame.
- SpdyFrame* ConstructSpdyPing(uint32 ping_id) const;
+ SpdyFrame* ConstructSpdyPing(uint32 ping_id, bool is_ack) const;
// Construct a SPDY GOAWAY frame with last_good_stream_id = 0.
// Returns the constructed frame. The caller takes ownership of the frame.
diff --git a/net/tools/flip_server/spdy_interface.h b/net/tools/flip_server/spdy_interface.h
index c12a895..5ab8cba 100644
--- a/net/tools/flip_server/spdy_interface.h
+++ b/net/tools/flip_server/spdy_interface.h
@@ -111,7 +111,7 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
uint32 value) OVERRIDE {}
// Called when a PING frame has been parsed.
- virtual void OnPing(SpdyPingId unique_id) OVERRIDE {}
+ virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
// Called when a RST_STREAM frame has been parsed.
virtual void OnRstStream(SpdyStreamId stream_id,
diff --git a/net/tools/flip_server/spdy_interface_test.cc b/net/tools/flip_server/spdy_interface_test.cc
index dd1980d..8b340a8 100644
--- a/net/tools/flip_server/spdy_interface_test.cc
+++ b/net/tools/flip_server/spdy_interface_test.cc
@@ -60,7 +60,7 @@ class SpdyFramerVisitor : public BufferedSpdyFramerVisitorInterface {
bool));
MOCK_METHOD1(OnSettings, void(bool clear_persisted));
MOCK_METHOD3(OnSetting, void(SpdySettingsIds, uint8, uint32));
- MOCK_METHOD1(OnPing, void(SpdyPingId unique_id));
+ MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
MOCK_METHOD2(OnRstStream, void(SpdyStreamId, SpdyRstStreamStatus));
MOCK_METHOD2(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus));
MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId, uint32));
@@ -292,7 +292,7 @@ TEST_P(SpdySMProxyTest, OnStreamFrameData_SPDY2) {
SpdyHeaderBlock block;
testing::MockFunction<void(int)> checkpoint; // NOLINT
- scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12));
+ scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12, false));
block["method"] = "GET";
block["url"] = "http://www.example.com/path";
block["scheme"] = "http";
@@ -325,7 +325,7 @@ TEST_P(SpdySMProxyTest, OnStreamFrameData) {
SpdyHeaderBlock block;
testing::MockFunction<void(int)> checkpoint; // NOLINT
- scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12));
+ scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12, false));
block[":method"] = "GET";
block[":host"] = "www.example.com";
block[":path"] = "/path";