summaryrefslogtreecommitdiffstats
path: root/chromium/net/spdy/spdy_frame_builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/spdy/spdy_frame_builder.cc')
-rw-r--r--chromium/net/spdy/spdy_frame_builder.cc94
1 files changed, 64 insertions, 30 deletions
diff --git a/chromium/net/spdy/spdy_frame_builder.cc b/chromium/net/spdy/spdy_frame_builder.cc
index 9e779ff4594..a7eb91d71ce 100644
--- a/chromium/net/spdy/spdy_frame_builder.cc
+++ b/chromium/net/spdy/spdy_frame_builder.cc
@@ -32,10 +32,12 @@ FlagsAndLength CreateFlagsAndLength(uint8 flags, size_t length) {
} // namespace
-SpdyFrameBuilder::SpdyFrameBuilder(size_t size)
+ SpdyFrameBuilder::SpdyFrameBuilder(size_t size, SpdyMajorVersion version)
: buffer_(new char[size]),
capacity_(size),
- length_(0) {
+ length_(0),
+ offset_(0),
+ version_(version) {
}
SpdyFrameBuilder::~SpdyFrameBuilder() {
@@ -45,7 +47,7 @@ char* SpdyFrameBuilder::GetWritableBuffer(size_t length) {
if (!CanWrite(length)) {
return NULL;
}
- return buffer_.get() + length_;
+ return buffer_.get() + offset_ + length_;
}
bool SpdyFrameBuilder::Seek(size_t length) {
@@ -60,14 +62,16 @@ bool SpdyFrameBuilder::Seek(size_t length) {
bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer,
SpdyFrameType type,
uint8 flags) {
- DCHECK_GE(type, FIRST_CONTROL_TYPE);
- DCHECK_LE(type, LAST_CONTROL_TYPE);
- DCHECK_GT(4, framer.protocol_version());
+ DCHECK_GE(SPDY3, version_);
+ DCHECK_NE(-1,
+ SpdyConstants::SerializeFrameType(version_, type));
bool success = true;
FlagsAndLength flags_length = CreateFlagsAndLength(
flags, capacity_ - framer.GetControlFrameHeaderSize());
- success &= WriteUInt16(kControlFlagMask | framer.protocol_version());
- success &= WriteUInt16(type);
+ success &= WriteUInt16(kControlFlagMask |
+ SpdyConstants::SerializeMajorVersion(version_));
+ success &= WriteUInt16(
+ SpdyConstants::SerializeFrameType(framer.protocol_version(), type));
success &= WriteBytes(&flags_length, sizeof(flags_length));
DCHECK_EQ(framer.GetControlFrameHeaderSize(), length());
return success;
@@ -75,9 +79,9 @@ bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer,
bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
SpdyStreamId stream_id,
- SpdyDataFlags flags) {
- if (framer.protocol_version() >= 4) {
- return WriteFramePrefix(framer, DATA, flags, stream_id);
+ uint8 flags) {
+ if (version_ > SPDY3) {
+ return BeginNewFrame(framer, DATA, flags, stream_id);
}
DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
bool success = true;
@@ -93,21 +97,36 @@ bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
return success;
}
-bool SpdyFrameBuilder::WriteFramePrefix(const SpdyFramer& framer,
- SpdyFrameType type,
- uint8 flags,
- SpdyStreamId stream_id) {
- DCHECK_LE(DATA, type);
- DCHECK_GE(LAST_CONTROL_TYPE, type);
+bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer,
+ SpdyFrameType type,
+ uint8 flags,
+ SpdyStreamId stream_id) {
+ DCHECK(SpdyConstants::IsValidFrameType(version_,
+ SpdyConstants::SerializeFrameType(version_, type)));
DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
- DCHECK_LE(4, framer.protocol_version());
+ DCHECK_LT(SPDY3, framer.protocol_version());
bool success = true;
- DCHECK_GT(1u<<16, capacity_); // Make sure length fits in 2B.
- success &= WriteUInt16(capacity_);
- success &= WriteUInt8(type);
+ if (length_ > 0) {
+ // Update length field for previous frame.
+ OverwriteLength(framer, length_ - framer.GetPrefixLength(type));
+ DLOG_IF(DFATAL, SpdyConstants::GetFrameMaximumSize(version_) < length_)
+ << "Frame length " << length_
+ << " is longer than the maximum allowed length.";
+ }
+
+ offset_ += length_;
+ length_ = 0;
+
+ // Assume all remaining capacity will be used for this frame. If not,
+ // the length will get overwritten when we begin the next frame.
+ // Don't check for length limits here because this may be larger than the
+ // actual frame length.
+ success &= WriteUInt16(capacity_ - offset_ - framer.GetPrefixLength(type));
+ success &= WriteUInt8(
+ SpdyConstants::SerializeFrameType(version_, type));
success &= WriteUInt8(flags);
success &= WriteUInt32(stream_id);
- DCHECK_EQ(framer.GetDataFrameMinimumSize(), length());
+ DCHECK_EQ(framer.GetDataFrameMinimumSize(), length_);
return success;
}
@@ -143,20 +162,23 @@ bool SpdyFrameBuilder::WriteBytes(const void* data, uint32 data_len) {
}
bool SpdyFrameBuilder::RewriteLength(const SpdyFramer& framer) {
- if (framer.protocol_version() < 4) {
- return OverwriteLength(framer,
- length_ - framer.GetControlFrameHeaderSize());
- } else {
- return OverwriteLength(framer, length_);
- }
+ return OverwriteLength(framer,
+ length_ - framer.GetControlFrameHeaderSize());
}
bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer,
size_t length) {
+ if (version_ <= SPDY3) {
+ DCHECK_GE(SpdyConstants::GetFrameMaximumSize(version_) -
+ framer.GetFrameMinimumSize(),
+ length);
+ } else {
+ DCHECK_GE(SpdyConstants::GetFrameMaximumSize(version_), length);
+ }
bool success = false;
const size_t old_length = length_;
- if (framer.protocol_version() < 4) {
+ if (version_ <= SPDY3) {
FlagsAndLength flags_length = CreateFlagsAndLength(
0, // We're not writing over the flags value anyway.
length);
@@ -174,13 +196,25 @@ bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer,
return success;
}
+bool SpdyFrameBuilder::OverwriteFlags(const SpdyFramer& framer,
+ uint8 flags) {
+ DCHECK_LT(SPDY3, framer.protocol_version());
+ bool success = false;
+ const size_t old_length = length_;
+ // Flags are the fourth octet in the frame prefix.
+ length_ = 3;
+ success = WriteUInt8(flags);
+ length_ = old_length;
+ return success;
+}
+
bool SpdyFrameBuilder::CanWrite(size_t length) const {
if (length > kLengthMask) {
DCHECK(false);
return false;
}
- if (length_ + length > capacity_) {
+ if (offset_ + length_ + length > capacity_) {
DCHECK(false);
return false;
}