summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-27 20:36:32 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-27 20:36:32 +0000
commitdda726d357e63bd7fe601f576a9fea0089273a3e (patch)
tree939ca1b851d86761027ae95636caea61cfeab01d
parent6bbac915b849e858deccc662c0ffe996b56481f1 (diff)
downloadchromium_src-dda726d357e63bd7fe601f576a9fea0089273a3e.zip
chromium_src-dda726d357e63bd7fe601f576a9fea0089273a3e.tar.gz
chromium_src-dda726d357e63bd7fe601f576a9fea0089273a3e.tar.bz2
Add FrameType and SerializeWith methods to SpdyFrameIR and friends
Replace SpdyFrameSerializer with a general SpdyFrameVisitor class Also add BufferedSpdyFramer::SerializeFrame(). This lands server changes 48519495 and 48579047. R=rch@chromium.org Review URL: https://codereview.chromium.org/17875003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@208992 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/spdy/buffered_spdy_framer.h6
-rw-r--r--net/spdy/spdy_framer.cc57
-rw-r--r--net/spdy/spdy_framer.h3
-rw-r--r--net/spdy/spdy_framer_test.cc6
-rw-r--r--net/spdy/spdy_protocol.cc45
-rw-r--r--net/spdy/spdy_protocol.h59
-rw-r--r--net/spdy/spdy_protocol_test.cc2
7 files changed, 171 insertions, 7 deletions
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h
index 2df0c9b..a355843 100644
--- a/net/spdy/buffered_spdy_framer.h
+++ b/net/spdy/buffered_spdy_framer.h
@@ -186,6 +186,12 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
const char* data,
uint32 len,
SpdyDataFlags flags);
+
+ // Serialize a frame of unknown type.
+ SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
+ return spdy_framer_.SerializeFrame(frame);
+ }
+
SpdyPriority GetHighestPriority() const;
size_t GetDataFrameMinimumSize() const {
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index f74fb02..ed53b38 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -1947,6 +1947,63 @@ SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader(
return builder.take();
}
+namespace {
+
+class FrameSerializationVisitor : public SpdyFrameVisitor {
+ public:
+ explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
+ virtual ~FrameSerializationVisitor() {}
+
+ SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }
+
+ virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE {
+ frame_.reset(framer_->SerializeSynStream(syn_stream));
+ }
+ virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE {
+ frame_.reset(framer_->SerializeSynReply(syn_reply));
+ }
+ virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE {
+ frame_.reset(framer_->SerializeRstStream(rst_stream));
+ }
+ virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE {
+ frame_.reset(framer_->SerializeSettings(settings));
+ }
+ virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE {
+ frame_.reset(framer_->SerializePing(ping));
+ }
+ virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE {
+ frame_.reset(framer_->SerializeGoAway(goaway));
+ }
+ virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE {
+ frame_.reset(framer_->SerializeHeaders(headers));
+ }
+ virtual void VisitWindowUpdate(
+ const SpdyWindowUpdateIR& window_update) OVERRIDE {
+ frame_.reset(framer_->SerializeWindowUpdate(window_update));
+ }
+ virtual void VisitCredential(const SpdyCredentialIR& credential) OVERRIDE {
+ frame_.reset(framer_->SerializeCredential(credential));
+ }
+ virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE {
+ frame_.reset(framer_->SerializeBlocked(blocked));
+ }
+ virtual void VisitData(const SpdyDataIR& data) OVERRIDE {
+ frame_.reset(framer_->SerializeData(data));
+ }
+
+ private:
+ SpdyFramer* framer_;
+ scoped_ptr<SpdySerializedFrame> frame_;
+};
+
+} // namespace
+
+SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
+ FrameSerializationVisitor visitor(this);
+ frame.Visit(&visitor);
+ return visitor.ReleaseSerializedFrame();
+}
+
size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
const size_t uncompressed_length =
GetSerializedLength(protocol_version(), &headers);
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index f9d6830..caea743 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -455,6 +455,9 @@ class NET_EXPORT_PRIVATE SpdyFramer {
// Serializes just the data frame header, excluding actual data payload.
SpdySerializedFrame* SerializeDataFrameHeader(const SpdyDataIR& data) const;
+ // Serialize a frame of unknown type.
+ SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame);
+
// NOTES about frame compression.
// We want spdy to compress headers across the entire session. As long as
// the session is over TCP, frames are sent serially. The client & server
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index d75dadb..b8919a9 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -1438,7 +1438,7 @@ TEST_P(SpdyFramerTest, HeaderCompression) {
SpdySynStreamIR syn_ir_1(1);
syn_ir_1.SetHeader(kHeader1, kValue1);
syn_ir_1.SetHeader(kHeader2, kValue2);
- scoped_ptr<SpdyFrame> syn_frame_1(send_framer.SerializeSynStream(syn_ir_1));
+ scoped_ptr<SpdyFrame> syn_frame_1(send_framer.SerializeFrame(syn_ir_1));
EXPECT_TRUE(syn_frame_1.get() != NULL);
// SYN_STREAM #2
@@ -2918,7 +2918,7 @@ TEST_P(SpdyFramerTest, SerializeBlocked) {
0x00, 0x00, 0x00, 0x00,
};
SpdyBlockedIR blocked_ir(0);
- scoped_ptr<SpdySerializedFrame> frame(framer.SerializeBlocked(blocked_ir));
+ scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
}
@@ -4214,7 +4214,7 @@ TEST_P(SpdyFramerTest, OnBlocked) {
EXPECT_CALL(visitor, OnBlocked(kStreamId));
SpdyBlockedIR blocked_ir(0);
- scoped_ptr<SpdySerializedFrame> frame(framer.SerializeBlocked(blocked_ir));
+ scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
framer.ProcessInput(frame->data(), framer.GetBlockedSize());
EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
diff --git a/net/spdy/spdy_protocol.cc b/net/spdy/spdy_protocol.cc
index 0373ab0..ecd8594 100644
--- a/net/spdy/spdy_protocol.cc
+++ b/net/spdy/spdy_protocol.cc
@@ -21,14 +21,59 @@ SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
SpdyDataIR::~SpdyDataIR() {}
+void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitData(*this);
+}
+
+void SpdySynStreamIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitSynStream(*this);
+}
+
+void SpdySynReplyIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitSynReply(*this);
+}
+
+void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitRstStream(*this);
+}
+
SpdySettingsIR::SpdySettingsIR() : clear_settings_(false) {}
SpdySettingsIR::~SpdySettingsIR() {}
+void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitSettings(*this);
+}
+
+void SpdyPingIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitPing(*this);
+}
+
+void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitGoAway(*this);
+}
+
+void SpdyHeadersIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitHeaders(*this);
+}
+
+void SpdyWindowUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitWindowUpdate(*this);
+}
+
SpdyCredentialIR::SpdyCredentialIR(int16 slot) {
set_slot(slot);
}
SpdyCredentialIR::~SpdyCredentialIR() {}
+
+void SpdyCredentialIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitCredential(*this);
+}
+
+void SpdyBlockedIR::Visit(SpdyFrameVisitor* visitor) const {
+ return visitor->VisitBlocked(*this);
+}
+
} // namespace
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
index db04415..2bf8c68 100644
--- a/net/spdy/spdy_protocol.h
+++ b/net/spdy/spdy_protocol.h
@@ -353,8 +353,7 @@ typedef uint32 SpdyPingId;
class SpdyFrame;
typedef SpdyFrame SpdySerializedFrame;
-class SpdyFramer;
-class SpdyFrameBuilder;
+class SpdyFrameVisitor;
// Intermediate representation for SPDY frames.
// TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
@@ -363,6 +362,8 @@ class SpdyFrameIR {
public:
virtual ~SpdyFrameIR() {}
+ virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
+
protected:
SpdyFrameIR() {}
@@ -460,6 +461,8 @@ class NET_EXPORT_PRIVATE SpdyDataIR
data_ = data;
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
// Used to store data that this SpdyDataIR should own.
scoped_ptr<std::string> data_store_;
@@ -468,7 +471,8 @@ class NET_EXPORT_PRIVATE SpdyDataIR
DISALLOW_COPY_AND_ASSIGN(SpdyDataIR);
};
-class SpdySynStreamIR : public SpdyFrameWithNameValueBlockIR {
+class NET_EXPORT_PRIVATE SpdySynStreamIR
+ : public SpdyFrameWithNameValueBlockIR {
public:
explicit SpdySynStreamIR(SpdyStreamId stream_id)
: SpdyFrameWithNameValueBlockIR(stream_id),
@@ -491,6 +495,8 @@ class SpdySynStreamIR : public SpdyFrameWithNameValueBlockIR {
unidirectional_ = unidirectional;
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
SpdyStreamId associated_to_stream_id_;
SpdyPriority priority_;
@@ -505,6 +511,8 @@ class SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR {
explicit SpdySynReplyIR(SpdyStreamId stream_id)
: SpdyFrameWithNameValueBlockIR(stream_id) {}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR);
};
@@ -524,6 +532,8 @@ class SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
status_ = status;
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
SpdyRstStreamStatus status_;
@@ -564,6 +574,8 @@ class SpdySettingsIR : public SpdyFrameIR {
clear_settings_ = clear_settings;
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
ValueMap values_;
bool clear_settings_;
@@ -576,6 +588,8 @@ class SpdyPingIR : public SpdyFrameIR {
explicit SpdyPingIR(SpdyPingId id) : id_(id) {}
SpdyPingId id() const { return id_; }
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
SpdyPingId id_;
@@ -600,6 +614,8 @@ class SpdyGoAwayIR : public SpdyFrameIR {
status_ = status;
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
SpdyStreamId last_good_stream_id_;
SpdyGoAwayStatus status_;
@@ -612,6 +628,8 @@ class SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR {
explicit SpdyHeadersIR(SpdyStreamId stream_id)
: SpdyFrameWithNameValueBlockIR(stream_id) {}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
};
@@ -629,6 +647,8 @@ class SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
delta_ = delta;
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
int32 delta_;
@@ -656,6 +676,8 @@ class SpdyCredentialIR : public SpdyFrameIR {
certificates_.push_back(certificate.as_string());
}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
int16 slot_;
std::string proof_;
@@ -664,11 +686,14 @@ class SpdyCredentialIR : public SpdyFrameIR {
DISALLOW_COPY_AND_ASSIGN(SpdyCredentialIR);
};
-class SpdyBlockedIR : public SpdyFrameWithStreamIdIR {
+class NET_EXPORT_PRIVATE SpdyBlockedIR
+ : public NON_EXPORTED_BASE(SpdyFrameWithStreamIdIR) {
public:
explicit SpdyBlockedIR(SpdyStreamId stream_id)
: SpdyFrameWithStreamIdIR(stream_id) {}
+ virtual void Visit(SpdyFrameVisitor* visitor) const OVERRIDE;
+
private:
DISALLOW_COPY_AND_ASSIGN(SpdyBlockedIR);
};
@@ -716,6 +741,32 @@ class SpdyFrame {
DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
};
+// This interface is for classes that want to process SpdyFrameIRs without
+// having to know what type they are. An instance of this interface can be
+// passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
+// method of this class will be called.
+class SpdyFrameVisitor {
+ public:
+ virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) = 0;
+ virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) = 0;
+ virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
+ virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
+ virtual void VisitPing(const SpdyPingIR& ping) = 0;
+ virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
+ virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
+ virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
+ virtual void VisitCredential(const SpdyCredentialIR& credential) = 0;
+ virtual void VisitBlocked(const SpdyBlockedIR& blocked) = 0;
+ virtual void VisitData(const SpdyDataIR& data) = 0;
+
+ protected:
+ SpdyFrameVisitor() {}
+ virtual ~SpdyFrameVisitor() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SpdyFrameVisitor);
+};
+
} // namespace net
#endif // NET_SPDY_SPDY_PROTOCOL_H_
diff --git a/net/spdy/spdy_protocol_test.cc b/net/spdy/spdy_protocol_test.cc
index c172520..c01c022 100644
--- a/net/spdy/spdy_protocol_test.cc
+++ b/net/spdy/spdy_protocol_test.cc
@@ -52,6 +52,8 @@ TEST_P(SpdyProtocolTest, ProtocolConstants) {
EXPECT_EQ(7, GOAWAY);
EXPECT_EQ(8, HEADERS);
EXPECT_EQ(9, WINDOW_UPDATE);
+ EXPECT_EQ(10, CREDENTIAL);
+ EXPECT_EQ(11, BLOCKED);
EXPECT_EQ(std::numeric_limits<int32>::max(), kSpdyMaximumWindowSize);
}