15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_frame_builder.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_framer.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A special structure for the 8 bit flags and 24 bit length fields. 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)union FlagsAndLength { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8 flags_[4]; // 8 bits 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 length_; // 24 bits 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a FlagsAndLength. 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FlagsAndLength CreateFlagsAndLength(uint8 flags, size_t length) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FlagsAndLength flags_length; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags_length.length_ = htonl(static_cast<uint32>(length)); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0, flags & ~kControlFlagsMask); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags_length.flags_[0] = flags; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return flags_length; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyFrameBuilder::SpdyFrameBuilder(size_t size, SpdyMajorVersion version) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : buffer_(new char[size]), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) capacity_(size), 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu length_(0), 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu offset_(0), 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu version_(version) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SpdyFrameBuilder::~SpdyFrameBuilder() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* SpdyFrameBuilder::GetWritableBuffer(size_t length) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CanWrite(length)) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return buffer_.get() + offset_ + length_; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::Seek(size_t length) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CanWrite(length)) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) length_ += length; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyFrameType type, 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8 flags) { 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_GE(SPDY3, version_); 664ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch DCHECK_NE(-1, 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyConstants::SerializeFrameType(version_, type)); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = true; 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FlagsAndLength flags_length = CreateFlagsAndLength( 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) flags, capacity_ - framer.GetControlFrameHeaderSize()); 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu success &= WriteUInt16(kControlFlagMask | 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyConstants::SerializeMajorVersion(version_)); 734ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch success &= WriteUInt16( 744ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch SpdyConstants::SerializeFrameType(framer.protocol_version(), type)); 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) success &= WriteBytes(&flags_length, sizeof(flags_length)); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(framer.GetControlFrameHeaderSize(), length()); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return success; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer, 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyStreamId stream_id, 824ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch uint8 flags) { 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (version_ > SPDY3) { 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return BeginNewFrame(framer, DATA, flags, stream_id); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = true; 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) success &= WriteUInt32(stream_id); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t length_field = capacity_ - framer.GetDataFrameMinimumSize(); 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(0u, length_field & ~static_cast<size_t>(kLengthMask)); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FlagsAndLength flags_length; 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) flags_length.length_ = htonl(length_field); 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(0, flags & ~kDataFlagsMask); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) flags_length.flags_[0] = flags; 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) success &= WriteBytes(&flags_length, sizeof(flags_length)); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(framer.GetDataFrameMinimumSize(), length()); 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return success; 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer, 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyFrameType type, 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uint8 flags, 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyStreamId stream_id) { 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(SpdyConstants::IsValidFrameType(version_, 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyConstants::SerializeFrameType(version_, type))); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_LT(SPDY3, framer.protocol_version()); 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool success = true; 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (length_ > 0) { 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Update length field for previous frame. 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu OverwriteLength(framer, length_ - framer.GetPrefixLength(type)); 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DLOG_IF(DFATAL, SpdyConstants::GetFrameMaximumSize(version_) < length_) 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << "Frame length " << length_ 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << " is longer than the maximum allowed length."; 1154ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch } 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu offset_ += length_; 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu length_ = 0; 1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Assume all remaining capacity will be used for this frame. If not, 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // the length will get overwritten when we begin the next frame. 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Don't check for length limits here because this may be larger than the 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // actual frame length. 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu success &= WriteUInt16(capacity_ - offset_ - framer.GetPrefixLength(type)); 1254ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch success &= WriteUInt8( 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyConstants::SerializeFrameType(version_, type)); 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) success &= WriteUInt8(flags); 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) success &= WriteUInt32(stream_id); 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_EQ(framer.GetDataFrameMinimumSize(), length_); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return success; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SpdyFrameBuilder::WriteString(const std::string& value) { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (value.size() > 0xffff) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(false) << "Tried to write string with length > 16bit."; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteUInt16(static_cast<int>(value.size()))) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), static_cast<uint16>(value.size())); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SpdyFrameBuilder::WriteStringPiece32(const base::StringPiece& value) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteUInt32(value.size())) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), value.size()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::WriteBytes(const void* data, uint32 data_len) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CanWrite(data_len)) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* dest = GetWritableBuffer(data_len); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcpy(dest, data, data_len); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Seek(data_len); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::RewriteLength(const SpdyFramer& framer) { 1654ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return OverwriteLength(framer, 1664ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch length_ - framer.GetControlFrameHeaderSize()); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t length) { 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (version_ <= SPDY3) { 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_GE(SpdyConstants::GetFrameMaximumSize(version_) - 1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu framer.GetFrameMinimumSize(), 17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) length); 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_GE(SpdyConstants::GetFrameMaximumSize(version_), length); 17723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = false; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t old_length = length_; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (version_ <= SPDY3) { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FlagsAndLength flags_length = CreateFlagsAndLength( 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, // We're not writing over the flags value anyway. 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) length); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write into the correct location by temporarily faking the offset. 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) length_ = 5; // Offset at which the length field occurs. 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success = WriteBytes(reinterpret_cast<char*>(&flags_length) + 1, 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sizeof(flags_length) - 1); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) length_ = 0; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success = WriteUInt16(length); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) length_ = old_length; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return success; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1994ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochbool SpdyFrameBuilder::OverwriteFlags(const SpdyFramer& framer, 2004ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch uint8 flags) { 2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_LT(SPDY3, framer.protocol_version()); 2024ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch bool success = false; 2034ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch const size_t old_length = length_; 2044ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Flags are the fourth octet in the frame prefix. 2054ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch length_ = 3; 2064ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch success = WriteUInt8(flags); 2074ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch length_ = old_length; 2084ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return success; 2094ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch} 2104ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SpdyFrameBuilder::CanWrite(size_t length) const { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (length > kLengthMask) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(false); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (offset_ + length_ + length > capacity_) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(false); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 226