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. 4 5 #include "net/http/http_server_properties_impl.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/containers/hash_tables.h" 12 #include "base/logging.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/values.h" 15 #include "net/base/host_port_pair.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 namespace base { 19 class ListValue; 20 } 21 22 namespace net { 23 24 namespace { 25 26 class HttpServerPropertiesImplTest : public testing::Test { 27 protected: 28 HttpServerPropertiesImpl impl_; 29 }; 30 31 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest; 32 33 TEST_F(SpdyServerPropertiesTest, Initialize) { 34 HostPortPair spdy_server_google("www.google.com", 443); 35 std::string spdy_server_g = 36 HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_google); 37 38 HostPortPair spdy_server_docs("docs.google.com", 443); 39 std::string spdy_server_d = 40 HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_docs); 41 42 // Check by initializing NULL spdy servers. 43 impl_.InitializeSpdyServers(NULL, true); 44 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); 45 46 // Check by initializing empty spdy servers. 47 std::vector<std::string> spdy_servers; 48 impl_.InitializeSpdyServers(&spdy_servers, true); 49 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); 50 51 // Check by initializing with www.google.com:443 spdy server. 52 std::vector<std::string> spdy_servers1; 53 spdy_servers1.push_back(spdy_server_g); 54 impl_.InitializeSpdyServers(&spdy_servers1, true); 55 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); 56 57 // Check by initializing with www.google.com:443 and docs.google.com:443 spdy 58 // servers. 59 std::vector<std::string> spdy_servers2; 60 spdy_servers2.push_back(spdy_server_g); 61 spdy_servers2.push_back(spdy_server_d); 62 impl_.InitializeSpdyServers(&spdy_servers2, true); 63 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); 64 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); 65 } 66 67 TEST_F(SpdyServerPropertiesTest, SupportsSpdyTest) { 68 HostPortPair spdy_server_empty(std::string(), 443); 69 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty)); 70 71 // Add www.google.com:443 as supporting SPDY. 72 HostPortPair spdy_server_google("www.google.com", 443); 73 impl_.SetSupportsSpdy(spdy_server_google, true); 74 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); 75 76 // Add mail.google.com:443 as not supporting SPDY. 77 HostPortPair spdy_server_mail("mail.google.com", 443); 78 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); 79 80 // Add docs.google.com:443 as supporting SPDY. 81 HostPortPair spdy_server_docs("docs.google.com", 443); 82 impl_.SetSupportsSpdy(spdy_server_docs, true); 83 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); 84 85 // Verify all the entries are the same after additions. 86 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); 87 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); 88 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); 89 } 90 91 TEST_F(SpdyServerPropertiesTest, SetSupportsSpdy) { 92 HostPortPair spdy_server_empty(std::string(), 443); 93 impl_.SetSupportsSpdy(spdy_server_empty, true); 94 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty)); 95 96 // Add www.google.com:443 as supporting SPDY. 97 HostPortPair spdy_server_google("www.google.com", 443); 98 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); 99 impl_.SetSupportsSpdy(spdy_server_google, true); 100 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); 101 102 // Make www.google.com:443 as not supporting SPDY. 103 impl_.SetSupportsSpdy(spdy_server_google, false); 104 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); 105 106 // Add mail.google.com:443 as supporting SPDY. 107 HostPortPair spdy_server_mail("mail.google.com", 443); 108 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); 109 impl_.SetSupportsSpdy(spdy_server_mail, true); 110 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_mail)); 111 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); 112 } 113 114 TEST_F(SpdyServerPropertiesTest, Clear) { 115 // Add www.google.com:443 and mail.google.com:443 as supporting SPDY. 116 HostPortPair spdy_server_google("www.google.com", 443); 117 impl_.SetSupportsSpdy(spdy_server_google, true); 118 HostPortPair spdy_server_mail("mail.google.com", 443); 119 impl_.SetSupportsSpdy(spdy_server_mail, true); 120 121 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); 122 EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_mail)); 123 124 impl_.Clear(); 125 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); 126 EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); 127 } 128 129 TEST_F(SpdyServerPropertiesTest, GetSpdyServerList) { 130 base::ListValue spdy_server_list; 131 132 // Check there are no spdy_servers. 133 impl_.GetSpdyServerList(&spdy_server_list); 134 EXPECT_EQ(0U, spdy_server_list.GetSize()); 135 136 // Check empty server is not added. 137 HostPortPair spdy_server_empty(std::string(), 443); 138 impl_.SetSupportsSpdy(spdy_server_empty, true); 139 impl_.GetSpdyServerList(&spdy_server_list); 140 EXPECT_EQ(0U, spdy_server_list.GetSize()); 141 142 std::string string_value_g; 143 std::string string_value_m; 144 HostPortPair spdy_server_google("www.google.com", 443); 145 std::string spdy_server_g = 146 HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_google); 147 HostPortPair spdy_server_mail("mail.google.com", 443); 148 std::string spdy_server_m = 149 HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_mail); 150 151 // Add www.google.com:443 as not supporting SPDY. 152 impl_.SetSupportsSpdy(spdy_server_google, false); 153 impl_.GetSpdyServerList(&spdy_server_list); 154 EXPECT_EQ(0U, spdy_server_list.GetSize()); 155 156 // Add www.google.com:443 as supporting SPDY. 157 impl_.SetSupportsSpdy(spdy_server_google, true); 158 impl_.GetSpdyServerList(&spdy_server_list); 159 ASSERT_EQ(1U, spdy_server_list.GetSize()); 160 ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); 161 ASSERT_EQ(spdy_server_g, string_value_g); 162 163 // Add mail.google.com:443 as not supporting SPDY. 164 impl_.SetSupportsSpdy(spdy_server_mail, false); 165 impl_.GetSpdyServerList(&spdy_server_list); 166 ASSERT_EQ(1U, spdy_server_list.GetSize()); 167 ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); 168 ASSERT_EQ(spdy_server_g, string_value_g); 169 170 // Add mail.google.com:443 as supporting SPDY. 171 impl_.SetSupportsSpdy(spdy_server_mail, true); 172 impl_.GetSpdyServerList(&spdy_server_list); 173 ASSERT_EQ(2U, spdy_server_list.GetSize()); 174 175 // Verify www.google.com:443 and mail.google.com:443 are in the list. 176 ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); 177 ASSERT_TRUE(spdy_server_list.GetString(1, &string_value_m)); 178 if (string_value_g.compare(spdy_server_g) == 0) { 179 ASSERT_EQ(spdy_server_g, string_value_g); 180 ASSERT_EQ(spdy_server_m, string_value_m); 181 } else { 182 ASSERT_EQ(spdy_server_g, string_value_m); 183 ASSERT_EQ(spdy_server_m, string_value_g); 184 } 185 } 186 187 typedef HttpServerPropertiesImplTest AlternateProtocolServerPropertiesTest; 188 189 TEST_F(AlternateProtocolServerPropertiesTest, Basic) { 190 HostPortPair test_host_port_pair("foo", 80); 191 EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); 192 impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3); 193 ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); 194 const PortAlternateProtocolPair alternate = 195 impl_.GetAlternateProtocol(test_host_port_pair); 196 EXPECT_EQ(443, alternate.port); 197 EXPECT_EQ(NPN_SPDY_3, alternate.protocol); 198 199 impl_.Clear(); 200 EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); 201 } 202 203 TEST_F(AlternateProtocolServerPropertiesTest, Initialize) { 204 HostPortPair test_host_port_pair1("foo1", 80); 205 impl_.SetBrokenAlternateProtocol(test_host_port_pair1); 206 HostPortPair test_host_port_pair2("foo2", 80); 207 impl_.SetAlternateProtocol(test_host_port_pair2, 443, NPN_SPDY_3); 208 209 AlternateProtocolMap alternate_protocol_map; 210 PortAlternateProtocolPair port_alternate_protocol_pair; 211 port_alternate_protocol_pair.port = 123; 212 port_alternate_protocol_pair.protocol = NPN_SPDY_3; 213 alternate_protocol_map[test_host_port_pair2] = port_alternate_protocol_pair; 214 impl_.InitializeAlternateProtocolServers(&alternate_protocol_map); 215 216 ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair1)); 217 ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair2)); 218 port_alternate_protocol_pair = 219 impl_.GetAlternateProtocol(test_host_port_pair1); 220 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, port_alternate_protocol_pair.protocol); 221 port_alternate_protocol_pair = 222 impl_.GetAlternateProtocol(test_host_port_pair2); 223 EXPECT_EQ(123, port_alternate_protocol_pair.port); 224 EXPECT_EQ(NPN_SPDY_3, port_alternate_protocol_pair.protocol); 225 } 226 227 TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) { 228 HostPortPair test_host_port_pair("foo", 80); 229 impl_.SetBrokenAlternateProtocol(test_host_port_pair); 230 ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); 231 PortAlternateProtocolPair alternate = 232 impl_.GetAlternateProtocol(test_host_port_pair); 233 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 234 235 impl_.SetAlternateProtocol( 236 test_host_port_pair, 237 1234, 238 NPN_SPDY_3); 239 alternate = impl_.GetAlternateProtocol(test_host_port_pair); 240 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol) 241 << "Second attempt should be ignored."; 242 } 243 244 TEST_F(AlternateProtocolServerPropertiesTest, Forced) { 245 // Test forced alternate protocols. 246 247 PortAlternateProtocolPair default_protocol; 248 default_protocol.port = 1234; 249 default_protocol.protocol = NPN_SPDY_3; 250 HttpServerPropertiesImpl::ForceAlternateProtocol(default_protocol); 251 252 // Verify the forced protocol. 253 HostPortPair test_host_port_pair("foo", 80); 254 EXPECT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); 255 PortAlternateProtocolPair alternate = 256 impl_.GetAlternateProtocol(test_host_port_pair); 257 EXPECT_EQ(default_protocol.port, alternate.port); 258 EXPECT_EQ(default_protocol.protocol, alternate.protocol); 259 260 // Verify the real protocol overrides the forced protocol. 261 impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3); 262 ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); 263 alternate = impl_.GetAlternateProtocol(test_host_port_pair); 264 EXPECT_EQ(443, alternate.port); 265 EXPECT_EQ(NPN_SPDY_3, alternate.protocol); 266 267 // Turn off the static, forced alternate protocol so that tests don't 268 // have this state. 269 HttpServerPropertiesImpl::DisableForcedAlternateProtocol(); 270 271 // Verify the forced protocol is off. 272 HostPortPair test_host_port_pair2("bar", 80); 273 EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair2)); 274 } 275 276 typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest; 277 278 TEST_F(SpdySettingsServerPropertiesTest, Initialize) { 279 HostPortPair spdy_server_google("www.google.com", 443); 280 281 // Check by initializing empty spdy settings. 282 SpdySettingsMap spdy_settings_map; 283 impl_.InitializeSpdySettingsServers(&spdy_settings_map); 284 EXPECT_TRUE(impl_.GetSpdySettings(spdy_server_google).empty()); 285 286 // Check by initializing with www.google.com:443 spdy server settings. 287 SettingsMap settings_map; 288 const SpdySettingsIds id = SETTINGS_UPLOAD_BANDWIDTH; 289 const SpdySettingsFlags flags = SETTINGS_FLAG_PERSISTED; 290 const uint32 value = 31337; 291 SettingsFlagsAndValue flags_and_value(flags, value); 292 settings_map[id] = flags_and_value; 293 spdy_settings_map[spdy_server_google] = settings_map; 294 impl_.InitializeSpdySettingsServers(&spdy_settings_map); 295 296 const SettingsMap& settings_map2 = impl_.GetSpdySettings(spdy_server_google); 297 ASSERT_EQ(1U, settings_map2.size()); 298 SettingsMap::const_iterator it = settings_map2.find(id); 299 EXPECT_TRUE(it != settings_map2.end()); 300 SettingsFlagsAndValue flags_and_value2 = it->second; 301 EXPECT_EQ(flags, flags_and_value2.first); 302 EXPECT_EQ(value, flags_and_value2.second); 303 } 304 305 TEST_F(SpdySettingsServerPropertiesTest, SetSpdySetting) { 306 HostPortPair spdy_server_empty(std::string(), 443); 307 const SettingsMap& settings_map0 = impl_.GetSpdySettings(spdy_server_empty); 308 EXPECT_EQ(0U, settings_map0.size()); // Returns kEmptySettingsMap. 309 310 // Add www.google.com:443 as persisting. 311 HostPortPair spdy_server_google("www.google.com", 443); 312 const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH; 313 const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST; 314 const uint32 value1 = 31337; 315 EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_google, id1, flags1, value1)); 316 // Check the values. 317 const SettingsMap& settings_map1_ret = 318 impl_.GetSpdySettings(spdy_server_google); 319 ASSERT_EQ(1U, settings_map1_ret.size()); 320 SettingsMap::const_iterator it1_ret = settings_map1_ret.find(id1); 321 EXPECT_TRUE(it1_ret != settings_map1_ret.end()); 322 SettingsFlagsAndValue flags_and_value1_ret = it1_ret->second; 323 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1_ret.first); 324 EXPECT_EQ(value1, flags_and_value1_ret.second); 325 326 // Add mail.google.com:443 as not persisting. 327 HostPortPair spdy_server_mail("mail.google.com", 443); 328 const SpdySettingsIds id2 = SETTINGS_DOWNLOAD_BANDWIDTH; 329 const SpdySettingsFlags flags2 = SETTINGS_FLAG_NONE; 330 const uint32 value2 = 62667; 331 EXPECT_FALSE(impl_.SetSpdySetting(spdy_server_mail, id2, flags2, value2)); 332 const SettingsMap& settings_map2_ret = 333 impl_.GetSpdySettings(spdy_server_mail); 334 EXPECT_EQ(0U, settings_map2_ret.size()); // Returns kEmptySettingsMap. 335 336 // Add docs.google.com:443 as persisting 337 HostPortPair spdy_server_docs("docs.google.com", 443); 338 const SpdySettingsIds id3 = SETTINGS_ROUND_TRIP_TIME; 339 const SpdySettingsFlags flags3 = SETTINGS_FLAG_PLEASE_PERSIST; 340 const uint32 value3 = 93997; 341 SettingsFlagsAndValue flags_and_value3(flags3, value3); 342 EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_docs, id3, flags3, value3)); 343 // Check the values. 344 const SettingsMap& settings_map3_ret = 345 impl_.GetSpdySettings(spdy_server_docs); 346 ASSERT_EQ(1U, settings_map3_ret.size()); 347 SettingsMap::const_iterator it3_ret = settings_map3_ret.find(id3); 348 EXPECT_TRUE(it3_ret != settings_map3_ret.end()); 349 SettingsFlagsAndValue flags_and_value3_ret = it3_ret->second; 350 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3_ret.first); 351 EXPECT_EQ(value3, flags_and_value3_ret.second); 352 353 // Check data for www.google.com:443 (id1). 354 const SettingsMap& settings_map4_ret = 355 impl_.GetSpdySettings(spdy_server_google); 356 ASSERT_EQ(1U, settings_map4_ret.size()); 357 SettingsMap::const_iterator it4_ret = settings_map4_ret.find(id1); 358 EXPECT_TRUE(it4_ret != settings_map4_ret.end()); 359 SettingsFlagsAndValue flags_and_value4_ret = it4_ret->second; 360 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value4_ret.first); 361 EXPECT_EQ(value1, flags_and_value1_ret.second); 362 363 // Clear www.google.com:443 as persisting. 364 impl_.ClearSpdySettings(spdy_server_google); 365 // Check the values. 366 const SettingsMap& settings_map5_ret = 367 impl_.GetSpdySettings(spdy_server_google); 368 ASSERT_EQ(0U, settings_map5_ret.size()); 369 370 // Clear all settings. 371 ASSERT_GT(impl_.spdy_settings_map().size(), 0U); 372 impl_.ClearAllSpdySettings(); 373 ASSERT_EQ(0U, impl_.spdy_settings_map().size()); 374 } 375 376 TEST_F(SpdySettingsServerPropertiesTest, Clear) { 377 // Add www.google.com:443 as persisting. 378 HostPortPair spdy_server_google("www.google.com", 443); 379 const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH; 380 const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST; 381 const uint32 value1 = 31337; 382 EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_google, id1, flags1, value1)); 383 // Check the values. 384 const SettingsMap& settings_map1_ret = 385 impl_.GetSpdySettings(spdy_server_google); 386 ASSERT_EQ(1U, settings_map1_ret.size()); 387 SettingsMap::const_iterator it1_ret = settings_map1_ret.find(id1); 388 EXPECT_TRUE(it1_ret != settings_map1_ret.end()); 389 SettingsFlagsAndValue flags_and_value1_ret = it1_ret->second; 390 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value1_ret.first); 391 EXPECT_EQ(value1, flags_and_value1_ret.second); 392 393 // Add docs.google.com:443 as persisting 394 HostPortPair spdy_server_docs("docs.google.com", 443); 395 const SpdySettingsIds id3 = SETTINGS_ROUND_TRIP_TIME; 396 const SpdySettingsFlags flags3 = SETTINGS_FLAG_PLEASE_PERSIST; 397 const uint32 value3 = 93997; 398 EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_docs, id3, flags3, value3)); 399 // Check the values. 400 const SettingsMap& settings_map3_ret = 401 impl_.GetSpdySettings(spdy_server_docs); 402 ASSERT_EQ(1U, settings_map3_ret.size()); 403 SettingsMap::const_iterator it3_ret = settings_map3_ret.find(id3); 404 EXPECT_TRUE(it3_ret != settings_map3_ret.end()); 405 SettingsFlagsAndValue flags_and_value3_ret = it3_ret->second; 406 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3_ret.first); 407 EXPECT_EQ(value3, flags_and_value3_ret.second); 408 409 impl_.Clear(); 410 EXPECT_EQ(0U, impl_.GetSpdySettings(spdy_server_google).size()); 411 EXPECT_EQ(0U, impl_.GetSpdySettings(spdy_server_docs).size()); 412 } 413 414 } // namespace 415 416 } // namespace net 417