1 // Copyright (c) 2011 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. 4 5 #include "net/spdy/spdy_protocol.h" 6 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" 11 12 using spdy::CONTROL_FLAG_FIN; 13 using spdy::CONTROL_FLAG_NONE; 14 using spdy::GOAWAY; 15 using spdy::HEADERS; 16 using spdy::NOOP; 17 using spdy::PING; 18 using spdy::RST_STREAM; 19 using spdy::SETTINGS; 20 using spdy::SYN_REPLY; 21 using spdy::SYN_STREAM; 22 using spdy::WINDOW_UPDATE; 23 using spdy::FlagsAndLength; 24 using spdy::SpdyControlFrame; 25 using spdy::SpdyControlType; 26 using spdy::SpdyDataFrame; 27 using spdy::SpdyFrame; 28 using spdy::SpdyFramer; 29 using spdy::SpdyHeaderBlock; 30 using spdy::SpdyGoAwayControlFrame; 31 using spdy::SpdyRstStreamControlFrame; 32 using spdy::SpdySettings; 33 using spdy::SpdySettingsControlFrame; 34 using spdy::SpdyStatusCodes; 35 using spdy::SpdySynReplyControlFrame; 36 using spdy::SpdySynStreamControlFrame; 37 using spdy::SpdyWindowUpdateControlFrame; 38 using spdy::SettingsFlagsAndId; 39 using spdy::kLengthMask; 40 using spdy::kSpdyProtocolVersion; 41 using spdy::kStreamIdMask; 42 43 namespace { 44 45 // Test our protocol constants 46 TEST(SpdyProtocolTest, ProtocolConstants) { 47 EXPECT_EQ(8u, SpdyFrame::size()); 48 EXPECT_EQ(8u, SpdyDataFrame::size()); 49 EXPECT_EQ(8u, SpdyControlFrame::size()); 50 EXPECT_EQ(18u, SpdySynStreamControlFrame::size()); 51 EXPECT_EQ(14u, SpdySynReplyControlFrame::size()); 52 EXPECT_EQ(16u, SpdyRstStreamControlFrame::size()); 53 EXPECT_EQ(12u, SpdyGoAwayControlFrame::size()); 54 EXPECT_EQ(12u, SpdySettingsControlFrame::size()); 55 EXPECT_EQ(16u, SpdyWindowUpdateControlFrame::size()); 56 EXPECT_EQ(4u, sizeof(FlagsAndLength)); 57 EXPECT_EQ(1, SYN_STREAM); 58 EXPECT_EQ(2, SYN_REPLY); 59 EXPECT_EQ(3, RST_STREAM); 60 EXPECT_EQ(4, SETTINGS); 61 EXPECT_EQ(5, NOOP); 62 EXPECT_EQ(6, PING); 63 EXPECT_EQ(7, GOAWAY); 64 EXPECT_EQ(8, HEADERS); 65 EXPECT_EQ(9, WINDOW_UPDATE); 66 } 67 68 // Test some of the protocol helper functions 69 TEST(SpdyProtocolTest, FrameStructs) { 70 SpdyFrame frame(SpdyFrame::size()); 71 frame.set_length(12345); 72 frame.set_flags(10); 73 EXPECT_EQ(12345u, frame.length()); 74 EXPECT_EQ(10u, frame.flags()); 75 EXPECT_FALSE(frame.is_control_frame()); 76 77 frame.set_length(0); 78 frame.set_flags(10); 79 EXPECT_EQ(0u, frame.length()); 80 EXPECT_EQ(10u, frame.flags()); 81 EXPECT_FALSE(frame.is_control_frame()); 82 } 83 84 TEST(SpdyProtocolTest, DataFrameStructs) { 85 SpdyDataFrame data_frame; 86 data_frame.set_stream_id(12345); 87 EXPECT_EQ(12345u, data_frame.stream_id()); 88 } 89 90 TEST(SpdyProtocolTest, ControlFrameStructs) { 91 SpdyFramer framer; 92 SpdyHeaderBlock headers; 93 94 scoped_ptr<SpdySynStreamControlFrame> syn_frame( 95 framer.CreateSynStream(123, 456, 2, CONTROL_FLAG_FIN, false, &headers)); 96 EXPECT_EQ(kSpdyProtocolVersion, 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(2, syn_frame->header_block_len()); 103 EXPECT_EQ(1u, syn_frame->flags()); 104 syn_frame->set_associated_stream_id(999u); 105 EXPECT_EQ(123u, syn_frame->stream_id()); 106 EXPECT_EQ(999u, syn_frame->associated_stream_id()); 107 108 scoped_ptr<SpdySynReplyControlFrame> syn_reply( 109 framer.CreateSynReply(123, CONTROL_FLAG_NONE, false, &headers)); 110 EXPECT_EQ(kSpdyProtocolVersion, syn_reply->version()); 111 EXPECT_TRUE(syn_reply->is_control_frame()); 112 EXPECT_EQ(SYN_REPLY, syn_reply->type()); 113 EXPECT_EQ(123u, syn_reply->stream_id()); 114 EXPECT_EQ(2, syn_reply->header_block_len()); 115 EXPECT_EQ(0, syn_reply->flags()); 116 117 scoped_ptr<SpdyRstStreamControlFrame> rst_frame( 118 framer.CreateRstStream(123, spdy::PROTOCOL_ERROR)); 119 EXPECT_EQ(kSpdyProtocolVersion, rst_frame->version()); 120 EXPECT_TRUE(rst_frame->is_control_frame()); 121 EXPECT_EQ(RST_STREAM, rst_frame->type()); 122 EXPECT_EQ(123u, rst_frame->stream_id()); 123 EXPECT_EQ(spdy::PROTOCOL_ERROR, rst_frame->status()); 124 rst_frame->set_status(spdy::INVALID_STREAM); 125 EXPECT_EQ(spdy::INVALID_STREAM, rst_frame->status()); 126 EXPECT_EQ(0, rst_frame->flags()); 127 128 scoped_ptr<SpdyGoAwayControlFrame> goaway_frame( 129 framer.CreateGoAway(123)); 130 EXPECT_EQ(kSpdyProtocolVersion, goaway_frame->version()); 131 EXPECT_TRUE(goaway_frame->is_control_frame()); 132 EXPECT_EQ(GOAWAY, goaway_frame->type()); 133 EXPECT_EQ(123u, goaway_frame->last_accepted_stream_id()); 134 135 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( 136 framer.CreateWindowUpdate(123, 456)); 137 EXPECT_EQ(kSpdyProtocolVersion, window_update_frame->version()); 138 EXPECT_TRUE(window_update_frame->is_control_frame()); 139 EXPECT_EQ(WINDOW_UPDATE, window_update_frame->type()); 140 EXPECT_EQ(123u, window_update_frame->stream_id()); 141 EXPECT_EQ(456u, window_update_frame->delta_window_size()); 142 } 143 144 TEST(SpdyProtocolTest, TestDataFrame) { 145 SpdyDataFrame frame; 146 147 // Set the stream ID to various values. 148 frame.set_stream_id(0); 149 EXPECT_EQ(0u, frame.stream_id()); 150 EXPECT_FALSE(frame.is_control_frame()); 151 frame.set_stream_id(~0 & kStreamIdMask); 152 EXPECT_EQ(~0 & kStreamIdMask, frame.stream_id()); 153 EXPECT_FALSE(frame.is_control_frame()); 154 155 // Set length to various values. Make sure that when you set_length(x), 156 // length() == x. Also make sure the flags are unaltered. 157 memset(frame.data(), '1', SpdyDataFrame::size()); 158 int8 flags = frame.flags(); 159 frame.set_length(0); 160 EXPECT_EQ(0u, frame.length()); 161 EXPECT_EQ(flags, frame.flags()); 162 frame.set_length(kLengthMask); 163 EXPECT_EQ(kLengthMask, frame.length()); 164 EXPECT_EQ(flags, frame.flags()); 165 frame.set_length(5u); 166 EXPECT_EQ(5u, frame.length()); 167 EXPECT_EQ(flags, frame.flags()); 168 169 // Set flags to various values. Make sure that when you set_flags(x), 170 // flags() == x. Also make sure the length is unaltered. 171 memset(frame.data(), '1', SpdyDataFrame::size()); 172 uint32 length = frame.length(); 173 frame.set_flags(0u); 174 EXPECT_EQ(0u, frame.flags()); 175 EXPECT_EQ(length, frame.length()); 176 int8 all_flags = ~0; 177 frame.set_flags(all_flags); 178 flags = frame.flags(); 179 EXPECT_EQ(all_flags, flags); 180 EXPECT_EQ(length, frame.length()); 181 frame.set_flags(5u); 182 EXPECT_EQ(5u, frame.flags()); 183 EXPECT_EQ(length, frame.length()); 184 } 185 186 // Test various types of SETTINGS frames. 187 TEST(SpdyProtocolTest, TestSpdySettingsFrame) { 188 SpdyFramer framer; 189 190 // Create a settings frame with no settings. 191 SpdySettings settings; 192 scoped_ptr<SpdySettingsControlFrame> settings_frame( 193 framer.CreateSettings(settings)); 194 EXPECT_EQ(kSpdyProtocolVersion, settings_frame->version()); 195 EXPECT_TRUE(settings_frame->is_control_frame()); 196 EXPECT_EQ(SETTINGS, settings_frame->type()); 197 EXPECT_EQ(0u, settings_frame->num_entries()); 198 199 // We'll add several different ID/Flag combinations and then verify 200 // that they encode and decode properly. 201 SettingsFlagsAndId ids[] = { 202 0x00000000, 203 0xffffffff, 204 0xff000001, 205 0x01000002, 206 }; 207 208 for (size_t index = 0; index < arraysize(ids); ++index) { 209 settings.insert(settings.end(), std::make_pair(ids[index], index)); 210 settings_frame.reset(framer.CreateSettings(settings)); 211 EXPECT_EQ(kSpdyProtocolVersion, settings_frame->version()); 212 EXPECT_TRUE(settings_frame->is_control_frame()); 213 EXPECT_EQ(SETTINGS, settings_frame->type()); 214 EXPECT_EQ(index + 1, settings_frame->num_entries()); 215 216 SpdySettings parsed_settings; 217 EXPECT_TRUE(framer.ParseSettings(settings_frame.get(), &parsed_settings)); 218 EXPECT_EQ(parsed_settings.size(), settings.size()); 219 SpdySettings::const_iterator it = parsed_settings.begin(); 220 int pos = 0; 221 while (it != parsed_settings.end()) { 222 SettingsFlagsAndId parsed = it->first; 223 uint32 value = it->second; 224 EXPECT_EQ(parsed.flags(), ids[pos].flags()); 225 EXPECT_EQ(parsed.id(), ids[pos].id()); 226 EXPECT_EQ(value, static_cast<uint32>(pos)); 227 ++it; 228 ++pos; 229 } 230 } 231 } 232 233 // Make sure that overflows both die in debug mode, and do not cause problems 234 // in opt mode. Note: The EXPECT_DEBUG_DEATH call does not work on Win32 yet, 235 // so we comment it out. 236 TEST(SpdyProtocolDeathTest, TestDataFrame) { 237 SpdyDataFrame frame; 238 239 frame.set_stream_id(0); 240 // TODO(mbelshe): implement EXPECT_DEBUG_DEATH on windows. 241 #ifndef WIN32 242 EXPECT_DEBUG_DEATH(frame.set_stream_id(~0), ""); 243 #endif 244 EXPECT_FALSE(frame.is_control_frame()); 245 246 frame.set_flags(0); 247 #ifndef WIN32 248 EXPECT_DEBUG_DEATH(frame.set_length(~0), ""); 249 #endif 250 EXPECT_EQ(0, frame.flags()); 251 } 252 253 TEST(SpdyProtocolDeathTest, TestSpdyControlFrameStreamId) { 254 SpdyControlFrame frame_store(SpdySynStreamControlFrame::size()); 255 memset(frame_store.data(), '1', SpdyControlFrame::size()); 256 SpdySynStreamControlFrame* frame = 257 reinterpret_cast<SpdySynStreamControlFrame*>(&frame_store); 258 259 // Set the stream ID to various values. 260 frame->set_stream_id(0); 261 EXPECT_EQ(0u, frame->stream_id()); 262 EXPECT_FALSE(frame->is_control_frame()); 263 frame->set_stream_id(kStreamIdMask); 264 EXPECT_EQ(kStreamIdMask, frame->stream_id()); 265 EXPECT_FALSE(frame->is_control_frame()); 266 } 267 268 TEST(SpdyProtocolDeathTest, TestSpdyControlFrameVersion) { 269 const unsigned int kVersionMask = 0x7fff; 270 SpdyControlFrame frame(SpdySynStreamControlFrame::size()); 271 memset(frame.data(), '1', SpdyControlFrame::size()); 272 273 // Set the version to various values, and make sure it does not affect the 274 // type. 275 frame.set_type(SYN_STREAM); 276 frame.set_version(0); 277 EXPECT_EQ(0, frame.version()); 278 EXPECT_TRUE(frame.is_control_frame()); 279 EXPECT_EQ(SYN_STREAM, frame.type()); 280 281 SpdySynStreamControlFrame* syn_stream = 282 reinterpret_cast<SpdySynStreamControlFrame*>(&frame); 283 syn_stream->set_stream_id(~0 & kVersionMask); 284 EXPECT_EQ(~0 & kVersionMask, syn_stream->stream_id()); 285 EXPECT_TRUE(frame.is_control_frame()); 286 EXPECT_EQ(SYN_STREAM, frame.type()); 287 } 288 289 TEST(SpdyProtocolDeathTest, TestSpdyControlFrameType) { 290 SpdyControlFrame frame(SpdyControlFrame::size()); 291 memset(frame.data(), 255, SpdyControlFrame::size()); 292 293 // type() should be out of bounds. 294 EXPECT_FALSE(frame.AppearsToBeAValidControlFrame()); 295 296 uint16 version = frame.version(); 297 298 for (int i = SYN_STREAM; i <= spdy::NOOP; ++i) { 299 frame.set_type(static_cast<SpdyControlType>(i)); 300 EXPECT_EQ(i, static_cast<int>(frame.type())); 301 EXPECT_TRUE(frame.AppearsToBeAValidControlFrame()); 302 // Make sure setting type does not alter the version block. 303 EXPECT_EQ(version, frame.version()); 304 EXPECT_TRUE(frame.is_control_frame()); 305 } 306 } 307 308 } // namespace 309