Home | History | Annotate | Download | only in http
      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