| 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 |
| 25 const base::TimeDelta BROKEN_ALT_SVC_EXPIRE_DELAYS[10] = { |
| 26 base::TimeDelta::FromSeconds(300), base::TimeDelta::FromSeconds(600), |
| 27 base::TimeDelta::FromSeconds(1200), base::TimeDelta::FromSeconds(2400), |
| 28 base::TimeDelta::FromSeconds(4800), base::TimeDelta::FromSeconds(9600), |
| 29 base::TimeDelta::FromSeconds(19200), base::TimeDelta::FromSeconds(38400), |
| 30 base::TimeDelta::FromSeconds(76800), base::TimeDelta::FromSeconds(153600), |
| 31 }; |
| 32 |
| 24 class HttpServerPropertiesImplPeer { | 33 class HttpServerPropertiesImplPeer { |
| 25 public: | 34 public: |
| 26 static void AddBrokenAlternativeServiceWithExpirationTime( | 35 static void AddBrokenAlternativeServiceWithExpirationTime( |
| 27 HttpServerPropertiesImpl* impl, | 36 HttpServerPropertiesImpl* impl, |
| 28 AlternativeService alternative_service, | 37 const AlternativeService& alternative_service, |
| 29 base::TimeTicks when) { | 38 base::TimeTicks when) { |
| 30 impl->broken_alternative_services_.insert( | 39 BrokenAlternativeServices::BrokenAlternativeServiceList::iterator unused_it; |
| 31 std::make_pair(alternative_service, when)); | 40 impl->broken_alternative_services_.AddToBrokenAlternativeServiceListAndMap( |
| 41 alternative_service, when, &unused_it); |
| 32 auto it = | 42 auto it = |
| 33 impl->recently_broken_alternative_services_.Get(alternative_service); | 43 impl->broken_alternative_services_.recently_broken_alternative_services_ |
| 34 if (it == impl->recently_broken_alternative_services_.end()) { | 44 .Get(alternative_service); |
| 35 impl->recently_broken_alternative_services_.Put(alternative_service, 1); | 45 if (it == impl->broken_alternative_services_ |
| 46 .recently_broken_alternative_services_.end()) { |
| 47 impl->broken_alternative_services_.recently_broken_alternative_services_ |
| 48 .Put(alternative_service, 1); |
| 36 } else { | 49 } else { |
| 37 it->second++; | 50 it->second++; |
| 38 } | 51 } |
| 39 } | 52 } |
| 40 | 53 |
| 41 static void ExpireBrokenAlternateProtocolMappings( | 54 static void ExpireBrokenAlternateProtocolMappings( |
| 42 HttpServerPropertiesImpl* impl) { | 55 HttpServerPropertiesImpl* impl) { |
| 43 impl->ExpireBrokenAlternateProtocolMappings(); | 56 impl->broken_alternative_services_.ExpireBrokenAlternateProtocolMappings(); |
| 44 } | 57 } |
| 45 }; | 58 }; |
| 46 | 59 |
| 47 namespace { | 60 namespace { |
| 48 | 61 |
| 49 const int kMaxSupportsSpdyServerHosts = 500; | 62 const int kMaxSupportsSpdyServerHosts = 500; |
| 50 | 63 |
| 51 class HttpServerPropertiesImplTest : public testing::Test { | 64 class HttpServerPropertiesImplTest : public testing::Test { |
| 52 protected: | 65 protected: |
| 66 HttpServerPropertiesImplTest() |
| 67 : test_task_runner_(new base::TestMockTimeTaskRunner()), |
| 68 broken_services_clock_(test_task_runner_->GetMockTickClock()), |
| 69 impl_(broken_services_clock_.get()) {} |
| 70 |
| 53 bool HasAlternativeService(const url::SchemeHostPort& origin) { | 71 bool HasAlternativeService(const url::SchemeHostPort& origin) { |
| 54 const AlternativeServiceInfoVector alternative_service_info_vector = | 72 const AlternativeServiceInfoVector alternative_service_info_vector = |
| 55 impl_.GetAlternativeServiceInfos(origin); | 73 impl_.GetAlternativeServiceInfos(origin); |
| 56 return !alternative_service_info_vector.empty(); | 74 return !alternative_service_info_vector.empty(); |
| 57 } | 75 } |
| 58 | 76 |
| 59 bool SetAlternativeService(const url::SchemeHostPort& origin, | 77 bool SetAlternativeService(const url::SchemeHostPort& origin, |
| 60 const AlternativeService& alternative_service) { | 78 const AlternativeService& alternative_service) { |
| 61 const base::Time expiration = | 79 const base::Time expiration = |
| 62 base::Time::Now() + base::TimeDelta::FromDays(1); | 80 base::Time::Now() + base::TimeDelta::FromDays(1); |
| 63 return impl_.SetAlternativeService(origin, alternative_service, expiration); | 81 return impl_.SetAlternativeService(origin, alternative_service, expiration); |
| 64 } | 82 } |
| 65 | 83 |
| 84 void MarkBrokenAndLetExpireAlternativeServiceNTimes( |
| 85 const AlternativeService& alternative_service, |
| 86 int num_times) {} |
| 87 |
| 88 scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; |
| 89 |
| 90 std::unique_ptr<base::TickClock> broken_services_clock_; |
| 66 HttpServerPropertiesImpl impl_; | 91 HttpServerPropertiesImpl impl_; |
| 67 }; | 92 }; |
| 68 | 93 |
| 69 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest; | 94 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest; |
| 70 | 95 |
| 71 TEST_F(SpdyServerPropertiesTest, SetWithSchemeHostPort) { | 96 TEST_F(SpdyServerPropertiesTest, SetWithSchemeHostPort) { |
| 72 // Check spdy servers are correctly set with SchemeHostPort key. | 97 // Check spdy servers are correctly set with SchemeHostPort key. |
| 73 url::SchemeHostPort https_www_server("https", "www.google.com", 443); | 98 url::SchemeHostPort https_www_server("https", "www.google.com", 443); |
| 74 url::SchemeHostPort http_photo_server("http", "photos.google.com", 80); | 99 url::SchemeHostPort http_photo_server("http", "photos.google.com", 80); |
| 75 // Servers with port equal to default port in scheme will drop port components | 100 // Servers with port equal to default port in scheme will drop port components |
| (...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 TEST_F(AlternateProtocolServerPropertiesTest, | 966 TEST_F(AlternateProtocolServerPropertiesTest, |
| 942 ExpireBrokenAlternateProtocolMappings) { | 967 ExpireBrokenAlternateProtocolMappings) { |
| 943 url::SchemeHostPort server("https", "foo", 443); | 968 url::SchemeHostPort server("https", "foo", 443); |
| 944 AlternativeService alternative_service(kProtoQUIC, "foo", 443); | 969 AlternativeService alternative_service(kProtoQUIC, "foo", 443); |
| 945 SetAlternativeService(server, alternative_service); | 970 SetAlternativeService(server, alternative_service); |
| 946 EXPECT_TRUE(HasAlternativeService(server)); | 971 EXPECT_TRUE(HasAlternativeService(server)); |
| 947 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service)); | 972 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service)); |
| 948 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); | 973 EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 949 | 974 |
| 950 base::TimeTicks past = | 975 base::TimeTicks past = |
| 951 base::TimeTicks::Now() - base::TimeDelta::FromSeconds(42); | 976 broken_services_clock_->NowTicks() - base::TimeDelta::FromSeconds(42); |
| 952 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime( | 977 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime( |
| 953 &impl_, alternative_service, past); | 978 &impl_, alternative_service, past); |
| 954 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service)); | 979 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service)); |
| 955 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); | 980 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 956 | 981 |
| 957 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(&impl_); | 982 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(&impl_); |
| 958 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service)); | 983 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service)); |
| 959 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); | 984 EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service)); |
| 960 } | 985 } |
| 961 | 986 |
| 962 // Regression test for https://crbug.com/505413. | 987 // Regression test for https://crbug.com/505413. |
| 963 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) { | 988 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) { |
| 964 url::SchemeHostPort foo_server("https", "foo", 443); | 989 url::SchemeHostPort foo_server("https", "foo", 443); |
| 965 AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443); | 990 AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443); |
| 966 SetAlternativeService(foo_server, bar_alternative_service); | 991 SetAlternativeService(foo_server, bar_alternative_service); |
| 967 EXPECT_TRUE(HasAlternativeService(foo_server)); | 992 EXPECT_TRUE(HasAlternativeService(foo_server)); |
| 968 | 993 |
| 969 url::SchemeHostPort bar_server1("http", "bar", 80); | 994 url::SchemeHostPort bar_server1("http", "bar", 80); |
| 970 AlternativeService nohost_alternative_service(kProtoQUIC, "", 443); | 995 AlternativeService nohost_alternative_service(kProtoQUIC, "", 443); |
| 971 SetAlternativeService(bar_server1, nohost_alternative_service); | 996 SetAlternativeService(bar_server1, nohost_alternative_service); |
| 972 EXPECT_TRUE(HasAlternativeService(bar_server1)); | 997 EXPECT_TRUE(HasAlternativeService(bar_server1)); |
| 973 | 998 |
| 974 url::SchemeHostPort bar_server2("https", "bar", 443); | 999 url::SchemeHostPort bar_server2("https", "bar", 443); |
| 975 AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234); | 1000 AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234); |
| 976 SetAlternativeService(bar_server2, baz_alternative_service); | 1001 SetAlternativeService(bar_server2, baz_alternative_service); |
| 977 EXPECT_TRUE(HasAlternativeService(bar_server2)); | 1002 EXPECT_TRUE(HasAlternativeService(bar_server2)); |
| 978 | 1003 |
| 979 // Mark "bar:443" as broken. | 1004 // Mark "bar:443" as broken. |
| 980 base::TimeTicks past = | 1005 base::TimeTicks past = |
| 981 base::TimeTicks::Now() - base::TimeDelta::FromSeconds(42); | 1006 broken_services_clock_->NowTicks() - base::TimeDelta::FromSeconds(42); |
| 982 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime( | 1007 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime( |
| 983 &impl_, bar_alternative_service, past); | 1008 &impl_, bar_alternative_service, past); |
| 984 | 1009 |
| 985 // Expire brokenness of "bar:443". | 1010 // Expire brokenness of "bar:443". |
| 986 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(&impl_); | 1011 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(&impl_); |
| 987 | 1012 |
| 988 // "foo:443" should have no alternative service now. | 1013 // "foo:443" should have no alternative service now. |
| 989 EXPECT_FALSE(HasAlternativeService(foo_server)); | 1014 EXPECT_FALSE(HasAlternativeService(foo_server)); |
| 990 // "bar:80" should have no alternative service now. | 1015 // "bar:80" should have no alternative service now. |
| 991 EXPECT_FALSE(HasAlternativeService(bar_server1)); | 1016 EXPECT_FALSE(HasAlternativeService(bar_server1)); |
| 992 // The alternative service of "bar:443" should be unaffected. | 1017 // The alternative service of "bar:443" should be unaffected. |
| 993 EXPECT_TRUE(HasAlternativeService(bar_server2)); | 1018 EXPECT_TRUE(HasAlternativeService(bar_server2)); |
| 994 | 1019 |
| 995 EXPECT_TRUE( | 1020 EXPECT_TRUE( |
| 996 impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service)); | 1021 impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service)); |
| 997 EXPECT_FALSE( | 1022 EXPECT_FALSE( |
| 998 impl_.WasAlternativeServiceRecentlyBroken(baz_alternative_service)); | 1023 impl_.WasAlternativeServiceRecentlyBroken(baz_alternative_service)); |
| 999 } | 1024 } |
| 1000 | 1025 |
| 1026 // Regression test for https://crbug.com/724302 |
| 1027 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) { |
| 1028 // This test will mark an alternative service A that has already been marked |
| 1029 // broken many times, then immediately mark another alternative service B as |
| 1030 // broken for the first time. Because A's been marked broken many times |
| 1031 // already, its brokenness will be scheduled to expire much further in the |
| 1032 // future than B, even though it was marked broken before B. This test makes |
| 1033 // sure that even though A was marked broken before B, B's brokenness should |
| 1034 // expire before A. |
| 1035 |
| 1036 url::SchemeHostPort server1("https", "foo", 443); |
| 1037 AlternativeService alternative_service1(kProtoQUIC, "foo", 443); |
| 1038 SetAlternativeService(server1, alternative_service1); |
| 1039 |
| 1040 url::SchemeHostPort server2("https", "bar", 443); |
| 1041 AlternativeService alternative_service2(kProtoQUIC, "bar", 443); |
| 1042 SetAlternativeService(server2, alternative_service2); |
| 1043 |
| 1044 // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire. |
| 1045 // This will increase its time until expiration. |
| 1046 for (int i = 0; i < 3; ++i) { |
| 1047 { |
| 1048 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 1049 test_task_runner_); |
| 1050 impl_.MarkAlternativeServiceBroken(alternative_service1); |
| 1051 } |
| 1052 // |impl_| should have posted task to expire the brokenness of |
| 1053 // |alternative_service1| |
| 1054 EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); |
| 1055 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1056 |
| 1057 // Advance time by just enough so that |alternative_service1|'s brokenness |
| 1058 // expires. |
| 1059 test_task_runner_->FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]); |
| 1060 |
| 1061 // Ensure brokenness of |alternative_service1| has expired. |
| 1062 EXPECT_FALSE(test_task_runner_->HasPendingTask()); |
| 1063 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1064 } |
| 1065 |
| 1066 { |
| 1067 base::TestMockTimeTaskRunner::ScopedContext scoped_context( |
| 1068 test_task_runner_); |
| 1069 impl_.MarkAlternativeServiceBroken(alternative_service1); |
| 1070 impl_.MarkAlternativeServiceBroken(alternative_service2); |
| 1071 } |
| 1072 |
| 1073 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2)); |
| 1074 |
| 1075 // Advance time by just enough so that |alternative_service2|'s brokennness |
| 1076 // expires. |
| 1077 test_task_runner_->FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]); |
| 1078 |
| 1079 EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1080 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2)); |
| 1081 |
| 1082 // Advance time by enough so that |alternative_service1|'s brokenness expires. |
| 1083 test_task_runner_->FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] - |
| 1084 BROKEN_ALT_SVC_EXPIRE_DELAYS[0]); |
| 1085 |
| 1086 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1)); |
| 1087 EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2)); |
| 1088 } |
| 1089 |
| 1001 typedef HttpServerPropertiesImplTest SupportsQuicServerPropertiesTest; | 1090 typedef HttpServerPropertiesImplTest SupportsQuicServerPropertiesTest; |
| 1002 | 1091 |
| 1003 TEST_F(SupportsQuicServerPropertiesTest, Set) { | 1092 TEST_F(SupportsQuicServerPropertiesTest, Set) { |
| 1004 HostPortPair quic_server_google("www.google.com", 443); | 1093 HostPortPair quic_server_google("www.google.com", 443); |
| 1005 | 1094 |
| 1006 // Check by initializing empty address. | 1095 // Check by initializing empty address. |
| 1007 IPAddress initial_address; | 1096 IPAddress initial_address; |
| 1008 impl_.SetSupportsQuic(&initial_address); | 1097 impl_.SetSupportsQuic(&initial_address); |
| 1009 | 1098 |
| 1010 IPAddress address; | 1099 IPAddress address; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 EXPECT_EQ(quic_server_info1, *(impl_.GetQuicServerInfo(quic_server_id))); | 1328 EXPECT_EQ(quic_server_info1, *(impl_.GetQuicServerInfo(quic_server_id))); |
| 1240 | 1329 |
| 1241 impl_.Clear(); | 1330 impl_.Clear(); |
| 1242 EXPECT_EQ(0u, impl_.quic_server_info_map().size()); | 1331 EXPECT_EQ(0u, impl_.quic_server_info_map().size()); |
| 1243 EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(quic_server_id)); | 1332 EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(quic_server_id)); |
| 1244 } | 1333 } |
| 1245 | 1334 |
| 1246 } // namespace | 1335 } // namespace |
| 1247 | 1336 |
| 1248 } // namespace net | 1337 } // namespace net |
| OLD | NEW |