Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(561)

Unified Diff: net/spdy/spdy_framer.cc

Issue 138803002: SPDY4: Turn SYN_STREAM and SYN_REPLY into HEADERS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Windows bool-cast fix. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/buffered_spdy_framer_unittest.cc ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_framer.cc
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 80cfbd06886626ba78aa45fca39ccffca79c490d..3400ddd002ccff9f2d5c5b483b56cfa2cc4239e8 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -179,8 +179,8 @@ size_t SpdyFramer::GetSynStreamMinimumSize() const {
return GetControlFrameHeaderSize() + 10;
} else {
// Calculated as:
- // frame prefix + 4 (associated stream ID) + 1 (priority) + 1 (slot)
- return GetControlFrameHeaderSize() + 6;
+ // frame prefix + 4 (priority)
+ return GetControlFrameHeaderSize() + 4;
}
}
@@ -683,6 +683,7 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
// Do some sanity checking on the control frame sizes and flags.
switch (current_frame_type_) {
case SYN_STREAM:
+ DCHECK_GT(4, spdy_version_);
if (current_frame_length_ < GetSynStreamMinimumSize()) {
set_error(SPDY_INVALID_CONTROL_FRAME);
} else if (current_frame_flags_ &
@@ -734,10 +735,21 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
break;
}
case HEADERS:
- if (current_frame_length_ < GetHeadersMinimumSize()) {
- set_error(SPDY_INVALID_CONTROL_FRAME);
- } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
- set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
+ {
+ size_t min_size = GetHeadersMinimumSize();
+ if (spdy_version_ > 3 &&
+ (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
+ min_size += 4;
+ }
+ if (current_frame_length_ < min_size) {
+ set_error(SPDY_INVALID_CONTROL_FRAME);
+ } else if (spdy_version_ < 4 &&
+ current_frame_flags_ & ~CONTROL_FLAG_FIN) {
+ set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
+ } else if (spdy_version_ > 3 && current_frame_flags_ &
+ ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY)) {
+ set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
+ }
}
break;
case WINDOW_UPDATE:
@@ -815,6 +827,9 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
break;
case HEADERS:
frame_size_without_variable_data = GetHeadersMinimumSize();
+ if (spdy_version_ > 3 && current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
+ frame_size_without_variable_data += 4; // priority
+ }
break;
case PUSH_PROMISE:
frame_size_without_variable_data = GetPushPromiseMinimumSize();
@@ -1077,7 +1092,7 @@ void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
size_t len) {
DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
- size_t original_len = len;
+ const size_t original_len = len;
if (remaining_control_header_ > 0) {
size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
@@ -1094,6 +1109,7 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
switch (current_frame_type_) {
case SYN_STREAM:
{
+ DCHECK_GT(4, spdy_version_);
bool successful_read = true;
if (spdy_version_ < 4) {
successful_read = reader.ReadUInt31(&current_frame_stream_id_);
@@ -1152,6 +1168,9 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
case HEADERS:
// SYN_REPLY and HEADERS are the same, save for the visitor call.
{
+ if (spdy_version_ > 3) {
+ DCHECK_EQ(HEADERS, current_frame_type_);
+ }
bool successful_read = true;
if (spdy_version_ < 4) {
successful_read = reader.ReadUInt31(&current_frame_stream_id_);
@@ -1165,17 +1184,40 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
// SPDY 2 had two unused bytes here. Seek past them.
reader.Seek(2);
}
+ const bool has_priority =
+ (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
+ uint32 priority = 0;
+ if (protocol_version() > 3 && has_priority) {
+ successful_read = reader.ReadUInt31(&priority);
+ DCHECK(successful_read);
+ }
DCHECK(reader.IsDoneReading());
if (debug_visitor_) {
+ // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM.
+ SpdyFrameType reported_type = current_frame_type_;
+ if (protocol_version() > 3 && has_priority) {
+ reported_type = SYN_STREAM;
+ }
debug_visitor_->OnReceiveCompressedFrame(
current_frame_stream_id_,
- current_frame_type_,
+ reported_type,
current_frame_length_);
}
if (current_frame_type_ == SYN_REPLY) {
visitor_->OnSynReply(
current_frame_stream_id_,
(current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
+ } else if (spdy_version_ > 3 &&
+ current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
+ // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes
+ // can be made independent of wire changes.
+ visitor_->OnSynStream(
+ current_frame_stream_id_,
+ 0, // associated_to_stream_id
+ priority,
+ 0, // TODO(hkhalil): handle slot for SPDY 4+?
+ current_frame_flags_ & CONTROL_FLAG_FIN,
+ false); // unidirectional
} else {
visitor_->OnHeaders(
current_frame_stream_id_,
@@ -1663,8 +1705,19 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream(
flags |= CONTROL_FLAG_FIN;
}
if (syn_stream.unidirectional()) {
+ // TODO(hkhalil): invalid for HTTP2.
flags |= CONTROL_FLAG_UNIDIRECTIONAL;
}
+ if (spdy_version_ >= 4) {
+ flags |= HEADERS_FLAG_PRIORITY;
+ }
+
+ // Sanitize priority.
+ uint8 priority = syn_stream.priority();
+ if (priority > GetLowestPriority()) {
+ DLOG(DFATAL) << "Priority out-of-bounds.";
+ priority = GetLowestPriority();
+ }
// The size of this frame, including variable-length name-value block.
const size_t size = GetSynStreamMinimumSize()
@@ -1674,26 +1727,23 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream(
if (spdy_version_ < 4) {
builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
builder.WriteUInt32(syn_stream.stream_id());
+ builder.WriteUInt32(syn_stream.associated_to_stream_id());
+ builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
+ builder.WriteUInt8(syn_stream.slot());
} else {
builder.WriteFramePrefix(*this,
- SYN_STREAM,
+ HEADERS,
flags,
syn_stream.stream_id());
+ builder.WriteUInt32(priority);
}
- builder.WriteUInt32(syn_stream.associated_to_stream_id());
- uint8 priority = syn_stream.priority();
- if (priority > GetLowestPriority()) {
- DLOG(DFATAL) << "Priority out-of-bounds.";
- priority = GetLowestPriority();
- }
- builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
- builder.WriteUInt8(syn_stream.slot());
DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
SerializeNameValueBlock(&builder, syn_stream);
if (debug_visitor_) {
const size_t payload_len = GetSerializedLength(
protocol_version(), &(syn_stream.name_value_block()));
+ // SPDY 4 reports this compression as a SYN_STREAM compression.
debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
SYN_STREAM,
payload_len,
@@ -1734,7 +1784,7 @@ SpdySerializedFrame* SpdyFramer::SerializeSynReply(
builder.WriteUInt32(syn_reply.stream_id());
} else {
builder.WriteFramePrefix(*this,
- SYN_REPLY,
+ HEADERS,
flags,
syn_reply.stream_id());
}
« no previous file with comments | « net/spdy/buffered_spdy_framer_unittest.cc ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698