| Index: net/spdy/spdy_frame_builder.cc | 
| diff --git a/net/spdy/spdy_frame_builder.cc b/net/spdy/spdy_frame_builder.cc | 
| index ee9d36c9f73d5c56cf59dbec073824b659d4e397..1f82dd9d97f2500586d5cdc861e8544644fb936c 100644 | 
| --- a/net/spdy/spdy_frame_builder.cc | 
| +++ b/net/spdy/spdy_frame_builder.cc | 
| @@ -80,11 +80,42 @@ bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer, | 
| offset_ += length_; | 
| length_ = 0; | 
|  | 
| +  // TODO(yasong): remove after OverwriteLength() is deleted. | 
| +  bool length_written = false; | 
| +  // Remember where the length field is written. Used for OverwriteLength(). | 
| +  if (output_ != nullptr && CanWrite(kLengthFieldLength)) { | 
| +    // Can write the length field. | 
| +    char* dest = nullptr; | 
| +    // |size| is the available bytes in the current memory block. | 
| +    int size = 0; | 
| +    output_->Next(&dest, &size); | 
| +    start_of_current_frame_ = dest; | 
| +    bytes_of_length_written_in_first_block_ = | 
| +        size > (int)kLengthFieldLength ? kLengthFieldLength : size; | 
| +    // If the current block is not enough for the length field, write the | 
| +    // length field here, and remember the pointer to the next block. | 
| +    if (size < (int)kLengthFieldLength) { | 
| +      // Write the first portion of the length field. | 
| +      int value = base::HostToNet32(capacity_ - offset_ - kFrameHeaderSize); | 
| +      memcpy(dest, reinterpret_cast<char*>(&value) + 1, size); | 
| +      Seek(size); | 
| +      output_->Next(&dest, &size); | 
| +      start_of_current_frame_in_next_block_ = dest; | 
| +      int size_left = | 
| +          kLengthFieldLength - bytes_of_length_written_in_first_block_; | 
| +      memcpy(dest, reinterpret_cast<char*>(&value) + 1 + size, size_left); | 
| +      Seek(size_left); | 
| +      length_written = true; | 
| +    } | 
| +  } | 
| + | 
| // 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 &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize); | 
| +  if (!length_written) { | 
| +    success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize); | 
| +  } | 
| success &= WriteUInt8(type); | 
| success &= WriteUInt8(flags); | 
| success &= WriteUInt32(stream_id); | 
| @@ -169,6 +200,30 @@ bool SpdyFrameBuilder::WriteBytes(const void* data, uint32_t data_len) { | 
|  | 
| bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer, | 
| size_t length) { | 
| +  if (output_ != nullptr) { | 
| +    size_t value = base::HostToNet32(length); | 
| +    if (start_of_current_frame_ != nullptr && | 
| +        bytes_of_length_written_in_first_block_ == kLengthFieldLength) { | 
| +      // Length field of the current frame is within one memory block. | 
| +      memcpy(start_of_current_frame_, reinterpret_cast<char*>(&value) + 1, | 
| +             kLengthFieldLength); | 
| +      return true; | 
| +    } else if (start_of_current_frame_ != nullptr && | 
| +               start_of_current_frame_in_next_block_ != nullptr && | 
| +               bytes_of_length_written_in_first_block_ < kLengthFieldLength) { | 
| +      // Length field of the current frame crosses two memory blocks. | 
| +      memcpy(start_of_current_frame_, reinterpret_cast<char*>(&value) + 1, | 
| +             bytes_of_length_written_in_first_block_); | 
| +      memcpy(start_of_current_frame_in_next_block_, | 
| +             reinterpret_cast<char*>(&value) + 1 + | 
| +                 bytes_of_length_written_in_first_block_, | 
| +             kLengthFieldLength - bytes_of_length_written_in_first_block_); | 
| +      return true; | 
| +    } else { | 
| +      return false; | 
| +    } | 
| +  } | 
| + | 
| DCHECK_GE(framer.GetFrameMaximumSize(), length); | 
| bool success = false; | 
| const size_t old_length = length_; | 
|  |