| Index: net/spdy/spdy_frame_builder.cc
|
| diff --git a/net/spdy/spdy_frame_builder.cc b/net/spdy/spdy_frame_builder.cc
|
| index 7ea7716b41bfff075e51f796415e8130d2f209f0..fc37c0b4a290d534859b425a822ee3392d7418d3 100644
|
| --- a/net/spdy/spdy_frame_builder.cc
|
| +++ b/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) {
|
| @@ -78,7 +80,7 @@ bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
|
| SpdyStreamId stream_id,
|
| uint8 flags) {
|
| if (framer.protocol_version() >= 4) {
|
| - return WriteFramePrefix(framer, DATA, flags, stream_id);
|
| + return BeginNewFrame(framer, DATA, flags, stream_id);
|
| }
|
| DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
|
| bool success = true;
|
| @@ -94,28 +96,37 @@ bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
|
| return success;
|
| }
|
|
|
| -bool SpdyFrameBuilder::WriteFramePrefix(const SpdyFramer& framer,
|
| - SpdyFrameType type,
|
| - uint8 flags,
|
| - SpdyStreamId stream_id) {
|
| - DCHECK_NE(-1,
|
| - SpdyConstants::SerializeFrameType(framer.protocol_version(), 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_LE(4, version_);
|
| +
|
| bool success = true;
|
| - // Upstream DCHECK's that capacity_ is under the maximum frame size at this
|
| - // point. Chromium does not, because of the large additional zlib inflation
|
| - // factor we use. (Frame size is is still checked by OverwriteLength() below).
|
| - if (type != DATA) {
|
| - success &= WriteUInt16(capacity_ - framer.GetControlFrameHeaderSize());
|
| - } else {
|
| - success &= WriteUInt16(capacity_ - framer.GetDataFrameMinimumSize());
|
| + 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(framer.protocol_version(), type));
|
| + SpdyConstants::SerializeFrameType(version_, type));
|
| success &= WriteUInt8(flags);
|
| success &= WriteUInt32(stream_id);
|
| - DCHECK_EQ(framer.GetDataFrameMinimumSize(), length());
|
| + DCHECK_EQ(framer.GetDataFrameMinimumSize(), length_);
|
| return success;
|
| }
|
|
|
| @@ -157,16 +168,17 @@ bool SpdyFrameBuilder::RewriteLength(const SpdyFramer& framer) {
|
|
|
| bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer,
|
| size_t length) {
|
| - if (framer.protocol_version() < 4) {
|
| - DCHECK_GE(framer.GetFrameMaximumSize() - framer.GetFrameMinimumSize(),
|
| + if (version_ < 4) {
|
| + DCHECK_GE(SpdyConstants::GetFrameMaximumSize(version_) -
|
| + framer.GetFrameMinimumSize(),
|
| length);
|
| } else {
|
| - DCHECK_GE(framer.GetFrameMaximumSize(), length);
|
| + DCHECK_GE(SpdyConstants::GetFrameMaximumSize(version_), length);
|
| }
|
| bool success = false;
|
| const size_t old_length = length_;
|
|
|
| - if (framer.protocol_version() < 4) {
|
| + if (version_ < 4) {
|
| FlagsAndLength flags_length = CreateFlagsAndLength(
|
| 0, // We're not writing over the flags value anyway.
|
| length);
|
| @@ -202,7 +214,7 @@ bool SpdyFrameBuilder::CanWrite(size_t length) const {
|
| return false;
|
| }
|
|
|
| - if (length_ + length > capacity_) {
|
| + if (offset_ + length_ + length > capacity_) {
|
| DCHECK(false);
|
| return false;
|
| }
|
|
|