diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-27 20:36:32 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-27 20:36:32 +0000 |
commit | dda726d357e63bd7fe601f576a9fea0089273a3e (patch) | |
tree | 939ca1b851d86761027ae95636caea61cfeab01d | |
parent | 6bbac915b849e858deccc662c0ffe996b56481f1 (diff) | |
download | chromium_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.h | 6 | ||||
-rw-r--r-- | net/spdy/spdy_framer.cc | 57 | ||||
-rw-r--r-- | net/spdy/spdy_framer.h | 3 | ||||
-rw-r--r-- | net/spdy/spdy_framer_test.cc | 6 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.cc | 45 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.h | 59 | ||||
-rw-r--r-- | net/spdy/spdy_protocol_test.cc | 2 |
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); } |