Index: net/spdy/spdy_framer.cc |
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc |
index 96ccf9a9b87082f1a604ac44e05b51d93c453493..82a063b8eeeb9305eb12108c3345a0c32d6610f3 100644 |
--- a/net/spdy/spdy_framer.cc |
+++ b/net/spdy/spdy_framer.cc |
@@ -155,6 +155,93 @@ void SpdyFramer::Reset() { |
settings_scratch_.Reset(); |
} |
+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 |
+ // for this value as opposed to a constant. |
+ return 8; |
+} |
+ |
+size_t SpdyFramer::GetSynStreamMinimumSize() const { |
+ // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
+ // name-value block. Calculated as: |
+ // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) |
+ return GetControlFrameMinimumSize() + 10; |
+} |
+ |
+size_t SpdyFramer::GetSynReplyMinimumSize() const { |
+ // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
+ // name-value block. Calculated as: |
+ // control frame header + 4 (stream ID) |
+ size_t size = GetControlFrameMinimumSize() + 4; |
+ |
+ // In SPDY 2, there were 2 unused bytes before payload. |
+ if (protocol_version() < 3) { |
+ size += 2; |
+ } |
+ |
+ return size; |
+} |
+ |
+size_t SpdyFramer::GetRstStreamSize() const { |
+ // Size, in bytes, of a RST_STREAM frame. Calculated as: |
+ // control frame header + 4 (stream id) + 4 (status code) |
+ return GetControlFrameMinimumSize() + 8; |
+} |
+ |
+size_t SpdyFramer::GetSettingsMinimumSize() const { |
+ // Size, in bytes, of a SETTINGS frame not including the IDs and values |
+ // from the variable-length value block. Calculated as: |
+ // control frame header + 4 (number of ID/value pairs) |
+ return GetControlFrameMinimumSize() + 4; |
+} |
+ |
+size_t SpdyFramer::GetPingSize() const { |
+ // Size, in bytes, of this PING frame. Calculated as: |
+ // control frame header + 4 (id) |
+ return GetControlFrameMinimumSize() + 4; |
+} |
+ |
+size_t SpdyFramer::GetGoAwaySize() const { |
+ // Size, in bytes, of this GOAWAY frame. Calculated as: |
+ // control frame header + 4 (last good stream id) |
+ size_t size = GetControlFrameMinimumSize() + 4; |
+ |
+ // SPDY 3+ GOAWAY frames also contain a status. |
+ if (protocol_version() >= 3) { |
+ size += 4; |
+ } |
+ |
+ return size; |
+} |
+ |
+size_t SpdyFramer::GetHeadersMinimumSize() const { |
+ // Size, in bytes, of a HEADERS frame not including the variable-length |
+ // name-value block. Calculated as: |
+ // control frame header + 4 (stream ID) |
+ size_t size = GetControlFrameMinimumSize() + 4; |
+ |
+ // In SPDY 2, there were 2 unused bytes before payload. |
+ if (protocol_version() < 3) { |
+ size += 2; |
+ } |
+ |
+ return size; |
+} |
+ |
+size_t SpdyFramer::GetWindowUpdateSize() const { |
+ // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as: |
+ // control frame header + 4 (stream id) + 4 (delta) |
+ return GetControlFrameMinimumSize() + 8; |
+} |
+ |
+size_t SpdyFramer::GetCredentialMinimumSize() const { |
+ // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list |
+ // and proof. Calculated as: |
+ // control frame header + 2 (slot) |
+ return GetControlFrameMinimumSize() + 2; |
+} |
+ |
const char* SpdyFramer::StateToString(int state) { |
switch (state) { |
case SPDY_ERROR: |
@@ -468,7 +555,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
switch (current_control_frame.type()) { |
case SYN_STREAM: |
if (current_control_frame.length() < |
- SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
+ GetSynStreamMinimumSize() - SpdyControlFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() & |
~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
@@ -477,7 +564,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
break; |
case SYN_REPLY: |
if (current_control_frame.length() < |
- SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
+ GetSynReplyMinimumSize() - SpdyControlFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -485,7 +572,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
break; |
case RST_STREAM: |
if (current_control_frame.length() != |
- SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize) { |
+ GetRstStreamSize() - SpdyFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() != 0) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -495,7 +582,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
// Make sure that we have an integral number of 8-byte key/value pairs, |
// plus a 4-byte length field. |
if (current_control_frame.length() < |
- SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize || |
+ GetSettingsMinimumSize() - SpdyControlFrame::kHeaderSize || |
(current_control_frame.length() % 8 != 4)) { |
DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
<< current_control_frame.length(); |
@@ -507,12 +594,8 @@ void SpdyFramer::ProcessControlFrameHeader() { |
break; |
case GOAWAY: |
{ |
- // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account |
- // for this difference via a separate offset variable, since |
- // SpdyGoAwayControlFrame::size() returns the SPDY 3 size. |
- const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0; |
- if (current_control_frame.length() + goaway_offset != |
- SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize) { |
+ if (current_control_frame.length() != |
+ GetGoAwaySize() - SpdyFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() != 0) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -521,7 +604,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
} |
case HEADERS: |
if (current_control_frame.length() < |
- SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
+ GetHeadersMinimumSize() - SpdyControlFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -529,8 +612,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
break; |
case WINDOW_UPDATE: |
if (current_control_frame.length() != |
- SpdyWindowUpdateControlFrame::size() - |
- SpdyControlFrame::kHeaderSize) { |
+ GetWindowUpdateSize() - SpdyControlFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() != 0) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -538,7 +620,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
break; |
case PING: |
if (current_control_frame.length() != |
- SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
+ GetPingSize() - SpdyControlFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() != 0) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -546,7 +628,7 @@ void SpdyFramer::ProcessControlFrameHeader() { |
break; |
case CREDENTIAL: |
if (current_control_frame.length() < |
- SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
+ GetCredentialMinimumSize() - SpdyControlFrame::kHeaderSize) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_control_frame.flags() != 0) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
@@ -1323,13 +1405,8 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream( |
flags |= CONTROL_FLAG_UNIDIRECTIONAL; |
} |
- // The size, in bytes, of this frame not including the variable-length |
- // name-value block. Calculated as: |
- // 8 (control frame header) + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) |
- const size_t kSynStreamSizeBeforeNameValueBlock = 18; |
- |
// The size of this frame, including variable-length name-value block. |
- const size_t size = kSynStreamSizeBeforeNameValueBlock |
+ const size_t size = GetSynStreamMinimumSize() |
+ GetSerializedLength(protocol_version(), |
&(syn_stream.name_value_block())); |
@@ -1343,7 +1420,7 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream( |
} |
builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); |
builder.WriteUInt8(syn_stream.slot()); |
- DCHECK_EQ(kSynStreamSizeBeforeNameValueBlock, builder.length()); |
+ DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
SerializeNameValueBlock(&builder, syn_stream); |
return builder.take(); |
@@ -1378,17 +1455,8 @@ SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
flags |= CONTROL_FLAG_FIN; |
} |
- // The size, in bytes, of this frame not including the variable-length |
- // name-value block. Calculated as: |
- // 8 (control frame header) + 4 (stream ID) |
- size_t syn_reply_size_before_name_value_block = 12; |
- // In SPDY 2, there were 2 unused bytes before payload. |
- if (protocol_version() < 3) { |
- syn_reply_size_before_name_value_block += 2; |
- } |
- |
// The size of this frame, including variable-length name-value block. |
- size_t size = syn_reply_size_before_name_value_block |
+ size_t size = GetSynReplyMinimumSize() |
+ GetSerializedLength(protocol_version(), |
&(syn_reply.name_value_block())); |
@@ -1397,7 +1465,7 @@ SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
if (protocol_version() < 3) { |
builder.WriteUInt16(0); // Unused. |
} |
- DCHECK_EQ(syn_reply_size_before_name_value_block, builder.length()); |
+ DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); |
SerializeNameValueBlock(&builder, syn_reply); |
return builder.take(); |
@@ -1413,17 +1481,13 @@ SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream( |
SpdySerializedFrame* SpdyFramer::SerializeRstStream( |
const SpdyRstStreamIR& rst_stream) const { |
- // Size of our RST_STREAM frame. Calculated as: |
- // 8 (control frame header) + 4 (stream id) + 4 (status code) |
- const size_t kRstStreamFrameSize = 16; |
- |
SpdyFrameBuilder builder(RST_STREAM, |
kNoFlags, |
protocol_version(), |
- kRstStreamFrameSize); |
+ GetRstStreamSize()); |
builder.WriteUInt32(rst_stream.stream_id()); |
builder.WriteUInt32(rst_stream.status()); |
- DCHECK_EQ(kRstStreamFrameSize, builder.length()); |
+ DCHECK_EQ(GetRstStreamSize(), builder.length()); |
return builder.take(); |
} |
@@ -1450,16 +1514,12 @@ SpdySerializedFrame* SpdyFramer::SerializeSettings( |
} |
const SpdySettingsIR::ValueMap* values = &(settings.values()); |
- // Size, in bytes, of this SETTINGS frame not including the IDs and values |
- // from the variable-length value block. Calculated as: |
- // 8 (control frame header) + 4 (number of ID/value pairs) |
- const size_t kSettingsSizeWithoutValues = 12; |
// Size, in bytes, of this SETTINGS frame. |
- const size_t size = kSettingsSizeWithoutValues + (values->size() * 8); |
+ const size_t size = GetSettingsMinimumSize() + (values->size() * 8); |
SpdyFrameBuilder builder(SETTINGS, flags, protocol_version(), size); |
builder.WriteUInt32(values->size()); |
- DCHECK_EQ(kSettingsSizeWithoutValues, builder.length()); |
+ DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); |
for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); |
it != values->end(); |
++it) { |
@@ -1485,12 +1545,9 @@ SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { |
} |
SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
- // Size, in bytes, of this PING frame. Calculated as: |
- // 8 (control frame header) + 4 (id) |
- const size_t kPingSize = 12; |
- SpdyFrameBuilder builder(PING, 0, protocol_version(), kPingSize); |
+ SpdyFrameBuilder builder(PING, 0, protocol_version(), GetPingSize()); |
builder.WriteUInt32(ping.id()); |
- DCHECK_EQ(kPingSize, builder.length()); |
+ DCHECK_EQ(GetPingSize(), builder.length()); |
return builder.take(); |
} |
@@ -1503,19 +1560,12 @@ SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( |
SpdySerializedFrame* SpdyFramer::SerializeGoAway( |
const SpdyGoAwayIR& goaway) const { |
- // Size, in bytes, of this GOAWAY frame. Calculated as: |
- // 8 (control frame header) + 4 (last good stream id) |
- size_t size = 12; |
- // SPDY 3+ GOAWAY frames also contain a status. |
- if (protocol_version() >= 3) { |
- size += 4; |
- } |
- SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), size); |
+ SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), GetGoAwaySize()); |
builder.WriteUInt32(goaway.last_good_stream_id()); |
if (protocol_version() >= 3) { |
builder.WriteUInt32(goaway.status()); |
} |
- DCHECK_EQ(size, builder.length()); |
+ DCHECK_EQ(GetGoAwaySize(), builder.length()); |
return builder.take(); |
} |
@@ -1549,17 +1599,8 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders( |
flags |= CONTROL_FLAG_FIN; |
} |
- // The size, in bytes, of this frame not including the variable-length |
- // name-value block. Calculated as: |
- // 8 (control frame header) + 4 (stream ID) |
- size_t headers_size_before_name_value_block = 12; |
- // In SPDY 2, there were 2 unused bytes before payload. |
- if (protocol_version() < 3) { |
- headers_size_before_name_value_block += 2; |
- } |
- |
// The size of this frame, including variable-length name-value block. |
- size_t size = headers_size_before_name_value_block |
+ size_t size = GetHeadersMinimumSize() |
+ GetSerializedLength(protocol_version(), |
&(headers.name_value_block())); |
@@ -1568,7 +1609,7 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders( |
if (protocol_version() < 3) { |
builder.WriteUInt16(0); // Unused. |
} |
- DCHECK_EQ(headers_size_before_name_value_block, builder.length()); |
+ DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
SerializeNameValueBlock(&builder, headers); |
DCHECK_EQ(size, builder.length()); |
@@ -1586,17 +1627,13 @@ SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( |
SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( |
const SpdyWindowUpdateIR& window_update) const { |
- // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as: |
- // 8 (control frame header) + 4 (stream id) + 4 (delta) |
- const size_t kWindowUpdateSize = 16; |
- |
SpdyFrameBuilder builder(WINDOW_UPDATE, |
kNoFlags, |
protocol_version(), |
- kWindowUpdateSize); |
+ GetWindowUpdateSize()); |
builder.WriteUInt32(window_update.stream_id()); |
builder.WriteUInt32(window_update.delta()); |
- DCHECK_EQ(kWindowUpdateSize, builder.length()); |
+ DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
return builder.take(); |
} |
@@ -1616,8 +1653,7 @@ SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame( |
SpdySerializedFrame* SpdyFramer::SerializeCredential( |
const SpdyCredentialIR& credential) const { |
- size_t size = 8; // Room for frame header. |
- size += 2; // Room for slot. |
+ size_t size = GetCredentialMinimumSize(); |
size += 4 + credential.proof().length(); // Room for proof. |
for (SpdyCredentialIR::CertificateList::const_iterator it = |
credential.certificates()->begin(); |
@@ -1628,6 +1664,7 @@ SpdySerializedFrame* SpdyFramer::SerializeCredential( |
SpdyFrameBuilder builder(CREDENTIAL, 0, protocol_version(), size); |
builder.WriteUInt16(credential.slot()); |
+ DCHECK_EQ(GetCredentialMinimumSize(), builder.length()); |
builder.WriteStringPiece32(credential.proof()); |
for (SpdyCredentialIR::CertificateList::const_iterator it = |
credential.certificates()->begin(); |
@@ -1986,46 +2023,6 @@ bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const { |
return false; |
} |
-size_t SpdyFramer::GetMinimumControlFrameSize(int version, |
- SpdyControlType type) { |
- switch (type) { |
- case SYN_STREAM: |
- return SpdySynStreamControlFrame::size(); |
- case SYN_REPLY: |
- return SpdySynReplyControlFrame::size(); |
- case RST_STREAM: |
- return SpdyRstStreamControlFrame::size(); |
- case SETTINGS: |
- return SpdySettingsControlFrame::size(); |
- case NOOP: |
- // Even though NOOP is no longer supported, we still correctly report its |
- // size so that it can be handled correctly as incoming data if |
- // implementations so desire. |
- return SpdyFrame::kHeaderSize; |
- case PING: |
- return SpdyPingControlFrame::size(); |
- case GOAWAY: |
- if (version < 3) { |
- // SPDY 2 GOAWAY is smaller by 32 bits. Since |
- // SpdyGoAwayControlFrame::size() returns the size for SPDY 3, we adjust |
- // before returning here. |
- return SpdyGoAwayControlFrame::size() - 4; |
- } else { |
- return SpdyGoAwayControlFrame::size(); |
- } |
- case HEADERS: |
- return SpdyHeadersControlFrame::size(); |
- case WINDOW_UPDATE: |
- return SpdyWindowUpdateControlFrame::size(); |
- case CREDENTIAL: |
- return SpdyCredentialControlFrame::size(); |
- case NUM_CONTROL_FRAME_TYPES: |
- break; |
- } |
- LOG(ERROR) << "Unknown control frame type " << type; |
- return std::numeric_limits<size_t>::max(); |
-} |
- |
/* static */ |
SpdyStreamId SpdyFramer::GetControlFrameStreamId( |
const SpdyControlFrame* control_frame) { |