http_server_properties_unittest.cc 148 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035
  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. #include "net/http/http_server_properties.h"
  5. #include <memory>
  6. #include <string>
  7. #include <vector>
  8. #include "base/bind.h"
  9. #include "base/callback.h"
  10. #include "base/check.h"
  11. #include "base/feature_list.h"
  12. #include "base/json/json_writer.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/run_loop.h"
  15. #include "base/test/scoped_feature_list.h"
  16. #include "base/test/simple_test_clock.h"
  17. #include "base/test/task_environment.h"
  18. #include "base/time/time.h"
  19. #include "base/values.h"
  20. #include "net/base/features.h"
  21. #include "net/base/host_port_pair.h"
  22. #include "net/base/ip_address.h"
  23. #include "net/base/schemeful_site.h"
  24. #include "net/http/http_network_session.h"
  25. #include "net/test/test_with_task_environment.h"
  26. #include "testing/gtest/include/gtest/gtest.h"
  27. #include "url/gurl.h"
  28. namespace net {
  29. const base::TimeDelta BROKEN_ALT_SVC_EXPIRE_DELAYS[10] = {
  30. base::Seconds(300), base::Seconds(600), base::Seconds(1200),
  31. base::Seconds(2400), base::Seconds(4800), base::Seconds(9600),
  32. base::Seconds(19200), base::Seconds(38400), base::Seconds(76800),
  33. base::Seconds(153600),
  34. };
  35. class HttpServerPropertiesPeer {
  36. public:
  37. static void AddBrokenAlternativeServiceWithExpirationTime(
  38. HttpServerProperties* impl,
  39. const AlternativeService& alternative_service,
  40. base::TimeTicks when,
  41. const NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
  42. BrokenAlternativeService broken_alternative_service(
  43. alternative_service, network_isolation_key,
  44. true /* use_network_isolation_key */);
  45. BrokenAlternativeServiceList::iterator unused_it;
  46. impl->broken_alternative_services_.AddToBrokenListAndMap(
  47. broken_alternative_service, when, &unused_it);
  48. auto it =
  49. impl->broken_alternative_services_.recently_broken_alternative_services_
  50. .Get(broken_alternative_service);
  51. if (it == impl->broken_alternative_services_
  52. .recently_broken_alternative_services_.end()) {
  53. impl->broken_alternative_services_.recently_broken_alternative_services_
  54. .Put(broken_alternative_service, 1);
  55. } else {
  56. it->second++;
  57. }
  58. }
  59. static void ExpireBrokenAlternateProtocolMappings(
  60. HttpServerProperties* impl) {
  61. impl->broken_alternative_services_.ExpireBrokenAlternateProtocolMappings();
  62. }
  63. };
  64. namespace {
  65. // Creates a ServerInfoMapKey without a NetworkIsolationKey.
  66. HttpServerProperties::ServerInfoMapKey CreateSimpleKey(
  67. const url::SchemeHostPort& server) {
  68. return HttpServerProperties::ServerInfoMapKey(
  69. server, net::NetworkIsolationKey(),
  70. false /* use_network_isolation_key */);
  71. }
  72. class HttpServerPropertiesTest : public TestWithTaskEnvironment {
  73. protected:
  74. HttpServerPropertiesTest()
  75. : TestWithTaskEnvironment(
  76. base::test::TaskEnvironment::TimeSource::MOCK_TIME),
  77. // Many tests assume partitioning is disabled by default.
  78. feature_list_(CreateFeatureListWithPartitioningDisabled()),
  79. test_tick_clock_(GetMockTickClock()),
  80. impl_(nullptr /* pref_delegate */,
  81. nullptr /* net_log */,
  82. test_tick_clock_,
  83. &test_clock_) {
  84. // Set |test_clock_| to some random time.
  85. test_clock_.Advance(base::Seconds(12345));
  86. SchemefulSite site1(GURL("https://foo.test/"));
  87. network_isolation_key1_ = NetworkIsolationKey(site1, site1);
  88. SchemefulSite site2(GURL("https://bar.test/"));
  89. network_isolation_key2_ = NetworkIsolationKey(site2, site2);
  90. }
  91. // This is a little awkward, but need to create and configure the
  92. // ScopedFeatureList before creating the HttpServerProperties.
  93. static std::unique_ptr<base::test::ScopedFeatureList>
  94. CreateFeatureListWithPartitioningDisabled() {
  95. std::unique_ptr<base::test::ScopedFeatureList> feature_list =
  96. std::make_unique<base::test::ScopedFeatureList>();
  97. feature_list->InitAndDisableFeature(
  98. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  99. return feature_list;
  100. }
  101. bool HasAlternativeService(const url::SchemeHostPort& origin,
  102. const NetworkIsolationKey& network_isolation_key) {
  103. const AlternativeServiceInfoVector alternative_service_info_vector =
  104. impl_.GetAlternativeServiceInfos(origin, network_isolation_key);
  105. return !alternative_service_info_vector.empty();
  106. }
  107. void SetAlternativeService(const url::SchemeHostPort& origin,
  108. const AlternativeService& alternative_service) {
  109. const base::Time expiration = test_clock_.Now() + base::Days(1);
  110. if (alternative_service.protocol == kProtoQUIC) {
  111. impl_.SetQuicAlternativeService(origin, NetworkIsolationKey(),
  112. alternative_service, expiration,
  113. DefaultSupportedQuicVersions());
  114. } else {
  115. impl_.SetHttp2AlternativeService(origin, NetworkIsolationKey(),
  116. alternative_service, expiration);
  117. }
  118. }
  119. void MarkBrokenAndLetExpireAlternativeServiceNTimes(
  120. const AlternativeService& alternative_service,
  121. int num_times) {}
  122. std::unique_ptr<base::test::ScopedFeatureList> feature_list_;
  123. raw_ptr<const base::TickClock> test_tick_clock_;
  124. base::SimpleTestClock test_clock_;
  125. // Two different non-empty network isolation keys for use in tests that need
  126. // them.
  127. NetworkIsolationKey network_isolation_key1_;
  128. NetworkIsolationKey network_isolation_key2_;
  129. HttpServerProperties impl_;
  130. };
  131. TEST_F(HttpServerPropertiesTest, SetSupportsSpdy) {
  132. // Check spdy servers are correctly set with SchemeHostPort key.
  133. url::SchemeHostPort https_www_server("https", "www.google.com", 443);
  134. url::SchemeHostPort http_photo_server("http", "photos.google.com", 80);
  135. url::SchemeHostPort https_mail_server("https", "mail.google.com", 443);
  136. // Servers with port equal to default port in scheme will drop port components
  137. // when calling Serialize().
  138. url::SchemeHostPort http_google_server("http", "www.google.com", 443);
  139. url::SchemeHostPort https_photos_server("https", "photos.google.com", 443);
  140. url::SchemeHostPort valid_google_server((GURL("https://www.google.com")));
  141. impl_.SetSupportsSpdy(https_www_server, NetworkIsolationKey(), true);
  142. impl_.SetSupportsSpdy(http_photo_server, NetworkIsolationKey(), true);
  143. impl_.SetSupportsSpdy(https_mail_server, NetworkIsolationKey(), false);
  144. EXPECT_TRUE(impl_.GetSupportsSpdy(https_www_server, NetworkIsolationKey()));
  145. EXPECT_TRUE(
  146. impl_.SupportsRequestPriority(https_www_server, NetworkIsolationKey()));
  147. EXPECT_TRUE(impl_.GetSupportsSpdy(http_photo_server, NetworkIsolationKey()));
  148. EXPECT_TRUE(
  149. impl_.SupportsRequestPriority(http_photo_server, NetworkIsolationKey()));
  150. EXPECT_FALSE(impl_.GetSupportsSpdy(https_mail_server, NetworkIsolationKey()));
  151. EXPECT_FALSE(
  152. impl_.SupportsRequestPriority(https_mail_server, NetworkIsolationKey()));
  153. EXPECT_FALSE(
  154. impl_.GetSupportsSpdy(http_google_server, NetworkIsolationKey()));
  155. EXPECT_FALSE(
  156. impl_.SupportsRequestPriority(http_google_server, NetworkIsolationKey()));
  157. EXPECT_FALSE(
  158. impl_.GetSupportsSpdy(https_photos_server, NetworkIsolationKey()));
  159. EXPECT_FALSE(impl_.SupportsRequestPriority(https_photos_server,
  160. NetworkIsolationKey()));
  161. EXPECT_TRUE(
  162. impl_.GetSupportsSpdy(valid_google_server, NetworkIsolationKey()));
  163. EXPECT_TRUE(impl_.SupportsRequestPriority(valid_google_server,
  164. NetworkIsolationKey()));
  165. // Flip values of two servers.
  166. impl_.SetSupportsSpdy(https_www_server, NetworkIsolationKey(), false);
  167. impl_.SetSupportsSpdy(https_mail_server, NetworkIsolationKey(), true);
  168. EXPECT_FALSE(impl_.GetSupportsSpdy(https_www_server, NetworkIsolationKey()));
  169. EXPECT_FALSE(
  170. impl_.SupportsRequestPriority(https_www_server, NetworkIsolationKey()));
  171. EXPECT_TRUE(impl_.GetSupportsSpdy(https_mail_server, NetworkIsolationKey()));
  172. EXPECT_TRUE(
  173. impl_.SupportsRequestPriority(https_mail_server, NetworkIsolationKey()));
  174. }
  175. TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWebSockets) {
  176. // The https and wss servers should be treated as the same server, as should
  177. // the http and ws servers.
  178. url::SchemeHostPort https_server("https", "www.test.com", 443);
  179. url::SchemeHostPort wss_server("wss", "www.test.com", 443);
  180. url::SchemeHostPort http_server("http", "www.test.com", 443);
  181. url::SchemeHostPort ws_server("ws", "www.test.com", 443);
  182. EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
  183. EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
  184. EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
  185. EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
  186. impl_.SetSupportsSpdy(wss_server, NetworkIsolationKey(), true);
  187. EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
  188. EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
  189. EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
  190. EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
  191. impl_.SetSupportsSpdy(http_server, NetworkIsolationKey(), true);
  192. EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
  193. EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
  194. EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
  195. EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
  196. impl_.SetSupportsSpdy(https_server, NetworkIsolationKey(), false);
  197. EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
  198. EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
  199. EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
  200. EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
  201. impl_.SetSupportsSpdy(ws_server, NetworkIsolationKey(), false);
  202. EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
  203. EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
  204. EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
  205. EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
  206. }
  207. TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) {
  208. const url::SchemeHostPort kServer("https", "foo.test", 443);
  209. EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
  210. EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
  211. EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  212. EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  213. // Without network isolation keys enabled for HttpServerProperties, passing in
  214. // a NetworkIsolationKey should have no effect on behavior.
  215. for (const auto& network_isolation_key_to_set :
  216. {NetworkIsolationKey(), network_isolation_key1_}) {
  217. impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, true);
  218. EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
  219. EXPECT_TRUE(
  220. impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
  221. EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  222. EXPECT_TRUE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  223. impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, false);
  224. EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
  225. EXPECT_FALSE(
  226. impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
  227. EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  228. EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  229. }
  230. // With network isolation keys enabled for HttpServerProperties, the
  231. // NetworkIsolationKey argument should be respected.
  232. base::test::ScopedFeatureList feature_list;
  233. feature_list.InitAndEnableFeature(
  234. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  235. // Since HttpServerProperties caches the feature value, have to create a new
  236. // one.
  237. HttpServerProperties properties(nullptr /* pref_delegate */,
  238. nullptr /* net_log */, test_tick_clock_,
  239. &test_clock_);
  240. EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
  241. EXPECT_FALSE(
  242. properties.SupportsRequestPriority(kServer, network_isolation_key1_));
  243. EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  244. EXPECT_FALSE(
  245. properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  246. properties.SetSupportsSpdy(kServer, network_isolation_key1_, true);
  247. EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
  248. EXPECT_TRUE(
  249. properties.SupportsRequestPriority(kServer, network_isolation_key1_));
  250. EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  251. EXPECT_FALSE(
  252. properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  253. properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), true);
  254. EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
  255. EXPECT_TRUE(
  256. properties.SupportsRequestPriority(kServer, network_isolation_key1_));
  257. EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  258. EXPECT_TRUE(
  259. properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  260. properties.SetSupportsSpdy(kServer, network_isolation_key1_, false);
  261. EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
  262. EXPECT_FALSE(
  263. properties.SupportsRequestPriority(kServer, network_isolation_key1_));
  264. EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  265. EXPECT_TRUE(
  266. properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  267. properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), false);
  268. EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
  269. EXPECT_FALSE(
  270. properties.SupportsRequestPriority(kServer, network_isolation_key1_));
  271. EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
  272. EXPECT_FALSE(
  273. properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
  274. }
  275. TEST_F(HttpServerPropertiesTest, LoadSupportsSpdy) {
  276. HttpServerProperties::ServerInfo supports_spdy;
  277. supports_spdy.supports_spdy = true;
  278. HttpServerProperties::ServerInfo no_spdy;
  279. no_spdy.supports_spdy = false;
  280. url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
  281. url::SchemeHostPort spdy_server_photos("https", "photos.google.com", 443);
  282. url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
  283. url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
  284. // Check by initializing empty spdy servers.
  285. std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers =
  286. std::make_unique<HttpServerProperties::ServerInfoMap>();
  287. impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers));
  288. EXPECT_FALSE(
  289. impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  290. // Check by initializing www.google.com:443 and photos.google.com:443 as spdy
  291. // servers.
  292. std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers1 =
  293. std::make_unique<HttpServerProperties::ServerInfoMap>();
  294. spdy_servers1->Put(CreateSimpleKey(spdy_server_google), supports_spdy);
  295. spdy_servers1->Put(CreateSimpleKey(spdy_server_photos), no_spdy);
  296. impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers1));
  297. // Note: these calls affect MRU order.
  298. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  299. EXPECT_FALSE(
  300. impl_.GetSupportsSpdy(spdy_server_photos, NetworkIsolationKey()));
  301. // Verify google and photos are in the list in MRU order.
  302. ASSERT_EQ(2U, impl_.server_info_map_for_testing().size());
  303. auto it = impl_.server_info_map_for_testing().begin();
  304. EXPECT_EQ(spdy_server_photos, it->first.server);
  305. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  306. ASSERT_TRUE(it->second.supports_spdy.has_value());
  307. EXPECT_FALSE(*it->second.supports_spdy);
  308. ++it;
  309. EXPECT_EQ(spdy_server_google, it->first.server);
  310. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  311. ASSERT_TRUE(it->second.supports_spdy.has_value());
  312. EXPECT_TRUE(*it->second.supports_spdy);
  313. // Check by initializing mail.google.com:443 and docs.google.com:443.
  314. std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers2 =
  315. std::make_unique<HttpServerProperties::ServerInfoMap>();
  316. spdy_servers2->Put(CreateSimpleKey(spdy_server_mail), supports_spdy);
  317. spdy_servers2->Put(CreateSimpleKey(spdy_server_docs), supports_spdy);
  318. impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers2));
  319. // Verify all the servers are in the list in MRU order. Note that
  320. // OnServerInfoLoadedForTesting will put existing spdy server entries in
  321. // front of newly added entries.
  322. ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
  323. it = impl_.server_info_map_for_testing().begin();
  324. EXPECT_EQ(spdy_server_photos, it->first.server);
  325. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  326. ASSERT_TRUE(it->second.supports_spdy.has_value());
  327. EXPECT_FALSE(*it->second.supports_spdy);
  328. ++it;
  329. EXPECT_EQ(spdy_server_google, it->first.server);
  330. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  331. ASSERT_TRUE(it->second.supports_spdy.has_value());
  332. EXPECT_TRUE(*it->second.supports_spdy);
  333. ++it;
  334. EXPECT_EQ(spdy_server_docs, it->first.server);
  335. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  336. ASSERT_TRUE(it->second.supports_spdy.has_value());
  337. EXPECT_TRUE(*it->second.supports_spdy);
  338. ++it;
  339. EXPECT_EQ(spdy_server_mail, it->first.server);
  340. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  341. ASSERT_TRUE(it->second.supports_spdy.has_value());
  342. EXPECT_TRUE(*it->second.supports_spdy);
  343. // Check these in reverse MRU order so that MRU order stays the same.
  344. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
  345. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_docs, NetworkIsolationKey()));
  346. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  347. EXPECT_FALSE(
  348. impl_.GetSupportsSpdy(spdy_server_photos, NetworkIsolationKey()));
  349. // Verify that old values loaded from disk take precedence over newer learned
  350. // values and also verify the recency list order is unchanged.
  351. std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers3 =
  352. std::make_unique<HttpServerProperties::ServerInfoMap>();
  353. spdy_servers3->Put(CreateSimpleKey(spdy_server_mail), no_spdy);
  354. spdy_servers3->Put(CreateSimpleKey(spdy_server_photos), supports_spdy);
  355. impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers3));
  356. // Verify the entries are in the same order.
  357. ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
  358. it = impl_.server_info_map_for_testing().begin();
  359. EXPECT_EQ(spdy_server_photos, it->first.server);
  360. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  361. ASSERT_TRUE(it->second.supports_spdy.has_value());
  362. EXPECT_TRUE(*it->second.supports_spdy);
  363. ++it;
  364. EXPECT_EQ(spdy_server_google, it->first.server);
  365. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  366. ASSERT_TRUE(it->second.supports_spdy.has_value());
  367. EXPECT_TRUE(*it->second.supports_spdy);
  368. ++it;
  369. EXPECT_EQ(spdy_server_docs, it->first.server);
  370. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  371. ASSERT_TRUE(it->second.supports_spdy.has_value());
  372. EXPECT_TRUE(*it->second.supports_spdy);
  373. ++it;
  374. EXPECT_EQ(spdy_server_mail, it->first.server);
  375. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  376. ASSERT_TRUE(it->second.supports_spdy.has_value());
  377. EXPECT_FALSE(*it->second.supports_spdy);
  378. // Verify photos server doesn't support SPDY and other servers support SPDY.
  379. EXPECT_FALSE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
  380. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_docs, NetworkIsolationKey()));
  381. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  382. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_photos, NetworkIsolationKey()));
  383. }
  384. TEST_F(HttpServerPropertiesTest, SupportsRequestPriority) {
  385. url::SchemeHostPort spdy_server_empty("https", std::string(), 443);
  386. EXPECT_FALSE(
  387. impl_.SupportsRequestPriority(spdy_server_empty, NetworkIsolationKey()));
  388. // Add www.google.com:443 as supporting SPDY.
  389. url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
  390. impl_.SetSupportsSpdy(spdy_server_google, NetworkIsolationKey(), true);
  391. EXPECT_TRUE(
  392. impl_.SupportsRequestPriority(spdy_server_google, NetworkIsolationKey()));
  393. // Add mail.google.com:443 as not supporting SPDY.
  394. url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
  395. EXPECT_FALSE(
  396. impl_.SupportsRequestPriority(spdy_server_mail, NetworkIsolationKey()));
  397. // Add docs.google.com:443 as supporting SPDY.
  398. url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
  399. impl_.SetSupportsSpdy(spdy_server_docs, NetworkIsolationKey(), true);
  400. EXPECT_TRUE(
  401. impl_.SupportsRequestPriority(spdy_server_docs, NetworkIsolationKey()));
  402. // Add www.youtube.com:443 as supporting QUIC.
  403. url::SchemeHostPort youtube_server("https", "www.youtube.com", 443);
  404. const AlternativeService alternative_service1(kProtoQUIC, "www.youtube.com",
  405. 443);
  406. SetAlternativeService(youtube_server, alternative_service1);
  407. EXPECT_TRUE(
  408. impl_.SupportsRequestPriority(youtube_server, NetworkIsolationKey()));
  409. // Add www.example.com:443 with two alternative services, one supporting QUIC.
  410. url::SchemeHostPort example_server("https", "www.example.com", 443);
  411. const AlternativeService alternative_service2(kProtoHTTP2, "", 443);
  412. SetAlternativeService(example_server, alternative_service2);
  413. SetAlternativeService(example_server, alternative_service1);
  414. EXPECT_TRUE(
  415. impl_.SupportsRequestPriority(example_server, NetworkIsolationKey()));
  416. // Verify all the entries are the same after additions.
  417. EXPECT_TRUE(
  418. impl_.SupportsRequestPriority(spdy_server_google, NetworkIsolationKey()));
  419. EXPECT_FALSE(
  420. impl_.SupportsRequestPriority(spdy_server_mail, NetworkIsolationKey()));
  421. EXPECT_TRUE(
  422. impl_.SupportsRequestPriority(spdy_server_docs, NetworkIsolationKey()));
  423. EXPECT_TRUE(
  424. impl_.SupportsRequestPriority(youtube_server, NetworkIsolationKey()));
  425. EXPECT_TRUE(
  426. impl_.SupportsRequestPriority(example_server, NetworkIsolationKey()));
  427. }
  428. TEST_F(HttpServerPropertiesTest, ClearSupportsSpdy) {
  429. // Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
  430. url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
  431. impl_.SetSupportsSpdy(spdy_server_google, NetworkIsolationKey(), true);
  432. url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
  433. impl_.SetSupportsSpdy(spdy_server_mail, NetworkIsolationKey(), true);
  434. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  435. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
  436. base::RunLoop run_loop;
  437. bool callback_invoked_ = false;
  438. impl_.Clear(base::BindOnce(
  439. [](bool* callback_invoked, base::OnceClosure quit_closure) {
  440. *callback_invoked = true;
  441. std::move(quit_closure).Run();
  442. },
  443. &callback_invoked_, run_loop.QuitClosure()));
  444. EXPECT_FALSE(
  445. impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  446. EXPECT_FALSE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
  447. // Callback should be run asynchronously.
  448. EXPECT_FALSE(callback_invoked_);
  449. run_loop.Run();
  450. EXPECT_TRUE(callback_invoked_);
  451. }
  452. TEST_F(HttpServerPropertiesTest, MRUOfServerInfoMap) {
  453. url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
  454. url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
  455. // Add www.google.com:443 as supporting SPDY.
  456. impl_.SetSupportsSpdy(spdy_server_google, NetworkIsolationKey(), true);
  457. ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
  458. auto it = impl_.server_info_map_for_testing().begin();
  459. ASSERT_EQ(spdy_server_google, it->first.server);
  460. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  461. // Add mail.google.com:443 as supporting SPDY. Verify mail.google.com:443 and
  462. // www.google.com:443 are in the list.
  463. impl_.SetSupportsSpdy(spdy_server_mail, NetworkIsolationKey(), true);
  464. ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
  465. it = impl_.server_info_map_for_testing().begin();
  466. ASSERT_EQ(spdy_server_mail, it->first.server);
  467. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  468. ++it;
  469. ASSERT_EQ(spdy_server_google, it->first.server);
  470. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  471. // Get www.google.com:443. It should become the most-recently-used server.
  472. EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
  473. ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
  474. it = impl_.server_info_map_for_testing().begin();
  475. ASSERT_EQ(spdy_server_google, it->first.server);
  476. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  477. ++it;
  478. ASSERT_EQ(spdy_server_mail, it->first.server);
  479. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  480. }
  481. typedef HttpServerPropertiesTest AlternateProtocolServerPropertiesTest;
  482. TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
  483. url::SchemeHostPort test_server("http", "foo", 80);
  484. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  485. AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  486. SetAlternativeService(test_server, alternative_service);
  487. const AlternativeServiceInfoVector alternative_service_info_vector =
  488. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  489. ASSERT_EQ(1u, alternative_service_info_vector.size());
  490. EXPECT_EQ(alternative_service,
  491. alternative_service_info_vector[0].alternative_service());
  492. impl_.Clear(base::OnceClosure());
  493. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  494. }
  495. TEST_F(AlternateProtocolServerPropertiesTest, ExcludeOrigin) {
  496. AlternativeServiceInfoVector alternative_service_info_vector;
  497. base::Time expiration = test_clock_.Now() + base::Days(1);
  498. // Same hostname, same port, TCP: should be ignored.
  499. AlternativeServiceInfo alternative_service_info1 =
  500. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  501. AlternativeService(kProtoHTTP2, "foo", 443), expiration);
  502. alternative_service_info_vector.push_back(alternative_service_info1);
  503. // Different hostname: GetAlternativeServiceInfos should return this one.
  504. AlternativeServiceInfo alternative_service_info2 =
  505. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  506. AlternativeService(kProtoHTTP2, "bar", 443), expiration);
  507. alternative_service_info_vector.push_back(alternative_service_info2);
  508. // Different port: GetAlternativeServiceInfos should return this one too.
  509. AlternativeServiceInfo alternative_service_info3 =
  510. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  511. AlternativeService(kProtoHTTP2, "foo", 80), expiration);
  512. alternative_service_info_vector.push_back(alternative_service_info3);
  513. // QUIC: GetAlternativeServices should return this one too.
  514. AlternativeServiceInfo alternative_service_info4 =
  515. AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
  516. AlternativeService(kProtoQUIC, "foo", 443), expiration,
  517. DefaultSupportedQuicVersions());
  518. alternative_service_info_vector.push_back(alternative_service_info4);
  519. url::SchemeHostPort test_server("https", "foo", 443);
  520. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  521. alternative_service_info_vector);
  522. const AlternativeServiceInfoVector alternative_service_info_vector2 =
  523. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  524. ASSERT_EQ(3u, alternative_service_info_vector2.size());
  525. EXPECT_EQ(alternative_service_info2, alternative_service_info_vector2[0]);
  526. EXPECT_EQ(alternative_service_info3, alternative_service_info_vector2[1]);
  527. EXPECT_EQ(alternative_service_info4, alternative_service_info_vector2[2]);
  528. }
  529. TEST_F(AlternateProtocolServerPropertiesTest, Set) {
  530. // |test_server1| has an alternative service, which will not be
  531. // affected by OnServerInfoLoadedForTesting(), because
  532. // |server_info_map| does not have an entry for
  533. // |test_server1|.
  534. url::SchemeHostPort test_server1("http", "foo1", 80);
  535. const AlternativeService alternative_service1(kProtoHTTP2, "bar1", 443);
  536. const base::Time now = test_clock_.Now();
  537. base::Time expiration1 = now + base::Days(1);
  538. // 1st entry in the memory.
  539. impl_.SetHttp2AlternativeService(test_server1, NetworkIsolationKey(),
  540. alternative_service1, expiration1);
  541. // |test_server2| has an alternative service, which will be
  542. // overwritten by OnServerInfoLoadedForTesting(), because
  543. // |server_info_map| has an entry for |test_server2|.
  544. AlternativeServiceInfoVector alternative_service_info_vector;
  545. const AlternativeService alternative_service2(kProtoHTTP2, "bar2", 443);
  546. base::Time expiration2 = now + base::Days(2);
  547. alternative_service_info_vector.push_back(
  548. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  549. alternative_service2, expiration2));
  550. url::SchemeHostPort test_server2("http", "foo2", 80);
  551. // 0th entry in the memory.
  552. impl_.SetAlternativeServices(test_server2, NetworkIsolationKey(),
  553. alternative_service_info_vector);
  554. // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
  555. std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
  556. std::make_unique<HttpServerProperties::ServerInfoMap>();
  557. const AlternativeService alternative_service3(kProtoHTTP2, "bar3", 123);
  558. base::Time expiration3 = now + base::Days(3);
  559. const AlternativeServiceInfo alternative_service_info1 =
  560. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  561. alternative_service3, expiration3);
  562. // Simulate updating data for 0th entry with data from Preferences.
  563. server_info_map->GetOrPut(CreateSimpleKey(test_server2))
  564. ->second.alternative_services =
  565. AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1);
  566. url::SchemeHostPort test_server3("http", "foo3", 80);
  567. const AlternativeService alternative_service4(kProtoHTTP2, "bar4", 1234);
  568. base::Time expiration4 = now + base::Days(4);
  569. const AlternativeServiceInfo alternative_service_info2 =
  570. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  571. alternative_service4, expiration4);
  572. // Add an old entry from Preferences, this will be added to end of recency
  573. // list.
  574. server_info_map->GetOrPut(CreateSimpleKey(test_server3))
  575. ->second.alternative_services =
  576. AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2);
  577. // MRU list will be test_server2, test_server1, test_server3.
  578. impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
  579. // Verify server_info_map.
  580. const HttpServerProperties::ServerInfoMap& map =
  581. impl_.server_info_map_for_testing();
  582. ASSERT_EQ(3u, map.size());
  583. auto map_it = map.begin();
  584. EXPECT_EQ(test_server2, map_it->first.server);
  585. EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
  586. ASSERT_TRUE(map_it->second.alternative_services.has_value());
  587. const AlternativeServiceInfoVector* service_info =
  588. &map_it->second.alternative_services.value();
  589. ASSERT_EQ(1u, service_info->size());
  590. EXPECT_EQ(alternative_service3, (*service_info)[0].alternative_service());
  591. EXPECT_EQ(expiration3, (*service_info)[0].expiration());
  592. ++map_it;
  593. EXPECT_EQ(test_server1, map_it->first.server);
  594. EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
  595. ASSERT_TRUE(map_it->second.alternative_services.has_value());
  596. service_info = &map_it->second.alternative_services.value();
  597. ASSERT_EQ(1u, service_info->size());
  598. EXPECT_EQ(alternative_service1, (*service_info)[0].alternative_service());
  599. EXPECT_EQ(expiration1, (*service_info)[0].expiration());
  600. ++map_it;
  601. EXPECT_EQ(map_it->first.server, test_server3);
  602. EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
  603. ASSERT_TRUE(map_it->second.alternative_services.has_value());
  604. service_info = &map_it->second.alternative_services.value();
  605. ASSERT_EQ(1u, service_info->size());
  606. EXPECT_EQ(alternative_service4, (*service_info)[0].alternative_service());
  607. EXPECT_EQ(expiration4, (*service_info)[0].expiration());
  608. }
  609. TEST_F(AlternateProtocolServerPropertiesTest, SetWebSockets) {
  610. // The https and wss servers should be treated as the same server, as should
  611. // the http and ws servers.
  612. url::SchemeHostPort https_server("https", "www.test.com", 443);
  613. url::SchemeHostPort wss_server("wss", "www.test.com", 443);
  614. url::SchemeHostPort http_server("http", "www.test.com", 443);
  615. url::SchemeHostPort ws_server("ws", "www.test.com", 443);
  616. AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
  617. EXPECT_EQ(
  618. 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  619. .size());
  620. EXPECT_EQ(0u,
  621. impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
  622. .size());
  623. EXPECT_EQ(0u,
  624. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  625. .size());
  626. EXPECT_EQ(0u,
  627. impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
  628. .size());
  629. SetAlternativeService(wss_server, alternative_service);
  630. EXPECT_EQ(
  631. 1u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  632. .size());
  633. EXPECT_EQ(1u,
  634. impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
  635. .size());
  636. EXPECT_EQ(0u,
  637. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  638. .size());
  639. EXPECT_EQ(0u,
  640. impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
  641. .size());
  642. SetAlternativeService(http_server, alternative_service);
  643. EXPECT_EQ(
  644. 1u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  645. .size());
  646. EXPECT_EQ(1u,
  647. impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
  648. .size());
  649. EXPECT_EQ(1u,
  650. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  651. .size());
  652. EXPECT_EQ(1u,
  653. impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
  654. .size());
  655. impl_.SetAlternativeServices(https_server, NetworkIsolationKey(),
  656. AlternativeServiceInfoVector());
  657. EXPECT_EQ(
  658. 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  659. .size());
  660. EXPECT_EQ(0u,
  661. impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
  662. .size());
  663. EXPECT_EQ(1u,
  664. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  665. .size());
  666. EXPECT_EQ(1u,
  667. impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
  668. .size());
  669. impl_.SetAlternativeServices(ws_server, NetworkIsolationKey(),
  670. AlternativeServiceInfoVector());
  671. EXPECT_EQ(
  672. 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  673. .size());
  674. EXPECT_EQ(0u,
  675. impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
  676. .size());
  677. EXPECT_EQ(0u,
  678. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  679. .size());
  680. EXPECT_EQ(0u,
  681. impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
  682. .size());
  683. }
  684. TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
  685. const url::SchemeHostPort kServer("https", "foo.test", 443);
  686. const AlternativeServiceInfoVector kAlternativeServices(
  687. {AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  688. AlternativeService(kProtoHTTP2, "foo", 443),
  689. base::Time::Now() + base::Days(1) /* expiration */)});
  690. EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
  691. .empty());
  692. EXPECT_TRUE(
  693. impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()).empty());
  694. // Without network isolation keys enabled for HttpServerProperties, passing in
  695. // a NetworkIsolationKey should have no effect on behavior.
  696. for (const auto& network_isolation_key_to_set :
  697. {NetworkIsolationKey(), network_isolation_key1_}) {
  698. impl_.SetAlternativeServices(kServer, network_isolation_key_to_set,
  699. kAlternativeServices);
  700. EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
  701. kServer, network_isolation_key1_));
  702. EXPECT_EQ(kAlternativeServices,
  703. impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()));
  704. impl_.SetAlternativeServices(kServer, network_isolation_key_to_set,
  705. AlternativeServiceInfoVector());
  706. EXPECT_TRUE(
  707. impl_.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
  708. .empty());
  709. EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
  710. .empty());
  711. }
  712. // Check that with network isolation keys enabled for HttpServerProperties,
  713. // the NetworkIsolationKey argument is respected.
  714. base::test::ScopedFeatureList feature_list;
  715. feature_list.InitAndEnableFeature(
  716. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  717. // Since HttpServerProperties caches the feature value, have to create a new
  718. // one.
  719. HttpServerProperties properties(nullptr /* pref_delegate */,
  720. nullptr /* net_log */, test_tick_clock_,
  721. &test_clock_);
  722. properties.SetAlternativeServices(kServer, network_isolation_key1_,
  723. kAlternativeServices);
  724. EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
  725. kServer, network_isolation_key1_));
  726. EXPECT_TRUE(
  727. properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
  728. .empty());
  729. properties.SetAlternativeServices(kServer, NetworkIsolationKey(),
  730. kAlternativeServices);
  731. EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
  732. kServer, network_isolation_key1_));
  733. EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
  734. kServer, NetworkIsolationKey()));
  735. properties.SetAlternativeServices(kServer, network_isolation_key1_,
  736. AlternativeServiceInfoVector());
  737. EXPECT_TRUE(
  738. properties.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
  739. .empty());
  740. EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
  741. kServer, NetworkIsolationKey()));
  742. properties.SetAlternativeServices(kServer, NetworkIsolationKey(),
  743. AlternativeServiceInfoVector());
  744. EXPECT_TRUE(
  745. properties.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
  746. .empty());
  747. EXPECT_TRUE(
  748. properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
  749. .empty());
  750. }
  751. // Regression test for https://crbug.com/504032:
  752. // OnServerInfoLoadedForTesting() should not crash if there is an
  753. // empty hostname is the mapping.
  754. TEST_F(AlternateProtocolServerPropertiesTest, SetWithEmptyHostname) {
  755. url::SchemeHostPort server("https", "foo", 443);
  756. const AlternativeService alternative_service_with_empty_hostname(kProtoHTTP2,
  757. "", 1234);
  758. const AlternativeService alternative_service_with_foo_hostname(kProtoHTTP2,
  759. "foo", 1234);
  760. SetAlternativeService(server, alternative_service_with_empty_hostname);
  761. impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname,
  762. NetworkIsolationKey());
  763. std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
  764. std::make_unique<HttpServerProperties::ServerInfoMap>();
  765. impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
  766. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(
  767. alternative_service_with_foo_hostname, NetworkIsolationKey()));
  768. const AlternativeServiceInfoVector alternative_service_info_vector =
  769. impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey());
  770. ASSERT_EQ(1u, alternative_service_info_vector.size());
  771. EXPECT_EQ(alternative_service_with_foo_hostname,
  772. alternative_service_info_vector[0].alternative_service());
  773. }
  774. // Regression test for https://crbug.com/516486:
  775. // GetAlternativeServiceInfos() should remove |server_info_map_|
  776. // elements with empty value.
  777. TEST_F(AlternateProtocolServerPropertiesTest, EmptyVector) {
  778. url::SchemeHostPort server("https", "foo", 443);
  779. const AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
  780. base::Time expiration = test_clock_.Now() - base::Days(1);
  781. const AlternativeServiceInfo alternative_service_info =
  782. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  783. alternative_service, expiration);
  784. std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
  785. std::make_unique<HttpServerProperties::ServerInfoMap>();
  786. server_info_map->GetOrPut(CreateSimpleKey(server))
  787. ->second.alternative_services = AlternativeServiceInfoVector(
  788. /*size=*/1, alternative_service_info);
  789. // Prepare |server_info_map_| with a single key that has a single
  790. // AlternativeServiceInfo with identical hostname and port.
  791. impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
  792. // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
  793. // |server_info_map_|, emptying the AlternativeServiceInfoVector
  794. // corresponding to |server|.
  795. ASSERT_TRUE(
  796. impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
  797. // GetAlternativeServiceInfos() should remove this key from
  798. // |server_info_map_|, and SetAlternativeServices() should not crash.
  799. impl_.SetAlternativeServices(
  800. server, NetworkIsolationKey(),
  801. AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
  802. // There should still be no alternative service assigned to |server|.
  803. ASSERT_TRUE(
  804. impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
  805. }
  806. // Regression test for https://crbug.com/516486 for the canonical host case.
  807. TEST_F(AlternateProtocolServerPropertiesTest, EmptyVectorForCanonical) {
  808. url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
  809. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  810. const AlternativeService alternative_service(kProtoHTTP2, "", 443);
  811. base::Time expiration = test_clock_.Now() - base::Days(1);
  812. const AlternativeServiceInfo alternative_service_info =
  813. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  814. alternative_service, expiration);
  815. std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
  816. std::make_unique<HttpServerProperties::ServerInfoMap>();
  817. server_info_map->GetOrPut(CreateSimpleKey(canonical_server))
  818. ->second.alternative_services =
  819. AlternativeServiceInfoVector(/*size=*/1, alternative_service_info);
  820. // Prepare |server_info_map_| with a single key that has a single
  821. // AlternativeServiceInfo with identical hostname and port.
  822. impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
  823. // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
  824. // |server_info_map_|, emptying the AlternativeServiceInfoVector
  825. // corresponding to |canonical_server|, even when looking up
  826. // alternative services for |server|.
  827. ASSERT_TRUE(
  828. impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
  829. // GetAlternativeServiceInfos() should remove this key from
  830. // |server_info_map_|, and SetAlternativeServices() should not crash.
  831. impl_.SetAlternativeServices(
  832. canonical_server, NetworkIsolationKey(),
  833. AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
  834. // There should still be no alternative service assigned to
  835. // |canonical_server|.
  836. ASSERT_TRUE(
  837. impl_.GetAlternativeServiceInfos(canonical_server, NetworkIsolationKey())
  838. .empty());
  839. }
  840. TEST_F(AlternateProtocolServerPropertiesTest, ClearServerWithCanonical) {
  841. url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
  842. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  843. const AlternativeService alternative_service(kProtoQUIC, "", 443);
  844. base::Time expiration = test_clock_.Now() + base::Days(1);
  845. const AlternativeServiceInfo alternative_service_info =
  846. AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
  847. alternative_service, expiration, DefaultSupportedQuicVersions());
  848. impl_.SetAlternativeServices(
  849. canonical_server, NetworkIsolationKey(),
  850. AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
  851. // Make sure the canonical service is returned for the other server.
  852. const AlternativeServiceInfoVector alternative_service_info_vector =
  853. impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey());
  854. ASSERT_EQ(1u, alternative_service_info_vector.size());
  855. EXPECT_EQ(kProtoQUIC,
  856. alternative_service_info_vector[0].alternative_service().protocol);
  857. EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
  858. // Now clear the alternatives for the other server and make sure it stays
  859. // cleared.
  860. // GetAlternativeServices() should remove this key from
  861. // |server_info_map_|, and SetAlternativeServices() should not crash.
  862. impl_.SetAlternativeServices(server, NetworkIsolationKey(),
  863. AlternativeServiceInfoVector());
  864. ASSERT_TRUE(
  865. impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
  866. }
  867. TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServiceInfos) {
  868. url::SchemeHostPort test_server1("http", "foo1", 80);
  869. const AlternativeService alternative_service1(kProtoHTTP2, "foo1", 443);
  870. SetAlternativeService(test_server1, alternative_service1);
  871. url::SchemeHostPort test_server2("http", "foo2", 80);
  872. const AlternativeService alternative_service2(kProtoHTTP2, "foo2", 1234);
  873. SetAlternativeService(test_server2, alternative_service2);
  874. const HttpServerProperties::ServerInfoMap& map =
  875. impl_.server_info_map_for_testing();
  876. auto it = map.begin();
  877. EXPECT_EQ(test_server2, it->first.server);
  878. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  879. ASSERT_TRUE(it->second.alternative_services.has_value());
  880. ASSERT_EQ(1u, it->second.alternative_services->size());
  881. EXPECT_EQ(alternative_service2,
  882. it->second.alternative_services.value()[0].alternative_service());
  883. const AlternativeServiceInfoVector alternative_service_info_vector =
  884. impl_.GetAlternativeServiceInfos(test_server1, NetworkIsolationKey());
  885. ASSERT_EQ(1u, alternative_service_info_vector.size());
  886. EXPECT_EQ(alternative_service1,
  887. alternative_service_info_vector[0].alternative_service());
  888. // GetAlternativeServices should reorder the AlternateProtocol map.
  889. it = map.begin();
  890. EXPECT_EQ(test_server1, it->first.server);
  891. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  892. ASSERT_TRUE(it->second.alternative_services.has_value());
  893. ASSERT_EQ(1u, it->second.alternative_services->size());
  894. EXPECT_EQ(alternative_service1,
  895. it->second.alternative_services.value()[0].alternative_service());
  896. }
  897. TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
  898. url::SchemeHostPort test_server("http", "foo", 80);
  899. const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
  900. SetAlternativeService(test_server, alternative_service1);
  901. AlternativeServiceInfoVector alternative_service_info_vector =
  902. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  903. ASSERT_EQ(1u, alternative_service_info_vector.size());
  904. EXPECT_EQ(alternative_service1,
  905. alternative_service_info_vector[0].alternative_service());
  906. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
  907. NetworkIsolationKey()));
  908. // GetAlternativeServiceInfos should return the broken alternative service.
  909. impl_.MarkAlternativeServiceBroken(alternative_service1,
  910. NetworkIsolationKey());
  911. alternative_service_info_vector =
  912. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  913. ASSERT_EQ(1u, alternative_service_info_vector.size());
  914. EXPECT_EQ(alternative_service1,
  915. alternative_service_info_vector[0].alternative_service());
  916. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  917. NetworkIsolationKey()));
  918. // SetAlternativeServices should add a broken alternative service to the map.
  919. AlternativeServiceInfoVector alternative_service_info_vector2;
  920. base::Time expiration = test_clock_.Now() + base::Days(1);
  921. alternative_service_info_vector2.push_back(
  922. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  923. alternative_service1, expiration));
  924. const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
  925. alternative_service_info_vector2.push_back(
  926. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  927. alternative_service2, expiration));
  928. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  929. alternative_service_info_vector2);
  930. alternative_service_info_vector =
  931. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  932. ASSERT_EQ(2u, alternative_service_info_vector.size());
  933. EXPECT_EQ(alternative_service1,
  934. alternative_service_info_vector[0].alternative_service());
  935. EXPECT_EQ(alternative_service2,
  936. alternative_service_info_vector[1].alternative_service());
  937. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  938. NetworkIsolationKey()));
  939. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
  940. NetworkIsolationKey()));
  941. // SetAlternativeService should add a broken alternative service to the map.
  942. SetAlternativeService(test_server, alternative_service1);
  943. alternative_service_info_vector =
  944. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  945. ASSERT_EQ(1u, alternative_service_info_vector.size());
  946. EXPECT_EQ(alternative_service1,
  947. alternative_service_info_vector[0].alternative_service());
  948. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  949. NetworkIsolationKey()));
  950. }
  951. TEST_F(AlternateProtocolServerPropertiesTest,
  952. SetBrokenUntilDefaultNetworkChanges) {
  953. url::SchemeHostPort test_server("http", "foo", 80);
  954. const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
  955. SetAlternativeService(test_server, alternative_service1);
  956. AlternativeServiceInfoVector alternative_service_info_vector =
  957. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  958. ASSERT_EQ(1u, alternative_service_info_vector.size());
  959. EXPECT_EQ(alternative_service1,
  960. alternative_service_info_vector[0].alternative_service());
  961. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
  962. NetworkIsolationKey()));
  963. // Mark the alternative service as broken until the default network changes.
  964. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  965. alternative_service1, NetworkIsolationKey());
  966. // The alternative service should be persisted and marked as broken.
  967. alternative_service_info_vector =
  968. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  969. ASSERT_EQ(1u, alternative_service_info_vector.size());
  970. EXPECT_EQ(alternative_service1,
  971. alternative_service_info_vector[0].alternative_service());
  972. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  973. NetworkIsolationKey()));
  974. // SetAlternativeServices should add a broken alternative service to the map.
  975. AlternativeServiceInfoVector alternative_service_info_vector2;
  976. base::Time expiration = test_clock_.Now() + base::Days(1);
  977. alternative_service_info_vector2.push_back(
  978. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  979. alternative_service1, expiration));
  980. const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
  981. alternative_service_info_vector2.push_back(
  982. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  983. alternative_service2, expiration));
  984. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  985. alternative_service_info_vector2);
  986. alternative_service_info_vector =
  987. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  988. ASSERT_EQ(2u, alternative_service_info_vector.size());
  989. EXPECT_EQ(alternative_service1,
  990. alternative_service_info_vector[0].alternative_service());
  991. EXPECT_EQ(alternative_service2,
  992. alternative_service_info_vector[1].alternative_service());
  993. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  994. NetworkIsolationKey()));
  995. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
  996. NetworkIsolationKey()));
  997. // SetAlternativeService should add a broken alternative service to the map.
  998. SetAlternativeService(test_server, alternative_service1);
  999. alternative_service_info_vector =
  1000. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  1001. ASSERT_EQ(1u, alternative_service_info_vector.size());
  1002. EXPECT_EQ(alternative_service1,
  1003. alternative_service_info_vector[0].alternative_service());
  1004. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  1005. NetworkIsolationKey()));
  1006. }
  1007. TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
  1008. AlternativeServiceInfoVector alternative_service_info_vector;
  1009. base::Time now = test_clock_.Now();
  1010. base::TimeDelta one_day = base::Days(1);
  1011. // First alternative service expired one day ago, should not be returned by
  1012. // GetAlternativeServiceInfos().
  1013. const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
  1014. alternative_service_info_vector.push_back(
  1015. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1016. alternative_service1, now - one_day));
  1017. // Second alterrnative service will expire one day from now, should be
  1018. // returned by GetAlternativeSerices().
  1019. const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
  1020. alternative_service_info_vector.push_back(
  1021. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1022. alternative_service2, now + one_day));
  1023. url::SchemeHostPort test_server("http", "foo", 80);
  1024. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  1025. alternative_service_info_vector);
  1026. AlternativeServiceInfoVector alternative_service_info_vector2 =
  1027. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  1028. ASSERT_EQ(1u, alternative_service_info_vector2.size());
  1029. EXPECT_EQ(alternative_service2,
  1030. alternative_service_info_vector2[0].alternative_service());
  1031. }
  1032. TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) {
  1033. AlternativeServiceInfoVector alternative_service_info_vector;
  1034. base::Time now = test_clock_.Now();
  1035. base::TimeDelta one_day = base::Days(1);
  1036. // First alternative service expired one day ago, should not be returned by
  1037. // GetAlternativeServiceInfos().
  1038. const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
  1039. alternative_service_info_vector.push_back(
  1040. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1041. alternative_service1, now - one_day));
  1042. // Second alterrnative service will expire one day from now, should be
  1043. // returned by GetAlternativeSerices().
  1044. const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
  1045. alternative_service_info_vector.push_back(
  1046. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1047. alternative_service2, now + one_day));
  1048. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1049. impl_.SetAlternativeServices(canonical_server, NetworkIsolationKey(),
  1050. alternative_service_info_vector);
  1051. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1052. AlternativeServiceInfoVector alternative_service_info_vector2 =
  1053. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  1054. ASSERT_EQ(1u, alternative_service_info_vector2.size());
  1055. EXPECT_EQ(alternative_service2,
  1056. alternative_service_info_vector2[0].alternative_service());
  1057. }
  1058. TEST_F(AlternateProtocolServerPropertiesTest, AlternativeServiceWithScheme) {
  1059. AlternativeServiceInfoVector alternative_service_info_vector;
  1060. const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
  1061. base::Time expiration = test_clock_.Now() + base::Days(1);
  1062. alternative_service_info_vector.push_back(
  1063. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1064. alternative_service1, expiration));
  1065. const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
  1066. alternative_service_info_vector.push_back(
  1067. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1068. alternative_service2, expiration));
  1069. // Set Alt-Svc list for |http_server|.
  1070. url::SchemeHostPort http_server("http", "foo", 80);
  1071. impl_.SetAlternativeServices(http_server, NetworkIsolationKey(),
  1072. alternative_service_info_vector);
  1073. const net::HttpServerProperties::ServerInfoMap& map =
  1074. impl_.server_info_map_for_testing();
  1075. auto it = map.begin();
  1076. EXPECT_EQ(http_server, it->first.server);
  1077. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  1078. ASSERT_TRUE(it->second.alternative_services.has_value());
  1079. ASSERT_EQ(2u, it->second.alternative_services->size());
  1080. EXPECT_EQ(alternative_service1,
  1081. it->second.alternative_services.value()[0].alternative_service());
  1082. EXPECT_EQ(alternative_service2,
  1083. it->second.alternative_services.value()[1].alternative_service());
  1084. // Check Alt-Svc list should not be set for |https_server|.
  1085. url::SchemeHostPort https_server("https", "foo", 80);
  1086. EXPECT_EQ(
  1087. 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  1088. .size());
  1089. // Set Alt-Svc list for |https_server|.
  1090. impl_.SetAlternativeServices(https_server, NetworkIsolationKey(),
  1091. alternative_service_info_vector);
  1092. EXPECT_EQ(
  1093. 2u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  1094. .size());
  1095. EXPECT_EQ(2u,
  1096. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  1097. .size());
  1098. // Clear Alt-Svc list for |http_server|.
  1099. impl_.SetAlternativeServices(http_server, NetworkIsolationKey(),
  1100. AlternativeServiceInfoVector());
  1101. EXPECT_EQ(0u,
  1102. impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
  1103. .size());
  1104. EXPECT_EQ(
  1105. 2u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
  1106. .size());
  1107. }
  1108. TEST_F(AlternateProtocolServerPropertiesTest, ClearAlternativeServices) {
  1109. AlternativeServiceInfoVector alternative_service_info_vector;
  1110. const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
  1111. base::Time expiration = test_clock_.Now() + base::Days(1);
  1112. alternative_service_info_vector.push_back(
  1113. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1114. alternative_service1, expiration));
  1115. const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
  1116. alternative_service_info_vector.push_back(
  1117. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1118. alternative_service2, expiration));
  1119. url::SchemeHostPort test_server("http", "foo", 80);
  1120. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  1121. alternative_service_info_vector);
  1122. const net::HttpServerProperties::ServerInfoMap& map =
  1123. impl_.server_info_map_for_testing();
  1124. auto it = map.begin();
  1125. EXPECT_EQ(test_server, it->first.server);
  1126. EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
  1127. ASSERT_TRUE(it->second.alternative_services.has_value());
  1128. ASSERT_EQ(2u, it->second.alternative_services->size());
  1129. EXPECT_EQ(alternative_service1,
  1130. it->second.alternative_services.value()[0].alternative_service());
  1131. EXPECT_EQ(alternative_service2,
  1132. it->second.alternative_services.value()[1].alternative_service());
  1133. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  1134. AlternativeServiceInfoVector());
  1135. EXPECT_TRUE(map.empty());
  1136. }
  1137. // A broken alternative service in the mapping carries meaningful information,
  1138. // therefore it should not be ignored by SetAlternativeService(). In
  1139. // particular, an alternative service mapped to an origin shadows alternative
  1140. // services of canonical hosts.
  1141. TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
  1142. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1143. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1144. AlternativeService canonical_alternative_service(kProtoQUIC,
  1145. "bar.c.youtube.com", 1234);
  1146. SetAlternativeService(canonical_server, canonical_alternative_service);
  1147. AlternativeServiceInfoVector alternative_service_info_vector =
  1148. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  1149. ASSERT_EQ(1u, alternative_service_info_vector.size());
  1150. EXPECT_EQ(canonical_alternative_service,
  1151. alternative_service_info_vector[0].alternative_service());
  1152. const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443);
  1153. impl_.MarkAlternativeServiceBroken(broken_alternative_service,
  1154. NetworkIsolationKey());
  1155. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
  1156. NetworkIsolationKey()));
  1157. SetAlternativeService(test_server, broken_alternative_service);
  1158. alternative_service_info_vector =
  1159. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  1160. ASSERT_EQ(1u, alternative_service_info_vector.size());
  1161. EXPECT_EQ(broken_alternative_service,
  1162. alternative_service_info_vector[0].alternative_service());
  1163. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
  1164. NetworkIsolationKey()));
  1165. }
  1166. TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
  1167. url::SchemeHostPort test_server("http", "foo", 80);
  1168. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1169. SetAlternativeService(test_server, alternative_service);
  1170. impl_.MarkAlternativeServiceBroken(alternative_service,
  1171. NetworkIsolationKey());
  1172. ASSERT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1173. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1174. NetworkIsolationKey()));
  1175. // SetAlternativeServices should leave a broken alternative service marked
  1176. // as such.
  1177. impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
  1178. AlternativeServiceInfoVector());
  1179. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1180. NetworkIsolationKey()));
  1181. }
  1182. TEST_F(AlternateProtocolServerPropertiesTest,
  1183. MarkBrokenWithNetworkIsolationKey) {
  1184. url::SchemeHostPort server("http", "foo", 80);
  1185. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1186. const base::Time expiration = test_clock_.Now() + base::Days(1);
  1187. // Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
  1188. // should be ignored.
  1189. impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
  1190. alternative_service, expiration);
  1191. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1192. network_isolation_key1_));
  1193. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1194. alternative_service, network_isolation_key1_));
  1195. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1196. network_isolation_key2_));
  1197. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1198. alternative_service, network_isolation_key2_));
  1199. impl_.MarkAlternativeServiceBroken(alternative_service,
  1200. network_isolation_key1_);
  1201. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1202. network_isolation_key1_));
  1203. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
  1204. alternative_service, network_isolation_key1_));
  1205. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1206. network_isolation_key2_));
  1207. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
  1208. alternative_service, network_isolation_key2_));
  1209. impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
  1210. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1211. network_isolation_key1_));
  1212. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1213. alternative_service, network_isolation_key1_));
  1214. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1215. network_isolation_key2_));
  1216. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1217. alternative_service, network_isolation_key2_));
  1218. base::test::ScopedFeatureList feature_list;
  1219. feature_list.InitAndEnableFeature(
  1220. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  1221. // Since HttpServerProperties caches the feature value, have to create a new
  1222. // one.
  1223. HttpServerProperties properties(nullptr /* pref_delegate */,
  1224. nullptr /* net_log */, test_tick_clock_,
  1225. &test_clock_);
  1226. properties.SetHttp2AlternativeService(server, network_isolation_key1_,
  1227. alternative_service, expiration);
  1228. properties.SetHttp2AlternativeService(server, network_isolation_key2_,
  1229. alternative_service, expiration);
  1230. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1231. network_isolation_key1_));
  1232. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1233. alternative_service, network_isolation_key1_));
  1234. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1235. network_isolation_key2_));
  1236. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1237. alternative_service, network_isolation_key2_));
  1238. properties.MarkAlternativeServiceBroken(alternative_service,
  1239. network_isolation_key1_);
  1240. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1241. network_isolation_key1_));
  1242. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1243. alternative_service, network_isolation_key1_));
  1244. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1245. network_isolation_key2_));
  1246. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1247. alternative_service, network_isolation_key2_));
  1248. properties.MarkAlternativeServiceBroken(alternative_service,
  1249. network_isolation_key2_);
  1250. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1251. network_isolation_key1_));
  1252. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1253. alternative_service, network_isolation_key1_));
  1254. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1255. network_isolation_key2_));
  1256. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1257. alternative_service, network_isolation_key2_));
  1258. properties.ConfirmAlternativeService(alternative_service,
  1259. network_isolation_key1_);
  1260. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1261. network_isolation_key1_));
  1262. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1263. alternative_service, network_isolation_key1_));
  1264. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1265. network_isolation_key2_));
  1266. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1267. alternative_service, network_isolation_key2_));
  1268. properties.ConfirmAlternativeService(alternative_service,
  1269. network_isolation_key2_);
  1270. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1271. network_isolation_key1_));
  1272. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1273. alternative_service, network_isolation_key1_));
  1274. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1275. network_isolation_key2_));
  1276. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1277. alternative_service, network_isolation_key2_));
  1278. }
  1279. TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
  1280. url::SchemeHostPort server("http", "foo", 80);
  1281. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1282. SetAlternativeService(server, alternative_service);
  1283. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1284. NetworkIsolationKey()));
  1285. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1286. alternative_service, NetworkIsolationKey()));
  1287. impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
  1288. NetworkIsolationKey());
  1289. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1290. NetworkIsolationKey()));
  1291. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1292. NetworkIsolationKey()));
  1293. impl_.ConfirmAlternativeService(alternative_service, NetworkIsolationKey());
  1294. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1295. NetworkIsolationKey()));
  1296. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1297. alternative_service, NetworkIsolationKey()));
  1298. }
  1299. TEST_F(AlternateProtocolServerPropertiesTest,
  1300. MarkRecentlyBrokenWithNetworkIsolationKey) {
  1301. url::SchemeHostPort server("http", "foo", 80);
  1302. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1303. const base::Time expiration = test_clock_.Now() + base::Days(1);
  1304. // Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
  1305. // should be ignored.
  1306. impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
  1307. alternative_service, expiration);
  1308. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1309. network_isolation_key1_));
  1310. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1311. alternative_service, network_isolation_key1_));
  1312. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1313. network_isolation_key2_));
  1314. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1315. alternative_service, network_isolation_key2_));
  1316. impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
  1317. network_isolation_key1_);
  1318. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1319. network_isolation_key1_));
  1320. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
  1321. alternative_service, network_isolation_key1_));
  1322. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1323. network_isolation_key2_));
  1324. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
  1325. alternative_service, network_isolation_key2_));
  1326. impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
  1327. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1328. network_isolation_key1_));
  1329. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1330. alternative_service, network_isolation_key1_));
  1331. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1332. network_isolation_key2_));
  1333. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1334. alternative_service, network_isolation_key2_));
  1335. base::test::ScopedFeatureList feature_list;
  1336. feature_list.InitAndEnableFeature(
  1337. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  1338. // Since HttpServerProperties caches the feature value, have to create a new
  1339. // one.
  1340. HttpServerProperties properties(nullptr /* pref_delegate */,
  1341. nullptr /* net_log */, test_tick_clock_,
  1342. &test_clock_);
  1343. properties.SetHttp2AlternativeService(server, network_isolation_key1_,
  1344. alternative_service, expiration);
  1345. properties.SetHttp2AlternativeService(server, network_isolation_key2_,
  1346. alternative_service, expiration);
  1347. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1348. network_isolation_key1_));
  1349. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1350. alternative_service, network_isolation_key1_));
  1351. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1352. network_isolation_key2_));
  1353. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1354. alternative_service, network_isolation_key2_));
  1355. properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
  1356. network_isolation_key1_);
  1357. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1358. network_isolation_key1_));
  1359. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1360. alternative_service, network_isolation_key1_));
  1361. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1362. network_isolation_key2_));
  1363. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1364. alternative_service, network_isolation_key2_));
  1365. properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
  1366. network_isolation_key2_);
  1367. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1368. network_isolation_key1_));
  1369. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1370. alternative_service, network_isolation_key1_));
  1371. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1372. network_isolation_key2_));
  1373. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1374. alternative_service, network_isolation_key2_));
  1375. properties.ConfirmAlternativeService(alternative_service,
  1376. network_isolation_key1_);
  1377. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1378. network_isolation_key1_));
  1379. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1380. alternative_service, network_isolation_key1_));
  1381. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1382. network_isolation_key2_));
  1383. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1384. alternative_service, network_isolation_key2_));
  1385. properties.ConfirmAlternativeService(alternative_service,
  1386. network_isolation_key2_);
  1387. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1388. network_isolation_key1_));
  1389. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1390. alternative_service, network_isolation_key1_));
  1391. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1392. network_isolation_key2_));
  1393. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1394. alternative_service, network_isolation_key2_));
  1395. }
  1396. TEST_F(AlternateProtocolServerPropertiesTest,
  1397. MarkBrokenUntilDefaultNetworkChanges) {
  1398. url::SchemeHostPort server("http", "foo", 80);
  1399. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1400. SetAlternativeService(server, alternative_service);
  1401. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1402. NetworkIsolationKey()));
  1403. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1404. alternative_service, NetworkIsolationKey()));
  1405. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1406. alternative_service, NetworkIsolationKey());
  1407. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1408. NetworkIsolationKey()));
  1409. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1410. NetworkIsolationKey()));
  1411. impl_.ConfirmAlternativeService(alternative_service, NetworkIsolationKey());
  1412. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1413. NetworkIsolationKey()));
  1414. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1415. alternative_service, NetworkIsolationKey()));
  1416. }
  1417. TEST_F(AlternateProtocolServerPropertiesTest,
  1418. MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey) {
  1419. url::SchemeHostPort server("http", "foo", 80);
  1420. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1421. const base::Time expiration = test_clock_.Now() + base::Days(1);
  1422. // Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
  1423. // should be ignored.
  1424. impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
  1425. alternative_service, expiration);
  1426. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1427. network_isolation_key1_));
  1428. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1429. alternative_service, network_isolation_key1_));
  1430. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1431. network_isolation_key2_));
  1432. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1433. alternative_service, network_isolation_key2_));
  1434. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1435. alternative_service, network_isolation_key1_);
  1436. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1437. network_isolation_key1_));
  1438. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
  1439. alternative_service, network_isolation_key1_));
  1440. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1441. network_isolation_key2_));
  1442. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
  1443. alternative_service, network_isolation_key2_));
  1444. impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
  1445. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1446. network_isolation_key1_));
  1447. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1448. alternative_service, network_isolation_key1_));
  1449. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1450. network_isolation_key2_));
  1451. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1452. alternative_service, network_isolation_key2_));
  1453. base::test::ScopedFeatureList feature_list;
  1454. feature_list.InitAndEnableFeature(
  1455. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  1456. // Since HttpServerProperties caches the feature value, have to create a new
  1457. // one.
  1458. HttpServerProperties properties(nullptr /* pref_delegate */,
  1459. nullptr /* net_log */, test_tick_clock_,
  1460. &test_clock_);
  1461. properties.SetHttp2AlternativeService(server, network_isolation_key1_,
  1462. alternative_service, expiration);
  1463. properties.SetHttp2AlternativeService(server, network_isolation_key2_,
  1464. alternative_service, expiration);
  1465. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1466. network_isolation_key1_));
  1467. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1468. alternative_service, network_isolation_key1_));
  1469. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1470. network_isolation_key2_));
  1471. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1472. alternative_service, network_isolation_key2_));
  1473. properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1474. alternative_service, network_isolation_key1_);
  1475. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1476. network_isolation_key1_));
  1477. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1478. alternative_service, network_isolation_key1_));
  1479. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1480. network_isolation_key2_));
  1481. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1482. alternative_service, network_isolation_key2_));
  1483. properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1484. alternative_service, network_isolation_key2_);
  1485. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1486. network_isolation_key1_));
  1487. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1488. alternative_service, network_isolation_key1_));
  1489. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1490. network_isolation_key2_));
  1491. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1492. alternative_service, network_isolation_key2_));
  1493. properties.ConfirmAlternativeService(alternative_service,
  1494. network_isolation_key1_);
  1495. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1496. network_isolation_key1_));
  1497. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1498. alternative_service, network_isolation_key1_));
  1499. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1500. network_isolation_key2_));
  1501. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1502. alternative_service, network_isolation_key2_));
  1503. properties.ConfirmAlternativeService(alternative_service,
  1504. network_isolation_key2_);
  1505. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1506. network_isolation_key1_));
  1507. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1508. alternative_service, network_isolation_key1_));
  1509. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1510. network_isolation_key2_));
  1511. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1512. alternative_service, network_isolation_key2_));
  1513. }
  1514. TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
  1515. url::SchemeHostPort server("http", "foo", 80);
  1516. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1517. SetAlternativeService(server, alternative_service);
  1518. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1519. NetworkIsolationKey()));
  1520. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1521. alternative_service, NetworkIsolationKey()));
  1522. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1523. alternative_service, NetworkIsolationKey());
  1524. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1525. NetworkIsolationKey()));
  1526. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1527. NetworkIsolationKey()));
  1528. // Default network change clears alt svc broken until default network changes.
  1529. impl_.OnDefaultNetworkChanged();
  1530. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1531. NetworkIsolationKey()));
  1532. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1533. alternative_service, NetworkIsolationKey()));
  1534. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1535. alternative_service, NetworkIsolationKey());
  1536. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1537. NetworkIsolationKey()));
  1538. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1539. NetworkIsolationKey()));
  1540. impl_.MarkAlternativeServiceBroken(alternative_service,
  1541. NetworkIsolationKey());
  1542. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1543. NetworkIsolationKey()));
  1544. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1545. NetworkIsolationKey()));
  1546. // Default network change doesn't affect alt svc that was simply marked broken
  1547. // most recently.
  1548. impl_.OnDefaultNetworkChanged();
  1549. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1550. NetworkIsolationKey()));
  1551. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1552. NetworkIsolationKey()));
  1553. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1554. alternative_service, NetworkIsolationKey());
  1555. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1556. NetworkIsolationKey()));
  1557. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1558. NetworkIsolationKey()));
  1559. // Default network change clears alt svc that was marked broken until default
  1560. // network change most recently even if the alt svc was initially marked
  1561. // broken.
  1562. impl_.OnDefaultNetworkChanged();
  1563. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1564. NetworkIsolationKey()));
  1565. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1566. alternative_service, NetworkIsolationKey()));
  1567. }
  1568. TEST_F(AlternateProtocolServerPropertiesTest,
  1569. OnDefaultNetworkChangedWithNetworkIsolationKey) {
  1570. url::SchemeHostPort server("http", "foo", 80);
  1571. const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
  1572. base::test::ScopedFeatureList feature_list;
  1573. feature_list.InitAndEnableFeature(
  1574. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  1575. // Since HttpServerProperties caches the feature value, have to create a new
  1576. // one.
  1577. HttpServerProperties properties(nullptr /* pref_delegate */,
  1578. nullptr /* net_log */, test_tick_clock_,
  1579. &test_clock_);
  1580. const base::Time expiration = test_clock_.Now() + base::Days(1);
  1581. properties.SetHttp2AlternativeService(server, network_isolation_key1_,
  1582. alternative_service, expiration);
  1583. properties.SetHttp2AlternativeService(server, network_isolation_key2_,
  1584. alternative_service, expiration);
  1585. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1586. network_isolation_key1_));
  1587. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1588. alternative_service, network_isolation_key1_));
  1589. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1590. network_isolation_key2_));
  1591. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1592. alternative_service, network_isolation_key2_));
  1593. properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1594. alternative_service, network_isolation_key1_);
  1595. properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1596. alternative_service, network_isolation_key2_);
  1597. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1598. network_isolation_key1_));
  1599. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1600. alternative_service, network_isolation_key1_));
  1601. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1602. network_isolation_key2_));
  1603. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1604. alternative_service, network_isolation_key2_));
  1605. // Default network change clears alt svc broken until default network changes.
  1606. properties.OnDefaultNetworkChanged();
  1607. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1608. network_isolation_key1_));
  1609. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1610. alternative_service, network_isolation_key1_));
  1611. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1612. network_isolation_key2_));
  1613. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1614. alternative_service, network_isolation_key2_));
  1615. }
  1616. TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
  1617. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1618. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1619. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1620. EXPECT_FALSE(HasAlternativeService(canonical_server, NetworkIsolationKey()));
  1621. AlternativeServiceInfoVector alternative_service_info_vector;
  1622. const AlternativeService canonical_alternative_service1(
  1623. kProtoQUIC, "bar.c.youtube.com", 1234);
  1624. base::Time expiration = test_clock_.Now() + base::Days(1);
  1625. alternative_service_info_vector.push_back(
  1626. AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
  1627. canonical_alternative_service1, expiration,
  1628. DefaultSupportedQuicVersions()));
  1629. const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
  1630. alternative_service_info_vector.push_back(
  1631. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1632. canonical_alternative_service2, expiration));
  1633. impl_.SetAlternativeServices(canonical_server, NetworkIsolationKey(),
  1634. alternative_service_info_vector);
  1635. // Since |test_server| does not have an alternative service itself,
  1636. // GetAlternativeServiceInfos should return those of |canonical_server|.
  1637. AlternativeServiceInfoVector alternative_service_info_vector2 =
  1638. impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
  1639. ASSERT_EQ(2u, alternative_service_info_vector2.size());
  1640. EXPECT_EQ(canonical_alternative_service1,
  1641. alternative_service_info_vector2[0].alternative_service());
  1642. // Since |canonical_alternative_service2| has an empty host,
  1643. // GetAlternativeServiceInfos should substitute the hostname of its |origin|
  1644. // argument.
  1645. EXPECT_EQ(test_server.host(),
  1646. alternative_service_info_vector2[1].alternative_service().host);
  1647. EXPECT_EQ(canonical_alternative_service2.protocol,
  1648. alternative_service_info_vector2[1].alternative_service().protocol);
  1649. EXPECT_EQ(canonical_alternative_service2.port,
  1650. alternative_service_info_vector2[1].alternative_service().port);
  1651. // Verify the canonical suffix.
  1652. EXPECT_EQ(".c.youtube.com",
  1653. *impl_.GetCanonicalSuffixForTesting(test_server.host()));
  1654. EXPECT_EQ(".c.youtube.com",
  1655. *impl_.GetCanonicalSuffixForTesting(canonical_server.host()));
  1656. }
  1657. TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
  1658. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1659. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1660. AlternativeService canonical_alternative_service(kProtoQUIC,
  1661. "bar.c.youtube.com", 1234);
  1662. SetAlternativeService(canonical_server, canonical_alternative_service);
  1663. impl_.SetAlternativeServices(canonical_server, NetworkIsolationKey(),
  1664. AlternativeServiceInfoVector());
  1665. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1666. }
  1667. TEST_F(AlternateProtocolServerPropertiesTest,
  1668. CanonicalWithNetworkIsolationKey) {
  1669. base::test::ScopedFeatureList feature_list;
  1670. feature_list.InitAndEnableFeature(
  1671. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  1672. // Since HttpServerProperties caches the feature value, have to create a new
  1673. // one.
  1674. HttpServerProperties properties(nullptr /* pref_delegate */,
  1675. nullptr /* net_log */, test_tick_clock_,
  1676. &test_clock_);
  1677. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1678. EXPECT_FALSE(HasAlternativeService(test_server, network_isolation_key1_));
  1679. url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443);
  1680. EXPECT_FALSE(
  1681. HasAlternativeService(canonical_server1, network_isolation_key1_));
  1682. AlternativeServiceInfoVector alternative_service_info_vector;
  1683. const AlternativeService canonical_alternative_service1(
  1684. kProtoQUIC, "bar.c.youtube.com", 1234);
  1685. base::Time expiration = test_clock_.Now() + base::Days(1);
  1686. alternative_service_info_vector.push_back(
  1687. AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
  1688. canonical_alternative_service1, expiration,
  1689. DefaultSupportedQuicVersions()));
  1690. const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
  1691. alternative_service_info_vector.push_back(
  1692. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  1693. canonical_alternative_service2, expiration));
  1694. properties.SetAlternativeServices(canonical_server1, network_isolation_key1_,
  1695. alternative_service_info_vector);
  1696. // Since |test_server| does not have an alternative service itself,
  1697. // GetAlternativeServiceInfos should return those of |canonical_server|.
  1698. AlternativeServiceInfoVector alternative_service_info_vector2 =
  1699. properties.GetAlternativeServiceInfos(test_server,
  1700. network_isolation_key1_);
  1701. ASSERT_EQ(2u, alternative_service_info_vector2.size());
  1702. EXPECT_EQ(canonical_alternative_service1,
  1703. alternative_service_info_vector2[0].alternative_service());
  1704. // Canonical information should not be visible for other NetworkIsolationKeys.
  1705. EXPECT_TRUE(
  1706. properties
  1707. .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
  1708. .empty());
  1709. EXPECT_TRUE(
  1710. properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
  1711. .empty());
  1712. // Now add an alternative service entry for network_isolation_key2_ for a
  1713. // different server and different NetworkIsolationKey, but with the same
  1714. // canonical suffix.
  1715. url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443);
  1716. properties.SetAlternativeServices(canonical_server2, network_isolation_key2_,
  1717. {alternative_service_info_vector[0]});
  1718. // The canonical server information should reachable, and different, for both
  1719. // NetworkIsolationKeys.
  1720. EXPECT_EQ(
  1721. 1u, properties
  1722. .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
  1723. .size());
  1724. EXPECT_EQ(
  1725. 2u, properties
  1726. .GetAlternativeServiceInfos(test_server, network_isolation_key1_)
  1727. .size());
  1728. EXPECT_TRUE(
  1729. properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
  1730. .empty());
  1731. // Clearing the alternate service state of network_isolation_key1_'s canonical
  1732. // server should only affect network_isolation_key1_.
  1733. properties.SetAlternativeServices(canonical_server1, network_isolation_key1_,
  1734. {});
  1735. EXPECT_EQ(
  1736. 1u, properties
  1737. .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
  1738. .size());
  1739. EXPECT_TRUE(
  1740. properties
  1741. .GetAlternativeServiceInfos(test_server, network_isolation_key1_)
  1742. .empty());
  1743. EXPECT_TRUE(
  1744. properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
  1745. .empty());
  1746. }
  1747. TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) {
  1748. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1749. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1750. AlternativeService canonical_alternative_service(kProtoQUIC,
  1751. "bar.c.youtube.com", 1234);
  1752. SetAlternativeService(canonical_server, canonical_alternative_service);
  1753. EXPECT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1754. impl_.MarkAlternativeServiceBroken(canonical_alternative_service,
  1755. NetworkIsolationKey());
  1756. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1757. }
  1758. TEST_F(AlternateProtocolServerPropertiesTest,
  1759. CanonicalBrokenUntilDefaultNetworkChanges) {
  1760. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1761. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1762. AlternativeService canonical_alternative_service(kProtoQUIC,
  1763. "bar.c.youtube.com", 1234);
  1764. SetAlternativeService(canonical_server, canonical_alternative_service);
  1765. EXPECT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1766. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  1767. canonical_alternative_service, NetworkIsolationKey());
  1768. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1769. }
  1770. // Adding an alternative service for a new host overrides canonical host.
  1771. TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
  1772. url::SchemeHostPort foo_server("https", "foo.c.youtube.com", 443);
  1773. url::SchemeHostPort bar_server("https", "bar.c.youtube.com", 443);
  1774. AlternativeService bar_alternative_service(kProtoQUIC, "bar.c.youtube.com",
  1775. 1234);
  1776. SetAlternativeService(bar_server, bar_alternative_service);
  1777. AlternativeServiceInfoVector alternative_service_info_vector =
  1778. impl_.GetAlternativeServiceInfos(foo_server, NetworkIsolationKey());
  1779. ASSERT_EQ(1u, alternative_service_info_vector.size());
  1780. EXPECT_EQ(bar_alternative_service,
  1781. alternative_service_info_vector[0].alternative_service());
  1782. url::SchemeHostPort qux_server("https", "qux.c.youtube.com", 443);
  1783. AlternativeService qux_alternative_service(kProtoQUIC, "qux.c.youtube.com",
  1784. 443);
  1785. SetAlternativeService(qux_server, qux_alternative_service);
  1786. alternative_service_info_vector =
  1787. impl_.GetAlternativeServiceInfos(foo_server, NetworkIsolationKey());
  1788. ASSERT_EQ(1u, alternative_service_info_vector.size());
  1789. EXPECT_EQ(qux_alternative_service,
  1790. alternative_service_info_vector[0].alternative_service());
  1791. }
  1792. TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
  1793. url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
  1794. url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
  1795. AlternativeService canonical_alternative_service(kProtoQUIC,
  1796. "bar.c.youtube.com", 1234);
  1797. SetAlternativeService(canonical_server, canonical_alternative_service);
  1798. impl_.Clear(base::OnceClosure());
  1799. EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
  1800. }
  1801. TEST_F(AlternateProtocolServerPropertiesTest,
  1802. ExpireBrokenAlternateProtocolMappings) {
  1803. url::SchemeHostPort server("https", "foo", 443);
  1804. AlternativeService alternative_service(kProtoQUIC, "foo", 443);
  1805. SetAlternativeService(server, alternative_service);
  1806. EXPECT_TRUE(HasAlternativeService(server, NetworkIsolationKey()));
  1807. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1808. NetworkIsolationKey()));
  1809. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1810. alternative_service, NetworkIsolationKey()));
  1811. base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
  1812. HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
  1813. &impl_, alternative_service, past);
  1814. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1815. NetworkIsolationKey()));
  1816. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1817. NetworkIsolationKey()));
  1818. HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
  1819. EXPECT_FALSE(HasAlternativeService(server, NetworkIsolationKey()));
  1820. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1821. NetworkIsolationKey()));
  1822. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
  1823. NetworkIsolationKey()));
  1824. }
  1825. TEST_F(AlternateProtocolServerPropertiesTest,
  1826. ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey) {
  1827. url::SchemeHostPort server("https", "foo", 443);
  1828. AlternativeService alternative_service(kProtoHTTP2, "foo", 444);
  1829. base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
  1830. base::TimeTicks future = test_tick_clock_->NowTicks() + base::Seconds(42);
  1831. const base::Time alt_service_expiration = test_clock_.Now() + base::Days(1);
  1832. base::test::ScopedFeatureList feature_list;
  1833. feature_list.InitAndEnableFeature(
  1834. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  1835. // Since HttpServerProperties caches the feature value, have to create a new
  1836. // one.
  1837. HttpServerProperties properties(nullptr /* pref_delegate */,
  1838. nullptr /* net_log */, test_tick_clock_,
  1839. &test_clock_);
  1840. properties.SetHttp2AlternativeService(server, network_isolation_key1_,
  1841. alternative_service,
  1842. alt_service_expiration);
  1843. properties.SetHttp2AlternativeService(server, network_isolation_key2_,
  1844. alternative_service,
  1845. alt_service_expiration);
  1846. EXPECT_FALSE(
  1847. properties.GetAlternativeServiceInfos(server, network_isolation_key1_)
  1848. .empty());
  1849. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1850. network_isolation_key1_));
  1851. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1852. alternative_service, network_isolation_key1_));
  1853. EXPECT_FALSE(
  1854. properties.GetAlternativeServiceInfos(server, network_isolation_key2_)
  1855. .empty());
  1856. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1857. network_isolation_key2_));
  1858. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1859. alternative_service, network_isolation_key2_));
  1860. // Set broken alternative service with expiration date in the past for
  1861. // |network_isolation_key1_|.
  1862. HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
  1863. &properties, alternative_service, past, network_isolation_key1_);
  1864. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1865. network_isolation_key1_));
  1866. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1867. alternative_service, network_isolation_key1_));
  1868. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1869. network_isolation_key2_));
  1870. EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
  1871. alternative_service, network_isolation_key2_));
  1872. // Set broken alternative service with expiration date in the future for
  1873. // |network_isolation_key1_|.
  1874. HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
  1875. &properties, alternative_service, future, network_isolation_key2_);
  1876. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1877. network_isolation_key1_));
  1878. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1879. alternative_service, network_isolation_key1_));
  1880. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1881. network_isolation_key2_));
  1882. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1883. alternative_service, network_isolation_key2_));
  1884. // Only the broken entry for |network_isolation_key1_| should be expired.
  1885. HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&properties);
  1886. EXPECT_TRUE(
  1887. properties.GetAlternativeServiceInfos(server, network_isolation_key1_)
  1888. .empty());
  1889. EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
  1890. network_isolation_key1_));
  1891. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1892. alternative_service, network_isolation_key1_));
  1893. EXPECT_FALSE(
  1894. properties.GetAlternativeServiceInfos(server, network_isolation_key2_)
  1895. .empty());
  1896. EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
  1897. network_isolation_key2_));
  1898. EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
  1899. alternative_service, network_isolation_key2_));
  1900. }
  1901. // Regression test for https://crbug.com/505413.
  1902. TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
  1903. url::SchemeHostPort foo_server("https", "foo", 443);
  1904. AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443);
  1905. SetAlternativeService(foo_server, bar_alternative_service);
  1906. EXPECT_TRUE(HasAlternativeService(foo_server, NetworkIsolationKey()));
  1907. url::SchemeHostPort bar_server1("http", "bar", 80);
  1908. AlternativeService nohost_alternative_service(kProtoQUIC, "", 443);
  1909. SetAlternativeService(bar_server1, nohost_alternative_service);
  1910. EXPECT_TRUE(HasAlternativeService(bar_server1, NetworkIsolationKey()));
  1911. url::SchemeHostPort bar_server2("https", "bar", 443);
  1912. AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234);
  1913. SetAlternativeService(bar_server2, baz_alternative_service);
  1914. EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkIsolationKey()));
  1915. // Mark "bar:443" as broken.
  1916. base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
  1917. HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
  1918. &impl_, bar_alternative_service, past);
  1919. // Expire brokenness of "bar:443".
  1920. HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
  1921. // "foo:443" should have no alternative service now.
  1922. EXPECT_FALSE(HasAlternativeService(foo_server, NetworkIsolationKey()));
  1923. // "bar:80" should have no alternative service now.
  1924. EXPECT_FALSE(HasAlternativeService(bar_server1, NetworkIsolationKey()));
  1925. // The alternative service of "bar:443" should be unaffected.
  1926. EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkIsolationKey()));
  1927. EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service,
  1928. NetworkIsolationKey()));
  1929. EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
  1930. baz_alternative_service, NetworkIsolationKey()));
  1931. }
  1932. TEST_F(AlternateProtocolServerPropertiesTest,
  1933. SetBrokenAlternativeServicesDelayParams1) {
  1934. url::SchemeHostPort server("https", "foo", 443);
  1935. AlternativeService alternative_service(kProtoQUIC, "foo", 443);
  1936. SetAlternativeService(server, alternative_service);
  1937. const base::TimeDelta initial_delay = base::Seconds(1);
  1938. impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, true);
  1939. for (int i = 0; i < 10; ++i) {
  1940. impl_.MarkAlternativeServiceBroken(alternative_service,
  1941. NetworkIsolationKey());
  1942. // |impl_| should have posted task to expire the brokenness of
  1943. // |alternative_service|
  1944. EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
  1945. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1946. NetworkIsolationKey()));
  1947. // Advance time by just enough so that |alternative_service|'s brokenness
  1948. // expires.
  1949. FastForwardBy(initial_delay * (1 << i));
  1950. // Ensure brokenness of |alternative_service| has expired.
  1951. EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
  1952. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1953. NetworkIsolationKey()));
  1954. }
  1955. }
  1956. TEST_F(AlternateProtocolServerPropertiesTest,
  1957. SetBrokenAlternativeServicesDelayParams2) {
  1958. url::SchemeHostPort server("https", "foo", 443);
  1959. AlternativeService alternative_service(kProtoQUIC, "foo", 443);
  1960. SetAlternativeService(server, alternative_service);
  1961. const base::TimeDelta initial_delay = base::Seconds(5);
  1962. impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, false);
  1963. for (int i = 0; i < 10; ++i) {
  1964. impl_.MarkAlternativeServiceBroken(alternative_service,
  1965. NetworkIsolationKey());
  1966. // |impl_| should have posted task to expire the brokenness of
  1967. // |alternative_service|
  1968. EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
  1969. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
  1970. NetworkIsolationKey()));
  1971. // Advance time by just enough so that |alternative_service|'s brokenness
  1972. // expires.
  1973. if (i == 0) {
  1974. FastForwardBy(initial_delay);
  1975. } else {
  1976. FastForwardBy(base::Seconds(300) * (1 << (i - 1)));
  1977. }
  1978. // Ensure brokenness of |alternative_service| has expired.
  1979. EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
  1980. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
  1981. NetworkIsolationKey()));
  1982. }
  1983. }
  1984. // Regression test for https://crbug.com/724302
  1985. TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) {
  1986. // This test will mark an alternative service A that has already been marked
  1987. // broken many times, then immediately mark another alternative service B as
  1988. // broken for the first time. Because A's been marked broken many times
  1989. // already, its brokenness will be scheduled to expire much further in the
  1990. // future than B, even though it was marked broken before B. This test makes
  1991. // sure that even though A was marked broken before B, B's brokenness should
  1992. // expire before A.
  1993. url::SchemeHostPort server1("https", "foo", 443);
  1994. AlternativeService alternative_service1(kProtoQUIC, "foo", 443);
  1995. SetAlternativeService(server1, alternative_service1);
  1996. url::SchemeHostPort server2("https", "bar", 443);
  1997. AlternativeService alternative_service2(kProtoQUIC, "bar", 443);
  1998. SetAlternativeService(server2, alternative_service2);
  1999. // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire.
  2000. // This will increase its time until expiration.
  2001. for (int i = 0; i < 3; ++i) {
  2002. impl_.MarkAlternativeServiceBroken(alternative_service1,
  2003. NetworkIsolationKey());
  2004. // |impl_| should have posted task to expire the brokenness of
  2005. // |alternative_service1|
  2006. EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
  2007. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  2008. NetworkIsolationKey()));
  2009. // Advance time by just enough so that |alternative_service1|'s brokenness
  2010. // expires.
  2011. FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]);
  2012. // Ensure brokenness of |alternative_service1| has expired.
  2013. EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
  2014. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
  2015. NetworkIsolationKey()));
  2016. }
  2017. impl_.MarkAlternativeServiceBroken(alternative_service1,
  2018. NetworkIsolationKey());
  2019. impl_.MarkAlternativeServiceBroken(alternative_service2,
  2020. NetworkIsolationKey());
  2021. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2,
  2022. NetworkIsolationKey()));
  2023. // Advance time by just enough so that |alternative_service2|'s brokennness
  2024. // expires.
  2025. FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
  2026. EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
  2027. NetworkIsolationKey()));
  2028. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
  2029. NetworkIsolationKey()));
  2030. // Advance time by enough so that |alternative_service1|'s brokenness expires.
  2031. FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] -
  2032. BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
  2033. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
  2034. NetworkIsolationKey()));
  2035. EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
  2036. NetworkIsolationKey()));
  2037. }
  2038. // Regression test for https://crbug.com/994537. Having a ServerInfo entry
  2039. // without a populated |alternative_services| value would cause
  2040. // OnExpireBrokenAlternativeService() to hang..
  2041. TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc3) {
  2042. // Add an altertive service entry.
  2043. const url::SchemeHostPort kServer1("https", "foo", 443);
  2044. const AlternativeService kAltService(kProtoQUIC, "bar", 443);
  2045. SetAlternativeService(kServer1, kAltService);
  2046. EXPECT_TRUE(HasAlternativeService(kServer1, NetworkIsolationKey()));
  2047. // Add an entry to ServerInfo for another server, without an alternative
  2048. // service value.
  2049. const url::SchemeHostPort kServer2("http", "bar", 80);
  2050. impl_.SetSupportsSpdy(kServer2, NetworkIsolationKey(), false);
  2051. // Mark kAltService as broken.
  2052. base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
  2053. HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
  2054. &impl_, kAltService, past);
  2055. // Expire brokenness of kAltService. This call should not hang.
  2056. HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
  2057. EXPECT_FALSE(HasAlternativeService(kServer1, NetworkIsolationKey()));
  2058. }
  2059. TEST_F(AlternateProtocolServerPropertiesTest,
  2060. GetAlternativeServiceInfoAsValue) {
  2061. base::Time::Exploded now_exploded;
  2062. now_exploded.year = 2018;
  2063. now_exploded.month = 1;
  2064. now_exploded.day_of_week = 3;
  2065. now_exploded.day_of_month = 24;
  2066. now_exploded.hour = 15;
  2067. now_exploded.minute = 12;
  2068. now_exploded.second = 53;
  2069. now_exploded.millisecond = 0;
  2070. base::Time now;
  2071. bool result = base::Time::FromLocalExploded(now_exploded, &now);
  2072. DCHECK(result);
  2073. test_clock_.SetNow(now);
  2074. AlternativeServiceInfoVector alternative_service_info_vector;
  2075. alternative_service_info_vector.push_back(
  2076. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  2077. AlternativeService(kProtoHTTP2, "foo", 443), now + base::Minutes(1)));
  2078. alternative_service_info_vector.push_back(
  2079. AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
  2080. AlternativeService(kProtoQUIC, "bar", 443), now + base::Hours(1),
  2081. DefaultSupportedQuicVersions()));
  2082. alternative_service_info_vector.push_back(
  2083. AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
  2084. AlternativeService(kProtoQUIC, "baz", 443), now + base::Hours(1),
  2085. DefaultSupportedQuicVersions()));
  2086. impl_.SetAlternativeServices(url::SchemeHostPort("https", "youtube.com", 443),
  2087. NetworkIsolationKey(),
  2088. alternative_service_info_vector);
  2089. impl_.MarkAlternativeServiceBroken(AlternativeService(kProtoQUIC, "bar", 443),
  2090. NetworkIsolationKey());
  2091. impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
  2092. AlternativeService(kProtoQUIC, "baz", 443), NetworkIsolationKey());
  2093. alternative_service_info_vector.clear();
  2094. alternative_service_info_vector.push_back(
  2095. AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
  2096. AlternativeService(kProtoHTTP2, "foo2", 443), now + base::Days(1)));
  2097. impl_.SetAlternativeServices(url::SchemeHostPort("http", "test.com", 80),
  2098. NetworkIsolationKey(),
  2099. alternative_service_info_vector);
  2100. const char expected_json[] =
  2101. "["
  2102. "{"
  2103. "\"alternative_service\":"
  2104. "[\"h2 foo2:443, expires 2018-01-25 15:12:53\"],"
  2105. "\"network_isolation_key\":\"null null\","
  2106. "\"server\":\"http://test.com\""
  2107. "},"
  2108. "{"
  2109. "\"alternative_service\":"
  2110. "[\"h2 foo:443, expires 2018-01-24 15:13:53\","
  2111. "\"quic bar:443, expires 2018-01-24 16:12:53"
  2112. " (broken until 2018-01-24 15:17:53)\","
  2113. "\"quic baz:443, expires 2018-01-24 16:12:53"
  2114. " (broken until 2018-01-24 15:17:53)\"],"
  2115. "\"network_isolation_key\":\"null null\","
  2116. "\"server\":\"https://youtube.com\""
  2117. "}"
  2118. "]";
  2119. base::Value alternative_service_info_value =
  2120. impl_.GetAlternativeServiceInfoAsValue();
  2121. std::string alternative_service_info_json;
  2122. base::JSONWriter::Write(alternative_service_info_value,
  2123. &alternative_service_info_json);
  2124. EXPECT_EQ(expected_json, alternative_service_info_json);
  2125. }
  2126. TEST_F(HttpServerPropertiesTest, LoadLastLocalAddressWhenQuicWorked) {
  2127. const IPAddress kEmptyAddress;
  2128. const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
  2129. const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
  2130. // Check by initializing empty address.
  2131. impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
  2132. EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
  2133. // Empty address should not be considered an address that was used when QUIC
  2134. // worked.
  2135. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2136. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2137. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2138. // Check by initializing with a valid address.
  2139. impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress1);
  2140. EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
  2141. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2142. EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2143. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2144. // Try another valid address.
  2145. impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress2);
  2146. EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
  2147. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2148. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2149. EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2150. // And loading an empty address clears the current one.
  2151. // TODO(mmenke): This seems like a bug, since if we've learned the current
  2152. // network supports QUIC, surely we want to save that to disk? Seems like a
  2153. // pre-existing value should take precedence, if non-empty, since if the
  2154. // current network is already known to support QUIC, the loaded value is no
  2155. // longer relevant.
  2156. impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
  2157. EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
  2158. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2159. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2160. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2161. }
  2162. TEST_F(HttpServerPropertiesTest, SetLastLocalAddressWhenQuicWorked) {
  2163. const IPAddress kEmptyAddress;
  2164. const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
  2165. const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
  2166. EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
  2167. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2168. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2169. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2170. // Set to a valid address.
  2171. impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress1);
  2172. EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
  2173. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2174. EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2175. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2176. // Clear only this value.
  2177. impl_.ClearLastLocalAddressWhenQuicWorked();
  2178. EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
  2179. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2180. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2181. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2182. // Try another valid address.
  2183. impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress2);
  2184. EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
  2185. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2186. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2187. EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2188. // Clear all values.
  2189. impl_.Clear(base::OnceClosure());
  2190. EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
  2191. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
  2192. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
  2193. EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
  2194. }
  2195. TEST_F(HttpServerPropertiesTest, LoadServerNetworkStats) {
  2196. url::SchemeHostPort google_server("https", "www.google.com", 443);
  2197. // Check by initializing empty ServerNetworkStats.
  2198. std::unique_ptr<HttpServerProperties::ServerInfoMap> load_server_info_map =
  2199. std::make_unique<HttpServerProperties::ServerInfoMap>();
  2200. impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
  2201. const ServerNetworkStats* stats =
  2202. impl_.GetServerNetworkStats(google_server, NetworkIsolationKey());
  2203. EXPECT_EQ(nullptr, stats);
  2204. // Check by initializing with www.google.com:443.
  2205. ServerNetworkStats stats_google;
  2206. stats_google.srtt = base::Microseconds(10);
  2207. stats_google.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
  2208. load_server_info_map =
  2209. std::make_unique<HttpServerProperties::ServerInfoMap>();
  2210. load_server_info_map->GetOrPut(CreateSimpleKey(google_server))
  2211. ->second.server_network_stats = stats_google;
  2212. impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
  2213. // Verify data for www.google.com:443.
  2214. ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
  2215. EXPECT_EQ(stats_google, *(impl_.GetServerNetworkStats(
  2216. google_server, NetworkIsolationKey())));
  2217. // Test recency order and overwriting of data.
  2218. //
  2219. // |docs_server| has a ServerNetworkStats, which will be overwritten by
  2220. // OnServerInfoLoadedForTesting(), because |server_network_stats_map| has an
  2221. // entry for |docs_server|.
  2222. url::SchemeHostPort docs_server("https", "docs.google.com", 443);
  2223. ServerNetworkStats stats_docs;
  2224. stats_docs.srtt = base::Microseconds(20);
  2225. stats_docs.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(200);
  2226. // Recency order will be |docs_server| and |google_server|.
  2227. impl_.SetServerNetworkStats(docs_server, NetworkIsolationKey(), stats_docs);
  2228. // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
  2229. std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
  2230. std::make_unique<HttpServerProperties::ServerInfoMap>();
  2231. // Change the values for |docs_server|.
  2232. ServerNetworkStats new_stats_docs;
  2233. new_stats_docs.srtt = base::Microseconds(25);
  2234. new_stats_docs.bandwidth_estimate =
  2235. quic::QuicBandwidth::FromBitsPerSecond(250);
  2236. server_info_map->GetOrPut(CreateSimpleKey(docs_server))
  2237. ->second.server_network_stats = new_stats_docs;
  2238. // Add data for mail.google.com:443.
  2239. url::SchemeHostPort mail_server("https", "mail.google.com", 443);
  2240. ServerNetworkStats stats_mail;
  2241. stats_mail.srtt = base::Microseconds(30);
  2242. stats_mail.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(300);
  2243. server_info_map->GetOrPut(CreateSimpleKey(mail_server))
  2244. ->second.server_network_stats = stats_mail;
  2245. // Recency order will be |docs_server|, |google_server| and |mail_server|.
  2246. impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
  2247. const HttpServerProperties::ServerInfoMap& map =
  2248. impl_.server_info_map_for_testing();
  2249. ASSERT_EQ(3u, map.size());
  2250. auto map_it = map.begin();
  2251. EXPECT_EQ(docs_server, map_it->first.server);
  2252. EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
  2253. ASSERT_TRUE(map_it->second.server_network_stats.has_value());
  2254. EXPECT_EQ(new_stats_docs, *map_it->second.server_network_stats);
  2255. ++map_it;
  2256. EXPECT_EQ(google_server, map_it->first.server);
  2257. EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
  2258. ASSERT_TRUE(map_it->second.server_network_stats.has_value());
  2259. EXPECT_EQ(stats_google, *map_it->second.server_network_stats);
  2260. ++map_it;
  2261. EXPECT_EQ(mail_server, map_it->first.server);
  2262. EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
  2263. ASSERT_TRUE(map_it->second.server_network_stats.has_value());
  2264. EXPECT_EQ(stats_mail, *map_it->second.server_network_stats);
  2265. }
  2266. TEST_F(HttpServerPropertiesTest, SetServerNetworkStats) {
  2267. url::SchemeHostPort foo_http_server("http", "foo", 443);
  2268. url::SchemeHostPort foo_https_server("https", "foo", 443);
  2269. EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
  2270. NetworkIsolationKey()));
  2271. EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
  2272. NetworkIsolationKey()));
  2273. ServerNetworkStats stats1;
  2274. stats1.srtt = base::Microseconds(10);
  2275. stats1.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
  2276. impl_.SetServerNetworkStats(foo_http_server, NetworkIsolationKey(), stats1);
  2277. const ServerNetworkStats* stats2 =
  2278. impl_.GetServerNetworkStats(foo_http_server, NetworkIsolationKey());
  2279. EXPECT_EQ(10, stats2->srtt.ToInternalValue());
  2280. EXPECT_EQ(100, stats2->bandwidth_estimate.ToBitsPerSecond());
  2281. // Https server should have nothing set for server network stats.
  2282. EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
  2283. NetworkIsolationKey()));
  2284. impl_.Clear(base::OnceClosure());
  2285. EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
  2286. NetworkIsolationKey()));
  2287. EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
  2288. NetworkIsolationKey()));
  2289. }
  2290. TEST_F(HttpServerPropertiesTest, ClearServerNetworkStats) {
  2291. ServerNetworkStats stats;
  2292. stats.srtt = base::Microseconds(10);
  2293. stats.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
  2294. url::SchemeHostPort foo_https_server("https", "foo", 443);
  2295. impl_.SetServerNetworkStats(foo_https_server, NetworkIsolationKey(), stats);
  2296. impl_.ClearServerNetworkStats(foo_https_server, NetworkIsolationKey());
  2297. EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
  2298. NetworkIsolationKey()));
  2299. }
  2300. TEST_F(HttpServerPropertiesTest, OnQuicServerInfoMapLoaded) {
  2301. quic::QuicServerId google_quic_server_id("www.google.com", 443, true);
  2302. HttpServerProperties::QuicServerInfoMapKey google_key(
  2303. google_quic_server_id, NetworkIsolationKey(),
  2304. false /* use_network_isolation_key */);
  2305. const int kMaxQuicServerEntries = 10;
  2306. impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
  2307. EXPECT_EQ(10u, impl_.quic_server_info_map().max_size());
  2308. // Check empty map.
  2309. std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
  2310. init_quic_server_info_map =
  2311. std::make_unique<HttpServerProperties::QuicServerInfoMap>(
  2312. kMaxQuicServerEntries);
  2313. impl_.OnQuicServerInfoMapLoadedForTesting(
  2314. std::move(init_quic_server_info_map));
  2315. EXPECT_EQ(0u, impl_.quic_server_info_map().size());
  2316. // Check by initializing with www.google.com:443.
  2317. std::string google_server_info("google_quic_server_info");
  2318. init_quic_server_info_map =
  2319. std::make_unique<HttpServerProperties::QuicServerInfoMap>(
  2320. kMaxQuicServerEntries);
  2321. init_quic_server_info_map->Put(google_key, google_server_info);
  2322. impl_.OnQuicServerInfoMapLoadedForTesting(
  2323. std::move(init_quic_server_info_map));
  2324. // Verify data for www.google.com:443.
  2325. EXPECT_EQ(1u, impl_.quic_server_info_map().size());
  2326. EXPECT_EQ(
  2327. google_server_info,
  2328. *impl_.GetQuicServerInfo(google_quic_server_id, NetworkIsolationKey()));
  2329. // Test recency order and overwriting of data.
  2330. //
  2331. // |docs_server| has a QuicServerInfo, which will be overwritten by
  2332. // SetQuicServerInfoMap(), because |quic_server_info_map| has an
  2333. // entry for |docs_server|.
  2334. quic::QuicServerId docs_quic_server_id("docs.google.com", 443, true);
  2335. HttpServerProperties::QuicServerInfoMapKey docs_key(
  2336. docs_quic_server_id, NetworkIsolationKey(),
  2337. false /* use_network_isolation_key */);
  2338. std::string docs_server_info("docs_quic_server_info");
  2339. impl_.SetQuicServerInfo(docs_quic_server_id, NetworkIsolationKey(),
  2340. docs_server_info);
  2341. // Recency order will be |docs_server| and |google_server|.
  2342. const HttpServerProperties::QuicServerInfoMap& map =
  2343. impl_.quic_server_info_map();
  2344. ASSERT_EQ(2u, map.size());
  2345. auto map_it = map.begin();
  2346. EXPECT_EQ(map_it->first, docs_key);
  2347. EXPECT_EQ(docs_server_info, map_it->second);
  2348. ++map_it;
  2349. EXPECT_EQ(map_it->first, google_key);
  2350. EXPECT_EQ(google_server_info, map_it->second);
  2351. // Prepare |quic_server_info_map| to be loaded by
  2352. // SetQuicServerInfoMap().
  2353. std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
  2354. quic_server_info_map =
  2355. std::make_unique<HttpServerProperties::QuicServerInfoMap>(
  2356. kMaxQuicServerEntries);
  2357. // Change the values for |docs_server|.
  2358. std::string new_docs_server_info("new_docs_quic_server_info");
  2359. quic_server_info_map->Put(docs_key, new_docs_server_info);
  2360. // Add data for mail.google.com:443.
  2361. quic::QuicServerId mail_quic_server_id("mail.google.com", 443, true);
  2362. HttpServerProperties::QuicServerInfoMapKey mail_key(
  2363. mail_quic_server_id, NetworkIsolationKey(),
  2364. false /* use_network_isolation_key */);
  2365. std::string mail_server_info("mail_quic_server_info");
  2366. quic_server_info_map->Put(mail_key, mail_server_info);
  2367. impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
  2368. // Recency order will be |docs_server|, |google_server| and |mail_server|.
  2369. const HttpServerProperties::QuicServerInfoMap& memory_map =
  2370. impl_.quic_server_info_map();
  2371. ASSERT_EQ(3u, memory_map.size());
  2372. auto memory_map_it = memory_map.begin();
  2373. EXPECT_EQ(memory_map_it->first, docs_key);
  2374. EXPECT_EQ(new_docs_server_info, memory_map_it->second);
  2375. ++memory_map_it;
  2376. EXPECT_EQ(memory_map_it->first, google_key);
  2377. EXPECT_EQ(google_server_info, memory_map_it->second);
  2378. ++memory_map_it;
  2379. EXPECT_EQ(memory_map_it->first, mail_key);
  2380. EXPECT_EQ(mail_server_info, memory_map_it->second);
  2381. // Shrink the size of |quic_server_info_map| and verify the MRU order is
  2382. // maintained.
  2383. impl_.SetMaxServerConfigsStoredInProperties(2);
  2384. EXPECT_EQ(2u, impl_.quic_server_info_map().max_size());
  2385. const HttpServerProperties::QuicServerInfoMap& memory_map1 =
  2386. impl_.quic_server_info_map();
  2387. ASSERT_EQ(2u, memory_map1.size());
  2388. auto memory_map1_it = memory_map1.begin();
  2389. EXPECT_EQ(memory_map1_it->first, docs_key);
  2390. EXPECT_EQ(new_docs_server_info, memory_map1_it->second);
  2391. ++memory_map1_it;
  2392. EXPECT_EQ(memory_map1_it->first, google_key);
  2393. EXPECT_EQ(google_server_info, memory_map1_it->second);
  2394. // |QuicServerInfo| for |mail_quic_server_id| shouldn't be there.
  2395. EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(mail_quic_server_id,
  2396. NetworkIsolationKey()));
  2397. }
  2398. TEST_F(HttpServerPropertiesTest, SetQuicServerInfo) {
  2399. quic::QuicServerId server1("foo", 80, false /* privacy_mode_enabled */);
  2400. quic::QuicServerId server2("foo", 80, true /* privacy_mode_enabled */);
  2401. std::string quic_server_info1("quic_server_info1");
  2402. std::string quic_server_info2("quic_server_info2");
  2403. std::string quic_server_info3("quic_server_info3");
  2404. // Without network isolation keys enabled for HttpServerProperties, passing in
  2405. // a NetworkIsolationKey should have no effect on behavior.
  2406. impl_.SetQuicServerInfo(server1, NetworkIsolationKey(), quic_server_info1);
  2407. EXPECT_EQ(quic_server_info1,
  2408. *(impl_.GetQuicServerInfo(server1, NetworkIsolationKey())));
  2409. EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2410. EXPECT_EQ(quic_server_info1,
  2411. *(impl_.GetQuicServerInfo(server1, network_isolation_key1_)));
  2412. EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_isolation_key1_));
  2413. impl_.SetQuicServerInfo(server2, network_isolation_key1_, quic_server_info2);
  2414. EXPECT_EQ(quic_server_info1,
  2415. *(impl_.GetQuicServerInfo(server1, NetworkIsolationKey())));
  2416. EXPECT_EQ(quic_server_info2,
  2417. *(impl_.GetQuicServerInfo(server2, NetworkIsolationKey())));
  2418. EXPECT_EQ(quic_server_info1,
  2419. *(impl_.GetQuicServerInfo(server1, network_isolation_key1_)));
  2420. EXPECT_EQ(quic_server_info2,
  2421. *(impl_.GetQuicServerInfo(server2, network_isolation_key1_)));
  2422. impl_.SetQuicServerInfo(server1, network_isolation_key1_, quic_server_info3);
  2423. EXPECT_EQ(quic_server_info3,
  2424. *(impl_.GetQuicServerInfo(server1, NetworkIsolationKey())));
  2425. EXPECT_EQ(quic_server_info2,
  2426. *(impl_.GetQuicServerInfo(server2, NetworkIsolationKey())));
  2427. EXPECT_EQ(quic_server_info3,
  2428. *(impl_.GetQuicServerInfo(server1, network_isolation_key1_)));
  2429. EXPECT_EQ(quic_server_info2,
  2430. *(impl_.GetQuicServerInfo(server2, network_isolation_key1_)));
  2431. impl_.Clear(base::OnceClosure());
  2432. EXPECT_FALSE(impl_.GetQuicServerInfo(server1, NetworkIsolationKey()));
  2433. EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2434. EXPECT_FALSE(impl_.GetQuicServerInfo(server1, network_isolation_key1_));
  2435. EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_isolation_key1_));
  2436. base::test::ScopedFeatureList feature_list;
  2437. feature_list.InitAndEnableFeature(
  2438. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  2439. // Since HttpServerProperties caches the feature value, have to create a new
  2440. // one.
  2441. HttpServerProperties properties(nullptr /* pref_delegate */,
  2442. nullptr /* net_log */, test_tick_clock_,
  2443. &test_clock_);
  2444. properties.SetQuicServerInfo(server1, NetworkIsolationKey(),
  2445. quic_server_info1);
  2446. EXPECT_EQ(quic_server_info1,
  2447. *(properties.GetQuicServerInfo(server1, NetworkIsolationKey())));
  2448. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2449. EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key1_));
  2450. EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
  2451. properties.SetQuicServerInfo(server1, network_isolation_key1_,
  2452. quic_server_info2);
  2453. EXPECT_EQ(quic_server_info1,
  2454. *(properties.GetQuicServerInfo(server1, NetworkIsolationKey())));
  2455. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2456. EXPECT_EQ(quic_server_info2,
  2457. *(properties.GetQuicServerInfo(server1, network_isolation_key1_)));
  2458. EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
  2459. properties.SetQuicServerInfo(server2, network_isolation_key1_,
  2460. quic_server_info3);
  2461. EXPECT_EQ(quic_server_info1,
  2462. *(properties.GetQuicServerInfo(server1, NetworkIsolationKey())));
  2463. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2464. EXPECT_EQ(quic_server_info2,
  2465. *(properties.GetQuicServerInfo(server1, network_isolation_key1_)));
  2466. EXPECT_EQ(quic_server_info3,
  2467. *(properties.GetQuicServerInfo(server2, network_isolation_key1_)));
  2468. properties.Clear(base::OnceClosure());
  2469. EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
  2470. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2471. EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key1_));
  2472. EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
  2473. }
  2474. // Tests that GetQuicServerInfo() returns server info of a host
  2475. // with the same canonical suffix when there is no exact host match.
  2476. TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatch) {
  2477. // Set up HttpServerProperties.
  2478. // Add a host with a canonical suffix.
  2479. quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
  2480. std::string foo_server_info("foo_server_info");
  2481. impl_.SetQuicServerInfo(foo_server_id, NetworkIsolationKey(),
  2482. foo_server_info);
  2483. // Add a host that has a different canonical suffix.
  2484. quic::QuicServerId baz_server_id("baz.video.com", 443, false);
  2485. std::string baz_server_info("baz_server_info");
  2486. impl_.SetQuicServerInfo(baz_server_id, NetworkIsolationKey(),
  2487. baz_server_info);
  2488. // Create SchemeHostPort with a host that has the initial canonical suffix.
  2489. quic::QuicServerId bar_server_id("bar.googlevideo.com", 443, false);
  2490. // Check the the server info associated with "foo" is returned for "bar".
  2491. const std::string* bar_server_info =
  2492. impl_.GetQuicServerInfo(bar_server_id, NetworkIsolationKey());
  2493. ASSERT_TRUE(bar_server_info != nullptr);
  2494. EXPECT_EQ(foo_server_info, *bar_server_info);
  2495. }
  2496. // Make sure that canonical suffices respect NetworkIsolationKeys when using
  2497. // QuicServerInfo methods.
  2498. TEST_F(HttpServerPropertiesTest,
  2499. QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey) {
  2500. // Two servers with same canonical suffix.
  2501. quic::QuicServerId server1("foo.googlevideo.com", 80,
  2502. false /* privacy_mode_enabled */);
  2503. quic::QuicServerId server2("bar.googlevideo.com", 80,
  2504. false /* privacy_mode_enabled */);
  2505. std::string server_info1("server_info1");
  2506. std::string server_info2("server_info2");
  2507. base::test::ScopedFeatureList feature_list;
  2508. feature_list.InitAndEnableFeature(
  2509. features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
  2510. // Since HttpServerProperties caches the feature value, have to create a new
  2511. // one.
  2512. HttpServerProperties properties(nullptr /* pref_delegate */,
  2513. nullptr /* net_log */, test_tick_clock_,
  2514. &test_clock_);
  2515. // Set QuicServerInfo for one canononical suffix and
  2516. // |network_isolation_key1_|. It should be accessible via another
  2517. // SchemeHostPort, but only when the NetworkIsolationKeys match.
  2518. properties.SetQuicServerInfo(server1, network_isolation_key1_, server_info1);
  2519. const std::string* fetched_server_info =
  2520. properties.GetQuicServerInfo(server1, network_isolation_key1_);
  2521. ASSERT_TRUE(fetched_server_info);
  2522. EXPECT_EQ(server_info1, *fetched_server_info);
  2523. fetched_server_info =
  2524. properties.GetQuicServerInfo(server2, network_isolation_key1_);
  2525. ASSERT_TRUE(fetched_server_info);
  2526. EXPECT_EQ(server_info1, *fetched_server_info);
  2527. EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key2_));
  2528. EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key2_));
  2529. EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
  2530. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2531. // Set different QuicServerInfo for the same canononical suffix and
  2532. // |network_isolation_key2_|. Both infos should be retriveable by using the
  2533. // different NetworkIsolationKeys.
  2534. properties.SetQuicServerInfo(server1, network_isolation_key2_, server_info2);
  2535. fetched_server_info =
  2536. properties.GetQuicServerInfo(server1, network_isolation_key1_);
  2537. ASSERT_TRUE(fetched_server_info);
  2538. EXPECT_EQ(server_info1, *fetched_server_info);
  2539. fetched_server_info =
  2540. properties.GetQuicServerInfo(server2, network_isolation_key1_);
  2541. ASSERT_TRUE(fetched_server_info);
  2542. EXPECT_EQ(server_info1, *fetched_server_info);
  2543. fetched_server_info =
  2544. properties.GetQuicServerInfo(server1, network_isolation_key2_);
  2545. ASSERT_TRUE(fetched_server_info);
  2546. EXPECT_EQ(server_info2, *fetched_server_info);
  2547. fetched_server_info =
  2548. properties.GetQuicServerInfo(server2, network_isolation_key2_);
  2549. ASSERT_TRUE(fetched_server_info);
  2550. EXPECT_EQ(server_info2, *fetched_server_info);
  2551. EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
  2552. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2553. // Clearing should destroy all information.
  2554. properties.Clear(base::OnceClosure());
  2555. EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key1_));
  2556. EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
  2557. EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key2_));
  2558. EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key2_));
  2559. EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
  2560. EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
  2561. }
  2562. // Verifies that GetQuicServerInfo() returns the MRU entry if multiple records
  2563. // match a given canonical host.
  2564. TEST_F(HttpServerPropertiesTest,
  2565. QuicServerInfoCanonicalSuffixMatchReturnsMruEntry) {
  2566. // Set up HttpServerProperties by adding two hosts with the same canonical
  2567. // suffixes.
  2568. quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
  2569. std::string h1_server_info("h1_server_info");
  2570. impl_.SetQuicServerInfo(h1_server_id, NetworkIsolationKey(), h1_server_info);
  2571. quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
  2572. std::string h2_server_info("h2_server_info");
  2573. impl_.SetQuicServerInfo(h2_server_id, NetworkIsolationKey(), h2_server_info);
  2574. // Create quic::QuicServerId to use for the search.
  2575. quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
  2576. // Check that 'h2' info is returned since it is MRU.
  2577. const std::string* server_info =
  2578. impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
  2579. ASSERT_TRUE(server_info != nullptr);
  2580. EXPECT_EQ(h2_server_info, *server_info);
  2581. // Access 'h1' info, so it becomes MRU.
  2582. impl_.GetQuicServerInfo(h1_server_id, NetworkIsolationKey());
  2583. // Check that 'h1' info is returned since it is MRU now.
  2584. server_info = impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
  2585. ASSERT_TRUE(server_info != nullptr);
  2586. EXPECT_EQ(h1_server_info, *server_info);
  2587. }
  2588. // Verifies that |GetQuicServerInfo| doesn't change the MRU order of the server
  2589. // info map when a record is matched based on a canonical name.
  2590. TEST_F(HttpServerPropertiesTest,
  2591. QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder) {
  2592. // Add a host with a matching canonical name.
  2593. quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
  2594. HttpServerProperties::QuicServerInfoMapKey h1_key(
  2595. h1_server_id, NetworkIsolationKey(),
  2596. false /* use_network_isolation_key */);
  2597. std::string h1_server_info("h1_server_info");
  2598. impl_.SetQuicServerInfo(h1_server_id, NetworkIsolationKey(), h1_server_info);
  2599. // Add a host hosts with a non-matching canonical name.
  2600. quic::QuicServerId h2_server_id("h2.video.com", 443, false);
  2601. HttpServerProperties::QuicServerInfoMapKey h2_key(
  2602. h2_server_id, NetworkIsolationKey(),
  2603. false /* use_network_isolation_key */);
  2604. std::string h2_server_info("h2_server_info");
  2605. impl_.SetQuicServerInfo(h2_server_id, NetworkIsolationKey(), h2_server_info);
  2606. // Check that "h2.video.com" is the MRU entry in the map.
  2607. EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
  2608. // Search for the entry that matches the canonical name
  2609. // ("h1.googlevideo.com").
  2610. quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
  2611. const std::string* server_info =
  2612. impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
  2613. ASSERT_TRUE(server_info != nullptr);
  2614. // Check that the search (although successful) hasn't changed the MRU order of
  2615. // the map.
  2616. EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
  2617. // Search for "h1.googlevideo.com" directly, so it becomes MRU
  2618. impl_.GetQuicServerInfo(h1_server_id, NetworkIsolationKey());
  2619. // Check that "h1.googlevideo.com" is the MRU entry now.
  2620. EXPECT_EQ(h1_key, impl_.quic_server_info_map().begin()->first);
  2621. }
  2622. // Tests that the canonical host matching works for hosts stored in memory cache
  2623. // and the ones loaded from persistent storage, i.e. server info added
  2624. // using SetQuicServerInfo() and SetQuicServerInfoMap() is taken into
  2625. // cosideration when searching for server info for a host with the same
  2626. // canonical suffix.
  2627. TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatchSetInfoMap) {
  2628. // Add a host info using SetQuicServerInfo(). That will simulate an info
  2629. // entry stored in memory cache.
  2630. quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
  2631. std::string h1_server_info("h1_server_info_memory_cache");
  2632. impl_.SetQuicServerInfo(h1_server_id, NetworkIsolationKey(), h1_server_info);
  2633. // Prepare a map with host info and add it using SetQuicServerInfoMap(). That
  2634. // will simulate info records read from the persistence storage.
  2635. quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
  2636. HttpServerProperties::QuicServerInfoMapKey h2_key(
  2637. h2_server_id, NetworkIsolationKey(),
  2638. false /* use_network_isolation_key */);
  2639. std::string h2_server_info("h2_server_info_from_disk");
  2640. quic::QuicServerId h3_server_id("h3.ggpht.com", 443, false);
  2641. HttpServerProperties::QuicServerInfoMapKey h3_key(
  2642. h3_server_id, NetworkIsolationKey(),
  2643. false /* use_network_isolation_key */);
  2644. std::string h3_server_info("h3_server_info_from_disk");
  2645. const int kMaxQuicServerEntries = 10;
  2646. impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
  2647. std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
  2648. quic_server_info_map =
  2649. std::make_unique<HttpServerProperties::QuicServerInfoMap>(
  2650. kMaxQuicServerEntries);
  2651. quic_server_info_map->Put(h2_key, h2_server_info);
  2652. quic_server_info_map->Put(h3_key, h3_server_info);
  2653. impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
  2654. // Check that the server info from the memory cache is returned since unique
  2655. // entries from the memory cache are added after entries from the
  2656. // persistence storage and, therefore, are most recently used.
  2657. quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
  2658. const std::string* server_info =
  2659. impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
  2660. ASSERT_TRUE(server_info != nullptr);
  2661. EXPECT_EQ(h1_server_info, *server_info);
  2662. // Check that server info that was added using SetQuicServerInfoMap() can be
  2663. // found.
  2664. foo_server_id = quic::QuicServerId("foo.ggpht.com", 443, false);
  2665. server_info = impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
  2666. ASSERT_TRUE(server_info != nullptr);
  2667. EXPECT_EQ(h3_server_info, *server_info);
  2668. }
  2669. } // namespace
  2670. } // namespace net