summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-15 20:42:36 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-15 20:42:36 +0000
commitd5b42bdd76ee895b0b4f6895400ba23c60decc96 (patch)
treec22819d9514580389d15ed82e4a79b806ebfefd2
parent84981baa4338eec37363ad541054df96b3ad456a (diff)
downloadchromium_src-d5b42bdd76ee895b0b4f6895400ba23c60decc96.zip
chromium_src-d5b42bdd76ee895b0b4f6895400ba23c60decc96.tar.gz
chromium_src-d5b42bdd76ee895b0b4f6895400ba23c60decc96.tar.bz2
[SPDY] Incorporate latest framing changes from HTTP2 into SPDY 4 as SPDY 4a2.
Removes support for SPDY 4a1. Remove --enable-spdy4 flag for now (until we get test coverage). This lands server change 45362310. BUG=230124 TBR=jam@chromium.org Review URL: https://chromiumcodereview.appspot.com/14189003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200342 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--chrome/browser/io_thread.cc2
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--net/http/http_server_properties.cc2
-rw-r--r--net/http/http_server_properties.h2
-rw-r--r--net/http/http_stream_factory.cc16
-rw-r--r--net/http/http_stream_factory.h4
-rw-r--r--net/socket/next_proto.h4
-rw-r--r--net/socket/ssl_client_socket.cc8
-rw-r--r--net/spdy/spdy_frame_builder.cc63
-rw-r--r--net/spdy/spdy_frame_builder.h10
-rw-r--r--net/spdy/spdy_frame_builder_test.cc6
-rw-r--r--net/spdy/spdy_framer.cc193
-rw-r--r--net/spdy/spdy_framer_test.cc67
-rw-r--r--net/spdy/spdy_http_stream_spdy3_unittest.cc2
-rw-r--r--net/spdy/spdy_network_transaction_spdy3_unittest.cc2
-rw-r--r--net/spdy/spdy_session.cc4
-rw-r--r--net/spdy/spdy_session_spdy3_unittest.cc2
-rw-r--r--net/spdy/spdy_test_util_common.cc4
21 files changed, 246 insertions, 162 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 4146ca3..bcb5c98 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6691,12 +6691,6 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_DESCRIPTION" desc="Description for the flag to defer image decoding in WebKit.">
Defer image decoding operations in WebKit until painting.
</message>
- <message name="IDS_FLAGS_ENABLE_SPDY4A1_NAME" desc="Title for the flag to enable SPDY/4 alpha 1">
- Enable SPDY/4 alpha 1
- </message>
- <message name="IDS_FLAGS_ENABLE_SPDY4A1_DESCRIPTION" desc="Description for the flag to enable SPDY/4 alpha 1.">
- Enable experimental SPDY/4 alpha 1. Note that this also enables SPDY/3.1.
- </message>
<message name="IDS_FLAGS_ENABLE_ASYNC_DNS_NAME" desc="Title for the flag to enable asynchronous DNS client.">
Built-in Asynchronous DNS
</message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 47e19ff..5f0de4a 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -672,13 +672,6 @@ const Experiment kExperiments[] = {
SINGLE_VALUE_TYPE(switches::kEnableAutologin)
},
{
- "enable-spdy4a1",
- IDS_FLAGS_ENABLE_SPDY4A1_NAME,
- IDS_FLAGS_ENABLE_SPDY4A1_DESCRIPTION,
- kOsAll,
- SINGLE_VALUE_TYPE(switches::kEnableSpdy4a1)
- },
- {
"enable-async-dns",
IDS_FLAGS_ENABLE_ASYNC_DNS_NAME,
IDS_FLAGS_ENABLE_ASYNC_DNS_DESCRIPTION,
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 0631571..568734b 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -657,8 +657,6 @@ void IOThread::InitializeNetworkOptions(const CommandLine& command_line) {
std::string spdy_mode =
command_line.GetSwitchValueASCII(switches::kUseSpdy);
EnableSpdy(spdy_mode);
- } else if (command_line.HasSwitch(switches::kEnableSpdy4a1)) {
- net::HttpStreamFactory::EnableNpnSpdy4a1();
} else if (command_line.HasSwitch(switches::kDisableSpdy31)) {
net::HttpStreamFactory::EnableNpnSpdy3();
} else if (command_line.HasSwitch(switches::kEnableNpn)) {
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 8efec7a..bcb4e70 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -647,9 +647,6 @@ const char kEnableSdch[] = "enable-sdch";
// Disable SPDY/3.1. This is a temporary testing flag.
const char kDisableSpdy31[] = "disable-spdy31";
-// Enable SPDY/4 alpha 1. This is a temporary testing flag.
-const char kEnableSpdy4a1[] = "enable-spdy4a1";
-
// Enable SPDY CREDENTIAL frame support. This is a temporary testing flag.
const char kEnableSpdyCredentialFrames[] = "enable-spdy-credential-frames";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index d6a536f..094406d 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -182,7 +182,6 @@ extern const char kEnableQuic[];
extern const char kEnableResourceContentSettings[];
extern const char kEnableSdch[];
extern const char kDisableSpdy31[];
-extern const char kEnableSpdy4a1[];
extern const char kEnableSpdyCredentialFrames[];
extern const char kEnableSpellingAutoCorrect[];
extern const char kEnableStackedTabStrip[];
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc
index 48b21ac..81a0e98 100644
--- a/net/http/http_server_properties.cc
+++ b/net/http/http_server_properties.cc
@@ -17,7 +17,7 @@ const char* const kAlternateProtocolStrings[] = {
"npn-spdy/2",
"npn-spdy/3",
"npn-spdy/3.1",
- "npn-spdy/4a1",
+ "npn-spdy/4a2",
"quic"
};
const char kBrokenAlternateProtocol[] = "Broken";
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index 28a608f..e1fb9db 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -20,7 +20,7 @@ enum AlternateProtocol {
NPN_SPDY_2,
NPN_SPDY_3,
NPN_SPDY_3_1,
- NPN_SPDY_4a1,
+ NPN_SPDY_4A2,
QUIC,
NUM_ALTERNATE_PROTOCOLS,
ALTERNATE_PROTOCOL_BROKEN, // The alternate protocol is known to be broken.
diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc
index 8432fb6..05114ba 100644
--- a/net/http/http_stream_factory.cc
+++ b/net/http/http_stream_factory.cc
@@ -180,18 +180,6 @@ void HttpStreamFactory::EnableNpnSpdy31() {
}
// static
-void HttpStreamFactory::EnableNpnSpdy4a1() {
- set_use_alternate_protocols(true);
- std::vector<std::string> next_protos;
- next_protos.push_back("http/1.1");
- next_protos.push_back("spdy/2");
- next_protos.push_back("spdy/3");
- next_protos.push_back("spdy/3.1");
- next_protos.push_back("spdy/4a1");
- SetNextProtos(next_protos);
-}
-
-// static
void HttpStreamFactory::SetNextProtos(const std::vector<std::string>& value) {
if (!next_protos_)
next_protos_ = new std::vector<std::string>;
@@ -212,8 +200,8 @@ void HttpStreamFactory::SetNextProtos(const std::vector<std::string>& value) {
enabled_protocols_[NPN_SPDY_3] = true;
} else if (value[i] == "spdy/3.1") {
enabled_protocols_[NPN_SPDY_3_1] = true;
- } else if (value[i] == "spdy/4a1") {
- enabled_protocols_[NPN_SPDY_4a1] = true;
+ } else if (value[i] == "spdy/4a2") {
+ enabled_protocols_[NPN_SPDY_4A2] = true;
} else if (value[i] == "quic") {
enabled_protocols_[QUIC] = true;
}
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h
index c131897..eaadcc7 100644
--- a/net/http/http_stream_factory.h
+++ b/net/http/http_stream_factory.h
@@ -246,10 +246,6 @@ class NET_EXPORT HttpStreamFactory {
// supported via NPN.
static void EnableNpnSpdy31();
- // Sets http/1.1, spdy/2, spdy/3, spdy/3.1, and spdy/4a1 as the
- // protocols supported via NPN.
- static void EnableNpnSpdy4a1();
-
// Sets the protocols supported by NPN (next protocol negotiation) during the
// SSL handshake as well as by HTTP Alternate-Protocol.
static void SetNextProtos(const std::vector<std::string>& value);
diff --git a/net/socket/next_proto.h b/net/socket/next_proto.h
index 9d5b911..32fbff7 100644
--- a/net/socket/next_proto.h
+++ b/net/socket/next_proto.h
@@ -21,8 +21,8 @@ enum NextProto {
kProtoSPDY21 = 4,
kProtoSPDY3 = 5,
kProtoSPDY31 = 6,
- kProtoSPDY4a1 = 7,
- kProtoSPDYMaximumVersion = kProtoSPDY4a1,
+ kProtoSPDY4a2 = 7,
+ kProtoSPDYMaximumVersion = kProtoSPDY4a2,
kProtoMaximumVersion = 7,
};
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc
index 371f790..fa1b6af 100644
--- a/net/socket/ssl_client_socket.cc
+++ b/net/socket/ssl_client_socket.cc
@@ -28,8 +28,8 @@ NextProto SSLClientSocket::NextProtoFromString(
return kProtoSPDY3;
} else if (proto_string == "spdy/3.1") {
return kProtoSPDY31;
- } else if (proto_string == "spdy/4a1") {
- return kProtoSPDY4a1;
+ } else if (proto_string == "spdy/4a2") {
+ return kProtoSPDY4a2;
} else {
return kProtoUnknown;
}
@@ -48,8 +48,8 @@ const char* SSLClientSocket::NextProtoToString(NextProto next_proto) {
return "spdy/3";
case kProtoSPDY31:
return "spdy/3.1";
- case kProtoSPDY4a1:
- return "spdy/4a1";
+ case kProtoSPDY4a2:
+ return "spdy/4a2";
default:
break;
}
diff --git a/net/spdy/spdy_frame_builder.cc b/net/spdy/spdy_frame_builder.cc
index 73b9144..9e779ff 100644
--- a/net/spdy/spdy_frame_builder.cc
+++ b/net/spdy/spdy_frame_builder.cc
@@ -62,19 +62,13 @@ bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer,
uint8 flags) {
DCHECK_GE(type, FIRST_CONTROL_TYPE);
DCHECK_LE(type, LAST_CONTROL_TYPE);
+ DCHECK_GT(4, framer.protocol_version());
bool success = true;
- if (framer.protocol_version() < 4) {
- FlagsAndLength flags_length = CreateFlagsAndLength(
- flags, capacity_ - framer.GetControlFrameHeaderSize());
- success &= WriteUInt16(kControlFlagMask | framer.protocol_version());
- success &= WriteUInt16(type);
- success &= WriteBytes(&flags_length, sizeof(flags_length));
- } else {
- DCHECK_GT(1u<<16, capacity_); // Make sure length fits in 2B.
- success &= WriteUInt16(capacity_);
- success &= WriteUInt8(type);
- success &= WriteUInt8(flags);
- }
+ FlagsAndLength flags_length = CreateFlagsAndLength(
+ flags, capacity_ - framer.GetControlFrameHeaderSize());
+ success &= WriteUInt16(kControlFlagMask | framer.protocol_version());
+ success &= WriteUInt16(type);
+ success &= WriteBytes(&flags_length, sizeof(flags_length));
DCHECK_EQ(framer.GetControlFrameHeaderSize(), length());
return success;
}
@@ -82,24 +76,37 @@ bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer,
bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
SpdyStreamId stream_id,
SpdyDataFlags flags) {
+ if (framer.protocol_version() >= 4) {
+ return WriteFramePrefix(framer, DATA, flags, stream_id);
+ }
DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
bool success = true;
- if (framer.protocol_version() < 4) {
- success &= WriteUInt32(stream_id);
- size_t length_field = capacity_ - framer.GetDataFrameMinimumSize();
- DCHECK_EQ(0u, length_field & ~static_cast<size_t>(kLengthMask));
- FlagsAndLength flags_length;
- flags_length.length_ = htonl(length_field);
- DCHECK_EQ(0, flags & ~kDataFlagsMask);
- flags_length.flags_[0] = flags;
- success &= WriteBytes(&flags_length, sizeof(flags_length));
- } else {
- DCHECK_GT(1u<<16, capacity_); // Make sure length fits in 2B.
- success &= WriteUInt16(capacity_);
- success &= WriteUInt8(0);
- success &= WriteUInt8(flags);
- success &= WriteUInt32(stream_id);
- }
+ success &= WriteUInt32(stream_id);
+ size_t length_field = capacity_ - framer.GetDataFrameMinimumSize();
+ DCHECK_EQ(0u, length_field & ~static_cast<size_t>(kLengthMask));
+ FlagsAndLength flags_length;
+ flags_length.length_ = htonl(length_field);
+ DCHECK_EQ(0, flags & ~kDataFlagsMask);
+ flags_length.flags_[0] = flags;
+ success &= WriteBytes(&flags_length, sizeof(flags_length));
+ DCHECK_EQ(framer.GetDataFrameMinimumSize(), length());
+ return success;
+}
+
+bool SpdyFrameBuilder::WriteFramePrefix(const SpdyFramer& framer,
+ SpdyFrameType type,
+ uint8 flags,
+ SpdyStreamId stream_id) {
+ DCHECK_LE(DATA, type);
+ DCHECK_GE(LAST_CONTROL_TYPE, type);
+ DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+ DCHECK_LE(4, framer.protocol_version());
+ bool success = true;
+ DCHECK_GT(1u<<16, capacity_); // Make sure length fits in 2B.
+ success &= WriteUInt16(capacity_);
+ success &= WriteUInt8(type);
+ success &= WriteUInt8(flags);
+ success &= WriteUInt32(stream_id);
DCHECK_EQ(framer.GetDataFrameMinimumSize(), length());
return success;
}
diff --git a/net/spdy/spdy_frame_builder.h b/net/spdy/spdy_frame_builder.h
index 7f9b3b1..825254d 100644
--- a/net/spdy/spdy_frame_builder.h
+++ b/net/spdy/spdy_frame_builder.h
@@ -50,6 +50,7 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder {
// Populates this frame with a SPDY control frame header using
// version-specific information from the |framer| and length information from
// capacity_. The given type must be a control frame type.
+ // Used only for SPDY versions <4.
bool WriteControlFrameHeader(const SpdyFramer& framer,
SpdyFrameType type,
uint8 flags);
@@ -60,6 +61,15 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder {
SpdyStreamId stream_id,
SpdyDataFlags flags);
+ // Populates this frame with a SPDY4/HTTP2 frame prefix using
+ // version-specific information from the |framer| and length information from
+ // capacity_. The given type must be a control frame type.
+ // Used only for SPDY versions >=4.
+ bool WriteFramePrefix(const SpdyFramer& framer,
+ SpdyFrameType type,
+ uint8 flags,
+ SpdyStreamId stream_id);
+
// Takes the buffer from the SpdyFrameBuilder.
SpdyFrame* take() {
SpdyFrame* rv = new SpdyFrame(buffer_.release(), length_, true);
diff --git a/net/spdy/spdy_frame_builder_test.cc b/net/spdy/spdy_frame_builder_test.cc
index eeea2b6..65d9b05 100644
--- a/net/spdy/spdy_frame_builder_test.cc
+++ b/net/spdy/spdy_frame_builder_test.cc
@@ -53,7 +53,11 @@ TEST_P(SpdyFrameBuilderTest, RewriteLength) {
SettingsMap settings;
scoped_ptr<SpdyFrame> expected(framer.CreateSettings(settings));
SpdyFrameBuilder builder(expected->size() + 1);
- builder.WriteControlFrameHeader(framer, SETTINGS, 0);
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(framer, SETTINGS, 0);
+ } else {
+ builder.WriteFramePrefix(framer, SETTINGS, 0, 0);
+ }
builder.WriteUInt32(0); // Write the number of settings.
EXPECT_TRUE(builder.GetWritableBuffer(1) != NULL);
builder.RewriteLength(framer);
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 125b6cc..b3954484 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -167,7 +167,7 @@ size_t SpdyFramer::GetControlFrameHeaderSize() const {
case 3:
return 8;
case 4:
- return 4;
+ return 8;
}
LOG(DFATAL) << "Unhandled SPDY version.";
return 0;
@@ -175,16 +175,27 @@ size_t SpdyFramer::GetControlFrameHeaderSize() const {
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 GetControlFrameHeaderSize() + 10;
+ // name-value block.
+ if (spdy_version_ < 4) {
+ // Calculated as:
+ // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot)
+ return GetControlFrameHeaderSize() + 10;
+ } else {
+ // Calculated as:
+ // frame prefix + 4 (associated stream ID) + 1 (priority) + 1 (slot)
+ return GetControlFrameHeaderSize() + 6;
+ }
}
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 = GetControlFrameHeaderSize() + 4;
+ // name-value block.
+ size_t size = GetControlFrameHeaderSize();
+ if (spdy_version_ < 4) {
+ // Calculated as:
+ // control frame header + 4 (stream IDs)
+ size += 4;
+ }
// In SPDY 2, there were 2 unused bytes before payload.
if (protocol_version() < 3) {
@@ -195,9 +206,16 @@ size_t SpdyFramer::GetSynReplyMinimumSize() const {
}
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 GetControlFrameHeaderSize() + 8;
+ // Size, in bytes, of a RST_STREAM frame.
+ if (spdy_version_ < 4) {
+ // Calculated as:
+ // control frame header + 4 (stream id) + 4 (status code)
+ return GetControlFrameHeaderSize() + 8;
+ } else {
+ // Calculated as:
+ // frame prefix + 4 (status code)
+ return GetControlFrameHeaderSize() + 4;
+ }
}
size_t SpdyFramer::GetSettingsMinimumSize() const {
@@ -227,10 +245,14 @@ size_t SpdyFramer::GetGoAwaySize() const {
}
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 = GetControlFrameHeaderSize() + 4;
+ // Size, in bytes, of a SYN_REPLY frame not including the variable-length
+ // name-value block.
+ size_t size = GetControlFrameHeaderSize();
+ if (spdy_version_ < 4) {
+ // Calculated as:
+ // control frame header + 4 (stream IDs)
+ size += 4;
+ }
// In SPDY 2, there were 2 unused bytes before payload.
if (protocol_version() < 3) {
@@ -241,9 +263,16 @@ size_t SpdyFramer::GetHeadersMinimumSize() const {
}
size_t SpdyFramer::GetWindowUpdateSize() const {
- // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as:
- // control frame header + 4 (stream id) + 4 (delta)
- return GetControlFrameHeaderSize() + 8;
+ // Size, in bytes, of a WINDOW_UPDATE frame.
+ if (spdy_version_ < 4) {
+ // Calculated as:
+ // control frame header + 4 (stream id) + 4 (delta)
+ return GetControlFrameHeaderSize() + 8;
+ } else {
+ // Calculated as:
+ // frame prefix + 4 (delta)
+ return GetControlFrameHeaderSize() + 4;
+ }
}
size_t SpdyFramer::GetCredentialMinimumSize() const {
@@ -542,7 +571,6 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
remaining_data_length_ = length_field;
current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed();
} else {
- // TODO(hkhalil): Avoid re-reading fields as possible for DATA frames?
version = protocol_version();
uint16 length_field = 0;
bool successful_read = reader->ReadUInt16(&length_field);
@@ -560,23 +588,9 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
successful_read = reader->ReadUInt8(&current_frame_flags_);
DCHECK(successful_read);
- if (!is_control_frame) {
- // We may not have the entirety of the DATA frame header.
- if (current_frame_buffer_length_ < GetDataFrameMinimumSize()) {
- size_t bytes_desired =
- GetDataFrameMinimumSize() - current_frame_buffer_length_;
- UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
- if (current_frame_buffer_length_ < GetDataFrameMinimumSize()) {
- return original_len - len;
- }
- }
- // Construct a new SpdyFrameReader aware of the new frame length.
- reader.reset(new SpdyFrameReader(current_frame_buffer_.get(),
- current_frame_buffer_length_));
- reader->Seek(GetControlFrameHeaderSize());
- successful_read = reader->ReadUInt31(&current_frame_stream_id_);
- DCHECK(successful_read);
- }
+ successful_read = reader->ReadUInt31(&current_frame_stream_id_);
+ DCHECK(successful_read);
+
remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed();
}
DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize()
@@ -1042,8 +1056,11 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
switch (current_frame_type_) {
case SYN_STREAM:
{
- bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
- DCHECK(successful_read);
+ bool successful_read = true;
+ if (spdy_version_ < 4) {
+ successful_read = reader.ReadUInt31(&current_frame_stream_id_);
+ DCHECK(successful_read);
+ }
SpdyStreamId associated_to_stream_id = kInvalidStream;
successful_read = reader.ReadUInt31(&associated_to_stream_id);
@@ -1082,8 +1099,11 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
case HEADERS:
// SYN_REPLY and HEADERS are the same, save for the visitor call.
{
- bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
- DCHECK(successful_read);
+ bool successful_read = true;
+ if (spdy_version_ < 4) {
+ successful_read = reader.ReadUInt31(&current_frame_stream_id_);
+ DCHECK(successful_read);
+ }
if (protocol_version() < 3) {
// SPDY 2 had two unused bytes here. Seek past them.
reader.Seek(2);
@@ -1288,9 +1308,12 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
break;
case WINDOW_UPDATE: {
uint32 delta_window_size = 0;
- bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
- DCHECK(successful_read);
- successful_read = reader.ReadUInt31(&delta_window_size);
+ bool successful_read = true;
+ if (spdy_version_ < 4) {
+ successful_read = reader.ReadUInt31(&current_frame_stream_id_);
+ DCHECK(successful_read);
+ }
+ successful_read = reader.ReadUInt32(&delta_window_size);
DCHECK(successful_read);
DCHECK(reader.IsDoneReading());
visitor_->OnWindowUpdate(current_frame_stream_id_,
@@ -1298,8 +1321,11 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
}
break;
case RST_STREAM: {
- bool successful_read = reader.ReadUInt32(&current_frame_stream_id_);
- DCHECK(successful_read);
+ bool successful_read = true;
+ if (spdy_version_ < 4) {
+ successful_read = reader.ReadUInt31(&current_frame_stream_id_);
+ DCHECK(successful_read);
+ }
SpdyRstStreamStatus status = RST_STREAM_INVALID;
uint32 status_raw = status;
successful_read = reader.ReadUInt32(&status_raw);
@@ -1511,8 +1537,15 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream(
+ GetSerializedLength(syn_stream.name_value_block());
SpdyFrameBuilder builder(size);
- builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
- builder.WriteUInt32(syn_stream.stream_id());
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
+ builder.WriteUInt32(syn_stream.stream_id());
+ } else {
+ builder.WriteFramePrefix(*this,
+ SYN_STREAM,
+ flags,
+ syn_stream.stream_id());
+ }
builder.WriteUInt32(syn_stream.associated_to_stream_id());
uint8 priority = syn_stream.priority();
if (priority > GetLowestPriority()) {
@@ -1559,8 +1592,15 @@ SpdySerializedFrame* SpdyFramer::SerializeSynReply(
+ GetSerializedLength(syn_reply.name_value_block());
SpdyFrameBuilder builder(size);
- builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
- builder.WriteUInt32(syn_reply.stream_id());
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
+ builder.WriteUInt32(syn_reply.stream_id());
+ } else {
+ builder.WriteFramePrefix(*this,
+ SYN_REPLY,
+ flags,
+ syn_reply.stream_id());
+ }
if (protocol_version() < 3) {
builder.WriteUInt16(0); // Unused.
}
@@ -1580,8 +1620,15 @@ SpdyFrame* SpdyFramer::CreateRstStream(
SpdySerializedFrame* SpdyFramer::SerializeRstStream(
const SpdyRstStreamIR& rst_stream) const {
SpdyFrameBuilder builder(GetRstStreamSize());
- builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
- builder.WriteUInt32(rst_stream.stream_id());
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
+ builder.WriteUInt32(rst_stream.stream_id());
+ } else {
+ builder.WriteFramePrefix(*this,
+ RST_STREAM,
+ 0,
+ rst_stream.stream_id());
+ }
builder.WriteUInt32(rst_stream.status());
DCHECK_EQ(GetRstStreamSize(), builder.length());
return builder.take();
@@ -1613,7 +1660,11 @@ SpdySerializedFrame* SpdyFramer::SerializeSettings(
const size_t size = GetSettingsMinimumSize() + (values->size() * 8);
SpdyFrameBuilder builder(size);
- builder.WriteControlFrameHeader(*this, SETTINGS, flags);
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, SETTINGS, flags);
+ } else {
+ builder.WriteFramePrefix(*this, SETTINGS, flags, 0);
+ }
builder.WriteUInt32(values->size());
DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
@@ -1642,7 +1693,11 @@ SpdyFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
SpdyFrameBuilder builder(GetPingSize());
- builder.WriteControlFrameHeader(*this, PING, 0);
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, PING, kNoFlags);
+ } else {
+ builder.WriteFramePrefix(*this, PING, 0, 0);
+ }
builder.WriteUInt32(ping.id());
DCHECK_EQ(GetPingSize(), builder.length());
return builder.take();
@@ -1658,7 +1713,11 @@ SpdyFrame* SpdyFramer::CreateGoAway(
SpdySerializedFrame* SpdyFramer::SerializeGoAway(
const SpdyGoAwayIR& goaway) const {
SpdyFrameBuilder builder(GetGoAwaySize());
- builder.WriteControlFrameHeader(*this, GOAWAY, 0);
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
+ } else {
+ builder.WriteFramePrefix(*this, GOAWAY, 0, 0);
+ }
builder.WriteUInt32(goaway.last_good_stream_id());
if (protocol_version() >= 3) {
builder.WriteUInt32(goaway.status());
@@ -1697,8 +1756,15 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders(
+ GetSerializedLength(headers.name_value_block());
SpdyFrameBuilder builder(size);
- builder.WriteControlFrameHeader(*this, HEADERS, flags);
- builder.WriteUInt32(headers.stream_id());
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, HEADERS, flags);
+ builder.WriteUInt32(headers.stream_id());
+ } else {
+ builder.WriteFramePrefix(*this,
+ HEADERS,
+ flags,
+ headers.stream_id());
+ }
if (protocol_version() < 3) {
builder.WriteUInt16(0); // Unused.
}
@@ -1719,8 +1785,15 @@ SpdyFrame* SpdyFramer::CreateWindowUpdate(
SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
const SpdyWindowUpdateIR& window_update) const {
SpdyFrameBuilder builder(GetWindowUpdateSize());
- builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
- builder.WriteUInt32(window_update.stream_id());
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
+ builder.WriteUInt32(window_update.stream_id());
+ } else {
+ builder.WriteFramePrefix(*this,
+ WINDOW_UPDATE,
+ kNoFlags,
+ window_update.stream_id());
+ }
builder.WriteUInt32(window_update.delta());
DCHECK_EQ(GetWindowUpdateSize(), builder.length());
return builder.take();
@@ -1751,7 +1824,11 @@ SpdySerializedFrame* SpdyFramer::SerializeCredential(
}
SpdyFrameBuilder builder(size);
- builder.WriteControlFrameHeader(*this, CREDENTIAL, 0);
+ if (spdy_version_ < 4) {
+ builder.WriteControlFrameHeader(*this, CREDENTIAL, kNoFlags);
+ } else {
+ builder.WriteFramePrefix(*this, CREDENTIAL, kNoFlags, 0);
+ }
builder.WriteUInt16(credential.slot());
DCHECK_EQ(GetCredentialMinimumSize(), builder.length());
builder.WriteStringPiece32(credential.proof());
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 63e99a7..60d784a 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -692,9 +692,13 @@ TEST_P(SpdyFramerTest, OutOfOrderHeaders) {
// Frame builder with plentiful buffer size.
SpdyFrameBuilder frame(1024);
- frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
+ if (spdy_version_ < 4) {
+ frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
+ frame.WriteUInt32(3); // stream_id
+ } else {
+ frame.WriteFramePrefix(framer, SYN_STREAM, CONTROL_FLAG_NONE, 3);
+ }
- frame.WriteUInt32(3); // stream_id
frame.WriteUInt32(0); // Associated stream id
frame.WriteUInt16(0); // Priority.
@@ -746,7 +750,8 @@ TEST_P(SpdyFramerTest, CreateCredential) {
'e', 'r', 't',
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x37, 0x0A, 0x00,
+ 0x00, 0x3b, 0x0A, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00,
0x00, 0x05, 'p', 'r',
'o', 'o', 'f', 0x00,
@@ -799,6 +804,7 @@ TEST_P(SpdyFramerTest, ParseCredentialFrameData) {
};
const unsigned char kV4FrameData[] = {
0x00, 0x37, 0x0A, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00,
0x00, 0x05, 'p', 'r',
'o', 'o', 'f', 0x00,
@@ -844,9 +850,13 @@ TEST_P(SpdyFramerTest, DuplicateHeader) {
SpdyFramer framer(spdy_version_);
// Frame builder with plentiful buffer size.
SpdyFrameBuilder frame(1024);
- frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
+ if (spdy_version_ < 4) {
+ frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
+ frame.WriteUInt32(3); // stream_id
+ } else {
+ frame.WriteFramePrefix(framer, SYN_STREAM, CONTROL_FLAG_NONE, 3);
+ }
- frame.WriteUInt32(3); // stream_id
frame.WriteUInt32(0); // associated stream id
frame.WriteUInt16(0); // Priority.
@@ -881,9 +891,13 @@ TEST_P(SpdyFramerTest, MultiValueHeader) {
SpdyFramer framer(spdy_version_);
// Frame builder with plentiful buffer size.
SpdyFrameBuilder frame(1024);
- frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
+ if (spdy_version_ < 4) {
+ frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
+ frame.WriteUInt32(3); // stream_id
+ } else {
+ frame.WriteFramePrefix(framer, SYN_STREAM, CONTROL_FLAG_NONE, 3);
+ }
- frame.WriteUInt32(3); // stream_id
frame.WriteUInt32(0); // associated stream id
frame.WriteUInt16(0); // Priority.
@@ -2390,7 +2404,8 @@ TEST_P(SpdyFramerTest, CreateSettings) {
0x0a, 0x0b, 0x0c, 0x0d,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x10, 0x04, 0x00,
+ 0x00, 0x14, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x01, 0x02, 0x03, 0x04,
0x0a, 0x0b, 0x0c, 0x0d,
@@ -2433,7 +2448,8 @@ TEST_P(SpdyFramerTest, CreateSettings) {
0xff, 0x00, 0x00, 0x04,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x28, 0x04, 0x00,
+ 0x00, 0x2c, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, // 1st Setting
0x00, 0x00, 0x00, 0x01,
@@ -2463,7 +2479,8 @@ TEST_P(SpdyFramerTest, CreateSettings) {
0x00, 0x00, 0x00, 0x00,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x08, 0x04, 0x00,
+ 0x00, 0x0c, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
@@ -2486,7 +2503,8 @@ TEST_P(SpdyFramerTest, CreatePingFrame) {
0x12, 0x34, 0x56, 0x78,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x08, 0x06, 0x00,
+ 0x00, 0x0c, 0x06, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x12, 0x34, 0x56, 0x78,
};
scoped_ptr<SpdyFrame> frame(framer.CreatePingFrame(0x12345678u));
@@ -2515,7 +2533,8 @@ TEST_P(SpdyFramerTest, CreateGoAway) {
0x00, 0x00, 0x00, 0x00,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x0c, 0x07, 0x00,
+ 0x00, 0x10, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
@@ -2543,7 +2562,8 @@ TEST_P(SpdyFramerTest, CreateGoAway) {
0x00, 0x00, 0x00, 0x02,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x0c, 0x07, 0x00,
+ 0x00, 0x10, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02,
};
@@ -3270,7 +3290,8 @@ TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
0x00, 0x00, 0x00, 0x03,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x20, 0x04, 0x00,
+ 0x00, 0x24, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x01, // 1st Setting
0x00, 0x00, 0x00, 0x02,
@@ -3320,7 +3341,8 @@ TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
0x00, 0x00, 0x00, 0x03,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x20, 0x04, 0x00,
+ 0x00, 0x24, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x02, // 1st Setting
0x00, 0x00, 0x00, 0x02,
@@ -3507,17 +3529,15 @@ TEST_P(SpdyFramerTest, SizesTest) {
SpdyFramer framer(spdy_version_);
EXPECT_EQ(8u, framer.GetDataFrameMinimumSize());
if (IsSpdy4()) {
- EXPECT_EQ(4u, framer.GetControlFrameHeaderSize());
- EXPECT_EQ(14u, framer.GetSynStreamMinimumSize());
EXPECT_EQ(8u, framer.GetSynReplyMinimumSize());
EXPECT_EQ(12u, framer.GetRstStreamSize());
- EXPECT_EQ(8u, framer.GetSettingsMinimumSize());
- EXPECT_EQ(8u, framer.GetPingSize());
- EXPECT_EQ(12u, framer.GetGoAwaySize());
+ EXPECT_EQ(12u, framer.GetSettingsMinimumSize());
+ EXPECT_EQ(12u, framer.GetPingSize());
+ EXPECT_EQ(16u, framer.GetGoAwaySize());
EXPECT_EQ(8u, framer.GetHeadersMinimumSize());
EXPECT_EQ(12u, framer.GetWindowUpdateSize());
- EXPECT_EQ(6u, framer.GetCredentialMinimumSize());
- EXPECT_EQ(4u, framer.GetFrameMinimumSize());
+ EXPECT_EQ(10u, framer.GetCredentialMinimumSize());
+ EXPECT_EQ(8u, framer.GetFrameMinimumSize());
EXPECT_EQ(65535u, framer.GetFrameMaximumSize());
EXPECT_EQ(65527u, framer.GetDataFrameMaximumPayload());
} else {
@@ -4124,7 +4144,8 @@ TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
0x00, 0x00, 0x00, 0x00,
};
const unsigned char kV4FrameData[] = {
- 0x00, 0x0c, 0x07, 0x00,
+ 0x00, 0x10, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00,
};
diff --git a/net/spdy/spdy_http_stream_spdy3_unittest.cc b/net/spdy/spdy_http_stream_spdy3_unittest.cc
index d849f28..76f7a99 100644
--- a/net/spdy/spdy_http_stream_spdy3_unittest.cc
+++ b/net/spdy/spdy_http_stream_spdy3_unittest.cc
@@ -394,7 +394,7 @@ TEST_F(SpdyHttpStreamSpdy3Test, SendChunkedPost) {
}
TEST_F(SpdyHttpStreamSpdy3Test, SendChunkedPost4) {
- session_deps_.protocol = kProtoSPDY4a1;
+ session_deps_.protocol = kProtoSPDY4a2;
RunSendChunkedPostTest(kSpdyVersion4);
}
diff --git a/net/spdy/spdy_network_transaction_spdy3_unittest.cc b/net/spdy/spdy_network_transaction_spdy3_unittest.cc
index 0d7d732..121ccc9 100644
--- a/net/spdy/spdy_network_transaction_spdy3_unittest.cc
+++ b/net/spdy/spdy_network_transaction_spdy3_unittest.cc
@@ -152,7 +152,7 @@ class SpdyNetworkTransactionSpdy3Test
next_protos.push_back("spdy/2");
next_protos.push_back("spdy/3");
next_protos.push_back("spdy/3.1");
- next_protos.push_back("spdy/4a1");
+ next_protos.push_back("spdy/4a2");
switch (test_type_) {
case SPDYNPN:
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 67cf065..f143607 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -61,7 +61,7 @@ int NPNToSpdyVersion(NextProto next_proto) {
case kProtoSPDY3:
case kProtoSPDY31:
return kSpdyVersion3;
- case kProtoSPDY4a1:
+ case kProtoSPDY4a2:
return kSpdyVersion4;
default:
NOTREACHED();
@@ -444,7 +444,7 @@ Error SpdySession::InitializeWithSocket(
}
DCHECK_GE(protocol, kProtoSPDY2);
- DCHECK_LE(protocol, kProtoSPDY4a1);
+ DCHECK_LE(protocol, kProtoSPDY4a2);
if (protocol >= kProtoSPDY31) {
flow_control_state_ = FLOW_CONTROL_STREAM_AND_SESSION;
session_send_window_size_ = kSpdySessionInitialWindowSize;
diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc
index 723b473..a151501 100644
--- a/net/spdy/spdy_session_spdy3_unittest.cc
+++ b/net/spdy/spdy_session_spdy3_unittest.cc
@@ -2409,7 +2409,7 @@ TEST_F(SpdySessionSpdy3Test, ProtocolNegotiation31) {
// NOTE(akalin): We are still figuring out the story for SPDY4 test
// coverage.
TEST_F(SpdySessionSpdy3Test, ProtocolNegotiation4) {
- session_deps_.protocol = kProtoSPDY4a1;
+ session_deps_.protocol = kProtoSPDY4a2;
session_deps_.host_resolver->set_synchronous_mode(true);
MockConnect connect_data(SYNCHRONOUS, OK);
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 678ce79..d422021 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -517,7 +517,7 @@ NextProto NextProtoFromSpdyVersion(int spdy_version) {
case kSpdyVersion3:
return kProtoSPDY3;
case kSpdyVersion4:
- return kProtoSPDY4a1;
+ return kProtoSPDY4a2;
default:
NOTREACHED();
return kProtoUnknown;
@@ -532,7 +532,7 @@ int SpdyVersionFromNextProto(NextProto next_proto) {
case kProtoSPDY3:
case kProtoSPDY31:
return kSpdyVersion3;
- case kProtoSPDY4a1:
+ case kProtoSPDY4a2:
return kSpdyVersion4;
default:
NOTREACHED();