| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_server_properties_impl.h" | 5 #include "net/http/http_server_properties_impl.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/test/test_mock_time_task_runner.h" |
| 12 #include "base/values.h" | 13 #include "base/values.h" |
| 13 #include "net/base/host_port_pair.h" | 14 #include "net/base/host_port_pair.h" |
| 14 #include "net/base/ip_address.h" | 15 #include "net/base/ip_address.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "url/gurl.h" | 17 #include "url/gurl.h" |
| 17 | 18 |
| 18 namespace base { | 19 namespace base { |
| 19 class ListValue; | 20 class ListValue; |
| 20 } | 21 } |
| 21 | 22 |
| 22 namespace net { | 23 namespace net { |
| 23 | 24 |
| 24 class HttpServerPropertiesImplPeer { | 25 class HttpServerPropertiesImplPeer { |
| 25 public: | 26 public: |
| 26 static void AddBrokenAlternativeServiceWithExpirationTime( | 27 static void AddBrokenAlternativeServiceWithExpirationTime( |
| 27 HttpServerPropertiesImpl& impl, | 28 HttpServerPropertiesImpl& impl, |
| 28 AlternativeService alternative_service, | 29 const AlternativeService& alternative_service, |
| 29 base::TimeTicks when) { | 30 base::TimeTicks when) { |
| 30 impl.broken_alternative_services_.insert( | 31 HttpBrokenAlternativeServicesManager::BrokenAlternativeServiceList::iterator |
| 31 std::make_pair(alternative_service, when)); | 32 unused_it; |
| 33 impl.broken_alternative_services_.AddToBrokenAlternativeServiceListAndMap( |
| 34 alternative_service, when, &unused_it); |
| 32 auto it = | 35 auto it = |
| 33 impl.recently_broken_alternative_services_.Get(alternative_service); | 36 impl.broken_alternative_services_.recently_broken_alternative_services_ |
| 34 if (it == impl.recently_broken_alternative_services_.end()) { | 37 .Get(alternative_service); |
| 35 impl.recently_broken_alternative_services_.Put(alternative_service, 1); | 38 if (it == impl.broken_alternative_services_ |
| 39 .recently_broken_alternative_services_.end()) { |
| 40 impl.broken_alternative_services_.recently_broken_alternative_services_ |
| 41 .Put(alternative_service, 1); |
| 36 } else { | 42 } else { |
| 37 it->second++; | 43 it->second++; |
| 38 } | 44 } |
| 39 } | 45 } |
| 40 | 46 |
| 41 static void ExpireBrokenAlternateProtocolMappings( | 47 static void ExpireBrokenAlternateProtocolMappings( |
| 42 HttpServerPropertiesImpl& impl) { | 48 HttpServerPropertiesImpl& impl) { |
| 43 impl.ExpireBrokenAlternateProtocolMappings(); | 49 impl.broken_alternative_services_.ExpireBrokenAlternateProtocolMappings(); |
| 44 } | 50 } |
| 45 }; | 51 }; |
| 46 | 52 |
| 47 namespace { | 53 namespace { |
| 48 | 54 |
| 49 const int kMaxSupportsSpdyServerHosts = 500; | 55 const int kMaxSupportsSpdyServerHosts = 500; |
| 50 | 56 |
| 57 class TestClock : public HttpBrokenAlternativeServicesManager::Clock { |
| 58 public: |
| 59 TestClock() : now_(base::TimeTicks::Now()) {} |
| 60 ~TestClock() override {} |
| 61 |
| 62 base::TimeTicks Now() const override { return now_; } |
| 63 |
| 64 void SetNow(base::TimeTicks now) { now_ = now; } |
| 65 void AdvanceNow(base::TimeDelta delta) { now_ += delta; } |
| 66 |
| 67 private: |
| 68 base::TimeTicks now_; |
| 69 }; |
| 70 |
| 51 class HttpServerPropertiesImplTest : public testing::Test { | 71 class HttpServerPropertiesImplTest : public testing::Test { |
| 52 protected: | 72 protected: |
| 73 HttpServerPropertiesImplTest() : impl_(&test_clock_) {} |
| 74 |
| 53 bool HasAlternativeService(const url::SchemeHostPort& origin) { | 75 bool HasAlternativeService(const url::SchemeHostPort& origin) { |
| 54 const AlternativeServiceVector alternative_service_vector = | 76 const AlternativeServiceVector alternative_service_vector = |
| 55 impl_.GetAlternativeServices(origin); | 77 impl_.GetAlternativeServices(origin); |
| 56 return !alternative_service_vector.empty(); | 78 return !alternative_service_vector.empty(); |
| 57 } | 79 } |
| 58 | 80 |
| 59 bool SetAlternativeService(const url::SchemeHostPort& origin, | 81 bool SetAlternativeService(const url::SchemeHostPort& origin, |
| 60 const AlternativeService& alternative_service) { | 82 const AlternativeService& alternative_service) { |
| 61 const base::Time expiration = | 83 const base::Time expiration = |
| 62 base::Time::Now() + base::TimeDelta::FromDays(1); | 84 base::Time::Now() + base::TimeDelta::FromDays(1); |
| 63 return impl_.SetAlternativeService(origin, alternative_service, expiration); | 85 return impl_.SetAlternativeService(origin, alternative_service, expiration); |
| 64 } | 86 } |
| 65 | 87 |
| 88 void MarkBrokenAndLetExpireAlternativeServiceNTimes( |
| 89 const AlternativeService& alternative_service, |
| 90 int num_times) {} |
| 91 |
| 92 TestClock test_clock_; |
| 66 HttpServerPropertiesImpl impl_; | 93 HttpServerPropertiesImpl impl_; |
| 67 }; | 94 }; |
| 68 | 95 |
| 69 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest; | 96 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest; |
| 70 | 97 |
| 71 TEST_F(SpdyServerPropertiesTest, SetWithSchemeHostPort) { | 98 TEST_F(SpdyServerPropertiesTest, SetWithSchemeHostPort) { |
| 72 // Check spdy servers are correctly set with SchemeHostPort key. | 99 // Check spdy servers are correctly set with SchemeHostPort key. |
| 73 url::SchemeHostPort https_www_server("https", "www.google.com", 443); | 100 url::SchemeHostPort https_www_server("https", "www.google.com", 443); |
| 74 url::SchemeHostPort http_photo_server("http", "photos.google.com", 80); | 101 url::SchemeHostPort http_photo_server("http", "photos.google.com", 80); |
| 75 // Servers with port equal to default port in scheme will drop port components | 102 // Servers with port equal to default port in scheme will drop port components |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 EXPECT_FALSE(HasAlternativeService(bar_server1)); | 1003 EXPECT_FALSE(HasAlternativeService(bar_server1)); |
| 977 // The alternative service of "bar:443" should be unaffected. | 1004 // The alternative service of "bar:443" should be unaffected. |
| 978 EXPECT_TRUE(HasAlternativeService(bar_server2)); | 1005 EXPECT_TRUE(HasAlternativeService(bar_server2)); |
| 979 | 1006 |
| 980 EXPECT_TRUE( | 1007 EXPECT_TRUE( |
| 981 impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service)); | 1008 impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service)); |
| 982 EXPECT_FALSE( | 1009 EXPECT_FALSE( |
| 983 impl_.WasAlternativeServiceRecentlyBroken(baz_alternative_service)); | 1010 impl_.WasAlternativeServiceRecentlyBroken(baz_alternative_service)); |
| 984 } | 1011 } |
| 985 | 1012 |
| 1013 // Regression test for https://crbug.com/724302 |
| 1014 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) { |
| 1015 scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner = |
| 1016 new base::TestMockTimeTaskRunner; |
| 1017 |
| 1018 // This test will mark an alternative service A that has already been marked |
| 1019 // broken many times, then immediately mark another alternative service B as |
| 1020 // broken for the first time. Because A's been marked broken many times |
| 1021 // already, its brokenness will be scheduled to expire much further in the |
| 1022 // future than B, even though it was marked broken before B. This test makes |
| 1023 // sure that even though A was marked broken before B, B's brokenness should |
| 1024 // expire before A. |
| 1025 |
| 1026 // This test only makes sense if HttpServerPropertiesImpl's expiration delay |
| 1027 // for a broken AlternativeService is an increasing function of how many times |
| 1028 // that AlternativeService has been marked broken already. |
| 1029 DCHECK(HttpBrokenAlternativeServicesManager:: |
| 1030 ComputeBrokenAltSvcExpirationDelayForTest(3) > |
| 1031 HttpBrokenAlternativeServicesManager:: |
| 1032 ComputeBrokenAltSvcExpirationDelayForTest(0)); |
| 1033 |
| 1034 url::SchemeHostPort server1("https", "foo", 443); |
| 1035 AlternativeService alternative_service1(kProtoQUIC, "foo", 443); |
| 1036 SetAlternativeService(server1, alternative_service1); |
| 1037 |
| 1038 url::SchemeHostPort server2("https", "bar", 443); |
| 1039 AlternativeService alternative_service2(kProtoQUIC, "bar", 443); |
| 1040 SetAlternativeService(server2, alternative_service2); |
| 1041 |
| 1042 // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire. |
| 1043 // This will increase its time until expiration. |
| 1044 for (int i = 0; i < 3; ++i) { |
| 1045 { |
| 1046 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 1047 test_task_runner); |
| 1048 impl_.MarkAlternativeServiceBroken(alternative_service1); |
| 1049 } |
| 1050 // |impl_| should have posted task to expire the brokenness of |
| 1051 // |alternative_service1| |
| 1052 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 1053 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1054 |
| 1055 // Advance time by just enough so that |alternative_service1|'s brokenness |
| 1056 // expires. |
| 1057 base::TimeDelta delta = HttpBrokenAlternativeServicesManager:: |
| 1058 ComputeBrokenAltSvcExpirationDelayForTest(i) + |
| 1059 base::TimeDelta::FromInternalValue(1); |
| 1060 test_clock_.AdvanceNow(delta); |
| 1061 test_task_runner->FastForwardBy(delta); |
| 1062 |
| 1063 // Ensure brokenness of |alternative_service1| has expired. |
| 1064 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| 1065 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1066 } |
| 1067 |
| 1068 { |
| 1069 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 1070 test_task_runner); |
| 1071 impl_.MarkAlternativeServiceBroken(alternative_service1); |
| 1072 } |
| 1073 |
| 1074 // Advance time by one quantum |
| 1075 base::TimeDelta delta = base::TimeDelta::FromInternalValue(1); |
| 1076 test_clock_.AdvanceNow(delta); |
| 1077 test_task_runner->FastForwardBy(delta); |
| 1078 |
| 1079 { |
| 1080 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 1081 test_task_runner); |
| 1082 impl_.MarkAlternativeServiceBroken(alternative_service2); |
| 1083 } |
| 1084 |
| 1085 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2)); |
| 1086 |
| 1087 // Advance time by just enough so that |alternative_service2|'s brokennness |
| 1088 // expires. |
| 1089 delta = HttpBrokenAlternativeServicesManager:: |
| 1090 ComputeBrokenAltSvcExpirationDelayForTest(0) + |
| 1091 base::TimeDelta::FromInternalValue(1); |
| 1092 test_clock_.AdvanceNow(delta); |
| 1093 test_task_runner->FastForwardBy(delta); |
| 1094 |
| 1095 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1096 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2)); |
| 1097 |
| 1098 // Advance time by enough so that |alternative_service1|'s brokenness expires. |
| 1099 delta = HttpBrokenAlternativeServicesManager :: |
| 1100 ComputeBrokenAltSvcExpirationDelayForTest(3) + |
| 1101 base::TimeDelta::FromInternalValue(1); |
| 1102 test_clock_.AdvanceNow(delta); |
| 1103 test_task_runner->FastForwardBy(delta); |
| 1104 |
| 1105 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1106 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2)); |
| 1107 } |
| 1108 |
| 986 typedef HttpServerPropertiesImplTest SupportsQuicServerPropertiesTest; | 1109 typedef HttpServerPropertiesImplTest SupportsQuicServerPropertiesTest; |
| 987 | 1110 |
| 988 TEST_F(SupportsQuicServerPropertiesTest, Set) { | 1111 TEST_F(SupportsQuicServerPropertiesTest, Set) { |
| 989 HostPortPair quic_server_google("www.google.com", 443); | 1112 HostPortPair quic_server_google("www.google.com", 443); |
| 990 | 1113 |
| 991 // Check by initializing empty address. | 1114 // Check by initializing empty address. |
| 992 IPAddress initial_address; | 1115 IPAddress initial_address; |
| 993 impl_.SetSupportsQuic(&initial_address); | 1116 impl_.SetSupportsQuic(&initial_address); |
| 994 | 1117 |
| 995 IPAddress address; | 1118 IPAddress address; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 EXPECT_EQ(quic_server_info1, *(impl_.GetQuicServerInfo(quic_server_id))); | 1347 EXPECT_EQ(quic_server_info1, *(impl_.GetQuicServerInfo(quic_server_id))); |
| 1225 | 1348 |
| 1226 impl_.Clear(); | 1349 impl_.Clear(); |
| 1227 EXPECT_EQ(0u, impl_.quic_server_info_map().size()); | 1350 EXPECT_EQ(0u, impl_.quic_server_info_map().size()); |
| 1228 EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(quic_server_id)); | 1351 EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(quic_server_id)); |
| 1229 } | 1352 } |
| 1230 | 1353 |
| 1231 } // namespace | 1354 } // namespace |
| 1232 | 1355 |
| 1233 } // namespace net | 1356 } // namespace net |
| OLD | NEW |