diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-19 22:10:02 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-19 22:10:02 +0000 |
commit | 3b6c899fcb8afde86d499e3822c1e7f0be3d8f1c (patch) | |
tree | 288d82fe9d786af321a36bf9300ba34ee5e934db | |
parent | a5405268fd47d51aac20633f41d9f80ca1b84145 (diff) | |
download | chromium_src-3b6c899fcb8afde86d499e3822c1e7f0be3d8f1c.zip chromium_src-3b6c899fcb8afde86d499e3822c1e7f0be3d8f1c.tar.gz chromium_src-3b6c899fcb8afde86d499e3822c1e7f0be3d8f1c.tar.bz2 |
Remove SpdyDataFrame references from VTL.
Introduces API for creating SPDY DATA frame headers without payload (to avoid extra payload copies).
This lands server change 42554988.
Review URL: https://codereview.chromium.org/12207193
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@183305 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/spdy/spdy_frame_builder.cc | 7 | ||||
-rw-r--r-- | net/spdy/spdy_frame_builder.h | 7 | ||||
-rw-r--r-- | net/spdy/spdy_framer.cc | 30 | ||||
-rw-r--r-- | net/spdy/spdy_framer.h | 6 | ||||
-rw-r--r-- | net/spdy/spdy_framer_test.cc | 11 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.cc | 10 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.h | 33 |
7 files changed, 89 insertions, 15 deletions
diff --git a/net/spdy/spdy_frame_builder.cc b/net/spdy/spdy_frame_builder.cc index 5b87be0..361dede 100644 --- a/net/spdy/spdy_frame_builder.cc +++ b/net/spdy/spdy_frame_builder.cc @@ -114,9 +114,14 @@ bool SpdyFrameBuilder::WriteBytes(const void* data, uint32 data_len) { } bool SpdyFrameBuilder::RewriteLength(const SpdyFramer& framer) { + return OverwriteLength(framer, length_ - framer.GetControlFrameMinimumSize()); +} + +bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer, + size_t length) { FlagsAndLength flags_length = CreateFlagsAndLength( 0, // We're not writing over the flags value anyway. - length_ - framer.GetControlFrameMinimumSize()); + length); // Write into the correct location by temporarily faking the offset. const size_t old_length = length_; diff --git a/net/spdy/spdy_frame_builder.h b/net/spdy/spdy_frame_builder.h index 629bd87..7c52357 100644 --- a/net/spdy/spdy_frame_builder.h +++ b/net/spdy/spdy_frame_builder.h @@ -94,6 +94,13 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder { // with the correct version for the frame being written. bool RewriteLength(const SpdyFramer& framer); + // Update (in-place) the length field in the frame being built to reflect the + // given length. + // The framer parameter is used to determine version-specific location and + // size information of the length field to be written, and must be initialized + // with the correct version for the frame being written. + bool OverwriteLength(const SpdyFramer& framer, size_t length); + protected: const char* end_of_payload() const { return buffer_.get() + length_; } diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index d29150c..6164531 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc @@ -153,6 +153,13 @@ void SpdyFramer::Reset() { settings_scratch_.Reset(); } +size_t SpdyFramer::GetDataFrameMinimumSize() const { + // Size, in bytes, of the data frame header. Future versions of SPDY + // will likely vary this, so we allow for the flexibility of a function call + // for this value as opposed to a constant. + return 8; +} + size_t SpdyFramer::GetControlFrameMinimumSize() const { // Size, in bytes, of the control frame header. Future versions of SPDY // will likely vary this, so we allow for the flexibility of a function call @@ -1720,18 +1727,31 @@ SpdyDataFrame* SpdyFramer::CreateDataFrame( } SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const { - // Size, in bytes, of this DATA frame. Calculated as: - // 4 (stream id) + 1 (flags) + 3 (length) + payload length - const size_t size = 8 + data.data().length(); + const size_t kSize = GetDataFrameMinimumSize() + data.data().length(); SpdyDataFlags flags = DATA_FLAG_NONE; if (data.fin()) { flags = DATA_FLAG_FIN; } - SpdyFrameBuilder builder(data.stream_id(), flags, size); + SpdyFrameBuilder builder(data.stream_id(), flags, kSize); builder.WriteBytes(data.data().data(), data.data().length()); - DCHECK_EQ(size, builder.length()); + DCHECK_EQ(kSize, builder.length()); + return builder.take(); +} + +SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( + const SpdyDataIR& data) const { + const size_t kSize = GetDataFrameMinimumSize(); + + SpdyDataFlags flags = DATA_FLAG_NONE; + if (data.fin()) { + flags = DATA_FLAG_FIN; + } + + SpdyFrameBuilder builder(data.stream_id(), flags, kSize); + builder.OverwriteLength(*this, data.data().length()); + DCHECK_EQ(kSize, builder.length()); return builder.take(); } diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h index 2b48f93..4ee88a6 100644 --- a/net/spdy/spdy_framer.h +++ b/net/spdy/spdy_framer.h @@ -444,6 +444,8 @@ class NET_EXPORT_PRIVATE SpdyFramer { SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id, const char* data, uint32 len, SpdyDataFlags flags) const; SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const; + // Serializes just the data frame header, excluding actual data payload. + SpdySerializedFrame* SerializeDataFrameHeader(const SpdyDataIR& data) const; // NOTES about frame compression. // We want spdy to compress headers across the entire session. As long as @@ -477,8 +479,8 @@ class NET_EXPORT_PRIVATE SpdyFramer { display_protocol_ = protocol; } - // Returns the (minimum) size of control frames (sans variable-length - // portions). + // Returns the (minimum) size of frames (sans variable-length portions). + size_t GetDataFrameMinimumSize() const; size_t GetControlFrameMinimumSize() const; size_t GetSynStreamMinimumSize() const; size_t GetSynReplyMinimumSize() const; diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index b40753f..7c29273 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc @@ -1525,9 +1525,20 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { 'o' }; const char bytes[] = "hello"; + scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame( 1, bytes, strlen(bytes), DATA_FLAG_NONE)); CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); + + SpdyDataIR data_ir(1); + data_ir.SetDataShallow(base::StringPiece(bytes, strlen(bytes))); + frame.reset(framer.SerializeDataFrameHeader(data_ir)); + CompareCharArraysWithHexError( + kDescription, + reinterpret_cast<const unsigned char*>(frame->data()), + framer.GetDataFrameMinimumSize(), + kFrameData, + framer.GetDataFrameMinimumSize()); } { diff --git a/net/spdy/spdy_protocol.cc b/net/spdy/spdy_protocol.cc index 9a43c0d..0373ab0 100644 --- a/net/spdy/spdy_protocol.cc +++ b/net/spdy/spdy_protocol.cc @@ -11,6 +11,16 @@ SpdyFrameWithNameValueBlockIR::SpdyFrameWithNameValueBlockIR( SpdyFrameWithNameValueBlockIR::~SpdyFrameWithNameValueBlockIR() {} +SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data) + : SpdyFrameWithFinIR(stream_id) { + SetDataDeep(data); +} + +SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id) + : SpdyFrameWithFinIR(stream_id) {} + +SpdyDataIR::~SpdyDataIR() {} + SpdySettingsIR::SpdySettingsIR() : clear_settings_(false) {} SpdySettingsIR::~SpdySettingsIR() {} diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h index 322ba57..3fa80a8 100644 --- a/net/spdy/spdy_protocol.h +++ b/net/spdy/spdy_protocol.h @@ -14,6 +14,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "base/string_piece.h" #include "base/sys_byteorder.h" #include "net/base/net_export.h" @@ -574,17 +575,35 @@ class NET_EXPORT_PRIVATE SpdyFrameWithNameValueBlockIR DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR); }; -class SpdyDataIR : public SpdyFrameWithFinIR { +class NET_EXPORT_PRIVATE SpdyDataIR + : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { public: - SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data) - : SpdyFrameWithFinIR(stream_id) { - set_data(data); - } + // Performs deep copy on data. + SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data); + + // Use in conjunction with SetDataShallow() for shallow-copy on data. + explicit SpdyDataIR(SpdyStreamId stream_id); + + virtual ~SpdyDataIR(); + base::StringPiece data() const { return data_; } - void set_data(const base::StringPiece& data) { data.CopyToString(&data_); } + + // Deep-copy of data (keep private copy). + void SetDataDeep(const base::StringPiece& data) { + data_store_.reset(new std::string(data.data(), data.length())); + data_ = *(data_store_.get()); + } + + // Shallow-copy of data (do not keep private copy). + void SetDataShallow(const base::StringPiece& data) { + data_store_.reset(); + data_ = data; + } private: - std::string data_; + // Used to store data that this SpdyDataIR should own. + scoped_ptr<std::string> data_store_; + base::StringPiece data_; DISALLOW_COPY_AND_ASSIGN(SpdyDataIR); }; |