summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-19 22:10:02 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-19 22:10:02 +0000
commit3b6c899fcb8afde86d499e3822c1e7f0be3d8f1c (patch)
tree288d82fe9d786af321a36bf9300ba34ee5e934db
parenta5405268fd47d51aac20633f41d9f80ca1b84145 (diff)
downloadchromium_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.cc7
-rw-r--r--net/spdy/spdy_frame_builder.h7
-rw-r--r--net/spdy/spdy_framer.cc30
-rw-r--r--net/spdy/spdy_framer.h6
-rw-r--r--net/spdy/spdy_framer_test.cc11
-rw-r--r--net/spdy/spdy_protocol.cc10
-rw-r--r--net/spdy/spdy_protocol.h33
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);
};