1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_protocol.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "net/spdy/spdy_bitmasks.h"
9 #include "net/spdy/spdy_framer.h"
10 #include "testing/platform_test.h"
14 enum SpdyProtocolTestTypes
{
23 class SpdyProtocolTest
24 : public ::testing::TestWithParam
<SpdyProtocolTestTypes
> {
26 virtual void SetUp() {
27 spdy_version_
= GetParam();
30 bool IsSpdy2() { return spdy_version_
== SPDY2
; }
32 // Version of SPDY protocol to be used.
36 // All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
37 INSTANTIATE_TEST_CASE_P(SpdyProtocolTests
,
39 ::testing::Values(SPDY2
, SPDY3
));
41 // Test our protocol constants
42 TEST_P(SpdyProtocolTest
, ProtocolConstants
) {
43 EXPECT_EQ(8u, SpdyFrame::kHeaderSize
);
44 EXPECT_EQ(8u, SpdyDataFrame::size());
45 EXPECT_EQ(8u, SpdyControlFrame::kHeaderSize
);
46 EXPECT_EQ(18u, SpdySynStreamControlFrame::size());
47 EXPECT_EQ(12u, SpdySynReplyControlFrame::size());
48 EXPECT_EQ(16u, SpdyRstStreamControlFrame::size());
49 EXPECT_EQ(12u, SpdySettingsControlFrame::size());
50 EXPECT_EQ(12u, SpdyPingControlFrame::size());
51 EXPECT_EQ(16u, SpdyGoAwayControlFrame::size());
52 EXPECT_EQ(12u, SpdyHeadersControlFrame::size());
53 EXPECT_EQ(16u, SpdyWindowUpdateControlFrame::size());
54 EXPECT_EQ(4u, sizeof(FlagsAndLength
));
55 EXPECT_EQ(1, SYN_STREAM
);
56 EXPECT_EQ(2, SYN_REPLY
);
57 EXPECT_EQ(3, RST_STREAM
);
58 EXPECT_EQ(4, SETTINGS
);
62 EXPECT_EQ(8, HEADERS
);
63 EXPECT_EQ(9, WINDOW_UPDATE
);
66 // Test some of the protocol helper functions
67 TEST_P(SpdyProtocolTest
, FrameStructs
) {
68 SpdyFrame
frame(SpdyFrame::kHeaderSize
);
69 frame
.set_length(12345);
71 EXPECT_EQ(12345u, frame
.length());
72 EXPECT_EQ(10u, frame
.flags());
73 EXPECT_FALSE(frame
.is_control_frame());
77 EXPECT_EQ(0u, frame
.length());
78 EXPECT_EQ(10u, frame
.flags());
79 EXPECT_FALSE(frame
.is_control_frame());
82 TEST_P(SpdyProtocolTest
, DataFrameStructs
) {
83 SpdyDataFrame data_frame
;
84 data_frame
.set_stream_id(12345);
85 EXPECT_EQ(12345u, data_frame
.stream_id());
88 TEST_P(SpdyProtocolTest
, ControlFrameStructs
) {
89 SpdyFramer
framer(spdy_version_
);
90 SpdyHeaderBlock headers
;
92 const uint8 credential_slot
= IsSpdy2() ? 0 : 5;
94 scoped_ptr
<SpdySynStreamControlFrame
> syn_frame(framer
.CreateSynStream(
95 123, 456, 2, credential_slot
, CONTROL_FLAG_FIN
, false, &headers
));
96 EXPECT_EQ(framer
.protocol_version(), syn_frame
->version());
97 EXPECT_TRUE(syn_frame
->is_control_frame());
98 EXPECT_EQ(SYN_STREAM
, syn_frame
->type());
99 EXPECT_EQ(123u, syn_frame
->stream_id());
100 EXPECT_EQ(456u, syn_frame
->associated_stream_id());
101 EXPECT_EQ(2u, syn_frame
->priority());
102 EXPECT_EQ(credential_slot
, syn_frame
->credential_slot());
103 EXPECT_EQ(IsSpdy2() ? 2 : 4, syn_frame
->header_block_len());
104 EXPECT_EQ(1u, syn_frame
->flags());
105 syn_frame
->set_associated_stream_id(999u);
106 EXPECT_EQ(123u, syn_frame
->stream_id());
107 EXPECT_EQ(999u, syn_frame
->associated_stream_id());
109 scoped_ptr
<SpdySynReplyControlFrame
> syn_reply(
110 framer
.CreateSynReply(123, CONTROL_FLAG_NONE
, false, &headers
));
111 EXPECT_EQ(framer
.protocol_version(), syn_reply
->version());
112 EXPECT_TRUE(syn_reply
->is_control_frame());
113 EXPECT_EQ(SYN_REPLY
, syn_reply
->type());
114 EXPECT_EQ(123u, syn_reply
->stream_id());
115 EXPECT_EQ(IsSpdy2() ? 2 : 4, syn_reply
->header_block_len());
116 EXPECT_EQ(0, syn_reply
->flags());
118 scoped_ptr
<SpdyRstStreamControlFrame
> rst_frame(
119 framer
.CreateRstStream(123, PROTOCOL_ERROR
));
120 EXPECT_EQ(framer
.protocol_version(), rst_frame
->version());
121 EXPECT_TRUE(rst_frame
->is_control_frame());
122 EXPECT_EQ(RST_STREAM
, rst_frame
->type());
123 EXPECT_EQ(123u, rst_frame
->stream_id());
124 EXPECT_EQ(PROTOCOL_ERROR
, rst_frame
->status());
125 rst_frame
->set_status(INVALID_STREAM
);
126 EXPECT_EQ(INVALID_STREAM
, rst_frame
->status());
127 EXPECT_EQ(0, rst_frame
->flags());
129 const uint32 kUniqueId
= 1234567u;
130 const uint32 kUniqueId2
= 31415926u;
131 scoped_ptr
<SpdyPingControlFrame
> ping_frame(
132 framer
.CreatePingFrame(kUniqueId
));
133 EXPECT_EQ(framer
.protocol_version(), ping_frame
->version());
134 EXPECT_TRUE(ping_frame
->is_control_frame());
135 EXPECT_EQ(PING
, ping_frame
->type());
136 EXPECT_EQ(kUniqueId
, ping_frame
->unique_id());
137 ping_frame
->set_unique_id(kUniqueId2
);
138 EXPECT_EQ(kUniqueId2
, ping_frame
->unique_id());
140 scoped_ptr
<SpdyGoAwayControlFrame
> goaway_frame(
141 framer
.CreateGoAway(123, GOAWAY_INTERNAL_ERROR
));
142 EXPECT_EQ(framer
.protocol_version(), goaway_frame
->version());
143 EXPECT_TRUE(goaway_frame
->is_control_frame());
144 EXPECT_EQ(GOAWAY
, goaway_frame
->type());
145 EXPECT_EQ(123u, goaway_frame
->last_accepted_stream_id());
147 EXPECT_EQ(GOAWAY_INTERNAL_ERROR
, goaway_frame
->status());
150 scoped_ptr
<SpdyHeadersControlFrame
> headers_frame(
151 framer
.CreateHeaders(123, CONTROL_FLAG_NONE
, false, &headers
));
152 EXPECT_EQ(framer
.protocol_version(), headers_frame
->version());
153 EXPECT_TRUE(headers_frame
->is_control_frame());
154 EXPECT_EQ(HEADERS
, headers_frame
->type());
155 EXPECT_EQ(123u, headers_frame
->stream_id());
156 EXPECT_EQ(IsSpdy2() ? 2 : 4, headers_frame
->header_block_len());
157 EXPECT_EQ(0, headers_frame
->flags());
159 scoped_ptr
<SpdyWindowUpdateControlFrame
> window_update_frame(
160 framer
.CreateWindowUpdate(123, 456));
161 EXPECT_EQ(framer
.protocol_version(), window_update_frame
->version());
162 EXPECT_TRUE(window_update_frame
->is_control_frame());
163 EXPECT_EQ(WINDOW_UPDATE
, window_update_frame
->type());
164 EXPECT_EQ(123u, window_update_frame
->stream_id());
165 EXPECT_EQ(456u, window_update_frame
->delta_window_size());
168 TEST_P(SpdyProtocolTest
, TestDataFrame
) {
171 // Set the stream ID to various values.
172 frame
.set_stream_id(0);
173 EXPECT_EQ(0u, frame
.stream_id());
174 EXPECT_FALSE(frame
.is_control_frame());
175 frame
.set_stream_id(~0 & kStreamIdMask
);
176 EXPECT_EQ(~0 & kStreamIdMask
, frame
.stream_id());
177 EXPECT_FALSE(frame
.is_control_frame());
179 // Set length to various values. Make sure that when you set_length(x),
180 // length() == x. Also make sure the flags are unaltered.
181 memset(frame
.data(), '1', SpdyDataFrame::size());
182 int8 flags
= frame
.flags();
184 EXPECT_EQ(0u, frame
.length());
185 EXPECT_EQ(flags
, frame
.flags());
186 frame
.set_length(kLengthMask
);
187 EXPECT_EQ(kLengthMask
, frame
.length());
188 EXPECT_EQ(flags
, frame
.flags());
189 frame
.set_length(5u);
190 EXPECT_EQ(5u, frame
.length());
191 EXPECT_EQ(flags
, frame
.flags());
193 // Set flags to various values. Make sure that when you set_flags(x),
194 // flags() == x. Also make sure the length is unaltered.
195 memset(frame
.data(), '1', SpdyDataFrame::size());
196 uint32 length
= frame
.length();
198 EXPECT_EQ(0u, frame
.flags());
199 EXPECT_EQ(length
, frame
.length());
201 frame
.set_flags(all_flags
);
202 flags
= frame
.flags();
203 EXPECT_EQ(all_flags
, flags
);
204 EXPECT_EQ(length
, frame
.length());
206 EXPECT_EQ(5u, frame
.flags());
207 EXPECT_EQ(length
, frame
.length());
210 // Test various types of SETTINGS frames.
211 TEST_P(SpdyProtocolTest
, TestSpdySettingsFrame
) {
212 SpdyFramer
framer(spdy_version_
);
214 // Create a settings frame with no settings.
215 SettingsMap settings
;
216 scoped_ptr
<SpdySettingsControlFrame
> settings_frame(
217 framer
.CreateSettings(settings
));
218 EXPECT_EQ(framer
.protocol_version(), settings_frame
->version());
219 EXPECT_TRUE(settings_frame
->is_control_frame());
220 EXPECT_EQ(SETTINGS
, settings_frame
->type());
221 EXPECT_EQ(0u, settings_frame
->num_entries());
223 // We'll add several different ID/Flag combinations and then verify
224 // that they encode and decode properly.
225 SettingsFlagsAndId ids
[] = {
226 SettingsFlagsAndId::FromWireFormat(spdy_version_
, 0x00000000),
227 SettingsFlagsAndId::FromWireFormat(spdy_version_
, 0xffffffff),
228 SettingsFlagsAndId::FromWireFormat(spdy_version_
, 0xff000001),
229 SettingsFlagsAndId::FromWireFormat(spdy_version_
, 0x01000002),
230 SettingsFlagsAndId(6, 9)
233 for (size_t index
= 0; index
< arraysize(ids
); ++index
) {
234 SettingsFlagsAndId flags_and_id
= ids
[index
];
235 SpdySettingsIds id
= static_cast<SpdySettingsIds
>(flags_and_id
.id());
236 SpdySettingsFlags flags
=
237 static_cast<SpdySettingsFlags
>(flags_and_id
.flags());
238 settings
[id
] = SettingsFlagsAndValue(flags
, index
);
239 settings_frame
.reset(framer
.CreateSettings(settings
));
240 EXPECT_EQ(framer
.protocol_version(), settings_frame
->version());
241 EXPECT_TRUE(settings_frame
->is_control_frame());
242 EXPECT_EQ(SETTINGS
, settings_frame
->type());
243 EXPECT_EQ(index
+ 1, settings_frame
->num_entries());
245 SettingsMap parsed_settings
;
246 EXPECT_TRUE(framer
.ParseSettings(settings_frame
.get(), &parsed_settings
));
247 EXPECT_EQ(settings
.size(), parsed_settings
.size());
248 SettingsMap::const_iterator it
, it2
;
249 for (it
= parsed_settings
.begin(); it
!= parsed_settings
.end(); it
++) {
250 it2
= settings
.find(it
->first
);
251 EXPECT_EQ(it
->first
, it2
->first
);
252 SettingsFlagsAndValue parsed
= it
->second
;
253 SettingsFlagsAndValue created
= it2
->second
;
254 EXPECT_EQ(created
.first
, parsed
.first
);
255 EXPECT_EQ(created
.second
, parsed
.second
);
260 TEST_P(SpdyProtocolTest
, HasHeaderBlock
) {
261 SpdyControlFrame
frame(SpdyControlFrame::kHeaderSize
);
262 for (SpdyControlType type
= SYN_STREAM
;
263 type
< NUM_CONTROL_FRAME_TYPES
;
264 type
= static_cast<SpdyControlType
>(type
+ 1)) {
265 frame
.set_type(type
);
266 if (type
== SYN_STREAM
|| type
== SYN_REPLY
|| type
== HEADERS
) {
267 EXPECT_TRUE(frame
.has_header_block());
269 EXPECT_FALSE(frame
.has_header_block());
274 class SpdyProtocolDeathTest
: public SpdyProtocolTest
{};
276 // All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
277 INSTANTIATE_TEST_CASE_P(SpdyProtocolDeathTests
,
278 SpdyProtocolDeathTest
,
279 ::testing::Values(SPDY2
, SPDY3
));
281 // Make sure that overflows both die in debug mode, and do not cause problems
282 // in opt mode. Note: The EXPECT_DEBUG_DEATH call does not work on Win32 yet,
283 // so we comment it out.
284 TEST_P(SpdyProtocolDeathTest
, TestDataFrame
) {
287 frame
.set_stream_id(0);
288 // TODO(mbelshe): implement EXPECT_DEBUG_DEATH on windows.
289 #if !defined(WIN32) && defined(GTEST_HAS_DEATH_TEST)
290 #if !defined(DCHECK_ALWAYS_ON)
291 EXPECT_DEBUG_DEATH(frame
.set_stream_id(~0), "");
293 EXPECT_DEATH(frame
.set_stream_id(~0), "");
296 EXPECT_FALSE(frame
.is_control_frame());
299 #if !defined(WIN32) && defined(GTEST_HAS_DEATH_TEST)
300 #if !defined(DCHECK_ALWAYS_ON)
301 EXPECT_DEBUG_DEATH(frame
.set_length(~0), "");
303 EXPECT_DEATH(frame
.set_length(~0), "");
306 EXPECT_EQ(0, frame
.flags());
309 TEST_P(SpdyProtocolDeathTest
, TestSpdyControlFrameStreamId
) {
310 SpdyControlFrame
frame_store(SpdySynStreamControlFrame::size());
311 memset(frame_store
.data(), '1', SpdyControlFrame::kHeaderSize
);
312 SpdySynStreamControlFrame
* frame
=
313 reinterpret_cast<SpdySynStreamControlFrame
*>(&frame_store
);
315 // Set the stream ID to various values.
316 frame
->set_stream_id(0);
317 EXPECT_EQ(0u, frame
->stream_id());
318 EXPECT_FALSE(frame
->is_control_frame());
319 frame
->set_stream_id(kStreamIdMask
);
320 EXPECT_EQ(kStreamIdMask
, frame
->stream_id());
321 EXPECT_FALSE(frame
->is_control_frame());
324 TEST_P(SpdyProtocolDeathTest
, TestSpdyControlFrameVersion
) {
325 const unsigned int kVersionMask
= 0x7fff;
326 SpdyControlFrame
frame(SpdySynStreamControlFrame::size());
327 memset(frame
.data(), '1', SpdyControlFrame::kHeaderSize
);
329 // Set the version to various values, and make sure it does not affect the
331 frame
.set_type(SYN_STREAM
);
332 frame
.set_version(0);
333 EXPECT_EQ(0, frame
.version());
334 EXPECT_TRUE(frame
.is_control_frame());
335 EXPECT_EQ(SYN_STREAM
, frame
.type());
337 SpdySynStreamControlFrame
* syn_stream
=
338 reinterpret_cast<SpdySynStreamControlFrame
*>(&frame
);
339 syn_stream
->set_stream_id(~0 & kVersionMask
);
340 EXPECT_EQ(~0 & kVersionMask
, syn_stream
->stream_id());
341 EXPECT_TRUE(frame
.is_control_frame());
342 EXPECT_EQ(SYN_STREAM
, frame
.type());
345 TEST_P(SpdyProtocolDeathTest
, TestSpdyControlFrameType
) {
346 SpdyControlFrame
frame(SpdyControlFrame::kHeaderSize
);
347 memset(frame
.data(), 255, SpdyControlFrame::kHeaderSize
);
349 // type() should be out of bounds.
350 EXPECT_FALSE(frame
.AppearsToBeAValidControlFrame());
352 frame
.set_version(spdy_version_
);
353 uint16 version
= frame
.version();
355 for (int i
= SYN_STREAM
; i
<= WINDOW_UPDATE
; ++i
) {
356 frame
.set_type(static_cast<SpdyControlType
>(i
));
357 EXPECT_EQ(i
, static_cast<int>(frame
.type()));
358 if (!IsSpdy2() && i
== NOOP
) {
359 // NOOP frames aren't 'valid'.
360 EXPECT_FALSE(frame
.AppearsToBeAValidControlFrame());
362 EXPECT_TRUE(frame
.AppearsToBeAValidControlFrame());
364 // Make sure setting type does not alter the version block.
365 EXPECT_EQ(version
, frame
.version());
366 EXPECT_TRUE(frame
.is_control_frame());
370 TEST_P(SpdyProtocolDeathTest
, TestRstStreamStatusBounds
) {
371 SpdyFramer
framer(spdy_version_
);
372 scoped_ptr
<SpdyRstStreamControlFrame
> rst_frame
;
374 rst_frame
.reset(framer
.CreateRstStream(123, PROTOCOL_ERROR
));
375 EXPECT_EQ(PROTOCOL_ERROR
, rst_frame
->status());
377 rst_frame
->set_status(INVALID
);
378 EXPECT_EQ(INVALID
, rst_frame
->status());
380 rst_frame
->set_status(
381 static_cast<SpdyStatusCodes
>(INVALID
- 1));
382 EXPECT_EQ(INVALID
, rst_frame
->status());
384 rst_frame
->set_status(NUM_STATUS_CODES
);
385 EXPECT_EQ(INVALID
, rst_frame
->status());