12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/http/http_server_properties.h"
- #include <memory>
- #include <string>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/check.h"
- #include "base/feature_list.h"
- #include "base/json/json_writer.h"
- #include "base/memory/raw_ptr.h"
- #include "base/run_loop.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/simple_test_clock.h"
- #include "base/test/task_environment.h"
- #include "base/time/time.h"
- #include "base/values.h"
- #include "net/base/features.h"
- #include "net/base/host_port_pair.h"
- #include "net/base/ip_address.h"
- #include "net/base/schemeful_site.h"
- #include "net/http/http_network_session.h"
- #include "net/test/test_with_task_environment.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "url/gurl.h"
- namespace net {
- const base::TimeDelta BROKEN_ALT_SVC_EXPIRE_DELAYS[10] = {
- base::Seconds(300), base::Seconds(600), base::Seconds(1200),
- base::Seconds(2400), base::Seconds(4800), base::Seconds(9600),
- base::Seconds(19200), base::Seconds(38400), base::Seconds(76800),
- base::Seconds(153600),
- };
- class HttpServerPropertiesPeer {
- public:
- static void AddBrokenAlternativeServiceWithExpirationTime(
- HttpServerProperties* impl,
- const AlternativeService& alternative_service,
- base::TimeTicks when,
- const NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
- BrokenAlternativeService broken_alternative_service(
- alternative_service, network_isolation_key,
- true /* use_network_isolation_key */);
- BrokenAlternativeServiceList::iterator unused_it;
- impl->broken_alternative_services_.AddToBrokenListAndMap(
- broken_alternative_service, when, &unused_it);
- auto it =
- impl->broken_alternative_services_.recently_broken_alternative_services_
- .Get(broken_alternative_service);
- if (it == impl->broken_alternative_services_
- .recently_broken_alternative_services_.end()) {
- impl->broken_alternative_services_.recently_broken_alternative_services_
- .Put(broken_alternative_service, 1);
- } else {
- it->second++;
- }
- }
- static void ExpireBrokenAlternateProtocolMappings(
- HttpServerProperties* impl) {
- impl->broken_alternative_services_.ExpireBrokenAlternateProtocolMappings();
- }
- };
- namespace {
- // Creates a ServerInfoMapKey without a NetworkIsolationKey.
- HttpServerProperties::ServerInfoMapKey CreateSimpleKey(
- const url::SchemeHostPort& server) {
- return HttpServerProperties::ServerInfoMapKey(
- server, net::NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- }
- class HttpServerPropertiesTest : public TestWithTaskEnvironment {
- protected:
- HttpServerPropertiesTest()
- : TestWithTaskEnvironment(
- base::test::TaskEnvironment::TimeSource::MOCK_TIME),
- // Many tests assume partitioning is disabled by default.
- feature_list_(CreateFeatureListWithPartitioningDisabled()),
- test_tick_clock_(GetMockTickClock()),
- impl_(nullptr /* pref_delegate */,
- nullptr /* net_log */,
- test_tick_clock_,
- &test_clock_) {
- // Set |test_clock_| to some random time.
- test_clock_.Advance(base::Seconds(12345));
- SchemefulSite site1(GURL("https://foo.test/"));
- network_isolation_key1_ = NetworkIsolationKey(site1, site1);
- SchemefulSite site2(GURL("https://bar.test/"));
- network_isolation_key2_ = NetworkIsolationKey(site2, site2);
- }
- // This is a little awkward, but need to create and configure the
- // ScopedFeatureList before creating the HttpServerProperties.
- static std::unique_ptr<base::test::ScopedFeatureList>
- CreateFeatureListWithPartitioningDisabled() {
- std::unique_ptr<base::test::ScopedFeatureList> feature_list =
- std::make_unique<base::test::ScopedFeatureList>();
- feature_list->InitAndDisableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- return feature_list;
- }
- bool HasAlternativeService(const url::SchemeHostPort& origin,
- const NetworkIsolationKey& network_isolation_key) {
- const AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(origin, network_isolation_key);
- return !alternative_service_info_vector.empty();
- }
- void SetAlternativeService(const url::SchemeHostPort& origin,
- const AlternativeService& alternative_service) {
- const base::Time expiration = test_clock_.Now() + base::Days(1);
- if (alternative_service.protocol == kProtoQUIC) {
- impl_.SetQuicAlternativeService(origin, NetworkIsolationKey(),
- alternative_service, expiration,
- DefaultSupportedQuicVersions());
- } else {
- impl_.SetHttp2AlternativeService(origin, NetworkIsolationKey(),
- alternative_service, expiration);
- }
- }
- void MarkBrokenAndLetExpireAlternativeServiceNTimes(
- const AlternativeService& alternative_service,
- int num_times) {}
- std::unique_ptr<base::test::ScopedFeatureList> feature_list_;
- raw_ptr<const base::TickClock> test_tick_clock_;
- base::SimpleTestClock test_clock_;
- // Two different non-empty network isolation keys for use in tests that need
- // them.
- NetworkIsolationKey network_isolation_key1_;
- NetworkIsolationKey network_isolation_key2_;
- HttpServerProperties impl_;
- };
- TEST_F(HttpServerPropertiesTest, SetSupportsSpdy) {
- // Check spdy servers are correctly set with SchemeHostPort key.
- url::SchemeHostPort https_www_server("https", "www.google.com", 443);
- url::SchemeHostPort http_photo_server("http", "photos.google.com", 80);
- url::SchemeHostPort https_mail_server("https", "mail.google.com", 443);
- // Servers with port equal to default port in scheme will drop port components
- // when calling Serialize().
- url::SchemeHostPort http_google_server("http", "www.google.com", 443);
- url::SchemeHostPort https_photos_server("https", "photos.google.com", 443);
- url::SchemeHostPort valid_google_server((GURL("https://www.google.com")));
- impl_.SetSupportsSpdy(https_www_server, NetworkIsolationKey(), true);
- impl_.SetSupportsSpdy(http_photo_server, NetworkIsolationKey(), true);
- impl_.SetSupportsSpdy(https_mail_server, NetworkIsolationKey(), false);
- EXPECT_TRUE(impl_.GetSupportsSpdy(https_www_server, NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(https_www_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(http_photo_server, NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(http_photo_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(https_mail_server, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(https_mail_server, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.GetSupportsSpdy(http_google_server, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(http_google_server, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.GetSupportsSpdy(https_photos_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.SupportsRequestPriority(https_photos_server,
- NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.GetSupportsSpdy(valid_google_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.SupportsRequestPriority(valid_google_server,
- NetworkIsolationKey()));
- // Flip values of two servers.
- impl_.SetSupportsSpdy(https_www_server, NetworkIsolationKey(), false);
- impl_.SetSupportsSpdy(https_mail_server, NetworkIsolationKey(), true);
- EXPECT_FALSE(impl_.GetSupportsSpdy(https_www_server, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(https_www_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(https_mail_server, NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(https_mail_server, NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWebSockets) {
- // The https and wss servers should be treated as the same server, as should
- // the http and ws servers.
- url::SchemeHostPort https_server("https", "www.test.com", 443);
- url::SchemeHostPort wss_server("wss", "www.test.com", 443);
- url::SchemeHostPort http_server("http", "www.test.com", 443);
- url::SchemeHostPort ws_server("ws", "www.test.com", 443);
- EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
- impl_.SetSupportsSpdy(wss_server, NetworkIsolationKey(), true);
- EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
- impl_.SetSupportsSpdy(http_server, NetworkIsolationKey(), true);
- EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
- impl_.SetSupportsSpdy(https_server, NetworkIsolationKey(), false);
- EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
- impl_.SetSupportsSpdy(ws_server, NetworkIsolationKey(), false);
- EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) {
- const url::SchemeHostPort kServer("https", "foo.test", 443);
- EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- // Without network isolation keys enabled for HttpServerProperties, passing in
- // a NetworkIsolationKey should have no effect on behavior.
- for (const auto& network_isolation_key_to_set :
- {NetworkIsolationKey(), network_isolation_key1_}) {
- impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, true);
- EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- impl_.SetSupportsSpdy(kServer, network_isolation_key_to_set, false);
- EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- }
- // With network isolation keys enabled for HttpServerProperties, the
- // NetworkIsolationKey argument should be respected.
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_FALSE(
- properties.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_FALSE(
- properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- properties.SetSupportsSpdy(kServer, network_isolation_key1_, true);
- EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_TRUE(
- properties.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_FALSE(
- properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), true);
- EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_TRUE(
- properties.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_TRUE(
- properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- properties.SetSupportsSpdy(kServer, network_isolation_key1_, false);
- EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_FALSE(
- properties.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_TRUE(
- properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- properties.SetSupportsSpdy(kServer, NetworkIsolationKey(), false);
- EXPECT_FALSE(properties.GetSupportsSpdy(kServer, network_isolation_key1_));
- EXPECT_FALSE(
- properties.SupportsRequestPriority(kServer, network_isolation_key1_));
- EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkIsolationKey()));
- EXPECT_FALSE(
- properties.SupportsRequestPriority(kServer, NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, LoadSupportsSpdy) {
- HttpServerProperties::ServerInfo supports_spdy;
- supports_spdy.supports_spdy = true;
- HttpServerProperties::ServerInfo no_spdy;
- no_spdy.supports_spdy = false;
- url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
- url::SchemeHostPort spdy_server_photos("https", "photos.google.com", 443);
- url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
- url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
- // Check by initializing empty spdy servers.
- std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers));
- EXPECT_FALSE(
- impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- // Check by initializing www.google.com:443 and photos.google.com:443 as spdy
- // servers.
- std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers1 =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- spdy_servers1->Put(CreateSimpleKey(spdy_server_google), supports_spdy);
- spdy_servers1->Put(CreateSimpleKey(spdy_server_photos), no_spdy);
- impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers1));
- // Note: these calls affect MRU order.
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.GetSupportsSpdy(spdy_server_photos, NetworkIsolationKey()));
- // Verify google and photos are in the list in MRU order.
- ASSERT_EQ(2U, impl_.server_info_map_for_testing().size());
- auto it = impl_.server_info_map_for_testing().begin();
- EXPECT_EQ(spdy_server_photos, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_FALSE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_google, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- // Check by initializing mail.google.com:443 and docs.google.com:443.
- std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers2 =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- spdy_servers2->Put(CreateSimpleKey(spdy_server_mail), supports_spdy);
- spdy_servers2->Put(CreateSimpleKey(spdy_server_docs), supports_spdy);
- impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers2));
- // Verify all the servers are in the list in MRU order. Note that
- // OnServerInfoLoadedForTesting will put existing spdy server entries in
- // front of newly added entries.
- ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
- it = impl_.server_info_map_for_testing().begin();
- EXPECT_EQ(spdy_server_photos, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_FALSE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_google, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_docs, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_mail, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- // Check these in reverse MRU order so that MRU order stays the same.
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_docs, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.GetSupportsSpdy(spdy_server_photos, NetworkIsolationKey()));
- // Verify that old values loaded from disk take precedence over newer learned
- // values and also verify the recency list order is unchanged.
- std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers3 =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- spdy_servers3->Put(CreateSimpleKey(spdy_server_mail), no_spdy);
- spdy_servers3->Put(CreateSimpleKey(spdy_server_photos), supports_spdy);
- impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers3));
- // Verify the entries are in the same order.
- ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
- it = impl_.server_info_map_for_testing().begin();
- EXPECT_EQ(spdy_server_photos, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_google, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_docs, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_TRUE(*it->second.supports_spdy);
- ++it;
- EXPECT_EQ(spdy_server_mail, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.supports_spdy.has_value());
- EXPECT_FALSE(*it->second.supports_spdy);
- // Verify photos server doesn't support SPDY and other servers support SPDY.
- EXPECT_FALSE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_docs, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_photos, NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, SupportsRequestPriority) {
- url::SchemeHostPort spdy_server_empty("https", std::string(), 443);
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(spdy_server_empty, NetworkIsolationKey()));
- // Add www.google.com:443 as supporting SPDY.
- url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
- impl_.SetSupportsSpdy(spdy_server_google, NetworkIsolationKey(), true);
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(spdy_server_google, NetworkIsolationKey()));
- // Add mail.google.com:443 as not supporting SPDY.
- url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(spdy_server_mail, NetworkIsolationKey()));
- // Add docs.google.com:443 as supporting SPDY.
- url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
- impl_.SetSupportsSpdy(spdy_server_docs, NetworkIsolationKey(), true);
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(spdy_server_docs, NetworkIsolationKey()));
- // Add www.youtube.com:443 as supporting QUIC.
- url::SchemeHostPort youtube_server("https", "www.youtube.com", 443);
- const AlternativeService alternative_service1(kProtoQUIC, "www.youtube.com",
- 443);
- SetAlternativeService(youtube_server, alternative_service1);
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(youtube_server, NetworkIsolationKey()));
- // Add www.example.com:443 with two alternative services, one supporting QUIC.
- url::SchemeHostPort example_server("https", "www.example.com", 443);
- const AlternativeService alternative_service2(kProtoHTTP2, "", 443);
- SetAlternativeService(example_server, alternative_service2);
- SetAlternativeService(example_server, alternative_service1);
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(example_server, NetworkIsolationKey()));
- // Verify all the entries are the same after additions.
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(spdy_server_google, NetworkIsolationKey()));
- EXPECT_FALSE(
- impl_.SupportsRequestPriority(spdy_server_mail, NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(spdy_server_docs, NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(youtube_server, NetworkIsolationKey()));
- EXPECT_TRUE(
- impl_.SupportsRequestPriority(example_server, NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, ClearSupportsSpdy) {
- // Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
- url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
- impl_.SetSupportsSpdy(spdy_server_google, NetworkIsolationKey(), true);
- url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
- impl_.SetSupportsSpdy(spdy_server_mail, NetworkIsolationKey(), true);
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
- base::RunLoop run_loop;
- bool callback_invoked_ = false;
- impl_.Clear(base::BindOnce(
- [](bool* callback_invoked, base::OnceClosure quit_closure) {
- *callback_invoked = true;
- std::move(quit_closure).Run();
- },
- &callback_invoked_, run_loop.QuitClosure()));
- EXPECT_FALSE(
- impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetSupportsSpdy(spdy_server_mail, NetworkIsolationKey()));
- // Callback should be run asynchronously.
- EXPECT_FALSE(callback_invoked_);
- run_loop.Run();
- EXPECT_TRUE(callback_invoked_);
- }
- TEST_F(HttpServerPropertiesTest, MRUOfServerInfoMap) {
- url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
- url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
- // Add www.google.com:443 as supporting SPDY.
- impl_.SetSupportsSpdy(spdy_server_google, NetworkIsolationKey(), true);
- ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
- auto it = impl_.server_info_map_for_testing().begin();
- ASSERT_EQ(spdy_server_google, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- // Add mail.google.com:443 as supporting SPDY. Verify mail.google.com:443 and
- // www.google.com:443 are in the list.
- impl_.SetSupportsSpdy(spdy_server_mail, NetworkIsolationKey(), true);
- ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
- it = impl_.server_info_map_for_testing().begin();
- ASSERT_EQ(spdy_server_mail, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ++it;
- ASSERT_EQ(spdy_server_google, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- // Get www.google.com:443. It should become the most-recently-used server.
- EXPECT_TRUE(impl_.GetSupportsSpdy(spdy_server_google, NetworkIsolationKey()));
- ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
- it = impl_.server_info_map_for_testing().begin();
- ASSERT_EQ(spdy_server_google, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ++it;
- ASSERT_EQ(spdy_server_mail, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- }
- typedef HttpServerPropertiesTest AlternateProtocolServerPropertiesTest;
- TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
- url::SchemeHostPort test_server("http", "foo", 80);
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- SetAlternativeService(test_server, alternative_service);
- const AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service,
- alternative_service_info_vector[0].alternative_service());
- impl_.Clear(base::OnceClosure());
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, ExcludeOrigin) {
- AlternativeServiceInfoVector alternative_service_info_vector;
- base::Time expiration = test_clock_.Now() + base::Days(1);
- // Same hostname, same port, TCP: should be ignored.
- AlternativeServiceInfo alternative_service_info1 =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- AlternativeService(kProtoHTTP2, "foo", 443), expiration);
- alternative_service_info_vector.push_back(alternative_service_info1);
- // Different hostname: GetAlternativeServiceInfos should return this one.
- AlternativeServiceInfo alternative_service_info2 =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- AlternativeService(kProtoHTTP2, "bar", 443), expiration);
- alternative_service_info_vector.push_back(alternative_service_info2);
- // Different port: GetAlternativeServiceInfos should return this one too.
- AlternativeServiceInfo alternative_service_info3 =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- AlternativeService(kProtoHTTP2, "foo", 80), expiration);
- alternative_service_info_vector.push_back(alternative_service_info3);
- // QUIC: GetAlternativeServices should return this one too.
- AlternativeServiceInfo alternative_service_info4 =
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- AlternativeService(kProtoQUIC, "foo", 443), expiration,
- DefaultSupportedQuicVersions());
- alternative_service_info_vector.push_back(alternative_service_info4);
- url::SchemeHostPort test_server("https", "foo", 443);
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- const AlternativeServiceInfoVector alternative_service_info_vector2 =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(3u, alternative_service_info_vector2.size());
- EXPECT_EQ(alternative_service_info2, alternative_service_info_vector2[0]);
- EXPECT_EQ(alternative_service_info3, alternative_service_info_vector2[1]);
- EXPECT_EQ(alternative_service_info4, alternative_service_info_vector2[2]);
- }
- TEST_F(AlternateProtocolServerPropertiesTest, Set) {
- // |test_server1| has an alternative service, which will not be
- // affected by OnServerInfoLoadedForTesting(), because
- // |server_info_map| does not have an entry for
- // |test_server1|.
- url::SchemeHostPort test_server1("http", "foo1", 80);
- const AlternativeService alternative_service1(kProtoHTTP2, "bar1", 443);
- const base::Time now = test_clock_.Now();
- base::Time expiration1 = now + base::Days(1);
- // 1st entry in the memory.
- impl_.SetHttp2AlternativeService(test_server1, NetworkIsolationKey(),
- alternative_service1, expiration1);
- // |test_server2| has an alternative service, which will be
- // overwritten by OnServerInfoLoadedForTesting(), because
- // |server_info_map| has an entry for |test_server2|.
- AlternativeServiceInfoVector alternative_service_info_vector;
- const AlternativeService alternative_service2(kProtoHTTP2, "bar2", 443);
- base::Time expiration2 = now + base::Days(2);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, expiration2));
- url::SchemeHostPort test_server2("http", "foo2", 80);
- // 0th entry in the memory.
- impl_.SetAlternativeServices(test_server2, NetworkIsolationKey(),
- alternative_service_info_vector);
- // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
- std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- const AlternativeService alternative_service3(kProtoHTTP2, "bar3", 123);
- base::Time expiration3 = now + base::Days(3);
- const AlternativeServiceInfo alternative_service_info1 =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service3, expiration3);
- // Simulate updating data for 0th entry with data from Preferences.
- server_info_map->GetOrPut(CreateSimpleKey(test_server2))
- ->second.alternative_services =
- AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1);
- url::SchemeHostPort test_server3("http", "foo3", 80);
- const AlternativeService alternative_service4(kProtoHTTP2, "bar4", 1234);
- base::Time expiration4 = now + base::Days(4);
- const AlternativeServiceInfo alternative_service_info2 =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service4, expiration4);
- // Add an old entry from Preferences, this will be added to end of recency
- // list.
- server_info_map->GetOrPut(CreateSimpleKey(test_server3))
- ->second.alternative_services =
- AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2);
- // MRU list will be test_server2, test_server1, test_server3.
- impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
- // Verify server_info_map.
- const HttpServerProperties::ServerInfoMap& map =
- impl_.server_info_map_for_testing();
- ASSERT_EQ(3u, map.size());
- auto map_it = map.begin();
- EXPECT_EQ(test_server2, map_it->first.server);
- EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(map_it->second.alternative_services.has_value());
- const AlternativeServiceInfoVector* service_info =
- &map_it->second.alternative_services.value();
- ASSERT_EQ(1u, service_info->size());
- EXPECT_EQ(alternative_service3, (*service_info)[0].alternative_service());
- EXPECT_EQ(expiration3, (*service_info)[0].expiration());
- ++map_it;
- EXPECT_EQ(test_server1, map_it->first.server);
- EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(map_it->second.alternative_services.has_value());
- service_info = &map_it->second.alternative_services.value();
- ASSERT_EQ(1u, service_info->size());
- EXPECT_EQ(alternative_service1, (*service_info)[0].alternative_service());
- EXPECT_EQ(expiration1, (*service_info)[0].expiration());
- ++map_it;
- EXPECT_EQ(map_it->first.server, test_server3);
- EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(map_it->second.alternative_services.has_value());
- service_info = &map_it->second.alternative_services.value();
- ASSERT_EQ(1u, service_info->size());
- EXPECT_EQ(alternative_service4, (*service_info)[0].alternative_service());
- EXPECT_EQ(expiration4, (*service_info)[0].expiration());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, SetWebSockets) {
- // The https and wss servers should be treated as the same server, as should
- // the http and ws servers.
- url::SchemeHostPort https_server("https", "www.test.com", 443);
- url::SchemeHostPort wss_server("wss", "www.test.com", 443);
- url::SchemeHostPort http_server("http", "www.test.com", 443);
- url::SchemeHostPort ws_server("ws", "www.test.com", 443);
- AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
- EXPECT_EQ(
- 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
- .size());
- SetAlternativeService(wss_server, alternative_service);
- EXPECT_EQ(
- 1u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(1u,
- impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
- .size());
- SetAlternativeService(http_server, alternative_service);
- EXPECT_EQ(
- 1u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(1u,
- impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(1u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(1u,
- impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
- .size());
- impl_.SetAlternativeServices(https_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_EQ(
- 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(1u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(1u,
- impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
- .size());
- impl_.SetAlternativeServices(ws_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_EQ(
- 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(wss_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(ws_server, NetworkIsolationKey())
- .size());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
- const url::SchemeHostPort kServer("https", "foo.test", 443);
- const AlternativeServiceInfoVector kAlternativeServices(
- {AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- AlternativeService(kProtoHTTP2, "foo", 443),
- base::Time::Now() + base::Days(1) /* expiration */)});
- EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
- .empty());
- EXPECT_TRUE(
- impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()).empty());
- // Without network isolation keys enabled for HttpServerProperties, passing in
- // a NetworkIsolationKey should have no effect on behavior.
- for (const auto& network_isolation_key_to_set :
- {NetworkIsolationKey(), network_isolation_key1_}) {
- impl_.SetAlternativeServices(kServer, network_isolation_key_to_set,
- kAlternativeServices);
- EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
- kServer, network_isolation_key1_));
- EXPECT_EQ(kAlternativeServices,
- impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey()));
- impl_.SetAlternativeServices(kServer, network_isolation_key_to_set,
- AlternativeServiceInfoVector());
- EXPECT_TRUE(
- impl_.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
- .empty());
- EXPECT_TRUE(impl_.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
- .empty());
- }
- // Check that with network isolation keys enabled for HttpServerProperties,
- // the NetworkIsolationKey argument is respected.
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- properties.SetAlternativeServices(kServer, network_isolation_key1_,
- kAlternativeServices);
- EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
- kServer, network_isolation_key1_));
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
- .empty());
- properties.SetAlternativeServices(kServer, NetworkIsolationKey(),
- kAlternativeServices);
- EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
- kServer, network_isolation_key1_));
- EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
- kServer, NetworkIsolationKey()));
- properties.SetAlternativeServices(kServer, network_isolation_key1_,
- AlternativeServiceInfoVector());
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
- .empty());
- EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
- kServer, NetworkIsolationKey()));
- properties.SetAlternativeServices(kServer, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(kServer, network_isolation_key1_)
- .empty());
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(kServer, NetworkIsolationKey())
- .empty());
- }
- // Regression test for https://crbug.com/504032:
- // OnServerInfoLoadedForTesting() should not crash if there is an
- // empty hostname is the mapping.
- TEST_F(AlternateProtocolServerPropertiesTest, SetWithEmptyHostname) {
- url::SchemeHostPort server("https", "foo", 443);
- const AlternativeService alternative_service_with_empty_hostname(kProtoHTTP2,
- "", 1234);
- const AlternativeService alternative_service_with_foo_hostname(kProtoHTTP2,
- "foo", 1234);
- SetAlternativeService(server, alternative_service_with_empty_hostname);
- impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname,
- NetworkIsolationKey());
- std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(
- alternative_service_with_foo_hostname, NetworkIsolationKey()));
- const AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service_with_foo_hostname,
- alternative_service_info_vector[0].alternative_service());
- }
- // Regression test for https://crbug.com/516486:
- // GetAlternativeServiceInfos() should remove |server_info_map_|
- // elements with empty value.
- TEST_F(AlternateProtocolServerPropertiesTest, EmptyVector) {
- url::SchemeHostPort server("https", "foo", 443);
- const AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
- base::Time expiration = test_clock_.Now() - base::Days(1);
- const AlternativeServiceInfo alternative_service_info =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service, expiration);
- std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- server_info_map->GetOrPut(CreateSimpleKey(server))
- ->second.alternative_services = AlternativeServiceInfoVector(
- /*size=*/1, alternative_service_info);
- // Prepare |server_info_map_| with a single key that has a single
- // AlternativeServiceInfo with identical hostname and port.
- impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
- // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
- // |server_info_map_|, emptying the AlternativeServiceInfoVector
- // corresponding to |server|.
- ASSERT_TRUE(
- impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
- // GetAlternativeServiceInfos() should remove this key from
- // |server_info_map_|, and SetAlternativeServices() should not crash.
- impl_.SetAlternativeServices(
- server, NetworkIsolationKey(),
- AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
- // There should still be no alternative service assigned to |server|.
- ASSERT_TRUE(
- impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
- }
- // Regression test for https://crbug.com/516486 for the canonical host case.
- TEST_F(AlternateProtocolServerPropertiesTest, EmptyVectorForCanonical) {
- url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- const AlternativeService alternative_service(kProtoHTTP2, "", 443);
- base::Time expiration = test_clock_.Now() - base::Days(1);
- const AlternativeServiceInfo alternative_service_info =
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service, expiration);
- std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- server_info_map->GetOrPut(CreateSimpleKey(canonical_server))
- ->second.alternative_services =
- AlternativeServiceInfoVector(/*size=*/1, alternative_service_info);
- // Prepare |server_info_map_| with a single key that has a single
- // AlternativeServiceInfo with identical hostname and port.
- impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
- // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
- // |server_info_map_|, emptying the AlternativeServiceInfoVector
- // corresponding to |canonical_server|, even when looking up
- // alternative services for |server|.
- ASSERT_TRUE(
- impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
- // GetAlternativeServiceInfos() should remove this key from
- // |server_info_map_|, and SetAlternativeServices() should not crash.
- impl_.SetAlternativeServices(
- canonical_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
- // There should still be no alternative service assigned to
- // |canonical_server|.
- ASSERT_TRUE(
- impl_.GetAlternativeServiceInfos(canonical_server, NetworkIsolationKey())
- .empty());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, ClearServerWithCanonical) {
- url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- const AlternativeService alternative_service(kProtoQUIC, "", 443);
- base::Time expiration = test_clock_.Now() + base::Days(1);
- const AlternativeServiceInfo alternative_service_info =
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- alternative_service, expiration, DefaultSupportedQuicVersions());
- impl_.SetAlternativeServices(
- canonical_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
- // Make sure the canonical service is returned for the other server.
- const AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(kProtoQUIC,
- alternative_service_info_vector[0].alternative_service().protocol);
- EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
- // Now clear the alternatives for the other server and make sure it stays
- // cleared.
- // GetAlternativeServices() should remove this key from
- // |server_info_map_|, and SetAlternativeServices() should not crash.
- impl_.SetAlternativeServices(server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- ASSERT_TRUE(
- impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey()).empty());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServiceInfos) {
- url::SchemeHostPort test_server1("http", "foo1", 80);
- const AlternativeService alternative_service1(kProtoHTTP2, "foo1", 443);
- SetAlternativeService(test_server1, alternative_service1);
- url::SchemeHostPort test_server2("http", "foo2", 80);
- const AlternativeService alternative_service2(kProtoHTTP2, "foo2", 1234);
- SetAlternativeService(test_server2, alternative_service2);
- const HttpServerProperties::ServerInfoMap& map =
- impl_.server_info_map_for_testing();
- auto it = map.begin();
- EXPECT_EQ(test_server2, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.alternative_services.has_value());
- ASSERT_EQ(1u, it->second.alternative_services->size());
- EXPECT_EQ(alternative_service2,
- it->second.alternative_services.value()[0].alternative_service());
- const AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server1, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- // GetAlternativeServices should reorder the AlternateProtocol map.
- it = map.begin();
- EXPECT_EQ(test_server1, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.alternative_services.has_value());
- ASSERT_EQ(1u, it->second.alternative_services->size());
- EXPECT_EQ(alternative_service1,
- it->second.alternative_services.value()[0].alternative_service());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
- url::SchemeHostPort test_server("http", "foo", 80);
- const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
- SetAlternativeService(test_server, alternative_service1);
- AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- // GetAlternativeServiceInfos should return the broken alternative service.
- impl_.MarkAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey());
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- // SetAlternativeServices should add a broken alternative service to the map.
- AlternativeServiceInfoVector alternative_service_info_vector2;
- base::Time expiration = test_clock_.Now() + base::Days(1);
- alternative_service_info_vector2.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service1, expiration));
- const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
- alternative_service_info_vector2.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, expiration));
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- alternative_service_info_vector2);
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(2u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_EQ(alternative_service2,
- alternative_service_info_vector[1].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
- NetworkIsolationKey()));
- // SetAlternativeService should add a broken alternative service to the map.
- SetAlternativeService(test_server, alternative_service1);
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- SetBrokenUntilDefaultNetworkChanges) {
- url::SchemeHostPort test_server("http", "foo", 80);
- const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
- SetAlternativeService(test_server, alternative_service1);
- AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- // Mark the alternative service as broken until the default network changes.
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service1, NetworkIsolationKey());
- // The alternative service should be persisted and marked as broken.
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- // SetAlternativeServices should add a broken alternative service to the map.
- AlternativeServiceInfoVector alternative_service_info_vector2;
- base::Time expiration = test_clock_.Now() + base::Days(1);
- alternative_service_info_vector2.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service1, expiration));
- const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
- alternative_service_info_vector2.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, expiration));
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- alternative_service_info_vector2);
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(2u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_EQ(alternative_service2,
- alternative_service_info_vector[1].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
- NetworkIsolationKey()));
- // SetAlternativeService should add a broken alternative service to the map.
- SetAlternativeService(test_server, alternative_service1);
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(alternative_service1,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
- AlternativeServiceInfoVector alternative_service_info_vector;
- base::Time now = test_clock_.Now();
- base::TimeDelta one_day = base::Days(1);
- // First alternative service expired one day ago, should not be returned by
- // GetAlternativeServiceInfos().
- const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service1, now - one_day));
- // Second alterrnative service will expire one day from now, should be
- // returned by GetAlternativeSerices().
- const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, now + one_day));
- url::SchemeHostPort test_server("http", "foo", 80);
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- AlternativeServiceInfoVector alternative_service_info_vector2 =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector2.size());
- EXPECT_EQ(alternative_service2,
- alternative_service_info_vector2[0].alternative_service());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) {
- AlternativeServiceInfoVector alternative_service_info_vector;
- base::Time now = test_clock_.Now();
- base::TimeDelta one_day = base::Days(1);
- // First alternative service expired one day ago, should not be returned by
- // GetAlternativeServiceInfos().
- const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service1, now - one_day));
- // Second alterrnative service will expire one day from now, should be
- // returned by GetAlternativeSerices().
- const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, now + one_day));
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- impl_.SetAlternativeServices(canonical_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- AlternativeServiceInfoVector alternative_service_info_vector2 =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector2.size());
- EXPECT_EQ(alternative_service2,
- alternative_service_info_vector2[0].alternative_service());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, AlternativeServiceWithScheme) {
- AlternativeServiceInfoVector alternative_service_info_vector;
- const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
- base::Time expiration = test_clock_.Now() + base::Days(1);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service1, expiration));
- const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, expiration));
- // Set Alt-Svc list for |http_server|.
- url::SchemeHostPort http_server("http", "foo", 80);
- impl_.SetAlternativeServices(http_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- const net::HttpServerProperties::ServerInfoMap& map =
- impl_.server_info_map_for_testing();
- auto it = map.begin();
- EXPECT_EQ(http_server, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.alternative_services.has_value());
- ASSERT_EQ(2u, it->second.alternative_services->size());
- EXPECT_EQ(alternative_service1,
- it->second.alternative_services.value()[0].alternative_service());
- EXPECT_EQ(alternative_service2,
- it->second.alternative_services.value()[1].alternative_service());
- // Check Alt-Svc list should not be set for |https_server|.
- url::SchemeHostPort https_server("https", "foo", 80);
- EXPECT_EQ(
- 0u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- // Set Alt-Svc list for |https_server|.
- impl_.SetAlternativeServices(https_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- EXPECT_EQ(
- 2u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(2u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- // Clear Alt-Svc list for |http_server|.
- impl_.SetAlternativeServices(http_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_EQ(0u,
- impl_.GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
- .size());
- EXPECT_EQ(
- 2u, impl_.GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
- .size());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, ClearAlternativeServices) {
- AlternativeServiceInfoVector alternative_service_info_vector;
- const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
- base::Time expiration = test_clock_.Now() + base::Days(1);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service1, expiration));
- const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service2, expiration));
- url::SchemeHostPort test_server("http", "foo", 80);
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- const net::HttpServerProperties::ServerInfoMap& map =
- impl_.server_info_map_for_testing();
- auto it = map.begin();
- EXPECT_EQ(test_server, it->first.server);
- EXPECT_TRUE(it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(it->second.alternative_services.has_value());
- ASSERT_EQ(2u, it->second.alternative_services->size());
- EXPECT_EQ(alternative_service1,
- it->second.alternative_services.value()[0].alternative_service());
- EXPECT_EQ(alternative_service2,
- it->second.alternative_services.value()[1].alternative_service());
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_TRUE(map.empty());
- }
- // A broken alternative service in the mapping carries meaningful information,
- // therefore it should not be ignored by SetAlternativeService(). In
- // particular, an alternative service mapped to an origin shadows alternative
- // services of canonical hosts.
- TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- AlternativeService canonical_alternative_service(kProtoQUIC,
- "bar.c.youtube.com", 1234);
- SetAlternativeService(canonical_server, canonical_alternative_service);
- AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(canonical_alternative_service,
- alternative_service_info_vector[0].alternative_service());
- const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443);
- impl_.MarkAlternativeServiceBroken(broken_alternative_service,
- NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
- NetworkIsolationKey()));
- SetAlternativeService(test_server, broken_alternative_service);
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(broken_alternative_service,
- alternative_service_info_vector[0].alternative_service());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
- NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
- url::SchemeHostPort test_server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- SetAlternativeService(test_server, alternative_service);
- impl_.MarkAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey());
- ASSERT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- // SetAlternativeServices should leave a broken alternative service marked
- // as such.
- impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- MarkBrokenWithNetworkIsolationKey) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- const base::Time expiration = test_clock_.Now() + base::Days(1);
- // Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
- // should be ignored.
- impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- impl_.MarkAlternativeServiceBroken(alternative_service,
- network_isolation_key1_);
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- properties.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- properties.SetHttp2AlternativeService(server, network_isolation_key2_,
- alternative_service, expiration);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceBroken(alternative_service,
- network_isolation_key1_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceBroken(alternative_service,
- network_isolation_key2_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.ConfirmAlternativeService(alternative_service,
- network_isolation_key1_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.ConfirmAlternativeService(alternative_service,
- network_isolation_key2_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- SetAlternativeService(server, alternative_service);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- impl_.ConfirmAlternativeService(alternative_service, NetworkIsolationKey());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- MarkRecentlyBrokenWithNetworkIsolationKey) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- const base::Time expiration = test_clock_.Now() + base::Days(1);
- // Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
- // should be ignored.
- impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
- network_isolation_key1_);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- properties.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- properties.SetHttp2AlternativeService(server, network_isolation_key2_,
- alternative_service, expiration);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
- network_isolation_key1_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
- network_isolation_key2_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.ConfirmAlternativeService(alternative_service,
- network_isolation_key1_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.ConfirmAlternativeService(alternative_service,
- network_isolation_key2_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- MarkBrokenUntilDefaultNetworkChanges) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- SetAlternativeService(server, alternative_service);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- impl_.ConfirmAlternativeService(alternative_service, NetworkIsolationKey());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- const base::Time expiration = test_clock_.Now() + base::Days(1);
- // Without NetworkIsolationKeys enabled, the NetworkIsolationKey parameter
- // should be ignored.
- impl_.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, network_isolation_key1_);
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- impl_.ConfirmAlternativeService(alternative_service, network_isolation_key2_);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- properties.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- properties.SetHttp2AlternativeService(server, network_isolation_key2_,
- alternative_service, expiration);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, network_isolation_key1_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, network_isolation_key2_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.ConfirmAlternativeService(alternative_service,
- network_isolation_key1_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.ConfirmAlternativeService(alternative_service,
- network_isolation_key2_);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- SetAlternativeService(server, alternative_service);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- // Default network change clears alt svc broken until default network changes.
- impl_.OnDefaultNetworkChanged();
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- // Default network change doesn't affect alt svc that was simply marked broken
- // most recently.
- impl_.OnDefaultNetworkChanged();
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- // Default network change clears alt svc that was marked broken until default
- // network change most recently even if the alt svc was initially marked
- // broken.
- impl_.OnDefaultNetworkChanged();
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- OnDefaultNetworkChangedWithNetworkIsolationKey) {
- url::SchemeHostPort server("http", "foo", 80);
- const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- const base::Time expiration = test_clock_.Now() + base::Days(1);
- properties.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service, expiration);
- properties.SetHttp2AlternativeService(server, network_isolation_key2_,
- alternative_service, expiration);
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, network_isolation_key1_);
- properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- alternative_service, network_isolation_key2_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- // Default network change clears alt svc broken until default network changes.
- properties.OnDefaultNetworkChanged();
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- EXPECT_FALSE(HasAlternativeService(canonical_server, NetworkIsolationKey()));
- AlternativeServiceInfoVector alternative_service_info_vector;
- const AlternativeService canonical_alternative_service1(
- kProtoQUIC, "bar.c.youtube.com", 1234);
- base::Time expiration = test_clock_.Now() + base::Days(1);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- canonical_alternative_service1, expiration,
- DefaultSupportedQuicVersions()));
- const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- canonical_alternative_service2, expiration));
- impl_.SetAlternativeServices(canonical_server, NetworkIsolationKey(),
- alternative_service_info_vector);
- // Since |test_server| does not have an alternative service itself,
- // GetAlternativeServiceInfos should return those of |canonical_server|.
- AlternativeServiceInfoVector alternative_service_info_vector2 =
- impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
- ASSERT_EQ(2u, alternative_service_info_vector2.size());
- EXPECT_EQ(canonical_alternative_service1,
- alternative_service_info_vector2[0].alternative_service());
- // Since |canonical_alternative_service2| has an empty host,
- // GetAlternativeServiceInfos should substitute the hostname of its |origin|
- // argument.
- EXPECT_EQ(test_server.host(),
- alternative_service_info_vector2[1].alternative_service().host);
- EXPECT_EQ(canonical_alternative_service2.protocol,
- alternative_service_info_vector2[1].alternative_service().protocol);
- EXPECT_EQ(canonical_alternative_service2.port,
- alternative_service_info_vector2[1].alternative_service().port);
- // Verify the canonical suffix.
- EXPECT_EQ(".c.youtube.com",
- *impl_.GetCanonicalSuffixForTesting(test_server.host()));
- EXPECT_EQ(".c.youtube.com",
- *impl_.GetCanonicalSuffixForTesting(canonical_server.host()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- AlternativeService canonical_alternative_service(kProtoQUIC,
- "bar.c.youtube.com", 1234);
- SetAlternativeService(canonical_server, canonical_alternative_service);
- impl_.SetAlternativeServices(canonical_server, NetworkIsolationKey(),
- AlternativeServiceInfoVector());
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- CanonicalWithNetworkIsolationKey) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- EXPECT_FALSE(HasAlternativeService(test_server, network_isolation_key1_));
- url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443);
- EXPECT_FALSE(
- HasAlternativeService(canonical_server1, network_isolation_key1_));
- AlternativeServiceInfoVector alternative_service_info_vector;
- const AlternativeService canonical_alternative_service1(
- kProtoQUIC, "bar.c.youtube.com", 1234);
- base::Time expiration = test_clock_.Now() + base::Days(1);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- canonical_alternative_service1, expiration,
- DefaultSupportedQuicVersions()));
- const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- canonical_alternative_service2, expiration));
- properties.SetAlternativeServices(canonical_server1, network_isolation_key1_,
- alternative_service_info_vector);
- // Since |test_server| does not have an alternative service itself,
- // GetAlternativeServiceInfos should return those of |canonical_server|.
- AlternativeServiceInfoVector alternative_service_info_vector2 =
- properties.GetAlternativeServiceInfos(test_server,
- network_isolation_key1_);
- ASSERT_EQ(2u, alternative_service_info_vector2.size());
- EXPECT_EQ(canonical_alternative_service1,
- alternative_service_info_vector2[0].alternative_service());
- // Canonical information should not be visible for other NetworkIsolationKeys.
- EXPECT_TRUE(
- properties
- .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
- .empty());
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
- .empty());
- // Now add an alternative service entry for network_isolation_key2_ for a
- // different server and different NetworkIsolationKey, but with the same
- // canonical suffix.
- url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443);
- properties.SetAlternativeServices(canonical_server2, network_isolation_key2_,
- {alternative_service_info_vector[0]});
- // The canonical server information should reachable, and different, for both
- // NetworkIsolationKeys.
- EXPECT_EQ(
- 1u, properties
- .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
- .size());
- EXPECT_EQ(
- 2u, properties
- .GetAlternativeServiceInfos(test_server, network_isolation_key1_)
- .size());
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
- .empty());
- // Clearing the alternate service state of network_isolation_key1_'s canonical
- // server should only affect network_isolation_key1_.
- properties.SetAlternativeServices(canonical_server1, network_isolation_key1_,
- {});
- EXPECT_EQ(
- 1u, properties
- .GetAlternativeServiceInfos(test_server, network_isolation_key2_)
- .size());
- EXPECT_TRUE(
- properties
- .GetAlternativeServiceInfos(test_server, network_isolation_key1_)
- .empty());
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
- .empty());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) {
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- AlternativeService canonical_alternative_service(kProtoQUIC,
- "bar.c.youtube.com", 1234);
- SetAlternativeService(canonical_server, canonical_alternative_service);
- EXPECT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBroken(canonical_alternative_service,
- NetworkIsolationKey());
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- CanonicalBrokenUntilDefaultNetworkChanges) {
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- AlternativeService canonical_alternative_service(kProtoQUIC,
- "bar.c.youtube.com", 1234);
- SetAlternativeService(canonical_server, canonical_alternative_service);
- EXPECT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- canonical_alternative_service, NetworkIsolationKey());
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- }
- // Adding an alternative service for a new host overrides canonical host.
- TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
- url::SchemeHostPort foo_server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort bar_server("https", "bar.c.youtube.com", 443);
- AlternativeService bar_alternative_service(kProtoQUIC, "bar.c.youtube.com",
- 1234);
- SetAlternativeService(bar_server, bar_alternative_service);
- AlternativeServiceInfoVector alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(foo_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(bar_alternative_service,
- alternative_service_info_vector[0].alternative_service());
- url::SchemeHostPort qux_server("https", "qux.c.youtube.com", 443);
- AlternativeService qux_alternative_service(kProtoQUIC, "qux.c.youtube.com",
- 443);
- SetAlternativeService(qux_server, qux_alternative_service);
- alternative_service_info_vector =
- impl_.GetAlternativeServiceInfos(foo_server, NetworkIsolationKey());
- ASSERT_EQ(1u, alternative_service_info_vector.size());
- EXPECT_EQ(qux_alternative_service,
- alternative_service_info_vector[0].alternative_service());
- }
- TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
- url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
- url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
- AlternativeService canonical_alternative_service(kProtoQUIC,
- "bar.c.youtube.com", 1234);
- SetAlternativeService(canonical_server, canonical_alternative_service);
- impl_.Clear(base::OnceClosure());
- EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- ExpireBrokenAlternateProtocolMappings) {
- url::SchemeHostPort server("https", "foo", 443);
- AlternativeService alternative_service(kProtoQUIC, "foo", 443);
- SetAlternativeService(server, alternative_service);
- EXPECT_TRUE(HasAlternativeService(server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- alternative_service, NetworkIsolationKey()));
- base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
- HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
- &impl_, alternative_service, past);
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
- EXPECT_FALSE(HasAlternativeService(server, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
- NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey) {
- url::SchemeHostPort server("https", "foo", 443);
- AlternativeService alternative_service(kProtoHTTP2, "foo", 444);
- base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
- base::TimeTicks future = test_tick_clock_->NowTicks() + base::Seconds(42);
- const base::Time alt_service_expiration = test_clock_.Now() + base::Days(1);
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- properties.SetHttp2AlternativeService(server, network_isolation_key1_,
- alternative_service,
- alt_service_expiration);
- properties.SetHttp2AlternativeService(server, network_isolation_key2_,
- alternative_service,
- alt_service_expiration);
- EXPECT_FALSE(
- properties.GetAlternativeServiceInfos(server, network_isolation_key1_)
- .empty());
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(
- properties.GetAlternativeServiceInfos(server, network_isolation_key2_)
- .empty());
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- // Set broken alternative service with expiration date in the past for
- // |network_isolation_key1_|.
- HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
- &properties, alternative_service, past, network_isolation_key1_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- // Set broken alternative service with expiration date in the future for
- // |network_isolation_key1_|.
- HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
- &properties, alternative_service, future, network_isolation_key2_);
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- // Only the broken entry for |network_isolation_key1_| should be expired.
- HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&properties);
- EXPECT_TRUE(
- properties.GetAlternativeServiceInfos(server, network_isolation_key1_)
- .empty());
- EXPECT_FALSE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key1_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key1_));
- EXPECT_FALSE(
- properties.GetAlternativeServiceInfos(server, network_isolation_key2_)
- .empty());
- EXPECT_TRUE(properties.IsAlternativeServiceBroken(alternative_service,
- network_isolation_key2_));
- EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
- alternative_service, network_isolation_key2_));
- }
- // Regression test for https://crbug.com/505413.
- TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
- url::SchemeHostPort foo_server("https", "foo", 443);
- AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443);
- SetAlternativeService(foo_server, bar_alternative_service);
- EXPECT_TRUE(HasAlternativeService(foo_server, NetworkIsolationKey()));
- url::SchemeHostPort bar_server1("http", "bar", 80);
- AlternativeService nohost_alternative_service(kProtoQUIC, "", 443);
- SetAlternativeService(bar_server1, nohost_alternative_service);
- EXPECT_TRUE(HasAlternativeService(bar_server1, NetworkIsolationKey()));
- url::SchemeHostPort bar_server2("https", "bar", 443);
- AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234);
- SetAlternativeService(bar_server2, baz_alternative_service);
- EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkIsolationKey()));
- // Mark "bar:443" as broken.
- base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
- HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
- &impl_, bar_alternative_service, past);
- // Expire brokenness of "bar:443".
- HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
- // "foo:443" should have no alternative service now.
- EXPECT_FALSE(HasAlternativeService(foo_server, NetworkIsolationKey()));
- // "bar:80" should have no alternative service now.
- EXPECT_FALSE(HasAlternativeService(bar_server1, NetworkIsolationKey()));
- // The alternative service of "bar:443" should be unaffected.
- EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkIsolationKey()));
- EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
- baz_alternative_service, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- SetBrokenAlternativeServicesDelayParams1) {
- url::SchemeHostPort server("https", "foo", 443);
- AlternativeService alternative_service(kProtoQUIC, "foo", 443);
- SetAlternativeService(server, alternative_service);
- const base::TimeDelta initial_delay = base::Seconds(1);
- impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, true);
- for (int i = 0; i < 10; ++i) {
- impl_.MarkAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey());
- // |impl_| should have posted task to expire the brokenness of
- // |alternative_service|
- EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- // Advance time by just enough so that |alternative_service|'s brokenness
- // expires.
- FastForwardBy(initial_delay * (1 << i));
- // Ensure brokenness of |alternative_service| has expired.
- EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- }
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- SetBrokenAlternativeServicesDelayParams2) {
- url::SchemeHostPort server("https", "foo", 443);
- AlternativeService alternative_service(kProtoQUIC, "foo", 443);
- SetAlternativeService(server, alternative_service);
- const base::TimeDelta initial_delay = base::Seconds(5);
- impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, false);
- for (int i = 0; i < 10; ++i) {
- impl_.MarkAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey());
- // |impl_| should have posted task to expire the brokenness of
- // |alternative_service|
- EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- // Advance time by just enough so that |alternative_service|'s brokenness
- // expires.
- if (i == 0) {
- FastForwardBy(initial_delay);
- } else {
- FastForwardBy(base::Seconds(300) * (1 << (i - 1)));
- }
- // Ensure brokenness of |alternative_service| has expired.
- EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
- NetworkIsolationKey()));
- }
- }
- // Regression test for https://crbug.com/724302
- TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) {
- // This test will mark an alternative service A that has already been marked
- // broken many times, then immediately mark another alternative service B as
- // broken for the first time. Because A's been marked broken many times
- // already, its brokenness will be scheduled to expire much further in the
- // future than B, even though it was marked broken before B. This test makes
- // sure that even though A was marked broken before B, B's brokenness should
- // expire before A.
- url::SchemeHostPort server1("https", "foo", 443);
- AlternativeService alternative_service1(kProtoQUIC, "foo", 443);
- SetAlternativeService(server1, alternative_service1);
- url::SchemeHostPort server2("https", "bar", 443);
- AlternativeService alternative_service2(kProtoQUIC, "bar", 443);
- SetAlternativeService(server2, alternative_service2);
- // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire.
- // This will increase its time until expiration.
- for (int i = 0; i < 3; ++i) {
- impl_.MarkAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey());
- // |impl_| should have posted task to expire the brokenness of
- // |alternative_service1|
- EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- // Advance time by just enough so that |alternative_service1|'s brokenness
- // expires.
- FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]);
- // Ensure brokenness of |alternative_service1| has expired.
- EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- }
- impl_.MarkAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey());
- impl_.MarkAlternativeServiceBroken(alternative_service2,
- NetworkIsolationKey());
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2,
- NetworkIsolationKey()));
- // Advance time by just enough so that |alternative_service2|'s brokennness
- // expires.
- FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
- EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
- NetworkIsolationKey()));
- // Advance time by enough so that |alternative_service1|'s brokenness expires.
- FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] -
- BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
- NetworkIsolationKey()));
- EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
- NetworkIsolationKey()));
- }
- // Regression test for https://crbug.com/994537. Having a ServerInfo entry
- // without a populated |alternative_services| value would cause
- // OnExpireBrokenAlternativeService() to hang..
- TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc3) {
- // Add an altertive service entry.
- const url::SchemeHostPort kServer1("https", "foo", 443);
- const AlternativeService kAltService(kProtoQUIC, "bar", 443);
- SetAlternativeService(kServer1, kAltService);
- EXPECT_TRUE(HasAlternativeService(kServer1, NetworkIsolationKey()));
- // Add an entry to ServerInfo for another server, without an alternative
- // service value.
- const url::SchemeHostPort kServer2("http", "bar", 80);
- impl_.SetSupportsSpdy(kServer2, NetworkIsolationKey(), false);
- // Mark kAltService as broken.
- base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
- HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
- &impl_, kAltService, past);
- // Expire brokenness of kAltService. This call should not hang.
- HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
- EXPECT_FALSE(HasAlternativeService(kServer1, NetworkIsolationKey()));
- }
- TEST_F(AlternateProtocolServerPropertiesTest,
- GetAlternativeServiceInfoAsValue) {
- base::Time::Exploded now_exploded;
- now_exploded.year = 2018;
- now_exploded.month = 1;
- now_exploded.day_of_week = 3;
- now_exploded.day_of_month = 24;
- now_exploded.hour = 15;
- now_exploded.minute = 12;
- now_exploded.second = 53;
- now_exploded.millisecond = 0;
- base::Time now;
- bool result = base::Time::FromLocalExploded(now_exploded, &now);
- DCHECK(result);
- test_clock_.SetNow(now);
- AlternativeServiceInfoVector alternative_service_info_vector;
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- AlternativeService(kProtoHTTP2, "foo", 443), now + base::Minutes(1)));
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- AlternativeService(kProtoQUIC, "bar", 443), now + base::Hours(1),
- DefaultSupportedQuicVersions()));
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- AlternativeService(kProtoQUIC, "baz", 443), now + base::Hours(1),
- DefaultSupportedQuicVersions()));
- impl_.SetAlternativeServices(url::SchemeHostPort("https", "youtube.com", 443),
- NetworkIsolationKey(),
- alternative_service_info_vector);
- impl_.MarkAlternativeServiceBroken(AlternativeService(kProtoQUIC, "bar", 443),
- NetworkIsolationKey());
- impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- AlternativeService(kProtoQUIC, "baz", 443), NetworkIsolationKey());
- alternative_service_info_vector.clear();
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- AlternativeService(kProtoHTTP2, "foo2", 443), now + base::Days(1)));
- impl_.SetAlternativeServices(url::SchemeHostPort("http", "test.com", 80),
- NetworkIsolationKey(),
- alternative_service_info_vector);
- const char expected_json[] =
- "["
- "{"
- "\"alternative_service\":"
- "[\"h2 foo2:443, expires 2018-01-25 15:12:53\"],"
- "\"network_isolation_key\":\"null null\","
- "\"server\":\"http://test.com\""
- "},"
- "{"
- "\"alternative_service\":"
- "[\"h2 foo:443, expires 2018-01-24 15:13:53\","
- "\"quic bar:443, expires 2018-01-24 16:12:53"
- " (broken until 2018-01-24 15:17:53)\","
- "\"quic baz:443, expires 2018-01-24 16:12:53"
- " (broken until 2018-01-24 15:17:53)\"],"
- "\"network_isolation_key\":\"null null\","
- "\"server\":\"https://youtube.com\""
- "}"
- "]";
- base::Value alternative_service_info_value =
- impl_.GetAlternativeServiceInfoAsValue();
- std::string alternative_service_info_json;
- base::JSONWriter::Write(alternative_service_info_value,
- &alternative_service_info_json);
- EXPECT_EQ(expected_json, alternative_service_info_json);
- }
- TEST_F(HttpServerPropertiesTest, LoadLastLocalAddressWhenQuicWorked) {
- const IPAddress kEmptyAddress;
- const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
- const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
- // Check by initializing empty address.
- impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
- EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
- // Empty address should not be considered an address that was used when QUIC
- // worked.
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // Check by initializing with a valid address.
- impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress1);
- EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // Try another valid address.
- impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress2);
- EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // And loading an empty address clears the current one.
- // TODO(mmenke): This seems like a bug, since if we've learned the current
- // network supports QUIC, surely we want to save that to disk? Seems like a
- // pre-existing value should take precedence, if non-empty, since if the
- // current network is already known to support QUIC, the loaded value is no
- // longer relevant.
- impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
- EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- }
- TEST_F(HttpServerPropertiesTest, SetLastLocalAddressWhenQuicWorked) {
- const IPAddress kEmptyAddress;
- const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
- const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
- EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // Set to a valid address.
- impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress1);
- EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // Clear only this value.
- impl_.ClearLastLocalAddressWhenQuicWorked();
- EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // Try another valid address.
- impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress2);
- EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- // Clear all values.
- impl_.Clear(base::OnceClosure());
- EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
- EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
- }
- TEST_F(HttpServerPropertiesTest, LoadServerNetworkStats) {
- url::SchemeHostPort google_server("https", "www.google.com", 443);
- // Check by initializing empty ServerNetworkStats.
- std::unique_ptr<HttpServerProperties::ServerInfoMap> load_server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
- const ServerNetworkStats* stats =
- impl_.GetServerNetworkStats(google_server, NetworkIsolationKey());
- EXPECT_EQ(nullptr, stats);
- // Check by initializing with www.google.com:443.
- ServerNetworkStats stats_google;
- stats_google.srtt = base::Microseconds(10);
- stats_google.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
- load_server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- load_server_info_map->GetOrPut(CreateSimpleKey(google_server))
- ->second.server_network_stats = stats_google;
- impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
- // Verify data for www.google.com:443.
- ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
- EXPECT_EQ(stats_google, *(impl_.GetServerNetworkStats(
- google_server, NetworkIsolationKey())));
- // Test recency order and overwriting of data.
- //
- // |docs_server| has a ServerNetworkStats, which will be overwritten by
- // OnServerInfoLoadedForTesting(), because |server_network_stats_map| has an
- // entry for |docs_server|.
- url::SchemeHostPort docs_server("https", "docs.google.com", 443);
- ServerNetworkStats stats_docs;
- stats_docs.srtt = base::Microseconds(20);
- stats_docs.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(200);
- // Recency order will be |docs_server| and |google_server|.
- impl_.SetServerNetworkStats(docs_server, NetworkIsolationKey(), stats_docs);
- // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
- std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
- std::make_unique<HttpServerProperties::ServerInfoMap>();
- // Change the values for |docs_server|.
- ServerNetworkStats new_stats_docs;
- new_stats_docs.srtt = base::Microseconds(25);
- new_stats_docs.bandwidth_estimate =
- quic::QuicBandwidth::FromBitsPerSecond(250);
- server_info_map->GetOrPut(CreateSimpleKey(docs_server))
- ->second.server_network_stats = new_stats_docs;
- // Add data for mail.google.com:443.
- url::SchemeHostPort mail_server("https", "mail.google.com", 443);
- ServerNetworkStats stats_mail;
- stats_mail.srtt = base::Microseconds(30);
- stats_mail.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(300);
- server_info_map->GetOrPut(CreateSimpleKey(mail_server))
- ->second.server_network_stats = stats_mail;
- // Recency order will be |docs_server|, |google_server| and |mail_server|.
- impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
- const HttpServerProperties::ServerInfoMap& map =
- impl_.server_info_map_for_testing();
- ASSERT_EQ(3u, map.size());
- auto map_it = map.begin();
- EXPECT_EQ(docs_server, map_it->first.server);
- EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(map_it->second.server_network_stats.has_value());
- EXPECT_EQ(new_stats_docs, *map_it->second.server_network_stats);
- ++map_it;
- EXPECT_EQ(google_server, map_it->first.server);
- EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(map_it->second.server_network_stats.has_value());
- EXPECT_EQ(stats_google, *map_it->second.server_network_stats);
- ++map_it;
- EXPECT_EQ(mail_server, map_it->first.server);
- EXPECT_TRUE(map_it->first.network_isolation_key.IsEmpty());
- ASSERT_TRUE(map_it->second.server_network_stats.has_value());
- EXPECT_EQ(stats_mail, *map_it->second.server_network_stats);
- }
- TEST_F(HttpServerPropertiesTest, SetServerNetworkStats) {
- url::SchemeHostPort foo_http_server("http", "foo", 443);
- url::SchemeHostPort foo_https_server("https", "foo", 443);
- EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
- NetworkIsolationKey()));
- EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
- NetworkIsolationKey()));
- ServerNetworkStats stats1;
- stats1.srtt = base::Microseconds(10);
- stats1.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
- impl_.SetServerNetworkStats(foo_http_server, NetworkIsolationKey(), stats1);
- const ServerNetworkStats* stats2 =
- impl_.GetServerNetworkStats(foo_http_server, NetworkIsolationKey());
- EXPECT_EQ(10, stats2->srtt.ToInternalValue());
- EXPECT_EQ(100, stats2->bandwidth_estimate.ToBitsPerSecond());
- // Https server should have nothing set for server network stats.
- EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
- NetworkIsolationKey()));
- impl_.Clear(base::OnceClosure());
- EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
- NetworkIsolationKey()));
- EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
- NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, ClearServerNetworkStats) {
- ServerNetworkStats stats;
- stats.srtt = base::Microseconds(10);
- stats.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
- url::SchemeHostPort foo_https_server("https", "foo", 443);
- impl_.SetServerNetworkStats(foo_https_server, NetworkIsolationKey(), stats);
- impl_.ClearServerNetworkStats(foo_https_server, NetworkIsolationKey());
- EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
- NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, OnQuicServerInfoMapLoaded) {
- quic::QuicServerId google_quic_server_id("www.google.com", 443, true);
- HttpServerProperties::QuicServerInfoMapKey google_key(
- google_quic_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- const int kMaxQuicServerEntries = 10;
- impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
- EXPECT_EQ(10u, impl_.quic_server_info_map().max_size());
- // Check empty map.
- std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
- init_quic_server_info_map =
- std::make_unique<HttpServerProperties::QuicServerInfoMap>(
- kMaxQuicServerEntries);
- impl_.OnQuicServerInfoMapLoadedForTesting(
- std::move(init_quic_server_info_map));
- EXPECT_EQ(0u, impl_.quic_server_info_map().size());
- // Check by initializing with www.google.com:443.
- std::string google_server_info("google_quic_server_info");
- init_quic_server_info_map =
- std::make_unique<HttpServerProperties::QuicServerInfoMap>(
- kMaxQuicServerEntries);
- init_quic_server_info_map->Put(google_key, google_server_info);
- impl_.OnQuicServerInfoMapLoadedForTesting(
- std::move(init_quic_server_info_map));
- // Verify data for www.google.com:443.
- EXPECT_EQ(1u, impl_.quic_server_info_map().size());
- EXPECT_EQ(
- google_server_info,
- *impl_.GetQuicServerInfo(google_quic_server_id, NetworkIsolationKey()));
- // Test recency order and overwriting of data.
- //
- // |docs_server| has a QuicServerInfo, which will be overwritten by
- // SetQuicServerInfoMap(), because |quic_server_info_map| has an
- // entry for |docs_server|.
- quic::QuicServerId docs_quic_server_id("docs.google.com", 443, true);
- HttpServerProperties::QuicServerInfoMapKey docs_key(
- docs_quic_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- std::string docs_server_info("docs_quic_server_info");
- impl_.SetQuicServerInfo(docs_quic_server_id, NetworkIsolationKey(),
- docs_server_info);
- // Recency order will be |docs_server| and |google_server|.
- const HttpServerProperties::QuicServerInfoMap& map =
- impl_.quic_server_info_map();
- ASSERT_EQ(2u, map.size());
- auto map_it = map.begin();
- EXPECT_EQ(map_it->first, docs_key);
- EXPECT_EQ(docs_server_info, map_it->second);
- ++map_it;
- EXPECT_EQ(map_it->first, google_key);
- EXPECT_EQ(google_server_info, map_it->second);
- // Prepare |quic_server_info_map| to be loaded by
- // SetQuicServerInfoMap().
- std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
- quic_server_info_map =
- std::make_unique<HttpServerProperties::QuicServerInfoMap>(
- kMaxQuicServerEntries);
- // Change the values for |docs_server|.
- std::string new_docs_server_info("new_docs_quic_server_info");
- quic_server_info_map->Put(docs_key, new_docs_server_info);
- // Add data for mail.google.com:443.
- quic::QuicServerId mail_quic_server_id("mail.google.com", 443, true);
- HttpServerProperties::QuicServerInfoMapKey mail_key(
- mail_quic_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- std::string mail_server_info("mail_quic_server_info");
- quic_server_info_map->Put(mail_key, mail_server_info);
- impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
- // Recency order will be |docs_server|, |google_server| and |mail_server|.
- const HttpServerProperties::QuicServerInfoMap& memory_map =
- impl_.quic_server_info_map();
- ASSERT_EQ(3u, memory_map.size());
- auto memory_map_it = memory_map.begin();
- EXPECT_EQ(memory_map_it->first, docs_key);
- EXPECT_EQ(new_docs_server_info, memory_map_it->second);
- ++memory_map_it;
- EXPECT_EQ(memory_map_it->first, google_key);
- EXPECT_EQ(google_server_info, memory_map_it->second);
- ++memory_map_it;
- EXPECT_EQ(memory_map_it->first, mail_key);
- EXPECT_EQ(mail_server_info, memory_map_it->second);
- // Shrink the size of |quic_server_info_map| and verify the MRU order is
- // maintained.
- impl_.SetMaxServerConfigsStoredInProperties(2);
- EXPECT_EQ(2u, impl_.quic_server_info_map().max_size());
- const HttpServerProperties::QuicServerInfoMap& memory_map1 =
- impl_.quic_server_info_map();
- ASSERT_EQ(2u, memory_map1.size());
- auto memory_map1_it = memory_map1.begin();
- EXPECT_EQ(memory_map1_it->first, docs_key);
- EXPECT_EQ(new_docs_server_info, memory_map1_it->second);
- ++memory_map1_it;
- EXPECT_EQ(memory_map1_it->first, google_key);
- EXPECT_EQ(google_server_info, memory_map1_it->second);
- // |QuicServerInfo| for |mail_quic_server_id| shouldn't be there.
- EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(mail_quic_server_id,
- NetworkIsolationKey()));
- }
- TEST_F(HttpServerPropertiesTest, SetQuicServerInfo) {
- quic::QuicServerId server1("foo", 80, false /* privacy_mode_enabled */);
- quic::QuicServerId server2("foo", 80, true /* privacy_mode_enabled */);
- std::string quic_server_info1("quic_server_info1");
- std::string quic_server_info2("quic_server_info2");
- std::string quic_server_info3("quic_server_info3");
- // Without network isolation keys enabled for HttpServerProperties, passing in
- // a NetworkIsolationKey should have no effect on behavior.
- impl_.SetQuicServerInfo(server1, NetworkIsolationKey(), quic_server_info1);
- EXPECT_EQ(quic_server_info1,
- *(impl_.GetQuicServerInfo(server1, NetworkIsolationKey())));
- EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkIsolationKey()));
- EXPECT_EQ(quic_server_info1,
- *(impl_.GetQuicServerInfo(server1, network_isolation_key1_)));
- EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_isolation_key1_));
- impl_.SetQuicServerInfo(server2, network_isolation_key1_, quic_server_info2);
- EXPECT_EQ(quic_server_info1,
- *(impl_.GetQuicServerInfo(server1, NetworkIsolationKey())));
- EXPECT_EQ(quic_server_info2,
- *(impl_.GetQuicServerInfo(server2, NetworkIsolationKey())));
- EXPECT_EQ(quic_server_info1,
- *(impl_.GetQuicServerInfo(server1, network_isolation_key1_)));
- EXPECT_EQ(quic_server_info2,
- *(impl_.GetQuicServerInfo(server2, network_isolation_key1_)));
- impl_.SetQuicServerInfo(server1, network_isolation_key1_, quic_server_info3);
- EXPECT_EQ(quic_server_info3,
- *(impl_.GetQuicServerInfo(server1, NetworkIsolationKey())));
- EXPECT_EQ(quic_server_info2,
- *(impl_.GetQuicServerInfo(server2, NetworkIsolationKey())));
- EXPECT_EQ(quic_server_info3,
- *(impl_.GetQuicServerInfo(server1, network_isolation_key1_)));
- EXPECT_EQ(quic_server_info2,
- *(impl_.GetQuicServerInfo(server2, network_isolation_key1_)));
- impl_.Clear(base::OnceClosure());
- EXPECT_FALSE(impl_.GetQuicServerInfo(server1, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkIsolationKey()));
- EXPECT_FALSE(impl_.GetQuicServerInfo(server1, network_isolation_key1_));
- EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_isolation_key1_));
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- properties.SetQuicServerInfo(server1, NetworkIsolationKey(),
- quic_server_info1);
- EXPECT_EQ(quic_server_info1,
- *(properties.GetQuicServerInfo(server1, NetworkIsolationKey())));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key1_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
- properties.SetQuicServerInfo(server1, network_isolation_key1_,
- quic_server_info2);
- EXPECT_EQ(quic_server_info1,
- *(properties.GetQuicServerInfo(server1, NetworkIsolationKey())));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- EXPECT_EQ(quic_server_info2,
- *(properties.GetQuicServerInfo(server1, network_isolation_key1_)));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
- properties.SetQuicServerInfo(server2, network_isolation_key1_,
- quic_server_info3);
- EXPECT_EQ(quic_server_info1,
- *(properties.GetQuicServerInfo(server1, NetworkIsolationKey())));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- EXPECT_EQ(quic_server_info2,
- *(properties.GetQuicServerInfo(server1, network_isolation_key1_)));
- EXPECT_EQ(quic_server_info3,
- *(properties.GetQuicServerInfo(server2, network_isolation_key1_)));
- properties.Clear(base::OnceClosure());
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key1_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
- }
- // Tests that GetQuicServerInfo() returns server info of a host
- // with the same canonical suffix when there is no exact host match.
- TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatch) {
- // Set up HttpServerProperties.
- // Add a host with a canonical suffix.
- quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
- std::string foo_server_info("foo_server_info");
- impl_.SetQuicServerInfo(foo_server_id, NetworkIsolationKey(),
- foo_server_info);
- // Add a host that has a different canonical suffix.
- quic::QuicServerId baz_server_id("baz.video.com", 443, false);
- std::string baz_server_info("baz_server_info");
- impl_.SetQuicServerInfo(baz_server_id, NetworkIsolationKey(),
- baz_server_info);
- // Create SchemeHostPort with a host that has the initial canonical suffix.
- quic::QuicServerId bar_server_id("bar.googlevideo.com", 443, false);
- // Check the the server info associated with "foo" is returned for "bar".
- const std::string* bar_server_info =
- impl_.GetQuicServerInfo(bar_server_id, NetworkIsolationKey());
- ASSERT_TRUE(bar_server_info != nullptr);
- EXPECT_EQ(foo_server_info, *bar_server_info);
- }
- // Make sure that canonical suffices respect NetworkIsolationKeys when using
- // QuicServerInfo methods.
- TEST_F(HttpServerPropertiesTest,
- QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey) {
- // Two servers with same canonical suffix.
- quic::QuicServerId server1("foo.googlevideo.com", 80,
- false /* privacy_mode_enabled */);
- quic::QuicServerId server2("bar.googlevideo.com", 80,
- false /* privacy_mode_enabled */);
- std::string server_info1("server_info1");
- std::string server_info2("server_info2");
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
- // Since HttpServerProperties caches the feature value, have to create a new
- // one.
- HttpServerProperties properties(nullptr /* pref_delegate */,
- nullptr /* net_log */, test_tick_clock_,
- &test_clock_);
- // Set QuicServerInfo for one canononical suffix and
- // |network_isolation_key1_|. It should be accessible via another
- // SchemeHostPort, but only when the NetworkIsolationKeys match.
- properties.SetQuicServerInfo(server1, network_isolation_key1_, server_info1);
- const std::string* fetched_server_info =
- properties.GetQuicServerInfo(server1, network_isolation_key1_);
- ASSERT_TRUE(fetched_server_info);
- EXPECT_EQ(server_info1, *fetched_server_info);
- fetched_server_info =
- properties.GetQuicServerInfo(server2, network_isolation_key1_);
- ASSERT_TRUE(fetched_server_info);
- EXPECT_EQ(server_info1, *fetched_server_info);
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key2_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key2_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- // Set different QuicServerInfo for the same canononical suffix and
- // |network_isolation_key2_|. Both infos should be retriveable by using the
- // different NetworkIsolationKeys.
- properties.SetQuicServerInfo(server1, network_isolation_key2_, server_info2);
- fetched_server_info =
- properties.GetQuicServerInfo(server1, network_isolation_key1_);
- ASSERT_TRUE(fetched_server_info);
- EXPECT_EQ(server_info1, *fetched_server_info);
- fetched_server_info =
- properties.GetQuicServerInfo(server2, network_isolation_key1_);
- ASSERT_TRUE(fetched_server_info);
- EXPECT_EQ(server_info1, *fetched_server_info);
- fetched_server_info =
- properties.GetQuicServerInfo(server1, network_isolation_key2_);
- ASSERT_TRUE(fetched_server_info);
- EXPECT_EQ(server_info2, *fetched_server_info);
- fetched_server_info =
- properties.GetQuicServerInfo(server2, network_isolation_key2_);
- ASSERT_TRUE(fetched_server_info);
- EXPECT_EQ(server_info2, *fetched_server_info);
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- // Clearing should destroy all information.
- properties.Clear(base::OnceClosure());
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key1_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key1_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, network_isolation_key2_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, network_isolation_key2_));
- EXPECT_FALSE(properties.GetQuicServerInfo(server1, NetworkIsolationKey()));
- EXPECT_FALSE(properties.GetQuicServerInfo(server2, NetworkIsolationKey()));
- }
- // Verifies that GetQuicServerInfo() returns the MRU entry if multiple records
- // match a given canonical host.
- TEST_F(HttpServerPropertiesTest,
- QuicServerInfoCanonicalSuffixMatchReturnsMruEntry) {
- // Set up HttpServerProperties by adding two hosts with the same canonical
- // suffixes.
- quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
- std::string h1_server_info("h1_server_info");
- impl_.SetQuicServerInfo(h1_server_id, NetworkIsolationKey(), h1_server_info);
- quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
- std::string h2_server_info("h2_server_info");
- impl_.SetQuicServerInfo(h2_server_id, NetworkIsolationKey(), h2_server_info);
- // Create quic::QuicServerId to use for the search.
- quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
- // Check that 'h2' info is returned since it is MRU.
- const std::string* server_info =
- impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
- ASSERT_TRUE(server_info != nullptr);
- EXPECT_EQ(h2_server_info, *server_info);
- // Access 'h1' info, so it becomes MRU.
- impl_.GetQuicServerInfo(h1_server_id, NetworkIsolationKey());
- // Check that 'h1' info is returned since it is MRU now.
- server_info = impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
- ASSERT_TRUE(server_info != nullptr);
- EXPECT_EQ(h1_server_info, *server_info);
- }
- // Verifies that |GetQuicServerInfo| doesn't change the MRU order of the server
- // info map when a record is matched based on a canonical name.
- TEST_F(HttpServerPropertiesTest,
- QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder) {
- // Add a host with a matching canonical name.
- quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
- HttpServerProperties::QuicServerInfoMapKey h1_key(
- h1_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- std::string h1_server_info("h1_server_info");
- impl_.SetQuicServerInfo(h1_server_id, NetworkIsolationKey(), h1_server_info);
- // Add a host hosts with a non-matching canonical name.
- quic::QuicServerId h2_server_id("h2.video.com", 443, false);
- HttpServerProperties::QuicServerInfoMapKey h2_key(
- h2_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- std::string h2_server_info("h2_server_info");
- impl_.SetQuicServerInfo(h2_server_id, NetworkIsolationKey(), h2_server_info);
- // Check that "h2.video.com" is the MRU entry in the map.
- EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
- // Search for the entry that matches the canonical name
- // ("h1.googlevideo.com").
- quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
- const std::string* server_info =
- impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
- ASSERT_TRUE(server_info != nullptr);
- // Check that the search (although successful) hasn't changed the MRU order of
- // the map.
- EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
- // Search for "h1.googlevideo.com" directly, so it becomes MRU
- impl_.GetQuicServerInfo(h1_server_id, NetworkIsolationKey());
- // Check that "h1.googlevideo.com" is the MRU entry now.
- EXPECT_EQ(h1_key, impl_.quic_server_info_map().begin()->first);
- }
- // Tests that the canonical host matching works for hosts stored in memory cache
- // and the ones loaded from persistent storage, i.e. server info added
- // using SetQuicServerInfo() and SetQuicServerInfoMap() is taken into
- // cosideration when searching for server info for a host with the same
- // canonical suffix.
- TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatchSetInfoMap) {
- // Add a host info using SetQuicServerInfo(). That will simulate an info
- // entry stored in memory cache.
- quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
- std::string h1_server_info("h1_server_info_memory_cache");
- impl_.SetQuicServerInfo(h1_server_id, NetworkIsolationKey(), h1_server_info);
- // Prepare a map with host info and add it using SetQuicServerInfoMap(). That
- // will simulate info records read from the persistence storage.
- quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
- HttpServerProperties::QuicServerInfoMapKey h2_key(
- h2_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- std::string h2_server_info("h2_server_info_from_disk");
- quic::QuicServerId h3_server_id("h3.ggpht.com", 443, false);
- HttpServerProperties::QuicServerInfoMapKey h3_key(
- h3_server_id, NetworkIsolationKey(),
- false /* use_network_isolation_key */);
- std::string h3_server_info("h3_server_info_from_disk");
- const int kMaxQuicServerEntries = 10;
- impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
- std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
- quic_server_info_map =
- std::make_unique<HttpServerProperties::QuicServerInfoMap>(
- kMaxQuicServerEntries);
- quic_server_info_map->Put(h2_key, h2_server_info);
- quic_server_info_map->Put(h3_key, h3_server_info);
- impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
- // Check that the server info from the memory cache is returned since unique
- // entries from the memory cache are added after entries from the
- // persistence storage and, therefore, are most recently used.
- quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
- const std::string* server_info =
- impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
- ASSERT_TRUE(server_info != nullptr);
- EXPECT_EQ(h1_server_info, *server_info);
- // Check that server info that was added using SetQuicServerInfoMap() can be
- // found.
- foo_server_id = quic::QuicServerId("foo.ggpht.com", 443, false);
- server_info = impl_.GetQuicServerInfo(foo_server_id, NetworkIsolationKey());
- ASSERT_TRUE(server_info != nullptr);
- EXPECT_EQ(h3_server_info, *server_info);
- }
- } // namespace
- } // namespace net
|