123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494 |
- // Copyright 2017 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 "services/network/network_context.h"
- #include <algorithm>
- #include <map>
- #include <memory>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/barrier_closure.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/command_line.h"
- #include "base/containers/contains.h"
- #include "base/containers/span.h"
- #include "base/files/file.h"
- #include "base/files/file_path.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/location.h"
- #include "base/memory/raw_ptr.h"
- #include "base/metrics/field_trial.h"
- #include "base/power_monitor/power_monitor.h"
- #include "base/power_monitor/power_monitor_source.h"
- #include "base/run_loop.h"
- #include "base/strings/strcat.h"
- #include "base/strings/string_split.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/synchronization/waitable_event.h"
- #include "base/test/bind.h"
- #include "base/test/gtest_util.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/mock_entropy_provider.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/simple_test_clock.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread_restrictions.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/default_clock.h"
- #include "base/time/default_tick_clock.h"
- #include "base/time/time.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "components/network_session_configurator/browser/network_session_configurator.h"
- #include "components/network_session_configurator/common/network_switches.h"
- #include "components/prefs/testing_pref_service.h"
- #include "crypto/sha2.h"
- #include "mojo/public/cpp/bindings/self_owned_receiver.h"
- #include "mojo/public/cpp/system/data_pipe_utils.h"
- #include "mojo/public/cpp/system/functions.h"
- #include "net/base/cache_type.h"
- #include "net/base/features.h"
- #include "net/base/hash_value.h"
- #include "net/base/host_port_pair.h"
- #include "net/base/http_user_agent_settings.h"
- #include "net/base/ip_endpoint.h"
- #include "net/base/isolation_info.h"
- #include "net/base/net_errors.h"
- #include "net/base/network_change_notifier.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/proxy_server.h"
- #include "net/base/proxy_string_util.h"
- #include "net/base/test_completion_callback.h"
- #include "net/cert/cert_verify_result.h"
- #include "net/cert/mock_cert_verifier.h"
- #include "net/cert/sct_status_flags.h"
- #include "net/cert/x509_certificate.h"
- #include "net/cookies/canonical_cookie.h"
- #include "net/cookies/cookie_access_result.h"
- #include "net/cookies/cookie_options.h"
- #include "net/cookies/cookie_store.h"
- #include "net/cookies/cookie_util.h"
- #include "net/disk_cache/cache_util.h"
- #include "net/disk_cache/disk_cache.h"
- #include "net/disk_cache/memory/mem_backend_impl.h"
- #include "net/dns/context_host_resolver.h"
- #include "net/dns/dns_test_util.h"
- #include "net/dns/host_resolver_manager.h"
- #include "net/dns/mock_host_resolver.h"
- #include "net/dns/public/dns_query_type.h"
- #include "net/dns/public/host_resolver_source.h"
- #include "net/dns/public/secure_dns_policy.h"
- #include "net/dns/resolve_context.h"
- #include "net/http/http_auth.h"
- #include "net/http/http_cache.h"
- #include "net/http/http_network_session.h"
- #include "net/http/http_server_properties_manager.h"
- #include "net/http/http_transaction_factory.h"
- #include "net/http/http_transaction_test_util.h"
- #include "net/http/mock_http_cache.h"
- #include "net/http/transport_security_state.h"
- #include "net/http/transport_security_state_test_util.h"
- #include "net/nqe/network_quality_estimator_test_util.h"
- #include "net/proxy_resolution/configured_proxy_resolution_service.h"
- #include "net/proxy_resolution/proxy_config.h"
- #include "net/proxy_resolution/proxy_info.h"
- #include "net/socket/client_socket_pool.h"
- #include "net/socket/transport_client_socket_pool.h"
- #include "net/test/cert_test_util.h"
- #include "net/test/embedded_test_server/controllable_http_response.h"
- #include "net/test/embedded_test_server/default_handlers.h"
- #include "net/test/embedded_test_server/embedded_test_server.h"
- #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
- #include "net/test/gtest_util.h"
- #include "net/test/spawned_test_server/spawned_test_server.h"
- #include "net/test/test_data_directory.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "net/url_request/referrer_policy.h"
- #include "net/url_request/url_request_context.h"
- #include "net/url_request/url_request_context_builder.h"
- #include "net/url_request/url_request_job_factory.h"
- #include "net/url_request/url_request_test_util.h"
- #include "services/network/cookie_manager.h"
- #include "services/network/net_log_exporter.h"
- #include "services/network/network_qualities_pref_delegate.h"
- #include "services/network/network_service.h"
- #include "services/network/public/cpp/features.h"
- #include "services/network/public/cpp/network_service_buildflags.h"
- #include "services/network/public/cpp/resolve_host_client_base.h"
- #include "services/network/public/mojom/host_resolver.mojom.h"
- #include "services/network/public/mojom/net_log.mojom.h"
- #include "services/network/public/mojom/network_context.mojom.h"
- #include "services/network/public/mojom/network_service.mojom.h"
- #include "services/network/public/mojom/proxy_config.mojom.h"
- #include "services/network/public/mojom/url_loader.mojom-shared.h"
- #include "services/network/test/fake_test_cert_verifier_params_factory.h"
- #include "services/network/test/test_url_loader_client.h"
- #include "services/network/test/test_utils.h"
- #include "services/network/test/udp_socket_test_util.h"
- #include "services/network/test_mojo_proxy_resolver_factory.h"
- #include "services/network/trust_tokens/pending_trust_token_store.h"
- #include "services/network/trust_tokens/trust_token_parameterization.h"
- #include "services/network/trust_tokens/trust_token_store.h"
- #include "services/network/url_request_context_builder_mojo.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "url/gurl.h"
- #include "url/scheme_host_port.h"
- #include "url/url_constants.h"
- #if BUILDFLAG(IS_CT_SUPPORTED)
- #include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
- #include "services/network/public/mojom/ct_log_info.mojom.h"
- #endif
- #if BUILDFLAG(ENABLE_REPORTING)
- #include "net/network_error_logging/network_error_logging_service.h"
- #include "net/reporting/reporting_cache.h"
- #include "net/reporting/reporting_context.h"
- #include "net/reporting/reporting_report.h"
- #include "net/reporting/reporting_service.h"
- #include "net/reporting/reporting_test_util.h"
- #endif // BUILDFLAG(ENABLE_REPORTING)
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- #include "services/network/mock_mojo_dhcp_wpad_url_client.h"
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- #if BUILDFLAG(IS_P2P_ENABLED)
- #include "services/network/public/mojom/p2p.mojom.h"
- #include "services/network/public/mojom/p2p_trusted.mojom.h"
- #endif // BUILDFLAG(IS_P2P_ENABLED)
- namespace network {
- namespace {
- using net::CreateTestURLRequestContextBuilder;
- using ::testing::Optional;
- constexpr char kMockHost[] = "mock.host";
- #if BUILDFLAG(ENABLE_REPORTING)
- const base::FilePath::CharType kFilename[] =
- FILE_PATH_LITERAL("TempReportingAndNelStore");
- #endif // BUILDFLAG(ENABLE_REPORTING)
- #if BUILDFLAG(IS_CT_SUPPORTED)
- void StoreBool(bool* result, base::OnceClosure callback, bool value) {
- *result = value;
- std::move(callback).Run();
- }
- #endif // BUILDFLAG(IS_CT_SUPPORTED)
- void StoreValue(base::Value::Dict* result,
- base::OnceClosure callback,
- base::Value::Dict value) {
- *result = std::move(value);
- std::move(callback).Run();
- }
- void SetContentSetting(const GURL& primary_pattern,
- const GURL& secondary_pattern,
- ContentSetting setting,
- NetworkContext* network_context) {
- network_context->cookie_manager()->SetContentSettings(
- {ContentSettingPatternSource(
- ContentSettingsPattern::FromURL(primary_pattern),
- ContentSettingsPattern::FromURL(secondary_pattern),
- base::Value(setting), std::string(), false)});
- }
- void SetDefaultContentSetting(ContentSetting setting,
- NetworkContext* network_context) {
- network_context->cookie_manager()->SetContentSettings(
- {ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
- ContentSettingsPattern::Wildcard(),
- base::Value(setting), std::string(),
- false)});
- }
- std::unique_ptr<TestURLLoaderClient> FetchRequest(
- const ResourceRequest& request,
- NetworkContext* network_context,
- int url_loader_options = mojom::kURLLoadOptionNone,
- int process_id = mojom::kBrowserProcessId,
- mojom::URLLoaderFactoryParamsPtr params = nullptr) {
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- if (!params)
- params = mojom::URLLoaderFactoryParams::New();
- params->process_id = process_id;
- params->is_corb_enabled = false;
- // If |site_for_cookies| is null, any non-empty NIK is fine. Otherwise, the
- // NIK must be consistent with |site_for_cookies|.
- if (request.site_for_cookies.IsNull()) {
- params->isolation_info = net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther,
- url::Origin::Create(GURL("https://abc.com")),
- url::Origin::Create(GURL("https://xyz.com")), request.site_for_cookies);
- } else {
- params->isolation_info = net::IsolationInfo::CreateForInternalRequest(
- url::Origin::Create(request.site_for_cookies.RepresentativeUrl()));
- }
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- auto client = std::make_unique<TestURLLoaderClient>();
- mojo::PendingRemote<mojom::URLLoader> loader;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- url_loader_options, request, client->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client->RunUntilComplete();
- return client;
- }
- // proxy_resolver::mojom::ProxyResolverFactory that captures the most recent PAC
- // script passed to it, and the most recent URL/NetworkIsolationKey passed to
- // the GetProxyForUrl() method of proxy_resolver::mojom::ProxyResolver it
- // returns.
- class CapturingMojoProxyResolverFactory
- : public proxy_resolver::mojom::ProxyResolverFactory,
- public proxy_resolver::mojom::ProxyResolver {
- public:
- CapturingMojoProxyResolverFactory() {}
- CapturingMojoProxyResolverFactory(const CapturingMojoProxyResolverFactory&) =
- delete;
- CapturingMojoProxyResolverFactory& operator=(
- const CapturingMojoProxyResolverFactory&) = delete;
- ~CapturingMojoProxyResolverFactory() override {}
- mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
- CreateFactoryRemote() {
- return proxy_factory_receiver_.BindNewPipeAndPassRemote();
- }
- // proxy_resolver::mojom::ProxyResolverFactory:
- void CreateResolver(
- const std::string& pac_script,
- mojo::PendingReceiver<proxy_resolver::mojom::ProxyResolver> receiver,
- mojo::PendingRemote<
- proxy_resolver::mojom::ProxyResolverFactoryRequestClient> client)
- override {
- pac_script_ = pac_script;
- mojo::Remote<proxy_resolver::mojom::ProxyResolverFactoryRequestClient>
- factory_request_client(std::move(client));
- proxy_resolver_receiver_.Bind(std::move(receiver));
- factory_request_client->ReportResult(net::OK);
- }
- // proxy_resolver::mojom::ProxyResolver:
- void GetProxyForUrl(
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverRequestClient>
- client) override {
- url_ = url;
- network_isolation_key_ = network_isolation_key;
- mojo::Remote<proxy_resolver::mojom::ProxyResolverRequestClient>
- resolver_request_client(std::move(client));
- net::ProxyInfo proxy_info;
- proxy_info.UseDirect();
- resolver_request_client->ReportResult(net::OK, proxy_info);
- }
- const std::string& pac_script() const { return pac_script_; }
- // Return the GURL and NetworkIsolationKey passed to the most recent
- // GetProxyForUrl() call.
- const GURL& url() const { return url_; }
- const net::NetworkIsolationKey& network_isolation_key() const {
- return network_isolation_key_;
- }
- private:
- mojo::Receiver<ProxyResolverFactory> proxy_factory_receiver_{this};
- mojo::Receiver<ProxyResolver> proxy_resolver_receiver_{this};
- std::string pac_script_;
- GURL url_;
- net::NetworkIsolationKey network_isolation_key_;
- };
- // ProxyLookupClient that drives proxy lookups and can wait for the responses to
- // be received.
- class TestProxyLookupClient : public mojom::ProxyLookupClient {
- public:
- TestProxyLookupClient() = default;
- TestProxyLookupClient(const TestProxyLookupClient&) = delete;
- TestProxyLookupClient& operator=(const TestProxyLookupClient&) = delete;
- ~TestProxyLookupClient() override = default;
- void StartLookUpProxyForURL(
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- mojom::NetworkContext* network_context) {
- // Make sure this method is called at most once.
- EXPECT_FALSE(receiver_.is_bound());
- network_context->LookUpProxyForURL(url, network_isolation_key,
- receiver_.BindNewPipeAndPassRemote());
- }
- void WaitForResult() { run_loop_.Run(); }
- // mojom::ProxyLookupClient implementation:
- void OnProxyLookupComplete(
- int32_t net_error,
- const absl::optional<net::ProxyInfo>& proxy_info) override {
- EXPECT_FALSE(is_done_);
- EXPECT_FALSE(proxy_info_);
- EXPECT_EQ(net_error == net::OK, proxy_info.has_value());
- is_done_ = true;
- proxy_info_ = proxy_info;
- net_error_ = net_error;
- receiver_.reset();
- run_loop_.Quit();
- }
- const absl::optional<net::ProxyInfo>& proxy_info() const {
- return proxy_info_;
- }
- int32_t net_error() const { return net_error_; }
- bool is_done() const { return is_done_; }
- private:
- mojo::Receiver<mojom::ProxyLookupClient> receiver_{this};
- bool is_done_ = false;
- absl::optional<net::ProxyInfo> proxy_info_;
- int32_t net_error_ = net::ERR_UNEXPECTED;
- base::RunLoop run_loop_;
- };
- #if BUILDFLAG(IS_P2P_ENABLED)
- class MockP2PTrustedSocketManagerClient
- : public mojom::P2PTrustedSocketManagerClient {
- public:
- MockP2PTrustedSocketManagerClient() = default;
- ~MockP2PTrustedSocketManagerClient() override = default;
- // mojom::P2PTrustedSocketManagerClient:
- void InvalidSocketPortRangeRequested() override {}
- void DumpPacket(const std::vector<uint8_t>& packet_header,
- uint64_t packet_length,
- bool incoming) override {}
- };
- #endif // BUILDFLAG(IS_P2P_ENABLED)
- class HostResolverFactory final : public net::HostResolver::Factory {
- public:
- explicit HostResolverFactory(std::unique_ptr<net::HostResolver> resolver)
- : resolver_(std::move(resolver)) {}
- std::unique_ptr<net::HostResolver> CreateResolver(
- net::HostResolverManager* manager,
- base::StringPiece host_mapping_rules,
- bool enable_caching) override {
- DCHECK(resolver_);
- return std::move(resolver_);
- }
- // See HostResolver::CreateStandaloneResolver.
- std::unique_ptr<net::HostResolver> CreateStandaloneResolver(
- net::NetLog* net_log,
- const net::HostResolver::ManagerOptions& options,
- base::StringPiece host_mapping_rules,
- bool enable_caching) override {
- NOTREACHED();
- return nullptr;
- }
- private:
- std::unique_ptr<net::HostResolver> resolver_;
- };
- class NetworkContextTest : public testing::Test {
- public:
- explicit NetworkContextTest(
- base::test::TaskEnvironment::TimeSource time_source =
- base::test::TaskEnvironment::TimeSource::DEFAULT)
- : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
- time_source),
- network_change_notifier_(
- net::NetworkChangeNotifier::CreateMockIfNeeded()),
- network_service_(NetworkService::CreateForTesting()) {}
- ~NetworkContextTest() override {}
- std::unique_ptr<NetworkContext> CreateContextWithParams(
- mojom::NetworkContextParamsPtr context_params
- #if BUILDFLAG(ENABLE_REPORTING)
- ,
- std::unique_ptr<net::ReportingService> reporting_service = nullptr
- #endif
- ) {
- // Use a dummy CertVerifier that always passes cert verification, since
- // these unittests don't need to test CertVerifier behavior.
- DCHECK(!context_params->cert_verifier_params);
- context_params->cert_verifier_params =
- FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
- network_context_remote_.reset();
- return NetworkContext::CreateForTesting(
- network_service_.get(),
- network_context_remote_.BindNewPipeAndPassReceiver(),
- std::move(context_params),
- base::BindLambdaForTesting([&](net::URLRequestContextBuilder* builder) {
- #if BUILDFLAG(ENABLE_REPORTING)
- builder->set_reporting_service(std::move(reporting_service));
- #endif
- }));
- }
- // Searches through |backend|'s stats to discover its type. Only supports
- // blockfile and simple caches.
- net::URLRequestContextBuilder::HttpCacheParams::Type GetBackendType(
- disk_cache::Backend* backend) {
- base::StringPairs stats;
- backend->GetStats(&stats);
- for (const auto& pair : stats) {
- if (pair.first != "Cache type")
- continue;
- if (pair.second == "Simple Cache")
- return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE;
- if (pair.second == "Blockfile Cache")
- return net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE;
- break;
- }
- NOTREACHED();
- return net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY;
- }
- mojom::NetworkService* network_service() const {
- return network_service_.get();
- }
- // Looks up a value with the given name from the NetworkContext's
- // TransportSocketPool info dictionary.
- int GetSocketPoolInfo(NetworkContext* context, base::StringPiece name) {
- return context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->GetSocketPool(
- net::HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
- net::ProxyServer::Direct())
- ->GetInfoAsValue("", "")
- .FindIntPath(name)
- .value_or(-1);
- }
- int GetSocketCountForGroup(NetworkContext* context,
- const net::ClientSocketPool::GroupId& group) {
- base::Value pool_info =
- context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->GetSocketPool(
- net::HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
- net::ProxyServer::Direct())
- ->GetInfoAsValue("", "");
- int count = 0;
- base::Value* active_socket_count = pool_info.FindPathOfType(
- base::span<const base::StringPiece>{
- {"groups", group.ToString(), "active_socket_count"}},
- base::Value::Type::INTEGER);
- if (active_socket_count)
- count += active_socket_count->GetInt();
- base::Value* idle_sockets = pool_info.FindPathOfType(
- base::span<const base::StringPiece>{
- {"groups", group.ToString(), "idle_sockets"}},
- base::Value::Type::LIST);
- if (idle_sockets)
- count += idle_sockets->GetListDeprecated().size();
- base::Value* connect_jobs = pool_info.FindPathOfType(
- base::span<const base::StringPiece>{
- {"groups", group.ToString(), "connect_jobs"}},
- base::Value::Type::LIST);
- if (connect_jobs)
- count += connect_jobs->GetListDeprecated().size();
- return count;
- }
- GURL GetHttpUrlFromHttps(const GURL& https_url) {
- GURL::Replacements replacements;
- replacements.SetSchemeStr("http");
- return https_url.ReplaceComponents(replacements);
- }
- protected:
- base::test::TaskEnvironment task_environment_;
- std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
- std::unique_ptr<NetworkService> network_service_;
- // Stores the mojo::Remote<NetworkContext> of the most recently created
- // NetworkContext. Not strictly needed, but seems best to mimic real-world
- // usage.
- mojo::Remote<mojom::NetworkContext> network_context_remote_;
- };
- class NetworkContextTestWithMockTime : public NetworkContextTest {
- public:
- NetworkContextTestWithMockTime()
- : NetworkContextTest(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
- }
- };
- TEST_F(NetworkContextTest, DestroyContextWithLiveRequest) {
- net::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ResourceRequest request;
- request.url = test_server.GetURL("/hung-after-headers");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilResponseReceived();
- EXPECT_TRUE(client.has_received_response());
- EXPECT_FALSE(client.has_received_completion());
- // Destroying the loader factory should not delete the URLLoader.
- loader_factory.reset();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(client.has_received_completion());
- // Destroying the NetworkContext should result in destroying the loader and
- // the client receiving a connection error.
- network_context.reset();
- client.RunUntilDisconnect();
- EXPECT_FALSE(client.has_received_completion());
- }
- TEST_F(NetworkContextTest, DisableQuic) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableQuic);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // By default, QUIC should be enabled for new NetworkContexts when the command
- // line indicates it should be.
- EXPECT_TRUE(network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->params()
- .enable_quic);
- // Disabling QUIC should disable it on existing NetworkContexts.
- network_service()->DisableQuic();
- EXPECT_FALSE(network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->params()
- .enable_quic);
- // Disabling QUIC should disable it new NetworkContexts.
- std::unique_ptr<NetworkContext> network_context2 =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_FALSE(network_context2->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->params()
- .enable_quic);
- // Disabling QUIC again should be harmless.
- network_service()->DisableQuic();
- std::unique_ptr<NetworkContext> network_context3 =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_FALSE(network_context3->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->params()
- .enable_quic);
- }
- TEST_F(NetworkContextTest, UserAgentAndLanguage) {
- const char kUserAgent[] = "Chromium Unit Test";
- const char kAcceptLanguage[] = "en-US,en;q=0.9,uk;q=0.8";
- mojom::NetworkContextParamsPtr params =
- CreateNetworkContextParamsForTesting();
- params->user_agent = kUserAgent;
- // Not setting accept_language, to test the default.
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- EXPECT_EQ(kUserAgent, network_context->url_request_context()
- ->http_user_agent_settings()
- ->GetUserAgent());
- EXPECT_EQ("", network_context->url_request_context()
- ->http_user_agent_settings()
- ->GetAcceptLanguage());
- // Change accept-language.
- network_context->SetAcceptLanguage(kAcceptLanguage);
- EXPECT_EQ(kUserAgent, network_context->url_request_context()
- ->http_user_agent_settings()
- ->GetUserAgent());
- EXPECT_EQ(kAcceptLanguage, network_context->url_request_context()
- ->http_user_agent_settings()
- ->GetAcceptLanguage());
- // Create with custom accept-language configured.
- params = CreateNetworkContextParamsForTesting();
- params->user_agent = kUserAgent;
- params->accept_language = kAcceptLanguage;
- std::unique_ptr<NetworkContext> network_context2 =
- CreateContextWithParams(std::move(params));
- EXPECT_EQ(kUserAgent, network_context2->url_request_context()
- ->http_user_agent_settings()
- ->GetUserAgent());
- EXPECT_EQ(kAcceptLanguage, network_context2->url_request_context()
- ->http_user_agent_settings()
- ->GetAcceptLanguage());
- }
- TEST_F(NetworkContextTest, EnableBrotli) {
- for (bool enable_brotli : {true, false}) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->enable_brotli = enable_brotli;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- EXPECT_EQ(enable_brotli,
- network_context->url_request_context()->enable_brotli());
- }
- }
- TEST_F(NetworkContextTest, QuicUserAgentId) {
- const char kQuicUserAgentId[] = "007";
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->quic_user_agent_id = kQuicUserAgentId;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- EXPECT_EQ(kQuicUserAgentId, network_context->url_request_context()
- ->quic_context()
- ->params()
- ->user_agent_id);
- }
- TEST_F(NetworkContextTest, UnhandedProtocols) {
- const GURL kUnsupportedUrls[] = {
- // These are handled outside the network service.
- GURL("data:,foo"),
- GURL("file:///not/a/path/that/leads/anywhere/but/it/should/not/matter/"
- "anyways"),
- // FTP is not supported natively by Chrome.
- GURL("ftp://foo.test/"),
- };
- for (const GURL& url : kUnsupportedUrls) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- ResourceRequest request;
- request.url = url;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_TRUE(client.has_received_completion());
- EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME,
- client.completion_status().error_code);
- }
- }
- #if BUILDFLAG(ENABLE_REPORTING)
- TEST_F(NetworkContextTest, DisableReporting) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndDisableFeature(features::kReporting);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_FALSE(network_context->url_request_context()->reporting_service());
- }
- TEST_F(NetworkContextTest, EnableReportingWithoutStore) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(features::kReporting);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_TRUE(network_context->url_request_context()->reporting_service());
- EXPECT_FALSE(network_context->url_request_context()
- ->reporting_service()
- ->GetContextForTesting()
- ->store());
- }
- TEST_F(NetworkContextTest, EnableReportingWithStore) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(features::kReporting);
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath database_path = temp_dir.GetPath().Append(kFilename);
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory = database_path.DirName();
- context_params->file_paths->reporting_and_nel_store_database_name =
- database_path.BaseName();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- EXPECT_TRUE(network_context->url_request_context()->reporting_service());
- EXPECT_TRUE(network_context->url_request_context()
- ->reporting_service()
- ->GetContextForTesting()
- ->store());
- }
- TEST_F(NetworkContextTest, DisableNetworkErrorLogging) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndDisableFeature(features::kNetworkErrorLogging);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_FALSE(
- network_context->url_request_context()->network_error_logging_service());
- }
- TEST_F(NetworkContextTest, EnableNetworkErrorLoggingWithoutStore) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitWithFeatures(
- {features::kNetworkErrorLogging, features::kReporting}, {});
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_TRUE(
- network_context->url_request_context()->network_error_logging_service());
- EXPECT_FALSE(network_context->url_request_context()
- ->network_error_logging_service()
- ->GetPersistentNelStoreForTesting());
- EXPECT_FALSE(network_context->url_request_context()
- ->network_error_logging_service()
- ->GetReportingServiceForTesting()
- ->GetContextForTesting()
- ->store());
- }
- TEST_F(NetworkContextTest, EnableNetworkErrorLoggingWithStore) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitWithFeatures(
- {features::kNetworkErrorLogging, features::kReporting}, {});
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath reporting_and_nel_store = temp_dir.GetPath().Append(kFilename);
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory =
- reporting_and_nel_store.DirName();
- context_params->file_paths->reporting_and_nel_store_database_name =
- reporting_and_nel_store.BaseName();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- EXPECT_TRUE(
- network_context->url_request_context()->network_error_logging_service());
- EXPECT_TRUE(network_context->url_request_context()
- ->network_error_logging_service()
- ->GetPersistentNelStoreForTesting());
- EXPECT_TRUE(network_context->url_request_context()
- ->network_error_logging_service()
- ->GetReportingServiceForTesting()
- ->GetContextForTesting()
- ->store());
- }
- #endif // BUILDFLAG(ENABLE_REPORTING)
- TEST_F(NetworkContextTest, DefaultHttpNetworkSessionParams) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- const net::HttpNetworkSessionParams& params =
- network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->params();
- const net::QuicParams* quic_params =
- network_context->url_request_context()->quic_context()->params();
- EXPECT_TRUE(params.enable_http2);
- EXPECT_TRUE(params.enable_quic);
- EXPECT_EQ(1250u, quic_params->max_packet_length);
- EXPECT_TRUE(quic_params->origins_to_force_quic_on.empty());
- EXPECT_FALSE(params.enable_user_alternate_protocol_ports);
- EXPECT_FALSE(params.ignore_certificate_errors);
- EXPECT_EQ(0, params.testing_fixed_http_port);
- EXPECT_EQ(0, params.testing_fixed_https_port);
- }
- // Make sure that network_session_configurator is hooked up.
- TEST_F(NetworkContextTest, FixedHttpPort) {
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kTestingFixedHttpPort, "800");
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kTestingFixedHttpsPort, "801");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- const net::HttpNetworkSessionParams& params =
- network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->params();
- EXPECT_EQ(800, params.testing_fixed_http_port);
- EXPECT_EQ(801, params.testing_fixed_https_port);
- }
- TEST_F(NetworkContextTest, NoCache) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = false;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- EXPECT_FALSE(network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache());
- }
- TEST_F(NetworkContextTest, MemoryCache) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- ASSERT_TRUE(cache);
- disk_cache::Backend* backend = nullptr;
- net::TestCompletionCallback callback;
- int rv = cache->GetBackend(&backend, callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(rv));
- ASSERT_TRUE(backend);
- EXPECT_EQ(net::MEMORY_CACHE, backend->GetCacheType());
- }
- TEST_F(NetworkContextTest, DiskCache) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- context_params->http_cache_directory = temp_dir.GetPath();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- ASSERT_TRUE(cache);
- disk_cache::Backend* backend = nullptr;
- net::TestCompletionCallback callback;
- int rv = cache->GetBackend(&backend, callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(rv));
- ASSERT_TRUE(backend);
- EXPECT_EQ(net::DISK_CACHE, backend->GetCacheType());
- EXPECT_EQ(network_session_configurator::ChooseCacheType(),
- GetBackendType(backend));
- }
- class DiskCacheSizeTest : public NetworkContextTest {
- public:
- DiskCacheSizeTest() = default;
- ~DiskCacheSizeTest() override = default;
- int64_t VerifyDiskCacheSize(int scale = 100) {
- base::test::ScopedFeatureList scoped_feature_list;
- if (scale != 100) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["percent_relative_size"] = base::NumberToString(scale);
- scoped_feature_list.InitAndEnableFeatureWithParameters(
- disk_cache::kChangeDiskCacheSizeExperiment, field_trial_params);
- }
- base::HistogramTester histogram_tester;
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- base::ScopedTempDir temp_dir;
- EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
- context_params->http_cache_directory = temp_dir.GetPath();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- EXPECT_TRUE(cache);
- disk_cache::Backend* backend = nullptr;
- net::TestCompletionCallback callback;
- int rv = cache->GetBackend(&backend, callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(rv));
- EXPECT_TRUE(backend);
- EXPECT_EQ(net::DISK_CACHE, backend->GetCacheType());
- int64_t max_file_size = backend->MaxFileSize();
- histogram_tester.ExpectTotalCount("HttpCache.MaxFileSizeOnInit", 1);
- histogram_tester.ExpectUniqueSample("HttpCache.MaxFileSizeOnInit",
- max_file_size / 1024, 1);
- return max_file_size;
- }
- };
- TEST_F(DiskCacheSizeTest, DiskCacheSize) {
- int64_t max_file_size = VerifyDiskCacheSize();
- int64_t max_file_size_scaled = VerifyDiskCacheSize(200);
- // After scaling to 200%, the size will in most cases be twice of
- // |max_file_size| but it is dependent on the available size, and since we
- // cannot guarantee available size to be the same between the 2 runs to
- // VerifyDiskCacheSize(), only checking for the scaled size to be >=
- // max_file_size.
- EXPECT_GE(max_file_size_scaled, max_file_size);
- }
- // This makes sure that network_session_configurator::ChooseCacheType is
- // connected to NetworkContext.
- TEST_F(NetworkContextTest, SimpleCache) {
- base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial", "ExperimentYes");
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- context_params->http_cache_directory = temp_dir.GetPath();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- ASSERT_TRUE(cache);
- disk_cache::Backend* backend = nullptr;
- net::TestCompletionCallback callback;
- int rv = cache->GetBackend(&backend, callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(rv));
- ASSERT_TRUE(backend);
- base::StringPairs stats;
- backend->GetStats(&stats);
- EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE,
- GetBackendType(backend));
- }
- TEST_F(NetworkContextTest, HttpServerPropertiesToDisk) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath file_path = temp_dir.GetPath().AppendASCII("foo");
- EXPECT_FALSE(base::PathExists(file_path));
- const url::SchemeHostPort kSchemeHostPort("https", "foo", 443);
- // Create a context with on-disk storage of HTTP server properties.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory = file_path.DirName();
- context_params->file_paths->http_server_properties_file_name =
- file_path.BaseName();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Wait for properties to load from disk, and sanity check initial state.
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- // Set a property.
- network_context->url_request_context()
- ->http_server_properties()
- ->SetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey(), true);
- // Deleting the context will cause it to flush state. Wait for the pref
- // service to flush to disk.
- network_context.reset();
- task_environment_.RunUntilIdle();
- // Create a new NetworkContext using the same path for HTTP server properties.
- context_params = CreateNetworkContextParamsForTesting();
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory = file_path.DirName();
- context_params->file_paths->http_server_properties_file_name =
- file_path.BaseName();
- network_context = CreateContextWithParams(std::move(context_params));
- // Wait for properties to load from disk.
- task_environment_.RunUntilIdle();
- EXPECT_TRUE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- // Now check that ClearNetworkingHistoryBetween clears the data.
- base::RunLoop run_loop2;
- network_context->ClearNetworkingHistoryBetween(
- base::Time::Now() - base::Hours(1), base::Time::Max(),
- run_loop2.QuitClosure());
- run_loop2.Run();
- EXPECT_FALSE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- // Destroy the network context and let any pending writes complete before
- // destroying |temp_dir|, to avoid leaking any files.
- network_context.reset();
- task_environment_.RunUntilIdle();
- ASSERT_TRUE(temp_dir.Delete());
- }
- #if BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED)
- TEST_F(NetworkContextTest, DataDirectoryAsHandle) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath file_path = temp_dir.GetPath().AppendASCII("foo");
- ASSERT_TRUE(base::CreateDirectory(file_path.DirName()));
- const url::SchemeHostPort kSchemeHostPort("https", "foo", 443);
- // Create a context with on-disk storage of HTTP server properties.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- // Make |data_directory| into a path-less directory handle.
- // Moving a TransferableDirectory once it's been opened will drop the
- // path from the original.
- context_params->file_paths->data_directory =
- TransferableDirectory(file_path.DirName());
- context_params->file_paths->data_directory.OpenForTransfer();
- EXPECT_TRUE(context_params->file_paths->data_directory.NeedsMount());
- context_params->file_paths->http_server_properties_file_name =
- file_path.BaseName();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Wait for properties to load from disk, and sanity check initial state.
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- // Set a property.
- network_context->url_request_context()
- ->http_server_properties()
- ->SetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey(), true);
- // Deleting the context will cause it to flush state. Wait for the pref
- // service to flush to disk.
- network_context.reset();
- task_environment_.RunUntilIdle();
- // Create a new NetworkContext using the same path for HTTP server properties.
- context_params = CreateNetworkContextParamsForTesting();
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory = file_path.DirName();
- context_params->file_paths->http_server_properties_file_name =
- file_path.BaseName();
- network_context = CreateContextWithParams(std::move(context_params));
- // Wait for properties to load from disk.
- task_environment_.RunUntilIdle();
- EXPECT_TRUE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- // Now check that ClearNetworkingHistoryBetween clears the data.
- base::RunLoop run_loop2;
- network_context->ClearNetworkingHistoryBetween(
- base::Time::Now() - base::Hours(1), base::Time::Max(),
- run_loop2.QuitClosure());
- run_loop2.Run();
- EXPECT_FALSE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- // Destroy the network context and let any pending writes complete before
- // destroying |temp_dir|, to avoid leaking any files.
- network_context.reset();
- task_environment_.RunUntilIdle();
- ASSERT_TRUE(temp_dir.Delete());
- }
- #endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED)
- // Checks that ClearNetworkingHistoryBetween() clears in-memory pref stores and
- // invokes the closure passed to it.
- TEST_F(NetworkContextTest, ClearHttpServerPropertiesInMemory) {
- const url::SchemeHostPort kSchemeHostPort("https", "foo", 443);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_FALSE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- network_context->url_request_context()
- ->http_server_properties()
- ->SetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey(), true);
- EXPECT_TRUE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- base::RunLoop run_loop;
- network_context->ClearNetworkingHistoryBetween(
- base::Time::Now() - base::Hours(1), base::Time::Max(),
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_FALSE(
- network_context->url_request_context()
- ->http_server_properties()
- ->GetSupportsSpdy(kSchemeHostPort, net::NetworkIsolationKey()));
- }
- // Checks that ClearNetworkingHistoryBetween() clears network quality prefs.
- TEST_F(NetworkContextTest, ClearingNetworkingHistoryClearNetworkQualityPrefs) {
- const url::SchemeHostPort kSchemeHostPort("https", "foo", 443);
- net::TestNetworkQualityEstimator estimator;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- TestingPrefServiceSimple pref_service_simple;
- NetworkQualitiesPrefDelegate::RegisterPrefs(pref_service_simple.registry());
- std::unique_ptr<NetworkQualitiesPrefDelegate>
- network_qualities_pref_delegate =
- std::make_unique<NetworkQualitiesPrefDelegate>(&pref_service_simple,
- &estimator);
- NetworkQualitiesPrefDelegate* network_qualities_pref_delegate_ptr =
- network_qualities_pref_delegate.get();
- network_context->set_network_qualities_pref_delegate_for_testing(
- std::move(network_qualities_pref_delegate));
- // Running the loop allows prefs to be set.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(
- network_qualities_pref_delegate_ptr->ForceReadPrefsForTesting().empty());
- // Clear the networking history.
- base::RunLoop run_loop;
- base::HistogramTester histogram_tester;
- network_context->ClearNetworkingHistoryBetween(
- base::Time::Now() - base::Hours(1), base::Time::Max(),
- run_loop.QuitClosure());
- run_loop.Run();
- // Running the loop should clear the network quality prefs.
- base::RunLoop().RunUntilIdle();
- // Prefs should be empty now.
- EXPECT_TRUE(
- network_qualities_pref_delegate_ptr->ForceReadPrefsForTesting().empty());
- histogram_tester.ExpectTotalCount("NQE.PrefsSizeOnClearing", 1);
- }
- // Test that TransportSecurity state is persisted (or not) as expected.
- TEST_F(NetworkContextTest, TransportSecurityStatePersisted) {
- const char kDomain[] = "foo.test";
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath transport_security_persister_file_path =
- temp_dir.GetPath().AppendASCII("TransportSecurity");
- EXPECT_FALSE(base::PathExists(transport_security_persister_file_path));
- for (bool on_disk : {false, true}) {
- // Create a NetworkContext.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- if (on_disk) {
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory =
- transport_security_persister_file_path.DirName();
- context_params->file_paths->transport_security_persister_file_name =
- transport_security_persister_file_path.BaseName();
- }
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Add an STS entry.
- net::TransportSecurityState::STSState sts_state;
- net::TransportSecurityState* state =
- network_context->url_request_context()->transport_security_state();
- EXPECT_FALSE(state->GetDynamicSTSState(kDomain, &sts_state));
- state->AddHSTS(kDomain, base::Time::Now() + base::Seconds(1000),
- false /* include subdomains */);
- EXPECT_TRUE(state->GetDynamicSTSState(kDomain, &sts_state));
- ASSERT_EQ(kDomain, sts_state.domain);
- // Destroy the network context, and wait for all tasks to write state to
- // disk to finish running.
- network_context.reset();
- task_environment_.RunUntilIdle();
- EXPECT_EQ(on_disk,
- base::PathExists(transport_security_persister_file_path));
- // Create a new NetworkContext,with the same parameters, and check if the
- // added STS entry still exists.
- context_params = CreateNetworkContextParamsForTesting();
- if (on_disk) {
- context_params->file_paths = mojom::NetworkContextFilePaths::New();
- context_params->file_paths->data_directory =
- transport_security_persister_file_path.DirName();
- context_params->file_paths->transport_security_persister_file_name =
- transport_security_persister_file_path.BaseName();
- }
- network_context = CreateContextWithParams(std::move(context_params));
- // Wait for the entry to load.
- task_environment_.RunUntilIdle();
- state = network_context->url_request_context()->transport_security_state();
- ASSERT_EQ(on_disk, state->GetDynamicSTSState(kDomain, &sts_state));
- if (on_disk)
- EXPECT_EQ(kDomain, sts_state.domain);
- }
- }
- // Test that PKP failures are reported if and only if certificate reporting is
- // enabled.
- TEST_F(NetworkContextTest, CertReporting) {
- const char kPreloadedPKPHost[] = "with-report-uri-pkp.preloaded.test";
- const char kReportHost[] = "report-uri.preloaded.test";
- const char kReportPath[] = "/pkp";
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(
- net::features::kStaticKeyPinningEnforcement);
- for (bool reporting_enabled : {false, true}) {
- // Server that PKP reports are sent to.
- net::test_server::EmbeddedTestServer report_test_server;
- net::test_server::ControllableHttpResponse controllable_response(
- &report_test_server, kReportPath);
- ASSERT_TRUE(report_test_server.Start());
- // Configure the TransportSecurityStateSource so that kPreloadedPKPHost will
- // have static PKP pins set, with a report URI on kReportHost.
- net::ScopedTransportSecurityStateSource scoped_security_state_source(
- report_test_server.port());
- // Configure a test HTTPS server.
- net::test_server::EmbeddedTestServer pkp_test_server(
- net::test_server::EmbeddedTestServer::TYPE_HTTPS);
- pkp_test_server.SetSSLConfig(
- net::test_server::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
- ASSERT_TRUE(pkp_test_server.Start());
- // Configure mock cert verifier to cause the PKP check to fail.
- net::CertVerifyResult result;
- result.verified_cert = net::CreateCertificateChainFromFile(
- net::GetTestCertsDirectory(), "ok_cert.pem",
- net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
- ASSERT_TRUE(result.verified_cert);
- net::SHA256HashValue hash = {{0x00, 0x01}};
- result.public_key_hashes.push_back(net::HashValue(hash));
- result.is_issued_by_known_root = true;
- net::MockCertVerifier mock_verifier;
- mock_verifier.AddResultForCert(pkp_test_server.GetCertificate(), result,
- net::OK);
- NetworkContext::SetCertVerifierForTesting(&mock_verifier);
- // Configure a MockHostResolver to map requests to kPreloadedPKPHost and
- // kReportHost to the test servers:
- scoped_refptr<net::RuleBasedHostResolverProc> mock_resolver_proc =
- base::MakeRefCounted<net::RuleBasedHostResolverProc>(nullptr);
- mock_resolver_proc->AddIPLiteralRule(
- kPreloadedPKPHost, pkp_test_server.GetIPLiteralString(), std::string());
- mock_resolver_proc->AddIPLiteralRule(
- kReportHost, report_test_server.GetIPLiteralString(), std::string());
- net::ScopedDefaultHostResolverProc scoped_default_host_resolver(
- mock_resolver_proc.get());
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- EXPECT_FALSE(context_params->enable_certificate_reporting);
- context_params->enable_certificate_reporting = reporting_enabled;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Enable static pins so that requests made to kPreloadedPKPHost will check
- // the pins, and send a report if the pinning check fails.
- network_context->url_request_context()
- ->transport_security_state()
- ->EnableStaticPinsForTesting();
- network_context->url_request_context()
- ->transport_security_state()
- ->SetPinningListAlwaysTimelyForTesting(true);
- ResourceRequest request;
- request.url = pkp_test_server.GetURL(kPreloadedPKPHost, "/");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_TRUE(client.has_received_completion());
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
- client.completion_status().error_code);
- if (reporting_enabled) {
- // If reporting is enabled, wait to see the request from the ReportSender.
- // Don't respond to the request, effectively making it a hung request.
- controllable_response.WaitForRequest();
- } else {
- // Otherwise, there should be no pending URLRequest.
- // |controllable_response| will cause requests to hang, so if there's no
- // URLRequest, then either a reporting request was never started. This
- // relies on reported being sent immediately for correctness.
- network_context->url_request_context()->AssertNoURLRequests();
- }
- // Destroy the network context. This serves to check the case that reporting
- // requests are alive when a NetworkContext is torn down.
- network_context.reset();
- // Remove global reference to the MockCertVerifier before it falls out of
- // scope.
- NetworkContext::SetCertVerifierForTesting(nullptr);
- }
- }
- // Test that host resolution error information is available.
- TEST_F(NetworkContextTest, HostResolutionFailure) {
- auto context_builder = CreateTestURLRequestContextBuilder();
- std::unique_ptr<net::MockHostResolver> resolver =
- std::make_unique<net::MockHostResolver>();
- resolver->rules()->AddSimulatedTimeoutFailure("*");
- context_builder->set_host_resolver(std::move(resolver));
- auto url_request_context = context_builder->Build();
- network_context_remote_.reset();
- std::unique_ptr<NetworkContext> network_context =
- std::make_unique<NetworkContext>(
- network_service_.get(),
- network_context_remote_.BindNewPipeAndPassReceiver(),
- url_request_context.get(),
- /*cors_exempt_header_list=*/std::vector<std::string>());
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- ResourceRequest request;
- request.url = GURL("http://example.test");
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_TRUE(client.has_received_completion());
- EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, client.completion_status().error_code);
- EXPECT_EQ(net::ERR_DNS_TIMED_OUT,
- client.completion_status().resolve_error_info.error);
- }
- #if BUILDFLAG(IS_P2P_ENABLED)
- // Test the P2PSocketManager::GetHostAddress() works and uses the correct
- // NetworkIsolationKey.
- TEST_F(NetworkContextTest, P2PHostResolution) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- net::features::kSplitHostCacheByNetworkIsolationKey);
- const char kHostname[] = "foo.test.";
- net::IPAddress ip_address;
- ASSERT_TRUE(ip_address.AssignFromIPLiteral("1.2.3.4"));
- net::NetworkIsolationKey network_isolation_key =
- net::NetworkIsolationKey::CreateTransient();
- auto context_builder = CreateTestURLRequestContextBuilder();
- context_builder->set_host_resolver(
- std::make_unique<net::MockCachingHostResolver>());
- auto url_request_context = context_builder->Build();
- auto& host_resolver = *static_cast<net::MockCachingHostResolver*>(
- url_request_context->host_resolver());
- host_resolver.rules()->AddRule(kHostname, ip_address.ToString());
- network_context_remote_.reset();
- std::unique_ptr<NetworkContext> network_context =
- std::make_unique<NetworkContext>(
- network_service_.get(),
- network_context_remote_.BindNewPipeAndPassReceiver(),
- url_request_context.get(),
- std::vector<std::string>() /* cors_exempt_header_list */);
- MockP2PTrustedSocketManagerClient client;
- mojo::Receiver<network::mojom::P2PTrustedSocketManagerClient> receiver(
- &client);
- mojo::Remote<mojom::P2PTrustedSocketManager> trusted_socket_manager;
- mojo::Remote<mojom::P2PSocketManager> socket_manager;
- network_context_remote_->CreateP2PSocketManager(
- network_isolation_key, receiver.BindNewPipeAndPassRemote(),
- trusted_socket_manager.BindNewPipeAndPassReceiver(),
- socket_manager.BindNewPipeAndPassReceiver());
- base::RunLoop run_loop;
- std::vector<net::IPAddress> results;
- socket_manager->GetHostAddress(
- kHostname, false /* enable_mdns */,
- base::BindLambdaForTesting(
- [&](const std::vector<net::IPAddress>& addresses) {
- EXPECT_EQ(std::vector<net::IPAddress>{ip_address}, addresses);
- run_loop.Quit();
- }));
- run_loop.Run();
- // Check that the URL in kHostname is in the HostCache, with
- // |network_isolation_key|.
- const net::HostPortPair kHostPortPair = net::HostPortPair(kHostname, 0);
- net::HostResolver::ResolveHostParameters params;
- params.source = net::HostResolverSource::LOCAL_ONLY;
- std::unique_ptr<net::HostResolver::ResolveHostRequest> request1 =
- host_resolver.CreateRequest(kHostPortPair, network_isolation_key,
- net::NetLogWithSource(), params);
- net::TestCompletionCallback callback1;
- int result = request1->Start(callback1.callback());
- EXPECT_EQ(net::OK, callback1.GetResult(result));
- // Check that the hostname is not in the DNS cache for other possible NIKs.
- const url::Origin kDestinationOrigin =
- url::Origin::Create(GURL(base::StringPrintf("https://%s", kHostname)));
- const net::NetworkIsolationKey kOtherNiks[] = {
- net::NetworkIsolationKey(),
- net::NetworkIsolationKey(kDestinationOrigin /* top_frame_origin */,
- kDestinationOrigin /* frame_origin */)};
- for (const auto& other_nik : kOtherNiks) {
- std::unique_ptr<net::HostResolver::ResolveHostRequest> request2 =
- host_resolver.CreateRequest(kHostPortPair, other_nik,
- net::NetLogWithSource(), params);
- net::TestCompletionCallback callback2;
- result = request2->Start(callback2.callback());
- EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, callback2.GetResult(result));
- }
- }
- #endif // BUILDFLAG(IS_P2P_ENABLED)
- // Test that valid referrers are allowed, while invalid ones result in errors.
- TEST_F(NetworkContextTest, Referrers) {
- const GURL kReferrer = GURL("http://referrer/");
- net::test_server::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- for (bool validate_referrer_policy_on_initial_request : {false, true}) {
- for (net::ReferrerPolicy referrer_policy :
- {net::ReferrerPolicy::NEVER_CLEAR, net::ReferrerPolicy::NO_REFERRER}) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->validate_referrer_policy_on_initial_request =
- validate_referrer_policy_on_initial_request;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = 0;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- ResourceRequest request;
- request.url = test_server.GetURL("/echoheader?Referer");
- request.referrer = kReferrer;
- request.referrer_policy = referrer_policy;
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(
- TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_TRUE(client.has_received_completion());
- // If validating referrers, and the referrer policy is not to send
- // referrers, the request should fail.
- if (validate_referrer_policy_on_initial_request &&
- referrer_policy == net::ReferrerPolicy::NO_REFERRER) {
- EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT,
- client.completion_status().error_code);
- EXPECT_FALSE(client.response_body().is_valid());
- continue;
- }
- // Otherwise, the request should succeed.
- EXPECT_EQ(net::OK, client.completion_status().error_code);
- std::string response_body;
- ASSERT_TRUE(client.response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client.response_body_release(),
- &response_body));
- if (referrer_policy == net::ReferrerPolicy::NO_REFERRER) {
- // If not validating referrers, and the referrer policy is not to send
- // referrers, the referrer should be cleared.
- EXPECT_EQ("None", response_body);
- } else {
- // Otherwise, the referrer should be send.
- EXPECT_EQ(kReferrer.spec(), response_body);
- }
- }
- }
- }
- // Validates that clearing the HTTP cache when no cache exists does complete.
- TEST_F(NetworkContextTest, ClearHttpCacheWithNoCache) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = false;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- ASSERT_EQ(nullptr, cache);
- base::RunLoop run_loop;
- network_context->ClearHttpCache(base::Time(), base::Time(),
- nullptr /* filter */,
- base::BindOnce(run_loop.QuitClosure()));
- run_loop.Run();
- }
- TEST_F(NetworkContextTest, ClearHttpCache) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- context_params->http_cache_directory = temp_dir.GetPath();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- std::vector<std::string> entry_urls = {
- "http://www.google.com", "https://www.google.com",
- "http://www.wikipedia.com", "https://www.wikipedia.com",
- "http://localhost:1234", "https://localhost:1234",
- };
- ASSERT_TRUE(cache);
- disk_cache::Backend* backend = nullptr;
- net::TestCompletionCallback callback;
- int rv = cache->GetBackend(&backend, callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(rv));
- ASSERT_TRUE(backend);
- for (const auto& url : entry_urls) {
- disk_cache::EntryResult result;
- base::RunLoop run_loop;
- result = backend->CreateEntry(
- url, net::HIGHEST,
- base::BindLambdaForTesting([&](disk_cache::EntryResult got_result) {
- result = std::move(got_result);
- run_loop.Quit();
- }));
- if (result.net_error() == net::ERR_IO_PENDING)
- run_loop.Run();
- result.ReleaseEntry()->Close();
- }
- EXPECT_EQ(entry_urls.size(), static_cast<size_t>(backend->GetEntryCount()));
- base::RunLoop run_loop;
- network_context->ClearHttpCache(base::Time(), base::Time(),
- nullptr /* filter */,
- base::BindOnce(run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(0U, static_cast<size_t>(backend->GetEntryCount()));
- }
- // Checks that when multiple calls are made to clear the HTTP cache, all
- // callbacks are invoked.
- TEST_F(NetworkContextTest, MultipleClearHttpCacheCalls) {
- constexpr int kNumberOfClearCalls = 10;
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- context_params->http_cache_directory = temp_dir.GetPath();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- base::RunLoop run_loop;
- base::RepeatingClosure barrier_closure = base::BarrierClosure(
- kNumberOfClearCalls /* num_closures */, run_loop.QuitClosure());
- for (int i = 0; i < kNumberOfClearCalls; i++) {
- network_context->ClearHttpCache(base::Time(), base::Time(),
- nullptr /* filter */,
- base::BindOnce(barrier_closure));
- }
- run_loop.Run();
- // If all the callbacks were invoked, we should terminate.
- }
- TEST_F(NetworkContextTest, NotifyExternalCacheHit) {
- const std::vector<GURL> kUrls = {
- GURL("http://www.google.com/"),
- GURL("http://www.wikipedia.com/"),
- GURL("http://localhost:1234/"),
- };
- const url::Origin kOrigin = url::Origin::Create(GURL("http://a.com"));
- constexpr base::Time kNow1 = base::Time::UnixEpoch() + base::Hours(18);
- constexpr base::Time kNow2 = base::Time::UnixEpoch() + base::Hours(11);
- for (bool enabled : {false, true}) {
- base::test::ScopedFeatureList feature_list;
- if (enabled) {
- feature_list.InitAndEnableFeature(
- net::features::kSplitCacheByNetworkIsolationKey);
- } else {
- feature_list.InitAndDisableFeature(
- net::features::kSplitCacheByNetworkIsolationKey);
- }
- for (const GURL& url : kUrls) {
- for (bool is_subframe_document_resource : {false, true}) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- base::SimpleTestClock clock;
- net::HttpCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetCache();
- disk_cache::Backend* backend = nullptr;
- // We expect that every cache operation below is done synchronously
- // because we're using an in-memory backend.
- // The disk cache is lazily instantiated, force it and ensure it's
- // valid.
- ASSERT_EQ(cache->GetBackend(&backend, base::BindOnce([](int rv) {})),
- net::OK);
- ASSERT_NE(backend, nullptr);
- static_cast<disk_cache::MemBackendImpl*>(backend)->SetClockForTesting(
- &clock);
- clock.SetNow(kNow1);
- net::NetworkIsolationKey isolation_key(kOrigin, kOrigin);
- net::HttpRequestInfo request_info;
- request_info.url = url;
- request_info.is_subframe_document_resource =
- is_subframe_document_resource;
- request_info.network_isolation_key = isolation_key;
- disk_cache::EntryResult result = backend->OpenOrCreateEntry(
- *net::HttpCache::GenerateCacheKeyForRequest(&request_info),
- net::LOWEST, base::BindOnce([](disk_cache::EntryResult) {}));
- ASSERT_EQ(result.net_error(), net::OK);
- disk_cache::ScopedEntryPtr entry(result.ReleaseEntry());
- EXPECT_EQ(entry->GetLastUsed(), kNow1);
- clock.SetNow(kNow2);
- network_context->NotifyExternalCacheHit(
- url, url.scheme(), isolation_key, is_subframe_document_resource,
- /*include_credentials=*/true);
- EXPECT_EQ(entry->GetLastUsed(), kNow2);
- }
- }
- }
- }
- TEST_F(NetworkContextTest, CountHttpCache) {
- // Just ensure that a couple of concurrent calls go through, and produce
- // the expected "it's empty!" result. More detailed testing is left to
- // HttpCacheDataCounter unit tests.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->http_cache_enabled = true;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- int responses = 0;
- base::RunLoop run_loop;
- auto callback =
- base::BindLambdaForTesting([&](bool upper_bound, int64_t size_or_error) {
- // Don't expect approximation for full range.
- EXPECT_EQ(false, upper_bound);
- EXPECT_EQ(0, size_or_error);
- ++responses;
- if (responses == 2)
- run_loop.Quit();
- });
- network_context->ComputeHttpCacheSize(base::Time(), base::Time::Max(),
- callback);
- network_context->ComputeHttpCacheSize(base::Time(), base::Time::Max(),
- callback);
- run_loop.Run();
- }
- TEST_F(NetworkContextTest, ClearHostCache) {
- // List of domains added to the host cache before running each test case.
- const char* kDomains[] = {
- "domain0",
- "domain1",
- "domain2",
- "domain3",
- };
- // Each bit corresponds to one of the 4 domains above.
- enum Domains {
- NO_DOMAINS = 0x0,
- DOMAIN0 = 0x1,
- DOMAIN1 = 0x2,
- DOMAIN2 = 0x4,
- DOMAIN3 = 0x8,
- };
- const struct {
- // True if the ClearDataFilter should be a nullptr.
- bool null_filter;
- mojom::ClearDataFilter::Type type;
- // Bit field of Domains that appear in the filter. The origin vector is
- // never populated.
- int filter_domains;
- // Only domains that are expected to remain in the host cache.
- int expected_cached_domains;
- } kTestCases[] = {
- // A null filter should delete everything. The filter type and filter
- // domain lists are ignored.
- {
- true /* null_filter */, mojom::ClearDataFilter::Type::KEEP_MATCHES,
- NO_DOMAINS /* filter_domains */,
- NO_DOMAINS /* expected_cached_domains */
- },
- // An empty DELETE_MATCHES filter should delete nothing.
- {
- false /* null_filter */, mojom::ClearDataFilter::Type::DELETE_MATCHES,
- NO_DOMAINS /* filter_domains */,
- DOMAIN0 | DOMAIN1 | DOMAIN2 | DOMAIN3 /* expected_cached_domains */
- },
- // An empty KEEP_MATCHES filter should delete everything.
- {
- false /* null_filter */, mojom::ClearDataFilter::Type::KEEP_MATCHES,
- NO_DOMAINS /* filter_domains */,
- NO_DOMAINS /* expected_cached_domains */
- },
- // Test a non-empty DELETE_MATCHES filter.
- {
- false /* null_filter */, mojom::ClearDataFilter::Type::DELETE_MATCHES,
- DOMAIN0 | DOMAIN2 /* filter_domains */,
- DOMAIN1 | DOMAIN3 /* expected_cached_domains */
- },
- // Test a non-empty KEEP_MATCHES filter.
- {
- false /* null_filter */, mojom::ClearDataFilter::Type::KEEP_MATCHES,
- DOMAIN0 | DOMAIN2 /* filter_domains */,
- DOMAIN0 | DOMAIN2 /* expected_cached_domains */
- },
- };
- for (const auto& test_case : kTestCases) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::HostCache* host_cache =
- network_context->url_request_context()->host_resolver()->GetHostCache();
- ASSERT_TRUE(host_cache);
- // Add the 4 test domains to the host cache, each once with scheme and once
- // without.
- for (const auto* domain : kDomains) {
- host_cache->Set(
- net::HostCache::Key(domain, net::DnsQueryType::UNSPECIFIED, 0,
- net::HostResolverSource::ANY,
- net::NetworkIsolationKey()),
- net::HostCache::Entry(net::OK, /*ip_endpoints=*/{}, /*aliases=*/{},
- net::HostCache::Entry::SOURCE_UNKNOWN),
- base::TimeTicks::Now(), base::Days(1));
- host_cache->Set(
- net::HostCache::Key(
- url::SchemeHostPort(url::kHttpsScheme, domain, 443),
- net::DnsQueryType::UNSPECIFIED, 0, net::HostResolverSource::ANY,
- net::NetworkIsolationKey()),
- net::HostCache::Entry(net::OK, /*ip_endpoints=*/{}, /*aliases=*/{},
- net::HostCache::Entry::SOURCE_UNKNOWN),
- base::TimeTicks::Now(), base::Days(1));
- }
- // Sanity check.
- EXPECT_EQ(std::size(kDomains) * 2, host_cache->entries().size());
- // Set up and run the filter, according to |test_case|.
- mojom::ClearDataFilterPtr clear_data_filter;
- if (!test_case.null_filter) {
- clear_data_filter = mojom::ClearDataFilter::New();
- clear_data_filter->type = test_case.type;
- for (size_t i = 0; i < std::size(kDomains); ++i) {
- if (test_case.filter_domains & (1 << i))
- clear_data_filter->domains.push_back(kDomains[i]);
- }
- }
- base::RunLoop run_loop;
- network_context->ClearHostCache(std::move(clear_data_filter),
- run_loop.QuitClosure());
- run_loop.Run();
- // Check that only the expected domains remain in the cache.
- size_t expected_cached = 0;
- for (size_t i = 0; i < std::size(kDomains); ++i) {
- bool expect_domain_cached =
- ((test_case.expected_cached_domains & (1 << i)) != 0);
- EXPECT_EQ(expect_domain_cached,
- (host_cache->GetMatchingKeyForTesting(
- kDomains[i], nullptr /* source_out */,
- nullptr /* stale_out */) != nullptr));
- if (expect_domain_cached)
- expected_cached += 2;
- }
- EXPECT_EQ(host_cache->entries().size(), expected_cached);
- }
- }
- TEST_F(NetworkContextTest, ClearHttpAuthCache) {
- url::SchemeHostPort scheme_host_port(GURL("http://google.com"));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- base::Time start_time;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:00", &start_time));
- base::SimpleTestClock test_clock;
- test_clock.SetNow(start_time);
- cache->set_clock_for_testing(&test_clock);
- std::u16string user = u"user";
- std::u16string password = u"pass";
- cache->Add(scheme_host_port, net::HttpAuth::AUTH_SERVER, "Realm1",
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(),
- "basic realm=Realm1", net::AuthCredentials(user, password), "/");
- test_clock.Advance(base::Hours(1)); // Time now 13:00
- cache->Add(scheme_host_port, net::HttpAuth::AUTH_PROXY, "Realm2",
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(),
- "basic realm=Realm2", net::AuthCredentials(user, password), "/");
- ASSERT_EQ(2u, cache->GetEntriesSizeForTesting());
- ASSERT_NE(nullptr, cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- "Realm1", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- ASSERT_NE(nullptr, cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_PROXY,
- "Realm2", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- {
- base::RunLoop run_loop;
- base::Time test_time;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:30:00", &test_time));
- network_context->ClearHttpAuthCache(base::Time(), test_time,
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_EQ(1u, cache->GetEntriesSizeForTesting());
- EXPECT_EQ(nullptr,
- cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- "Realm1", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- EXPECT_NE(nullptr,
- cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_PROXY,
- "Realm2", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- }
- {
- base::RunLoop run_loop;
- base::Time test_time;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:30:00", &test_time));
- network_context->ClearHttpAuthCache(test_time, base::Time::Max(),
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_EQ(0u, cache->GetEntriesSizeForTesting());
- EXPECT_EQ(nullptr,
- cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- "Realm1", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- EXPECT_EQ(nullptr,
- cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_PROXY,
- "Realm2", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- }
- }
- TEST_F(NetworkContextTest, ClearAllHttpAuthCache) {
- url::SchemeHostPort scheme_host_port(GURL("http://google.com"));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- base::Time start_time;
- ASSERT_TRUE(base::Time::FromString("30 May 2018 12:00:00", &start_time));
- base::SimpleTestClock test_clock;
- test_clock.SetNow(start_time);
- cache->set_clock_for_testing(&test_clock);
- std::u16string user = u"user";
- std::u16string password = u"pass";
- cache->Add(scheme_host_port, net::HttpAuth::AUTH_SERVER, "Realm1",
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(),
- "basic realm=Realm1", net::AuthCredentials(user, password), "/");
- test_clock.Advance(base::Hours(1)); // Time now 13:00
- cache->Add(scheme_host_port, net::HttpAuth::AUTH_PROXY, "Realm2",
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(),
- "basic realm=Realm2", net::AuthCredentials(user, password), "/");
- ASSERT_EQ(2u, cache->GetEntriesSizeForTesting());
- ASSERT_NE(nullptr, cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- "Realm1", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- ASSERT_NE(nullptr, cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_PROXY,
- "Realm2", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- base::RunLoop run_loop;
- network_context->ClearHttpAuthCache(base::Time(), base::Time::Max(),
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_EQ(0u, cache->GetEntriesSizeForTesting());
- EXPECT_EQ(nullptr, cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- "Realm1", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- EXPECT_EQ(nullptr, cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_PROXY,
- "Realm2", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- }
- TEST_F(NetworkContextTest, ClearEmptyHttpAuthCache) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- ASSERT_EQ(0u, cache->GetEntriesSizeForTesting());
- base::RunLoop run_loop;
- network_context->ClearHttpAuthCache(base::Time::UnixEpoch(),
- base::Time::Max(),
- base::BindOnce(run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(0u, cache->GetEntriesSizeForTesting());
- }
- absl::optional<net::AuthCredentials> GetAuthCredentials(
- NetworkContext* network_context,
- const GURL& origin,
- const net::NetworkIsolationKey& network_isolation_key) {
- base::RunLoop run_loop;
- absl::optional<net::AuthCredentials> result;
- network_context->LookupServerBasicAuthCredentials(
- origin, network_isolation_key,
- base::BindLambdaForTesting(
- [&](const absl::optional<net::AuthCredentials>& credentials) {
- result = credentials;
- run_loop.Quit();
- }));
- run_loop.Run();
- return result;
- }
- TEST_F(NetworkContextTest, LookupServerBasicAuthCredentials) {
- GURL origin("http://foo.test");
- GURL origin2("http://bar.test");
- GURL origin3("http://baz.test");
- net::NetworkIsolationKey network_isolation_key1(url::Origin::Create(origin),
- url::Origin::Create(origin));
- net::NetworkIsolationKey network_isolation_key2(url::Origin::Create(origin2),
- url::Origin::Create(origin2));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- network_context->SetSplitAuthCacheByNetworkIsolationKey(true);
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- std::u16string user = u"user";
- std::u16string password = u"pass";
- cache->Add(url::SchemeHostPort(origin), net::HttpAuth::AUTH_SERVER, "Realm",
- net::HttpAuth::AUTH_SCHEME_BASIC, network_isolation_key1,
- "basic realm=Realm", net::AuthCredentials(user, password), "/");
- cache->Add(url::SchemeHostPort(origin2), net::HttpAuth::AUTH_PROXY, "Realm",
- net::HttpAuth::AUTH_SCHEME_BASIC, network_isolation_key1,
- "basic realm=Realm", net::AuthCredentials(user, password), "/");
- absl::optional<net::AuthCredentials> result =
- GetAuthCredentials(network_context.get(), origin, network_isolation_key1);
- ASSERT_TRUE(result.has_value());
- EXPECT_EQ(user, result->username());
- EXPECT_EQ(password, result->password());
- // Nothing should be returned when using a different NIK.
- EXPECT_FALSE(
- GetAuthCredentials(network_context.get(), origin, network_isolation_key2)
- .has_value());
- // Proxy credentials should not be returned
- result = GetAuthCredentials(network_context.get(), origin2,
- network_isolation_key1);
- EXPECT_FALSE(result.has_value());
- }
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- absl::optional<net::AuthCredentials> GetProxyAuthCredentials(
- NetworkContext* network_context,
- const net::ProxyServer& proxy_server,
- const std::string& scheme,
- const std::string& realm) {
- base::RunLoop run_loop;
- absl::optional<net::AuthCredentials> result;
- network_context->LookupProxyAuthCredentials(
- proxy_server, scheme, realm,
- base::BindLambdaForTesting(
- [&](const absl::optional<net::AuthCredentials>& credentials) {
- result = credentials;
- run_loop.Quit();
- }));
- run_loop.Run();
- return result;
- }
- TEST_F(NetworkContextTest, LookupProxyAuthCredentials) {
- GURL http_proxy("http://bar.test:1080");
- GURL https_proxy("https://bar.test:443");
- GURL http_proxy2("http://bar.test:443");
- GURL foo_proxy("foo://bar.test:1080");
- GURL server_origin("http://foo.test:3128");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- network_context->SetSplitAuthCacheByNetworkIsolationKey(true);
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- std::u16string user = u"user";
- std::u16string password = u"pass";
- cache->Add(url::SchemeHostPort(http_proxy), net::HttpAuth::AUTH_PROXY,
- "Realm", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey(), "basic realm=Realm",
- net::AuthCredentials(user, password),
- /* path = */ "");
- cache->Add(url::SchemeHostPort(https_proxy), net::HttpAuth::AUTH_PROXY,
- "Realm", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey(), "basic realm=Realm",
- net::AuthCredentials(user, password),
- /* path = */ "");
- cache->Add(url::SchemeHostPort(server_origin), net::HttpAuth::AUTH_SERVER,
- "Realm", net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey(), "basic realm=Realm",
- net::AuthCredentials(user, password),
- /* path = */ "/");
- absl::optional<net::AuthCredentials> result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP,
- net::HostPortPair::FromURL(http_proxy)),
- "bAsIc", "Realm");
- ASSERT_TRUE(result.has_value());
- EXPECT_EQ(user, result->username());
- EXPECT_EQ(password, result->password());
- result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTPS,
- net::HostPortPair::FromURL(https_proxy)),
- "bAsIc", "Realm");
- ASSERT_TRUE(result.has_value());
- EXPECT_EQ(user, result->username());
- EXPECT_EQ(password, result->password());
- // Check that the proxy scheme is taken into account when looking for
- // credentials
- result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP,
- net::HostPortPair::FromURL(http_proxy2)),
- "basic", "Realm");
- EXPECT_FALSE(result.has_value());
- // Check that the proxy authentication method is taken into account when
- // looking for credentials
- result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP,
- net::HostPortPair::FromURL(http_proxy)),
- "digest", "Realm");
- EXPECT_FALSE(result.has_value());
- // Check that the realm is taken into account when looking for credentials
- result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP,
- net::HostPortPair::FromURL(http_proxy)),
- "basic", "Realm 2");
- EXPECT_FALSE(result.has_value());
- // All non-https proxies are cached as "http://" proxies
- result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP,
- net::HostPortPair::FromURL(foo_proxy)),
- "basic", "Realm");
- EXPECT_FALSE(result.has_value());
- // Server credentials should not be returned
- result = GetProxyAuthCredentials(
- network_context.get(),
- net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP,
- net::HostPortPair::FromURL(server_origin)),
- "basic", "Realm");
- EXPECT_FALSE(result.has_value());
- }
- #endif
- #if BUILDFLAG(ENABLE_REPORTING)
- TEST_F(NetworkContextTest, ClearReportingCacheReports) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- GURL domain("http://google.com");
- network_context->url_request_context()->reporting_service()->QueueReport(
- domain, absl::nullopt, net::NetworkIsolationKey(), "Mozilla/1.0", "group",
- "type", base::Value::Dict(), 0);
- std::vector<const net::ReportingReport*> reports;
- reporting_cache->GetReports(&reports);
- ASSERT_EQ(1u, reports.size());
- base::RunLoop run_loop;
- network_context->ClearReportingCacheReports(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- reporting_cache->GetReports(&reports);
- EXPECT_EQ(0u, reports.size());
- }
- TEST_F(NetworkContextTest, ClearReportingCacheReportsWithFilter) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- net::ReportingService* reporting_service =
- network_context->url_request_context()->reporting_service();
- GURL url1("http://google.com");
- reporting_service->QueueReport(url1, absl::nullopt,
- net::NetworkIsolationKey(), "Mozilla/1.0",
- "group", "type", base::Value::Dict(), 0);
- GURL url2("http://chromium.org");
- reporting_service->QueueReport(url2, absl::nullopt,
- net::NetworkIsolationKey(), "Mozilla/1.0",
- "group", "type", base::Value::Dict(), 0);
- std::vector<const net::ReportingReport*> reports;
- reporting_cache->GetReports(&reports);
- ASSERT_EQ(2u, reports.size());
- mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New();
- filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES;
- filter->domains.push_back("chromium.org");
- base::RunLoop run_loop;
- network_context->ClearReportingCacheReports(std::move(filter),
- run_loop.QuitClosure());
- run_loop.Run();
- reporting_cache->GetReports(&reports);
- EXPECT_EQ(1u, reports.size());
- EXPECT_EQ(url2, reports.front()->url);
- }
- TEST_F(NetworkContextTest,
- ClearReportingCacheReportsWithNonRegisterableFilter) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- net::ReportingService* reporting_service =
- network_context->url_request_context()->reporting_service();
- GURL url1("http://192.168.0.1");
- reporting_service->QueueReport(url1, absl::nullopt,
- net::NetworkIsolationKey(), "Mozilla/1.0",
- "group", "type", base::Value::Dict(), 0);
- GURL url2("http://192.168.0.2");
- reporting_service->QueueReport(url2, absl::nullopt,
- net::NetworkIsolationKey(), "Mozilla/1.0",
- "group", "type", base::Value::Dict(), 0);
- std::vector<const net::ReportingReport*> reports;
- reporting_cache->GetReports(&reports);
- ASSERT_EQ(2u, reports.size());
- mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New();
- filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES;
- filter->domains.push_back("192.168.0.2");
- base::RunLoop run_loop;
- network_context->ClearReportingCacheReports(std::move(filter),
- run_loop.QuitClosure());
- run_loop.Run();
- reporting_cache->GetReports(&reports);
- EXPECT_EQ(1u, reports.size());
- EXPECT_EQ(url2, reports.front()->url);
- }
- TEST_F(NetworkContextTest, ClearEmptyReportingCacheReports) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- std::vector<const net::ReportingReport*> reports;
- reporting_cache->GetReports(&reports);
- ASSERT_TRUE(reports.empty());
- base::RunLoop run_loop;
- network_context->ClearReportingCacheReports(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- reporting_cache->GetReports(&reports);
- EXPECT_TRUE(reports.empty());
- }
- TEST_F(NetworkContextTest, ClearReportingCacheReportsWithNoService) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndDisableFeature(features::kReporting);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_EQ(nullptr,
- network_context->url_request_context()->reporting_service());
- base::RunLoop run_loop;
- network_context->ClearReportingCacheReports(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- }
- TEST_F(NetworkContextTest, ClearReportingCacheClients) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- GURL domain("https://google.com");
- net::ReportingEndpointGroupKey group_key(
- net::NetworkIsolationKey(), url::Origin::Create(domain), "group");
- reporting_cache->SetEndpointForTesting(
- group_key, domain, net::OriginSubdomains::DEFAULT, base::Time::Max(),
- 1 /* priority */, 1 /* weight */);
- ASSERT_EQ(1u, reporting_cache->GetEndpointCount());
- base::RunLoop run_loop;
- network_context->ClearReportingCacheClients(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_EQ(0u, reporting_cache->GetEndpointCount());
- }
- TEST_F(NetworkContextTest, ClearReportingCacheClientsWithFilter) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- GURL domain1("https://google.com");
- net::ReportingEndpointGroupKey group_key1(
- net::NetworkIsolationKey(), url::Origin::Create(domain1), "group");
- reporting_cache->SetEndpointForTesting(
- group_key1, domain1, net::OriginSubdomains::DEFAULT, base::Time::Max(),
- 1 /* priority */, 1 /* weight */);
- GURL domain2("https://chromium.org");
- net::ReportingEndpointGroupKey group_key2(
- net::NetworkIsolationKey(), url::Origin::Create(domain2), "group");
- reporting_cache->SetEndpointForTesting(
- group_key2, domain2, net::OriginSubdomains::DEFAULT, base::Time::Max(),
- 1 /* priority */, 1 /* weight */);
- ASSERT_EQ(2u, reporting_cache->GetEndpointCount());
- mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New();
- filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES;
- filter->domains.push_back("chromium.org");
- base::RunLoop run_loop;
- network_context->ClearReportingCacheClients(std::move(filter),
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_EQ(1u, reporting_cache->GetEndpointCount());
- EXPECT_TRUE(reporting_cache->GetEndpointForTesting(group_key2, domain2));
- EXPECT_FALSE(reporting_cache->GetEndpointForTesting(group_key1, domain1));
- }
- TEST_F(NetworkContextTest, ClearEmptyReportingCacheClients) {
- auto reporting_context = std::make_unique<net::TestReportingContext>(
- base::DefaultClock::GetInstance(), base::DefaultTickClock::GetInstance(),
- net::ReportingPolicy());
- net::ReportingCache* reporting_cache = reporting_context->cache();
- std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(
- CreateNetworkContextParamsForTesting(),
- net::ReportingService::CreateForTesting(std::move(reporting_context)));
- ASSERT_EQ(0u, reporting_cache->GetEndpointCount());
- base::RunLoop run_loop;
- network_context->ClearReportingCacheClients(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- ASSERT_EQ(0u, reporting_cache->GetEndpointCount());
- }
- TEST_F(NetworkContextTest, ClearReportingCacheClientsWithNoService) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndDisableFeature(features::kReporting);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_EQ(nullptr,
- network_context->url_request_context()->reporting_service());
- base::RunLoop run_loop;
- network_context->ClearReportingCacheClients(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- }
- TEST_F(NetworkContextTest, ClearNetworkErrorLogging) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(features::kNetworkErrorLogging);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::NetworkErrorLoggingService* logging_service =
- network_context->url_request_context()->network_error_logging_service();
- ASSERT_TRUE(logging_service);
- GURL domain("https://google.com");
- logging_service->OnHeader(net::NetworkIsolationKey(),
- url::Origin::Create(domain),
- net::IPAddress(192, 168, 0, 1),
- "{\"report_to\":\"group\",\"max_age\":86400}");
- ASSERT_EQ(1u, logging_service->GetPolicyKeysForTesting().size());
- base::RunLoop run_loop;
- network_context->ClearNetworkErrorLogging(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_TRUE(logging_service->GetPolicyKeysForTesting().empty());
- }
- TEST_F(NetworkContextTest, ClearNetworkErrorLoggingWithFilter) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(features::kNetworkErrorLogging);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::NetworkErrorLoggingService* logging_service =
- network_context->url_request_context()->network_error_logging_service();
- ASSERT_TRUE(logging_service);
- GURL domain1("https://google.com");
- logging_service->OnHeader(net::NetworkIsolationKey(),
- url::Origin::Create(domain1),
- net::IPAddress(192, 168, 0, 1),
- "{\"report_to\":\"group\",\"max_age\":86400}");
- GURL domain2("https://chromium.org");
- logging_service->OnHeader(net::NetworkIsolationKey(),
- url::Origin::Create(domain2),
- net::IPAddress(192, 168, 0, 1),
- "{\"report_to\":\"group\",\"max_age\":86400}");
- ASSERT_EQ(2u, logging_service->GetPolicyKeysForTesting().size());
- mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New();
- filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES;
- filter->domains.push_back("chromium.org");
- base::RunLoop run_loop;
- network_context->ClearNetworkErrorLogging(std::move(filter),
- run_loop.QuitClosure());
- run_loop.Run();
- std::set<net::NetworkErrorLoggingService::NelPolicyKey> policy_keys =
- logging_service->GetPolicyKeysForTesting();
- EXPECT_EQ(1u, policy_keys.size());
- EXPECT_THAT(
- policy_keys,
- testing::ElementsAre(net::NetworkErrorLoggingService::NelPolicyKey(
- net::NetworkIsolationKey(), url::Origin::Create(domain2))));
- }
- TEST_F(NetworkContextTest, ClearEmptyNetworkErrorLogging) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(features::kNetworkErrorLogging);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::NetworkErrorLoggingService* logging_service =
- network_context->url_request_context()->network_error_logging_service();
- ASSERT_TRUE(logging_service);
- ASSERT_TRUE(logging_service->GetPolicyKeysForTesting().empty());
- base::RunLoop run_loop;
- network_context->ClearNetworkErrorLogging(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_TRUE(logging_service->GetPolicyKeysForTesting().empty());
- }
- TEST_F(NetworkContextTest, ClearEmptyNetworkErrorLoggingWithNoService) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndDisableFeature(features::kNetworkErrorLogging);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_FALSE(
- network_context->url_request_context()->network_error_logging_service());
- base::RunLoop run_loop;
- network_context->ClearNetworkErrorLogging(nullptr /* filter */,
- run_loop.QuitClosure());
- run_loop.Run();
- }
- #endif // BUILDFLAG(ENABLE_REPORTING)
- void SetCookieCallback(base::RunLoop* run_loop,
- bool* result_out,
- net::CookieAccessResult result) {
- *result_out = result.status.IsInclude();
- run_loop->Quit();
- }
- void GetCookieListCallback(
- base::RunLoop* run_loop,
- net::CookieList* result_out,
- const net::CookieAccessResultList& result,
- const net::CookieAccessResultList& excluded_cookies) {
- *result_out = net::cookie_util::StripAccessResults(result);
- run_loop->Quit();
- }
- bool SetCookieHelper(NetworkContext* network_context,
- const GURL& url,
- const std::string& key,
- const std::string& value) {
- mojo::Remote<mojom::CookieManager> cookie_manager;
- network_context->GetCookieManager(
- cookie_manager.BindNewPipeAndPassReceiver());
- base::RunLoop run_loop;
- bool result = false;
- cookie_manager->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- key, value, url.host(), "/", base::Time(), base::Time(), base::Time(),
- base::Time(), true, false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_LOW, false),
- url, net::CookieOptions::MakeAllInclusive(),
- base::BindOnce(&SetCookieCallback, &run_loop, &result));
- run_loop.Run();
- return result;
- }
- TEST_F(NetworkContextTest, CookieManager) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::CookieManager> cookie_manager_remote;
- network_context->GetCookieManager(
- cookie_manager_remote.BindNewPipeAndPassReceiver());
- // Set a cookie through the cookie interface.
- base::RunLoop run_loop1;
- bool result = false;
- auto cookie = net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "TestCookie", "1", "www.test.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), false, false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_LOW, false);
- cookie_manager_remote->SetCanonicalCookie(
- *cookie, net::cookie_util::SimulatedCookieSource(*cookie, "https"),
- net::CookieOptions::MakeAllInclusive(),
- base::BindOnce(&SetCookieCallback, &run_loop1, &result));
- run_loop1.Run();
- EXPECT_TRUE(result);
- // Confirm that cookie is visible directly through the store associated with
- // the network context.
- base::RunLoop run_loop2;
- net::CookieList cookies;
- network_context->url_request_context()
- ->cookie_store()
- ->GetCookieListWithOptionsAsync(
- GURL("http://www.test.com/whatever"),
- net::CookieOptions::MakeAllInclusive(),
- net::CookiePartitionKeyCollection(),
- base::BindOnce(&GetCookieListCallback, &run_loop2, &cookies));
- run_loop2.Run();
- ASSERT_EQ(1u, cookies.size());
- EXPECT_EQ("TestCookie", cookies[0].Name());
- }
- TEST_F(NetworkContextTest, ProxyConfig) {
- // Each ProxyConfigSet consists of a net::ProxyConfig, and the net::ProxyInfos
- // that it will result in for http and ftp URLs. All that matters is that each
- // ProxyConfig is different. It's important that none of these configs require
- // fetching a PAC scripts, as this test checks
- // ConfiguredProxyResolutionService::config(), which is only updated after
- // fetching PAC scripts (if applicable).
- struct ProxyConfigSet {
- net::ProxyConfig proxy_config;
- net::ProxyInfo http_proxy_info;
- net::ProxyInfo ftp_proxy_info;
- } proxy_config_sets[3];
- proxy_config_sets[0].proxy_config.proxy_rules().ParseFromString(
- "http=foopy:80");
- proxy_config_sets[0].http_proxy_info.UsePacString("PROXY foopy:80");
- proxy_config_sets[0].ftp_proxy_info.UseDirect();
- proxy_config_sets[1].proxy_config.proxy_rules().ParseFromString(
- "http=foopy:80;ftp=foopy2");
- proxy_config_sets[1].http_proxy_info.UsePacString("PROXY foopy:80");
- proxy_config_sets[1].ftp_proxy_info.UsePacString("PROXY foopy2");
- proxy_config_sets[2].proxy_config = net::ProxyConfig::CreateDirect();
- proxy_config_sets[2].http_proxy_info.UseDirect();
- proxy_config_sets[2].ftp_proxy_info.UseDirect();
- // Sanity check.
- EXPECT_FALSE(proxy_config_sets[0].proxy_config.Equals(
- proxy_config_sets[1].proxy_config));
- EXPECT_FALSE(proxy_config_sets[0].proxy_config.Equals(
- proxy_config_sets[2].proxy_config));
- EXPECT_FALSE(proxy_config_sets[1].proxy_config.Equals(
- proxy_config_sets[2].proxy_config));
- // Try each proxy config as the initial config, to make sure setting the
- // initial config works.
- for (const auto& initial_proxy_config_set : proxy_config_sets) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
- initial_proxy_config_set.proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
- mojo::Remote<mojom::ProxyConfigClient> config_client;
- context_params->proxy_config_client_receiver =
- config_client.BindNewPipeAndPassReceiver();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::ConfiguredProxyResolutionService* proxy_resolution_service = nullptr;
- ASSERT_TRUE(network_context->url_request_context()
- ->proxy_resolution_service()
- ->CastToConfiguredProxyResolutionService(
- &proxy_resolution_service));
- // Need to do proxy resolutions before can check the ProxyConfig, as the
- // ProxyService doesn't start updating its config until it's first used.
- // This also gives some test coverage of LookUpProxyForURL.
- TestProxyLookupClient http_proxy_lookup_client;
- http_proxy_lookup_client.StartLookUpProxyForURL(
- GURL("http://foo"), net::NetworkIsolationKey(), network_context.get());
- http_proxy_lookup_client.WaitForResult();
- ASSERT_TRUE(http_proxy_lookup_client.proxy_info());
- EXPECT_EQ(initial_proxy_config_set.http_proxy_info.ToPacString(),
- http_proxy_lookup_client.proxy_info()->ToPacString());
- TestProxyLookupClient ftp_proxy_lookup_client;
- ftp_proxy_lookup_client.StartLookUpProxyForURL(
- GURL("ftp://foo"), net::NetworkIsolationKey(), network_context.get());
- ftp_proxy_lookup_client.WaitForResult();
- ASSERT_TRUE(ftp_proxy_lookup_client.proxy_info());
- EXPECT_EQ(initial_proxy_config_set.ftp_proxy_info.ToPacString(),
- ftp_proxy_lookup_client.proxy_info()->ToPacString());
- EXPECT_TRUE(proxy_resolution_service->config());
- EXPECT_TRUE(proxy_resolution_service->config()->value().Equals(
- initial_proxy_config_set.proxy_config));
- // Always go through the other configs in the same order. This has the
- // advantage of testing the case where there's no change, for
- // proxy_config[0].
- for (const auto& proxy_config_set : proxy_config_sets) {
- config_client->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
- proxy_config_set.proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
- task_environment_.RunUntilIdle();
- TestProxyLookupClient http_proxy_lookup_client2;
- http_proxy_lookup_client2.StartLookUpProxyForURL(
- GURL("http://foo"), net::NetworkIsolationKey(),
- network_context.get());
- http_proxy_lookup_client2.WaitForResult();
- ASSERT_TRUE(http_proxy_lookup_client2.proxy_info());
- EXPECT_EQ(proxy_config_set.http_proxy_info.ToPacString(),
- http_proxy_lookup_client2.proxy_info()->ToPacString());
- TestProxyLookupClient ftp_proxy_lookup_client2;
- ftp_proxy_lookup_client2.StartLookUpProxyForURL(
- GURL("ftp://foo"), net::NetworkIsolationKey(), network_context.get());
- ftp_proxy_lookup_client2.WaitForResult();
- ASSERT_TRUE(ftp_proxy_lookup_client2.proxy_info());
- EXPECT_EQ(proxy_config_set.ftp_proxy_info.ToPacString(),
- ftp_proxy_lookup_client2.proxy_info()->ToPacString());
- EXPECT_TRUE(proxy_resolution_service->config());
- EXPECT_TRUE(proxy_resolution_service->config()->value().Equals(
- proxy_config_set.proxy_config));
- }
- }
- }
- // Verify that a proxy config works without a ProxyConfigClient PendingReceiver.
- TEST_F(NetworkContextTest, StaticProxyConfig) {
- net::ProxyConfig proxy_config;
- proxy_config.proxy_rules().ParseFromString("http=foopy:80;ftp=foopy2");
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
- proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::ConfiguredProxyResolutionService* proxy_resolution_service = nullptr;
- ASSERT_TRUE(
- network_context->url_request_context()
- ->proxy_resolution_service()
- ->CastToConfiguredProxyResolutionService(&proxy_resolution_service));
- // Kick the ConfiguredProxyResolutionService into action, as it doesn't start
- // updating its config until it's first used.
- proxy_resolution_service->ForceReloadProxyConfig();
- EXPECT_TRUE(proxy_resolution_service->config());
- EXPECT_TRUE(proxy_resolution_service->config()->value().Equals(proxy_config));
- }
- TEST_F(NetworkContextTest, NoInitialProxyConfig) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->initial_proxy_config.reset();
- mojo::Remote<mojom::ProxyConfigClient> config_client;
- context_params->proxy_config_client_receiver =
- config_client.BindNewPipeAndPassReceiver();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::ConfiguredProxyResolutionService* proxy_resolution_service = nullptr;
- ASSERT_TRUE(
- network_context->url_request_context()
- ->proxy_resolution_service()
- ->CastToConfiguredProxyResolutionService(&proxy_resolution_service));
- EXPECT_FALSE(proxy_resolution_service->config());
- EXPECT_FALSE(proxy_resolution_service->fetched_config());
- // Before there's a proxy configuration, proxy requests should hang.
- // Create two lookups, to make sure two simultaneous lookups can be handled at
- // once.
- TestProxyLookupClient http_proxy_lookup_client;
- http_proxy_lookup_client.StartLookUpProxyForURL(
- GURL("http://foo/"), net::NetworkIsolationKey(), network_context.get());
- TestProxyLookupClient ftp_proxy_lookup_client;
- ftp_proxy_lookup_client.StartLookUpProxyForURL(
- GURL("ftp://foo/"), net::NetworkIsolationKey(), network_context.get());
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(proxy_resolution_service->config());
- EXPECT_FALSE(proxy_resolution_service->fetched_config());
- EXPECT_FALSE(http_proxy_lookup_client.is_done());
- EXPECT_FALSE(ftp_proxy_lookup_client.is_done());
- EXPECT_EQ(2u, network_context->pending_proxy_lookup_requests_for_testing());
- net::ProxyConfig proxy_config;
- proxy_config.proxy_rules().ParseFromString("http=foopy:80");
- config_client->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
- proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
- http_proxy_lookup_client.WaitForResult();
- ASSERT_TRUE(http_proxy_lookup_client.proxy_info());
- EXPECT_EQ("PROXY foopy:80",
- http_proxy_lookup_client.proxy_info()->ToPacString());
- ftp_proxy_lookup_client.WaitForResult();
- ASSERT_TRUE(ftp_proxy_lookup_client.proxy_info());
- EXPECT_EQ("DIRECT", ftp_proxy_lookup_client.proxy_info()->ToPacString());
- EXPECT_EQ(0u, network_context->pending_proxy_lookup_requests_for_testing());
- }
- TEST_F(NetworkContextTest, DestroyedWithoutProxyConfig) {
- // Create a NetworkContext without an initial proxy configuration.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->initial_proxy_config.reset();
- mojo::Remote<mojom::ProxyConfigClient> config_client;
- context_params->proxy_config_client_receiver =
- config_client.BindNewPipeAndPassReceiver();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Proxy requests should hang.
- TestProxyLookupClient proxy_lookup_client;
- proxy_lookup_client.StartLookUpProxyForURL(
- GURL("http://foo/"), net::NetworkIsolationKey(), network_context.get());
- task_environment_.RunUntilIdle();
- EXPECT_EQ(1u, network_context->pending_proxy_lookup_requests_for_testing());
- EXPECT_FALSE(proxy_lookup_client.is_done());
- // Destroying the NetworkContext should cause the pending lookup to fail with
- // ERR_ABORTED.
- network_context.reset();
- proxy_lookup_client.WaitForResult();
- EXPECT_FALSE(proxy_lookup_client.proxy_info());
- EXPECT_EQ(net::ERR_ABORTED, proxy_lookup_client.net_error());
- }
- TEST_F(NetworkContextTest, CancelPendingProxyLookup) {
- // Create a NetworkContext without an initial proxy configuration.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->initial_proxy_config.reset();
- mojo::Remote<mojom::ProxyConfigClient> config_client;
- context_params->proxy_config_client_receiver =
- config_client.BindNewPipeAndPassReceiver();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Proxy requests should hang.
- std::unique_ptr<TestProxyLookupClient> proxy_lookup_client =
- std::make_unique<TestProxyLookupClient>();
- proxy_lookup_client->StartLookUpProxyForURL(
- GURL("http://foo/"), net::NetworkIsolationKey(), network_context.get());
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(proxy_lookup_client->is_done());
- EXPECT_EQ(1u, network_context->pending_proxy_lookup_requests_for_testing());
- // Cancelling the proxy lookup should cause the proxy lookup request objects
- // to be deleted.
- proxy_lookup_client.reset();
- task_environment_.RunUntilIdle();
- EXPECT_EQ(0u, network_context->pending_proxy_lookup_requests_for_testing());
- }
- // Test to make sure the NetworkIsolationKey passed to LookUpProxyForURL() makes
- // it to the proxy resolver.
- TEST_F(NetworkContextTest, ProxyLookupWithNetworkIsolationKey) {
- const GURL kUrl("http://bar.test/");
- const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
- // Pac scripts must contain this string to be passed to the
- // ProxyResolverFactory.
- const std::string kPacScript("FindProxyForURL");
- // Create a NetworkContext without an initial proxy configuration.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- CapturingMojoProxyResolverFactory proxy_resolver_factory;
- context_params->proxy_resolver_factory =
- proxy_resolver_factory.CreateFactoryRemote();
- context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
- net::ProxyConfig::CreateFromCustomPacURL(GURL("data:," + kPacScript)),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- mojo::Remote<mojom::ProxyConfigClient> config_client;
- context_params->proxy_config_client_receiver =
- config_client.BindNewPipeAndPassReceiver();
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->dhcp_wpad_url_client =
- network::MockMojoDhcpWpadUrlClient::CreateWithSelfOwnedReceiver(
- std::string());
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- TestProxyLookupClient proxy_lookup_client;
- proxy_lookup_client.StartLookUpProxyForURL(kUrl, kNetworkIsolationKey,
- network_context.get());
- proxy_lookup_client.WaitForResult();
- ASSERT_TRUE(proxy_lookup_client.proxy_info());
- EXPECT_TRUE(proxy_lookup_client.proxy_info()->is_direct_only());
- EXPECT_EQ(kPacScript, proxy_resolver_factory.pac_script());
- EXPECT_EQ(kUrl, proxy_resolver_factory.url());
- EXPECT_EQ(kNetworkIsolationKey,
- proxy_resolver_factory.network_isolation_key());
- }
- // Test mojom::ProxyResolver that completes calls to GetProxyForUrl() with a
- // DIRECT "proxy". It additionally emits a script error on line 42 for every
- // call to GetProxyForUrl().
- class MockMojoProxyResolver : public proxy_resolver::mojom::ProxyResolver {
- public:
- MockMojoProxyResolver() {}
- MockMojoProxyResolver(const MockMojoProxyResolver&) = delete;
- MockMojoProxyResolver& operator=(const MockMojoProxyResolver&) = delete;
- private:
- // Overridden from proxy_resolver::mojom::ProxyResolver:
- void GetProxyForUrl(
- const GURL& url,
- const net::NetworkIsolationKey& network_isolation_key,
- mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverRequestClient>
- pending_client) override {
- // Report a Javascript error and then complete the request successfully,
- // having chosen DIRECT connections.
- mojo::Remote<proxy_resolver::mojom::ProxyResolverRequestClient> client(
- std::move(pending_client));
- client->OnError(42, "Failed: FindProxyForURL(url=" + url.spec() + ")");
- net::ProxyInfo result;
- result.UseDirect();
- client->ReportResult(net::OK, result);
- }
- };
- // Test mojom::ProxyResolverFactory implementation that successfully completes
- // any CreateResolver() requests, and binds the request to a new
- // MockMojoProxyResolver.
- class MockMojoProxyResolverFactory
- : public proxy_resolver::mojom::ProxyResolverFactory {
- public:
- MockMojoProxyResolverFactory() {}
- MockMojoProxyResolverFactory(const MockMojoProxyResolverFactory&) = delete;
- MockMojoProxyResolverFactory& operator=(const MockMojoProxyResolverFactory&) =
- delete;
- // Binds and returns a mock ProxyResolverFactory whose lifetime is bound to
- // the message pipe.
- static mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
- Create() {
- mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory> remote;
- mojo::MakeSelfOwnedReceiver(
- std::make_unique<MockMojoProxyResolverFactory>(),
- remote.InitWithNewPipeAndPassReceiver());
- return remote;
- }
- private:
- void CreateResolver(
- const std::string& pac_url,
- mojo::PendingReceiver<proxy_resolver::mojom::ProxyResolver> receiver,
- mojo::PendingRemote<
- proxy_resolver::mojom::ProxyResolverFactoryRequestClient>
- pending_client) override {
- // Bind |receiver| to a new MockMojoProxyResolver, and return success.
- mojo::MakeSelfOwnedReceiver(std::make_unique<MockMojoProxyResolver>(),
- std::move(receiver));
- mojo::Remote<proxy_resolver::mojom::ProxyResolverFactoryRequestClient>
- client(std::move(pending_client));
- client->ReportResult(net::OK);
- }
- };
- TEST_F(NetworkContextTest, PacQuickCheck) {
- // Check the default value.
- // Note that unless we explicitly create a proxy resolver factory, the code
- // will assume that we should use a system proxy resolver (i.e. use system
- // APIs to resolve a proxy). This isn't supported on all platforms. On
- // unsupported platforms, we'd simply ignore the PAC quick check input and
- // default to false.
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->dhcp_wpad_url_client =
- network::MockMojoDhcpWpadUrlClient::CreateWithSelfOwnedReceiver(
- std::string());
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->proxy_resolver_factory =
- MockMojoProxyResolverFactory::Create();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- net::ConfiguredProxyResolutionService* proxy_resolution_service = nullptr;
- ASSERT_TRUE(
- network_context->url_request_context()
- ->proxy_resolution_service()
- ->CastToConfiguredProxyResolutionService(&proxy_resolution_service));
- EXPECT_TRUE(proxy_resolution_service->quick_check_enabled_for_testing());
- // Explicitly enable.
- context_params = CreateNetworkContextParamsForTesting();
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->dhcp_wpad_url_client =
- network::MockMojoDhcpWpadUrlClient::CreateWithSelfOwnedReceiver(
- std::string());
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->proxy_resolver_factory =
- MockMojoProxyResolverFactory::Create();
- context_params->pac_quick_check_enabled = true;
- network_context = CreateContextWithParams(std::move(context_params));
- proxy_resolution_service = nullptr;
- ASSERT_TRUE(
- network_context->url_request_context()
- ->proxy_resolution_service()
- ->CastToConfiguredProxyResolutionService(&proxy_resolution_service));
- EXPECT_TRUE(proxy_resolution_service->quick_check_enabled_for_testing());
- // Explicitly disable.
- context_params = CreateNetworkContextParamsForTesting();
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->dhcp_wpad_url_client =
- network::MockMojoDhcpWpadUrlClient::CreateWithSelfOwnedReceiver(
- std::string());
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->proxy_resolver_factory =
- MockMojoProxyResolverFactory::Create();
- context_params->pac_quick_check_enabled = false;
- network_context = CreateContextWithParams(std::move(context_params));
- proxy_resolution_service = nullptr;
- ASSERT_TRUE(
- network_context->url_request_context()
- ->proxy_resolution_service()
- ->CastToConfiguredProxyResolutionService(&proxy_resolution_service));
- EXPECT_FALSE(proxy_resolution_service->quick_check_enabled_for_testing());
- }
- net::IPEndPoint GetLocalHostWithAnyPort() {
- return net::IPEndPoint(net::IPAddress(127, 0, 0, 1), 0);
- }
- std::vector<uint8_t> CreateTestMessage(uint8_t initial, size_t size) {
- std::vector<uint8_t> array(size);
- for (size_t i = 0; i < size; ++i)
- array[i] = static_cast<uint8_t>((i + initial) % 256);
- return array;
- }
- TEST_F(NetworkContextTest, CreateUDPSocket) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Create a server socket to listen for incoming datagrams.
- test::UDPSocketListenerImpl listener;
- mojo::Receiver<mojom::UDPSocketListener> listener_receiver(&listener);
- net::IPEndPoint server_addr(GetLocalHostWithAnyPort());
- mojo::Remote<mojom::UDPSocket> server_socket;
- network_context->CreateUDPSocket(
- server_socket.BindNewPipeAndPassReceiver(),
- listener_receiver.BindNewPipeAndPassRemote());
- test::UDPSocketTestHelper helper(&server_socket);
- ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr));
- // Create a client socket to send datagrams.
- mojo::Remote<mojom::UDPSocket> client_socket;
- network_context->CreateUDPSocket(client_socket.BindNewPipeAndPassReceiver(),
- mojo::NullRemote());
- net::IPEndPoint client_addr(GetLocalHostWithAnyPort());
- test::UDPSocketTestHelper client_helper(&client_socket);
- ASSERT_EQ(net::OK,
- client_helper.ConnectSync(server_addr, nullptr, &client_addr));
- // This test assumes that the loopback interface doesn't drop UDP packets for
- // a small number of packets.
- const size_t kDatagramCount = 6;
- const size_t kDatagramSize = 255;
- server_socket->ReceiveMore(kDatagramCount);
- for (size_t i = 0; i < kDatagramCount; ++i) {
- std::vector<uint8_t> test_msg(
- CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize));
- int result = client_helper.SendSync(test_msg);
- EXPECT_EQ(net::OK, result);
- }
- listener.WaitForReceivedResults(kDatagramCount);
- EXPECT_EQ(kDatagramCount, listener.results().size());
- int i = 0;
- for (const auto& result : listener.results()) {
- EXPECT_EQ(net::OK, result.net_error);
- EXPECT_EQ(result.src_addr, client_addr);
- EXPECT_EQ(CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize),
- result.data.value());
- i++;
- }
- }
- TEST_F(NetworkContextTest, CreateNetLogExporter) {
- // Basic flow around start/stop.
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::NetLogExporter> net_log_exporter;
- network_context->CreateNetLogExporter(
- net_log_exporter.BindNewPipeAndPassReceiver());
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath out_path(temp_dir.GetPath().AppendASCII("out.json"));
- base::File out_file(out_path,
- base::File::FLAG_CREATE | base::File::FLAG_WRITE);
- ASSERT_TRUE(out_file.IsValid());
- base::Value::Dict dict_start;
- const char kKeyEarly[] = "early";
- const char kValEarly[] = "morning";
- dict_start.Set(kKeyEarly, kValEarly);
- net::TestCompletionCallback start_callback;
- net_log_exporter->Start(std::move(out_file), std::move(dict_start),
- net::NetLogCaptureMode::kDefault, 100 * 1024,
- start_callback.callback());
- EXPECT_EQ(net::OK, start_callback.WaitForResult());
- base::Value::Dict dict_late;
- const char kKeyLate[] = "late";
- const char kValLate[] = "snowval";
- dict_late.Set(kKeyLate, kValLate);
- net::TestCompletionCallback stop_callback;
- net_log_exporter->Stop(std::move(dict_late), stop_callback.callback());
- EXPECT_EQ(net::OK, stop_callback.WaitForResult());
- // Check that file got written.
- std::string contents;
- ASSERT_TRUE(base::ReadFileToString(out_path, &contents));
- // Contents should have net constants, without the client needing any
- // net:: methods.
- EXPECT_NE(std::string::npos, contents.find("ERR_IO_PENDING")) << contents;
- // The additional stuff inject should also occur someplace.
- EXPECT_NE(std::string::npos, contents.find(kKeyEarly)) << contents;
- EXPECT_NE(std::string::npos, contents.find(kValEarly)) << contents;
- EXPECT_NE(std::string::npos, contents.find(kKeyLate)) << contents;
- EXPECT_NE(std::string::npos, contents.find(kValLate)) << contents;
- }
- TEST_F(NetworkContextTest, CreateNetLogExporterUnbounded) {
- // Make sure that exporting without size limit works.
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::NetLogExporter> net_log_exporter;
- network_context->CreateNetLogExporter(
- net_log_exporter.BindNewPipeAndPassReceiver());
- base::FilePath temp_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&temp_path));
- base::File out_file(temp_path,
- base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- ASSERT_TRUE(out_file.IsValid());
- net::TestCompletionCallback start_callback;
- net_log_exporter->Start(std::move(out_file), base::Value::Dict(),
- net::NetLogCaptureMode::kDefault,
- mojom::NetLogExporter::kUnlimitedFileSize,
- start_callback.callback());
- EXPECT_EQ(net::OK, start_callback.WaitForResult());
- net::TestCompletionCallback stop_callback;
- net_log_exporter->Stop(base::Value::Dict(), stop_callback.callback());
- EXPECT_EQ(net::OK, stop_callback.WaitForResult());
- // Check that file got written.
- std::string contents;
- ASSERT_TRUE(base::ReadFileToString(temp_path, &contents));
- // Contents should have net constants, without the client needing any
- // net:: methods.
- EXPECT_NE(std::string::npos, contents.find("ERR_IO_PENDING")) << contents;
- base::DeleteFile(temp_path);
- }
- TEST_F(NetworkContextTest, CreateNetLogExporterErrors) {
- // Some basic state machine misuses.
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::NetLogExporter> net_log_exporter;
- network_context->CreateNetLogExporter(
- net_log_exporter.BindNewPipeAndPassReceiver());
- net::TestCompletionCallback stop_callback;
- net_log_exporter->Stop(base::Value::Dict(), stop_callback.callback());
- EXPECT_EQ(net::ERR_UNEXPECTED, stop_callback.WaitForResult());
- base::FilePath temp_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&temp_path));
- base::File temp_file(temp_path,
- base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- ASSERT_TRUE(temp_file.IsValid());
- net::TestCompletionCallback start_callback;
- net_log_exporter->Start(std::move(temp_file), base::Value::Dict(),
- net::NetLogCaptureMode::kDefault, 100 * 1024,
- start_callback.callback());
- EXPECT_EQ(net::OK, start_callback.WaitForResult());
- // Can't start twice.
- base::FilePath temp_path2;
- ASSERT_TRUE(base::CreateTemporaryFile(&temp_path2));
- base::File temp_file2(
- temp_path2, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- ASSERT_TRUE(temp_file2.IsValid());
- net::TestCompletionCallback start_callback2;
- net_log_exporter->Start(std::move(temp_file2), base::Value::Dict(),
- net::NetLogCaptureMode::kDefault, 100 * 1024,
- start_callback2.callback());
- EXPECT_EQ(net::ERR_UNEXPECTED, start_callback2.WaitForResult());
- base::DeleteFile(temp_path);
- base::DeleteFile(temp_path2);
- // Forgetting to stop is recovered from.
- }
- TEST_F(NetworkContextTest, DestroyNetLogExporterWhileCreatingScratchDir) {
- // Make sure that things behave OK if NetLogExporter is destroyed during the
- // brief window it owns the scratch directory.
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- std::unique_ptr<NetLogExporter> net_log_exporter =
- std::make_unique<NetLogExporter>(network_context.get());
- base::WaitableEvent block_mktemp(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- base::ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- base::FilePath path = dir.Take();
- EXPECT_TRUE(base::PathExists(path));
- net_log_exporter->SetCreateScratchDirHandlerForTesting(base::BindRepeating(
- [](base::WaitableEvent* block_on,
- const base::FilePath& path) -> base::FilePath {
- base::ScopedAllowBaseSyncPrimitivesForTesting need_to_block;
- block_on->Wait();
- return path;
- },
- &block_mktemp, path));
- base::FilePath temp_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&temp_path));
- base::File temp_file(temp_path,
- base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- ASSERT_TRUE(temp_file.IsValid());
- net_log_exporter->Start(std::move(temp_file), base::Value::Dict(),
- net::NetLogCaptureMode::kDefault, 100,
- base::BindOnce([](int) {}));
- net_log_exporter = nullptr;
- block_mktemp.Signal();
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(base::PathExists(path));
- base::DeleteFile(temp_path);
- }
- net::IPEndPoint CreateExpectedEndPoint(const std::string& address,
- uint16_t port) {
- net::IPAddress ip_address;
- CHECK(ip_address.AssignFromIPLiteral(address));
- return net::IPEndPoint(ip_address, port);
- }
- class TestResolveHostClient : public ResolveHostClientBase {
- public:
- TestResolveHostClient(mojo::PendingRemote<mojom::ResolveHostClient>* remote,
- base::RunLoop* run_loop)
- : receiver_(this, remote->InitWithNewPipeAndPassReceiver()),
- complete_(false),
- run_loop_(run_loop) {
- DCHECK(run_loop_);
- }
- void CloseReceiver() { receiver_.reset(); }
- void OnComplete(int error,
- const net::ResolveErrorInfo& resolve_error_info,
- const absl::optional<net::AddressList>& addresses) override {
- DCHECK(!complete_);
- complete_ = true;
- top_level_result_error_ = error;
- result_error_ = resolve_error_info.error;
- result_addresses_ = addresses;
- run_loop_->Quit();
- }
- bool complete() const { return complete_; }
- int top_level_result_error() const {
- DCHECK(complete_);
- return top_level_result_error_;
- }
- int result_error() const {
- DCHECK(complete_);
- return result_error_;
- }
- const absl::optional<net::AddressList>& result_addresses() const {
- DCHECK(complete_);
- return result_addresses_;
- }
- private:
- mojo::Receiver<mojom::ResolveHostClient> receiver_;
- bool complete_;
- int top_level_result_error_;
- int result_error_;
- absl::optional<net::AddressList> result_addresses_;
- const raw_ptr<base::RunLoop> run_loop_;
- };
- TEST_F(NetworkContextTest, ResolveHost_Sync) {
- auto resolver = std::make_unique<net::MockHostResolver>();
- resolver->rules()->AddRule("sync.test", "1.2.3.4");
- resolver->set_synchronous_mode(true);
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("sync.test", 160), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.top_level_result_error());
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(
- response_client.result_addresses().value().endpoints(),
- testing::UnorderedElementsAre(CreateExpectedEndPoint("1.2.3.4", 160)));
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_Async) {
- auto resolver = std::make_unique<net::MockHostResolver>();
- resolver->rules()->AddRule("async.test", "1.2.3.4");
- resolver->set_synchronous_mode(false);
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("async.test", 160), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.top_level_result_error());
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(
- response_client.result_addresses().value().endpoints(),
- testing::UnorderedElementsAre(CreateExpectedEndPoint("1.2.3.4", 160)));
- EXPECT_TRUE(control_handle_closed);
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_Failure_Sync) {
- auto resolver = std::make_unique<net::MockHostResolver>();
- resolver->rules()->AddSimulatedTimeoutFailure("example.com");
- resolver->set_synchronous_mode(true);
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- run_loop.Run();
- EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED,
- response_client.top_level_result_error());
- EXPECT_EQ(net::ERR_DNS_TIMED_OUT, response_client.result_error());
- EXPECT_FALSE(response_client.result_addresses());
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_Failure_Async) {
- auto resolver = std::make_unique<net::MockHostResolver>();
- resolver->rules()->AddSimulatedTimeoutFailure("example.com");
- resolver->set_synchronous_mode(false);
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- run_loop.Run();
- EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED,
- response_client.top_level_result_error());
- EXPECT_EQ(net::ERR_DNS_TIMED_OUT, response_client.result_error());
- EXPECT_FALSE(response_client.result_addresses());
- EXPECT_TRUE(control_handle_closed);
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_NetworkIsolationKey) {
- const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
- auto resolver = std::make_unique<net::MockHostResolver>();
- resolver->rules()->AddRule("nik.test", "1.2.3.4");
- net::MockHostResolver* raw_resolver = resolver.get();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("nik.test", 160), kNetworkIsolationKey,
- std::move(optional_parameters), std::move(pending_response_client));
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(
- response_client.result_addresses().value().endpoints(),
- testing::UnorderedElementsAre(CreateExpectedEndPoint("1.2.3.4", 160)));
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- EXPECT_EQ(kNetworkIsolationKey,
- raw_resolver->last_request_network_isolation_key());
- }
- TEST_F(NetworkContextTest, ResolveHost_NoControlHandle) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- // Resolve "localhost" because it should always resolve fast and locally, even
- // when using a real HostResolver.
- network_context->ResolveHost(net::HostPortPair("localhost", 80),
- net::NetworkIsolationKey(), nullptr,
- std::move(pending_response_client));
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(
- response_client.result_addresses().value().endpoints(),
- testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
- CreateExpectedEndPoint("::1", 80)));
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_CloseControlHandle) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- // Resolve "localhost" because it should always resolve fast and locally, even
- // when using a real HostResolver.
- network_context->ResolveHost(
- net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- control_handle.reset();
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(
- response_client.result_addresses().value().endpoints(),
- testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 160),
- CreateExpectedEndPoint("::1", 160)));
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_Cancellation) {
- // Override the HostResolver with a hanging one, so the test can ensure the
- // request won't be completed before the cancellation arrives.
- auto resolver = std::make_unique<net::HangingHostResolver>();
- scoped_refptr<const net::HangingHostResolver::State> state =
- resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_EQ(0, state->num_cancellations());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- control_handle->Cancel(net::ERR_ABORTED);
- run_loop.Run();
- // On cancellation, should receive an ERR_FAILED result, and the internal
- // resolver request should have been cancelled.
- EXPECT_EQ(net::ERR_ABORTED, response_client.result_error());
- EXPECT_FALSE(response_client.result_addresses());
- EXPECT_EQ(1, state->num_cancellations());
- EXPECT_TRUE(control_handle_closed);
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, ResolveHost_DestroyContext) {
- // Override the HostResolver with a hanging one, so the test can ensure the
- // request won't be completed before the cancellation arrives.
- auto resolver = std::make_unique<net::HangingHostResolver>();
- scoped_refptr<const net::HangingHostResolver::State> state =
- resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_EQ(0, state->num_cancellations());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- network_context = nullptr;
- run_loop.Run();
- // On context destruction, should receive an ERR_FAILED result, and the
- // internal resolver request should have been cancelled.
- EXPECT_EQ(net::ERR_FAILED, response_client.result_error());
- EXPECT_FALSE(response_client.result_addresses());
- EXPECT_EQ(1, state->num_cancellations());
- EXPECT_TRUE(control_handle_closed);
- }
- TEST_F(NetworkContextTest, ResolveHost_CloseClient) {
- // Override the HostResolver with a hanging one, so the test can ensure the
- // request won't be completed before the cancellation arrives.
- auto resolver = std::make_unique<net::HangingHostResolver>();
- scoped_refptr<const net::HangingHostResolver::State> state =
- resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_EQ(0, state->num_cancellations());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- network_context->ResolveHost(
- net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- response_client.CloseReceiver();
- run_loop.RunUntilIdle();
- // Response pipe is closed, so no results to check. Internal request should be
- // cancelled.
- EXPECT_FALSE(response_client.complete());
- EXPECT_EQ(1, state->num_cancellations());
- EXPECT_TRUE(control_handle_closed);
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- // Test factory of net::HostResolvers. Creates standard (but potentially non-
- // caching) net::ContextHostResolver. Keeps pointers to all created resolvers.
- class TestResolverFactory : public net::HostResolver::Factory {
- public:
- static TestResolverFactory* CreateAndSetFactory(NetworkService* service) {
- auto factory = std::make_unique<TestResolverFactory>();
- auto* factory_ptr = factory.get();
- service->set_host_resolver_factory_for_testing(std::move(factory));
- return factory_ptr;
- }
- std::unique_ptr<net::HostResolver> CreateResolver(
- net::HostResolverManager* manager,
- base::StringPiece host_mapping_rules,
- bool enable_caching) override {
- DCHECK(host_mapping_rules.empty());
- auto resolve_context = std::make_unique<net::ResolveContext>(
- /*url_request_context=*/nullptr, /*enable_caching=*/false);
- auto resolver = std::make_unique<net::ContextHostResolver>(
- manager, std::move(resolve_context));
- resolvers_.push_back(resolver.get());
- return resolver;
- }
- std::unique_ptr<net::HostResolver> CreateStandaloneResolver(
- net::NetLog* net_log,
- const net::HostResolver::ManagerOptions& options,
- base::StringPiece host_mapping_rules,
- bool enable_caching) override {
- DCHECK(host_mapping_rules.empty());
- std::unique_ptr<net::ContextHostResolver> resolver =
- net::HostResolver::CreateStandaloneContextResolver(net_log, options,
- enable_caching);
- resolvers_.push_back(resolver.get());
- return resolver;
- }
- const std::vector<net::ContextHostResolver*>& resolvers() const {
- return resolvers_;
- }
- void ForgetResolvers() { resolvers_.clear(); }
- private:
- std::vector<net::ContextHostResolver*> resolvers_;
- };
- TEST_F(NetworkContextTest, CreateHostResolver) {
- // Inject a factory to control and capture created net::HostResolvers.
- TestResolverFactory* factory =
- TestResolverFactory::CreateAndSetFactory(network_service_.get());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Creates single shared (within the NetworkContext) internal HostResolver.
- EXPECT_EQ(1u, factory->resolvers().size());
- factory->ForgetResolvers();
- mojo::Remote<mojom::HostResolver> resolver;
- network_context->CreateHostResolver(absl::nullopt,
- resolver.BindNewPipeAndPassReceiver());
- // Expected to reuse shared (within the NetworkContext) internal HostResolver.
- EXPECT_TRUE(factory->resolvers().empty());
- base::RunLoop run_loop;
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- resolver->ResolveHost(net::HostPortPair("localhost", 80),
- net::NetworkIsolationKey(), nullptr,
- std::move(pending_response_client));
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(
- response_client.result_addresses().value().endpoints(),
- testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
- CreateExpectedEndPoint("::1", 80)));
- EXPECT_EQ(0u,
- network_context->GetNumOutstandingResolveHostRequestsForTesting());
- }
- TEST_F(NetworkContextTest, CreateHostResolver_CloseResolver) {
- // Override the HostResolver with a hanging one, so the test can ensure the
- // request won't be completed before the cancellation arrives.
- auto resolver = std::make_unique<net::HangingHostResolver>();
- scoped_refptr<const net::HangingHostResolver::State> state =
- resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::HostResolver> resolver_remote;
- network_context->CreateHostResolver(
- absl::nullopt, resolver_remote.BindNewPipeAndPassReceiver());
- ASSERT_EQ(0, state->num_cancellations());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- resolver_remote->ResolveHost(
- net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- resolver_remote.reset();
- run_loop.Run();
- // On resolver destruction, should receive an ERR_FAILED result, and the
- // internal resolver request should have been cancelled.
- EXPECT_EQ(net::ERR_FAILED, response_client.result_error());
- EXPECT_FALSE(response_client.result_addresses());
- EXPECT_EQ(1, state->num_cancellations());
- EXPECT_TRUE(control_handle_closed);
- }
- TEST_F(NetworkContextTest, CreateHostResolver_CloseContext) {
- // Override the HostResolver with a hanging one, so the test can ensure the
- // request won't be completed before the cancellation arrives.
- auto resolver = std::make_unique<net::HangingHostResolver>();
- scoped_refptr<const net::HangingHostResolver::State> state =
- resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::HostResolver> resolver_remote;
- network_context->CreateHostResolver(
- absl::nullopt, resolver_remote.BindNewPipeAndPassReceiver());
- ASSERT_EQ(0, state->num_cancellations());
- base::RunLoop run_loop;
- mojo::Remote<mojom::ResolveHostHandle> control_handle;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->control_handle =
- control_handle.BindNewPipeAndPassReceiver();
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- resolver_remote->ResolveHost(
- net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- // Run a bit to ensure the resolve request makes it to the resolver. Otherwise
- // the resolver will be destroyed and close its pipe before it even knows
- // about the request to send a failure.
- task_environment_.RunUntilIdle();
- bool control_handle_closed = false;
- auto connection_error_callback =
- base::BindLambdaForTesting([&]() { control_handle_closed = true; });
- control_handle.set_disconnect_handler(connection_error_callback);
- bool resolver_closed = false;
- auto resolver_closed_callback =
- base::BindLambdaForTesting([&]() { resolver_closed = true; });
- resolver_remote.set_disconnect_handler(resolver_closed_callback);
- network_context = nullptr;
- run_loop.Run();
- // On context destruction, should receive an ERR_FAILED result, and the
- // internal resolver request should have been cancelled.
- EXPECT_EQ(net::ERR_FAILED, response_client.result_error());
- EXPECT_FALSE(response_client.result_addresses());
- EXPECT_EQ(1, state->num_cancellations());
- EXPECT_TRUE(control_handle_closed);
- EXPECT_TRUE(resolver_closed);
- }
- // Config overrides are not supported on iOS.
- #if !BUILDFLAG(IS_IOS)
- TEST_F(NetworkContextTest, CreateHostResolverWithConfigOverrides) {
- // Inject a factory to control and capture created net::HostResolvers.
- TestResolverFactory* factory =
- TestResolverFactory::CreateAndSetFactory(network_service_.get());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Creates single shared (within the NetworkContext) internal HostResolver.
- EXPECT_EQ(1u, factory->resolvers().size());
- factory->ForgetResolvers();
- net::DnsConfigOverrides overrides;
- overrides.nameservers = std::vector<net::IPEndPoint>{
- CreateExpectedEndPoint("100.100.100.100", 22)};
- mojo::Remote<mojom::HostResolver> resolver;
- network_context->CreateHostResolver(overrides,
- resolver.BindNewPipeAndPassReceiver());
- // Should create 1 private resolver with a DnsClient (if DnsClient is
- // enablable for the build config).
- ASSERT_EQ(1u, factory->resolvers().size());
- net::ContextHostResolver* internal_resolver = factory->resolvers().front();
- EXPECT_TRUE(internal_resolver->GetDnsConfigAsValue().is_dict());
- // Override DnsClient with a basic mock.
- net::DnsConfig base_configuration;
- base_configuration.nameservers = {CreateExpectedEndPoint("12.12.12.12", 53)};
- const std::string kQueryHostname = "example.com";
- const std::string kResult = "1.2.3.4";
- net::IPAddress result;
- CHECK(result.AssignFromIPLiteral(kResult));
- net::MockDnsClientRuleList rules;
- rules.emplace_back(
- kQueryHostname, net::dns_protocol::kTypeA, false /* secure */,
- net::MockDnsClientRule::Result(
- net::BuildTestDnsAddressResponse(kQueryHostname, result)),
- false /* delay */);
- rules.emplace_back(kQueryHostname, net::dns_protocol::kTypeAAAA,
- false /* secure */,
- net::MockDnsClientRule::Result(
- net::MockDnsClientRule::ResultType::kEmpty),
- false /* delay */);
- auto mock_dns_client = std::make_unique<net::MockDnsClient>(
- base_configuration, std::move(rules));
- mock_dns_client->SetInsecureEnabled(/*enabled=*/true,
- /*additional_types_enabled=*/false);
- mock_dns_client->set_ignore_system_config_changes(true);
- auto* mock_dns_client_ptr = mock_dns_client.get();
- internal_resolver->GetManagerForTesting()->SetDnsClientForTesting(
- std::move(mock_dns_client));
- // Test that the DnsClient is getting the overridden configuration.
- EXPECT_TRUE(overrides.ApplyOverrides(base_configuration)
- .Equals(*mock_dns_client_ptr->GetEffectiveConfig()));
- // Ensure we are using the private resolver by testing that we get results
- // from the overridden DnsClient.
- base::RunLoop run_loop;
- mojom::ResolveHostParametersPtr optional_parameters =
- mojom::ResolveHostParameters::New();
- optional_parameters->dns_query_type = net::DnsQueryType::A;
- optional_parameters->source = net::HostResolverSource::DNS;
- mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
- TestResolveHostClient response_client(&pending_response_client, &run_loop);
- resolver->ResolveHost(
- net::HostPortPair(kQueryHostname, 80), net::NetworkIsolationKey(),
- std::move(optional_parameters), std::move(pending_response_client));
- run_loop.Run();
- EXPECT_EQ(net::OK, response_client.result_error());
- EXPECT_THAT(response_client.result_addresses().value().endpoints(),
- testing::ElementsAre(CreateExpectedEndPoint(kResult, 80)));
- }
- #endif // BUILDFLAG(IS_IOS)
- TEST_F(NetworkContextTest, ActivateDohProbes) {
- auto resolver = std::make_unique<net::MockHostResolver>();
- scoped_refptr<const net::MockHostResolver::State> state = resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- mojom::NetworkContextParamsPtr params =
- CreateNetworkContextParamsForTesting();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- ASSERT_FALSE(state->IsDohProbeRunning());
- network_context->ActivateDohProbes();
- EXPECT_TRUE(state->IsDohProbeRunning());
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(state->IsDohProbeRunning());
- network_context.reset();
- EXPECT_FALSE(state->IsDohProbeRunning());
- }
- TEST_F(NetworkContextTest, ActivateDohProbes_NotPrimaryContext) {
- auto resolver = std::make_unique<net::MockHostResolver>();
- scoped_refptr<const net::MockHostResolver::State> state = resolver->state();
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<HostResolverFactory>(std::move(resolver)));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ASSERT_FALSE(state->IsDohProbeRunning());
- network_context->ActivateDohProbes();
- EXPECT_TRUE(state->IsDohProbeRunning());
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(state->IsDohProbeRunning());
- network_context.reset();
- EXPECT_FALSE(state->IsDohProbeRunning());
- }
- TEST_F(NetworkContextTest, PrivacyModeDisabledByDefault) {
- const GURL kOtherURL("http://other.com");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_EQ(net::NetworkDelegate::PrivacySetting::kStateAllowed,
- network_context->url_request_context()
- ->network_delegate()
- ->ForcePrivacyMode(GURL("http://foo.com"),
- net::SiteForCookies::FromUrl(kOtherURL),
- url::Origin::Create(kOtherURL),
- net::SamePartyContext::Type::kCrossParty));
- }
- TEST_F(NetworkContextTest, PrivacyModeEnabledIfCookiesBlocked) {
- const GURL kURL("http://foo.com");
- const GURL kOtherURL("http://other.com");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- SetContentSetting(kURL, kOtherURL, CONTENT_SETTING_BLOCK,
- network_context.get());
- EXPECT_EQ(
- net::NetworkDelegate::PrivacySetting::kStateDisallowed,
- network_context->url_request_context()
- ->network_delegate()
- ->ForcePrivacyMode(kURL, net::SiteForCookies::FromUrl(kOtherURL),
- url::Origin::Create(kOtherURL),
- net::SamePartyContext::Type::kCrossParty));
- EXPECT_EQ(
- net::NetworkDelegate::PrivacySetting::kStateAllowed,
- network_context->url_request_context()
- ->network_delegate()
- ->ForcePrivacyMode(kOtherURL, net::SiteForCookies::FromUrl(kURL),
- url::Origin::Create(kURL),
- net::SamePartyContext::Type::kCrossParty));
- }
- TEST_F(NetworkContextTest, PrivacyModeDisabledIfCookiesAllowed) {
- const GURL kURL("http://foo.com");
- const GURL kOtherURL("http://other.com");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- SetContentSetting(kURL, kOtherURL, CONTENT_SETTING_ALLOW,
- network_context.get());
- EXPECT_EQ(
- net::NetworkDelegate::PrivacySetting::kStateAllowed,
- network_context->url_request_context()
- ->network_delegate()
- ->ForcePrivacyMode(kURL, net::SiteForCookies::FromUrl(kOtherURL),
- url::Origin::Create(kOtherURL),
- net::SamePartyContext::Type::kCrossParty));
- }
- TEST_F(NetworkContextTest, PrivacyModeDisabledIfCookiesSettingForOtherURL) {
- const GURL kURL("http://foo.com");
- const GURL kOtherURL("http://other.com");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // URLs are switched so setting should not apply.
- SetContentSetting(kOtherURL, kURL, CONTENT_SETTING_BLOCK,
- network_context.get());
- EXPECT_EQ(
- net::NetworkDelegate::PrivacySetting::kStateAllowed,
- network_context->url_request_context()
- ->network_delegate()
- ->ForcePrivacyMode(kURL, net::SiteForCookies::FromUrl(kOtherURL),
- url::Origin::Create(kOtherURL),
- net::SamePartyContext::Type::kCrossParty));
- }
- TEST_F(NetworkContextTest, PrivacyModeEnabledIfThirdPartyCookiesBlocked) {
- const GURL kURL("http://foo.com");
- const url::Origin kOrigin = url::Origin::Create(kURL);
- const GURL kOtherURL("http://other.com");
- const url::Origin kOtherOrigin = url::Origin::Create(kOtherURL);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::NetworkDelegate* delegate =
- network_context->url_request_context()->network_delegate();
- network_context->cookie_manager()->BlockThirdPartyCookies(true);
- EXPECT_EQ(net::NetworkDelegate::PrivacySetting::kPartitionedStateAllowedOnly,
- delegate->ForcePrivacyMode(
- kURL, net::SiteForCookies::FromUrl(kOtherURL), kOtherOrigin,
- net::SamePartyContext::Type::kCrossParty));
- EXPECT_EQ(net::NetworkDelegate::PrivacySetting::kStateAllowed,
- delegate->ForcePrivacyMode(
- kURL, net::SiteForCookies::FromUrl(kURL), kOrigin,
- net::SamePartyContext::Type::kSameParty));
- network_context->cookie_manager()->BlockThirdPartyCookies(false);
- EXPECT_EQ(net::NetworkDelegate::PrivacySetting::kStateAllowed,
- delegate->ForcePrivacyMode(
- kURL, net::SiteForCookies::FromUrl(kOtherURL), kOtherOrigin,
- net::SamePartyContext::Type::kCrossParty));
- EXPECT_EQ(net::NetworkDelegate::PrivacySetting::kStateAllowed,
- delegate->ForcePrivacyMode(
- kURL, net::SiteForCookies::FromUrl(kURL), kOrigin,
- net::SamePartyContext::Type::kSameParty));
- }
- TEST_F(NetworkContextTest, CanSetCookieFalseIfCookiesBlocked) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- auto context = CreateTestURLRequestContextBuilder()->Build();
- std::unique_ptr<net::URLRequest> request =
- context->CreateRequest(GURL("http://foo.com"), net::DEFAULT_PRIORITY,
- nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
- auto cookie = net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "TestCookie", "1", "www.test.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), false, false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_LOW, false);
- EXPECT_TRUE(
- network_context->url_request_context()->network_delegate()->CanSetCookie(
- *request, *cookie, nullptr));
- SetDefaultContentSetting(CONTENT_SETTING_BLOCK, network_context.get());
- EXPECT_FALSE(
- network_context->url_request_context()->network_delegate()->CanSetCookie(
- *request, *cookie, nullptr));
- }
- TEST_F(NetworkContextTest, CanSetCookieTrueIfCookiesAllowed) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- auto context = CreateTestURLRequestContextBuilder()->Build();
- std::unique_ptr<net::URLRequest> request =
- context->CreateRequest(GURL("http://foo.com"), net::DEFAULT_PRIORITY,
- nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
- auto cookie = net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "TestCookie", "1", "www.test.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), false, false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_LOW, false);
- SetDefaultContentSetting(CONTENT_SETTING_ALLOW, network_context.get());
- EXPECT_TRUE(
- network_context->url_request_context()->network_delegate()->CanSetCookie(
- *request, *cookie, nullptr));
- }
- TEST_F(NetworkContextTest,
- AnnotateAndMoveUserBlockedCookies_FalseIfCookiesBlocked) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- auto context = CreateTestURLRequestContextBuilder()->Build();
- std::unique_ptr<net::URLRequest> request =
- context->CreateRequest(GURL("http://foo.com"), net::DEFAULT_PRIORITY,
- nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
- net::CookieAccessResultList included;
- net::CookieAccessResultList excluded;
- EXPECT_TRUE(
- network_context->url_request_context()
- ->network_delegate()
- ->AnnotateAndMoveUserBlockedCookies(*request, included, excluded));
- SetDefaultContentSetting(CONTENT_SETTING_BLOCK, network_context.get());
- EXPECT_FALSE(
- network_context->url_request_context()
- ->network_delegate()
- ->AnnotateAndMoveUserBlockedCookies(*request, included, excluded));
- }
- TEST_F(NetworkContextTest,
- AnnotateAndMoveUserBlockedCookies_TrueIfCookiesAllowed) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- auto context = CreateTestURLRequestContextBuilder()->Build();
- std::unique_ptr<net::URLRequest> request =
- context->CreateRequest(GURL("http://foo.com"), net::DEFAULT_PRIORITY,
- nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
- net::CookieAccessResultList included;
- net::CookieAccessResultList excluded;
- SetDefaultContentSetting(CONTENT_SETTING_ALLOW, network_context.get());
- EXPECT_TRUE(
- network_context->url_request_context()
- ->network_delegate()
- ->AnnotateAndMoveUserBlockedCookies(*request, included, excluded));
- }
- // Gets notified by the EmbeddedTestServer on incoming connections being
- // accepted or read from, keeps track of them and exposes that info to
- // the tests.
- // A port being reused is currently considered an error. If a test
- // needs to verify multiple connections are opened in sequence, that will need
- // to be changed.
- class ConnectionListener
- : public net::test_server::EmbeddedTestServerConnectionListener {
- public:
- ConnectionListener() = default;
- ConnectionListener(const ConnectionListener&) = delete;
- ConnectionListener& operator=(const ConnectionListener&) = delete;
- ~ConnectionListener() override = default;
- // Get called from the EmbeddedTestServer thread to be notified that
- // a connection was accepted.
- std::unique_ptr<net::StreamSocket> AcceptedSocket(
- std::unique_ptr<net::StreamSocket> connection) override {
- base::AutoLock lock(lock_);
- uint16_t socket = GetPort(*connection);
- EXPECT_TRUE(sockets_.find(socket) == sockets_.end());
- sockets_[socket] = SOCKET_ACCEPTED;
- total_sockets_seen_++;
- CheckAccepted();
- return connection;
- }
- // Get called from the EmbeddedTestServer thread to be notified that
- // a connection was read from.
- void ReadFromSocket(const net::StreamSocket& connection, int rv) override {
- EXPECT_GE(rv, net::OK);
- }
- // Wait for exactly |n| items in |sockets_|. |n| must be greater than 0.
- void WaitForAcceptedConnections(size_t num_connections) {
- DCHECK(on_done_accepting_connections_.is_null());
- DCHECK_GT(num_connections, 0u);
- base::RunLoop run_loop;
- {
- base::AutoLock lock(lock_);
- EXPECT_GE(num_connections, sockets_.size() - total_sockets_waited_for_);
- // QuitWhenIdle() instead of regular Quit() because in Preconnect tests we
- // count "idle_socket_count" but tasks posted synchronously after
- // AcceptedSocket() need to resolve before the new sockets are considered
- // idle.
- on_done_accepting_connections_ = run_loop.QuitWhenIdleClosure();
- num_accepted_connections_needed_ = num_connections;
- CheckAccepted();
- }
- // Note that the previous call to CheckAccepted can quit this run loop
- // before this call, which will make this call a no-op.
- run_loop.Run();
- // Grab the mutex again and make sure that the number of accepted sockets is
- // indeed |num_connections|.
- base::AutoLock lock(lock_);
- total_sockets_waited_for_ += num_connections;
- EXPECT_EQ(total_sockets_seen_, total_sockets_waited_for_);
- }
- // Helper function to stop the waiting for sockets to be accepted for
- // WaitForAcceptedConnections. |num_accepted_connections_loop_| spins
- // until |num_accepted_connections_needed_| sockets are accepted by the test
- // server. The values will be null/0 if the loop is not running.
- void CheckAccepted() {
- lock_.AssertAcquired();
- // |num_accepted_connections_loop_| null implies
- // |num_accepted_connections_needed_| == 0.
- DCHECK(!on_done_accepting_connections_.is_null() ||
- num_accepted_connections_needed_ == 0);
- if (on_done_accepting_connections_.is_null() ||
- num_accepted_connections_needed_ !=
- sockets_.size() - total_sockets_waited_for_) {
- return;
- }
- num_accepted_connections_needed_ = 0;
- std::move(on_done_accepting_connections_).Run();
- }
- int GetTotalSocketsSeen() const {
- base::AutoLock lock(lock_);
- return total_sockets_seen_;
- }
- private:
- static uint16_t GetPort(const net::StreamSocket& connection) {
- // Get the remote port of the peer, since the local port will always be the
- // port the test server is listening on. This isn't strictly correct - it's
- // possible for multiple peers to connect with the same remote port but
- // different remote IPs - but the tests here assume that connections to the
- // test server (running on localhost) will always come from localhost, and
- // thus the peer port is all thats needed to distinguish two connections.
- // This also would be problematic if the OS reused ports, but that's not
- // something to worry about for these tests.
- net::IPEndPoint address;
- EXPECT_EQ(net::OK, connection.GetPeerAddress(&address));
- return address.port();
- }
- int total_sockets_seen_ = 0;
- int total_sockets_waited_for_ = 0;
- enum SocketStatus { SOCKET_ACCEPTED, SOCKET_READ_FROM };
- // This lock protects all the members below, which each are used on both the
- // IO and UI thread. Members declared after the lock are protected by it.
- mutable base::Lock lock_;
- typedef std::map<uint16_t, SocketStatus> SocketContainer;
- SocketContainer sockets_;
- // If |num_accepted_connections_needed_| is non zero, then the object is
- // waiting for |num_accepted_connections_needed_| sockets to be accepted
- // before invoking |on_done_accepting_connections_|.
- size_t num_accepted_connections_needed_ = 0;
- base::OnceClosure on_done_accepting_connections_;
- };
- TEST_F(NetworkContextTest, PreconnectOne) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- network_context->PreconnectSockets(1, test_server.base_url(),
- /*allow_credentials=*/true,
- net::NetworkIsolationKey());
- connection_listener.WaitForAcceptedConnections(1u);
- }
- TEST_F(NetworkContextTest, PreconnectHSTS) {
- net::NetworkIsolationKey network_isolation_key =
- net::NetworkIsolationKey::CreateTransient();
- for (bool partition_connections : {false, true}) {
- base::test::ScopedFeatureList feature_list;
- if (partition_connections) {
- feature_list.InitAndEnableFeature(
- net::features::kPartitionConnectionsByNetworkIsolationKey);
- } else {
- feature_list.InitAndDisableFeature(
- net::features::kPartitionConnectionsByNetworkIsolationKey);
- }
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- ASSERT_TRUE(test_server.base_url().SchemeIs(url::kHttpsScheme));
- net::ClientSocketPool::GroupId ssl_group(
- url::SchemeHostPort(test_server.base_url()),
- net::PrivacyMode::PRIVACY_MODE_ENABLED,
- partition_connections ? network_isolation_key
- : net::NetworkIsolationKey(),
- net::SecureDnsPolicy::kAllow);
- const GURL server_http_url = GetHttpUrlFromHttps(test_server.base_url());
- ASSERT_TRUE(server_http_url.SchemeIs(url::kHttpScheme));
- net::ClientSocketPool::GroupId group(url::SchemeHostPort(server_http_url),
- net::PrivacyMode::PRIVACY_MODE_ENABLED,
- partition_connections
- ? network_isolation_key
- : net::NetworkIsolationKey(),
- net::SecureDnsPolicy::kAllow);
- network_context->PreconnectSockets(1, server_http_url,
- /*allow_credentials=*/false,
- network_isolation_key);
- connection_listener.WaitForAcceptedConnections(1u);
- int num_sockets = GetSocketCountForGroup(network_context.get(), group);
- EXPECT_EQ(num_sockets, 1);
- const base::Time expiry = base::Time::Now() + base::Seconds(1000);
- network_context->url_request_context()->transport_security_state()->AddHSTS(
- server_http_url.host(), expiry, false);
- network_context->PreconnectSockets(1, server_http_url,
- /*allow_credentials=*/false,
- network_isolation_key);
- connection_listener.WaitForAcceptedConnections(1u);
- // If HSTS weren't respected, the initial connection would have been reused.
- num_sockets = GetSocketCountForGroup(network_context.get(), ssl_group);
- EXPECT_EQ(num_sockets, 1);
- }
- }
- TEST_F(NetworkContextTest, PreconnectZero) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- network_context->PreconnectSockets(0, test_server.base_url(),
- /*allow_credentials=*/true,
- net::NetworkIsolationKey());
- base::RunLoop().RunUntilIdle();
- int num_sockets =
- GetSocketPoolInfo(network_context.get(), "idle_socket_count");
- ASSERT_EQ(num_sockets, 0);
- int num_connecting_sockets =
- GetSocketPoolInfo(network_context.get(), "connecting_socket_count");
- ASSERT_EQ(num_connecting_sockets, 0);
- }
- TEST_F(NetworkContextTest, PreconnectTwo) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- network_context->PreconnectSockets(2, test_server.base_url(),
- /*allow_credentials=*/true,
- net::NetworkIsolationKey());
- connection_listener.WaitForAcceptedConnections(2u);
- int num_sockets =
- GetSocketPoolInfo(network_context.get(), "idle_socket_count");
- ASSERT_EQ(num_sockets, 2);
- }
- TEST_F(NetworkContextTest, PreconnectFour) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- network_context->PreconnectSockets(4, test_server.base_url(),
- /*allow_credentials=*/true,
- net::NetworkIsolationKey());
- connection_listener.WaitForAcceptedConnections(4u);
- int num_sockets =
- GetSocketPoolInfo(network_context.get(), "idle_socket_count");
- ASSERT_EQ(num_sockets, 4);
- }
- TEST_F(NetworkContextTest, PreconnectMax) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- int max_num_sockets =
- GetSocketPoolInfo(network_context.get(), "max_sockets_per_group");
- EXPECT_GT(76, max_num_sockets);
- network_context->PreconnectSockets(76, test_server.base_url(),
- /*allow_credentials=*/true,
- net::NetworkIsolationKey());
- // Wait until |max_num_sockets| have been connected.
- connection_listener.WaitForAcceptedConnections(max_num_sockets);
- // This is not guaranteed to wait long enough if more than |max_num_sockets|
- // connections are actually made, but experimentally, it fails consistently if
- // that's the case.
- base::RunLoop().RunUntilIdle();
- int num_sockets =
- GetSocketPoolInfo(network_context.get(), "idle_socket_count");
- ASSERT_EQ(num_sockets, max_num_sockets);
- }
- // Make sure preconnects for the same URL but with different network isolation
- // keys are not merged.
- TEST_F(NetworkContextTest, PreconnectNetworkIsolationKey) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- net::features::kPartitionConnectionsByNetworkIsolationKey);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- const auto kOriginFoo = url::Origin::Create(GURL("http://foo.test"));
- const auto kOriginBar = url::Origin::Create(GURL("http://bar.test"));
- const net::NetworkIsolationKey kKey1(kOriginFoo, kOriginFoo);
- const net::NetworkIsolationKey kKey2(kOriginBar, kOriginBar);
- network_context->PreconnectSockets(1, test_server.base_url(),
- /*allow_credentials=*/false, kKey1);
- network_context->PreconnectSockets(2, test_server.base_url(),
- /*allow_credentials=*/false, kKey2);
- connection_listener.WaitForAcceptedConnections(3u);
- url::SchemeHostPort destination(test_server.base_url());
- net::ClientSocketPool::GroupId group_id1(
- destination, net::PrivacyMode::PRIVACY_MODE_ENABLED, kKey1,
- net::SecureDnsPolicy::kAllow);
- EXPECT_EQ(1, GetSocketCountForGroup(network_context.get(), group_id1));
- net::ClientSocketPool::GroupId group_id2(
- destination, net::PrivacyMode::PRIVACY_MODE_ENABLED, kKey2,
- net::SecureDnsPolicy::kAllow);
- EXPECT_EQ(2, GetSocketCountForGroup(network_context.get(), group_id2));
- }
- // This tests both ClostAllConnetions and CloseIdleConnections.
- TEST_F(NetworkContextTest, CloseConnections) {
- // Have to close all connections first, as CloseIdleConnections leaves around
- // a connection at the end of the test.
- for (bool close_all_connections : {true, false}) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Use different paths to avoid running into the cache lock.
- const char kPath1[] = "/foo";
- const char kPath2[] = "/bar";
- const char kPath3[] = "/baz";
- net::EmbeddedTestServer test_server;
- net::test_server::ControllableHttpResponse controllable_response1(
- &test_server, kPath1);
- net::test_server::ControllableHttpResponse controllable_response2(
- &test_server, kPath2);
- net::test_server::ControllableHttpResponse controllable_response3(
- &test_server, kPath3);
- ASSERT_TRUE(test_server.Start());
- // Start three network requests. Requests have to all be started before any
- // one of them receives a response to be sure none of them tries to reuse
- // the socket created by another one.
- net::TestDelegate delegate1;
- base::RunLoop run_loop1;
- delegate1.set_on_complete(run_loop1.QuitClosure());
- std::unique_ptr<net::URLRequest> request1 =
- network_context->url_request_context()->CreateRequest(
- test_server.GetURL(kPath1), net::DEFAULT_PRIORITY, &delegate1,
- TRAFFIC_ANNOTATION_FOR_TESTS);
- request1->Start();
- controllable_response1.WaitForRequest();
- EXPECT_EQ(
- 1, GetSocketPoolInfo(network_context.get(), "handed_out_socket_count"));
- net::TestDelegate delegate2;
- base::RunLoop run_loop2;
- delegate2.set_on_complete(run_loop2.QuitClosure());
- std::unique_ptr<net::URLRequest> request2 =
- network_context->url_request_context()->CreateRequest(
- test_server.GetURL(kPath2), net::DEFAULT_PRIORITY, &delegate2,
- TRAFFIC_ANNOTATION_FOR_TESTS);
- request2->Start();
- controllable_response2.WaitForRequest();
- EXPECT_EQ(
- 2, GetSocketPoolInfo(network_context.get(), "handed_out_socket_count"));
- net::TestDelegate delegate3;
- base::RunLoop run_loop3;
- delegate3.set_on_complete(run_loop3.QuitClosure());
- std::unique_ptr<net::URLRequest> request3 =
- network_context->url_request_context()->CreateRequest(
- test_server.GetURL(kPath3), net::DEFAULT_PRIORITY, &delegate3,
- TRAFFIC_ANNOTATION_FOR_TESTS);
- request3->Start();
- controllable_response3.WaitForRequest();
- EXPECT_EQ(
- 3, GetSocketPoolInfo(network_context.get(), "handed_out_socket_count"));
- // Complete the first two requests successfully, with a keep-alive response.
- // The EmbeddedTestServer doesn't actually support connection reuse, but
- // this will send a raw response that will make the network stack think it
- // does, and will cause the connection not to be closed.
- controllable_response1.Send(
- "HTTP/1.1 200 OK\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n\r\n");
- controllable_response2.Send(
- "HTTP/1.1 200 OK\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n\r\n");
- run_loop1.Run();
- run_loop2.Run();
- // There should now be 2 idle and one handed out socket.
- EXPECT_EQ(2, GetSocketPoolInfo(network_context.get(), "idle_socket_count"));
- EXPECT_EQ(
- 1, GetSocketPoolInfo(network_context.get(), "handed_out_socket_count"));
- // Closing all or idle connections should result in closing the idle
- // sockets, but the handed out socket can't be closed.
- base::RunLoop run_loop;
- if (close_all_connections) {
- network_context->CloseAllConnections(run_loop.QuitClosure());
- } else {
- network_context->CloseIdleConnections(run_loop.QuitClosure());
- }
- run_loop.Run();
- EXPECT_EQ(0, GetSocketPoolInfo(network_context.get(), "idle_socket_count"));
- EXPECT_EQ(
- 1, GetSocketPoolInfo(network_context.get(), "handed_out_socket_count"));
- // The final request completes. In the close all connections case, its
- // socket should be closed as soon as it is returned to the pool, but in the
- // CloseIdleConnections case, it is added to the pool as an idle socket.
- controllable_response3.Send(
- "HTTP/1.1 200 OK\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n\r\n");
- run_loop3.Run();
- EXPECT_EQ(close_all_connections ? 0 : 1,
- GetSocketPoolInfo(network_context.get(), "idle_socket_count"));
- EXPECT_EQ(
- 0, GetSocketPoolInfo(network_context.get(), "handed_out_socket_count"));
- }
- }
- // Test that only trusted URLLoaderFactories accept
- // ResourceRequest::trusted_params.
- TEST_F(NetworkContextTest, TrustedParams) {
- for (bool trusted_factory : {false, true}) {
- ConnectionListener connection_listener;
- net::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- test_server.SetConnectionListener(&connection_listener);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- // URLLoaderFactories should not be trusted by default.
- EXPECT_FALSE(params->is_trusted);
- params->is_trusted = trusted_factory;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- ResourceRequest request;
- request.url = test_server.GetURL("/echo");
- request.trusted_params = ResourceRequest::TrustedParams();
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- // If the factory was trusted, the request should have succeeded. Otherwise,
- // it should have failed.
- EXPECT_EQ(trusted_factory, client.has_received_response());
- if (trusted_factory) {
- EXPECT_THAT(client.completion_status().error_code, net::test::IsOk());
- EXPECT_EQ(1, connection_listener.GetTotalSocketsSeen());
- } else {
- EXPECT_THAT(client.completion_status().error_code,
- net::test::IsError(net::ERR_INVALID_ARGUMENT));
- // No connection should have been made to the test server.
- EXPECT_EQ(0, connection_listener.GetTotalSocketsSeen());
- }
- }
- }
- // Test that the disable_secure_dns trusted param is passed through to the
- // host resolver.
- TEST_F(NetworkContextTest, TrustedParams_DisableSecureDns) {
- net::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- auto context_builder = CreateTestURLRequestContextBuilder();
- context_builder->set_host_resolver(std::make_unique<net::MockHostResolver>());
- auto url_request_context = context_builder->Build();
- auto& resolver = *static_cast<net::MockHostResolver*>(
- url_request_context->host_resolver());
- resolver.rules()->AddRule("example.test", test_server.GetIPLiteralString());
- network_context_remote_.reset();
- std::unique_ptr<NetworkContext> network_context =
- std::make_unique<NetworkContext>(
- network_service_.get(),
- network_context_remote_.BindNewPipeAndPassReceiver(),
- url_request_context.get(),
- /*cors_exempt_header_list=*/std::vector<std::string>());
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- params->is_trusted = true;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- for (bool disable_secure_dns : {false, true}) {
- ResourceRequest request;
- request.url = GURL("http://example.test/echo");
- request.load_flags = net::LOAD_BYPASS_CACHE;
- request.trusted_params = ResourceRequest::TrustedParams();
- request.trusted_params->disable_secure_dns = disable_secure_dns;
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- if (disable_secure_dns) {
- EXPECT_EQ(net::SecureDnsPolicy::kDisable,
- resolver.last_secure_dns_policy());
- } else {
- EXPECT_EQ(net::SecureDnsPolicy::kAllow,
- resolver.last_secure_dns_policy());
- }
- }
- }
- // Test that the disable_secure_dns factory param is passed through to the
- // host resolver.
- TEST_F(NetworkContextTest, FactoryParams_DisableSecureDns) {
- net::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- auto context_builder = CreateTestURLRequestContextBuilder();
- context_builder->set_host_resolver(std::make_unique<net::MockHostResolver>());
- auto url_request_context = context_builder->Build();
- auto& resolver = *static_cast<net::MockHostResolver*>(
- url_request_context->host_resolver());
- resolver.rules()->AddRule("example.test", test_server.GetIPLiteralString());
- network_context_remote_.reset();
- NetworkContext network_context(
- network_service_.get(),
- network_context_remote_.BindNewPipeAndPassReceiver(),
- url_request_context.get(),
- /*cors_exempt_header_list=*/std::vector<std::string>());
- for (bool disable_secure_dns : {false, true}) {
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- params->disable_secure_dns = disable_secure_dns;
- network_context.CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- ResourceRequest request;
- request.url = GURL("http://example.test/echo");
- request.load_flags = net::LOAD_BYPASS_CACHE;
- auto client = std::make_unique<TestURLLoaderClient>();
- mojo::Remote<mojom::URLLoader> loader;
- loader_factory->CreateLoaderAndStart(
- loader.BindNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client->RunUntilComplete();
- if (disable_secure_dns) {
- EXPECT_EQ(net::SecureDnsPolicy::kDisable,
- resolver.last_secure_dns_policy());
- } else {
- EXPECT_EQ(net::SecureDnsPolicy::kAllow,
- resolver.last_secure_dns_policy());
- }
- }
- }
- #if BUILDFLAG(IS_CT_SUPPORTED)
- TEST_F(NetworkContextTest, ExpectCT) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- net::features::kPartitionExpectCTStateByNetworkIsolationKey);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- const char kTestDomain[] = "example.com";
- const base::Time expiry = base::Time::Now() + base::Seconds(1000);
- const bool enforce = true;
- const GURL report_uri = GURL("https://example.com/foo/bar");
- net::NetworkIsolationKey network_isolation_key =
- net::NetworkIsolationKey::CreateTransient();
- // Assert we start with no data for the test host.
- {
- base::Value::Dict state;
- base::RunLoop run_loop;
- network_context->GetExpectCTState(
- kTestDomain, network_isolation_key,
- base::BindOnce(&StoreValue, &state, run_loop.QuitClosure()));
- run_loop.Run();
- absl::optional<bool> result = state.FindBool("result");
- EXPECT_TRUE(result.has_value());
- EXPECT_EQ(false, *result);
- }
- // Add the host data.
- {
- base::RunLoop run_loop;
- bool result = false;
- network_context->AddExpectCT(
- kTestDomain, expiry, enforce, report_uri, network_isolation_key,
- base::BindOnce(&StoreBool, &result, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_TRUE(result);
- }
- // Assert added host data is returned.
- {
- base::Value::Dict state;
- base::RunLoop run_loop;
- network_context->GetExpectCTState(
- kTestDomain, network_isolation_key,
- base::BindOnce(&StoreValue, &state, run_loop.QuitClosure()));
- run_loop.Run();
- const std::string* dynamic_expect_ct_domain =
- state.FindString("dynamic_expect_ct_domain");
- ASSERT_TRUE(dynamic_expect_ct_domain);
- EXPECT_EQ(kTestDomain, *dynamic_expect_ct_domain);
- absl::optional<double> dynamic_expect_ct_expiry =
- state.FindDouble("dynamic_expect_ct_expiry");
- EXPECT_EQ(expiry.ToDoubleT(), dynamic_expect_ct_expiry);
- absl::optional<bool> dynamic_expect_ct_enforce =
- state.FindBool("dynamic_expect_ct_enforce");
- EXPECT_EQ(enforce, *dynamic_expect_ct_enforce);
- const std::string* dynamic_expect_ct_report_uri =
- state.FindString("dynamic_expect_ct_report_uri");
- ASSERT_TRUE(dynamic_expect_ct_report_uri);
- EXPECT_EQ(report_uri, *dynamic_expect_ct_report_uri);
- }
- // Using a different NetworkIsolationKey should return no result.
- {
- base::Value::Dict state;
- base::RunLoop run_loop;
- network_context->GetExpectCTState(
- kTestDomain, net::NetworkIsolationKey::CreateTransient(),
- base::BindOnce(&StoreValue, &state, run_loop.QuitClosure()));
- run_loop.Run();
- absl::optional<bool> result = state.FindBool("result");
- EXPECT_TRUE(result.has_value());
- EXPECT_EQ(false, *result);
- }
- // Delete host data.
- {
- bool result;
- base::RunLoop run_loop;
- network_context->DeleteDynamicDataForHost(
- kTestDomain,
- base::BindOnce(&StoreBool, &result, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_TRUE(result);
- }
- // Assert data is removed.
- {
- base::Value::Dict state;
- base::RunLoop run_loop;
- network_context->GetExpectCTState(
- kTestDomain, network_isolation_key,
- base::BindOnce(&StoreValue, &state, run_loop.QuitClosure()));
- run_loop.Run();
- absl::optional<bool> result = state.FindBool("result");
- EXPECT_TRUE(result.has_value());
- EXPECT_EQ(false, *result);
- }
- }
- TEST_F(NetworkContextTest, SetExpectCTTestReport) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::EmbeddedTestServer test_server;
- std::set<GURL> requested_urls;
- auto monitor_callback = base::BindLambdaForTesting(
- [&](const net::test_server::HttpRequest& request) {
- requested_urls.insert(request.GetURL());
- });
- test_server.RegisterRequestMonitor(monitor_callback);
- ASSERT_TRUE(test_server.Start());
- const GURL kReportURL = test_server.base_url().Resolve("/report/path");
- base::RunLoop run_loop;
- bool result = false;
- network_context->SetExpectCTTestReport(
- kReportURL, base::BindOnce(&StoreBool, &result, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_FALSE(result);
- EXPECT_TRUE(base::Contains(requested_urls, kReportURL));
- }
- #endif // BUILDFLAG(IS_CT_SUPPORTED)
- TEST_F(NetworkContextTest, QueryHSTS) {
- const char kTestDomain[] = "example.com";
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- bool result = false, got_result = false;
- network_context->IsHSTSActiveForHost(
- kTestDomain, base::BindLambdaForTesting([&](bool is_hsts) {
- result = is_hsts;
- got_result = true;
- }));
- EXPECT_TRUE(got_result);
- EXPECT_FALSE(result);
- base::RunLoop run_loop;
- network_context->AddHSTS(kTestDomain, base::Time::Now() + base::Days(1000),
- false /*include_subdomains*/,
- run_loop.QuitClosure());
- run_loop.Run();
- bool result2 = false, got_result2 = false;
- network_context->IsHSTSActiveForHost(
- kTestDomain, base::BindLambdaForTesting([&](bool is_hsts) {
- result2 = is_hsts;
- got_result2 = true;
- }));
- EXPECT_TRUE(got_result2);
- EXPECT_TRUE(result2);
- }
- TEST_F(NetworkContextTest, GetHSTSState) {
- const char kTestDomain[] = "example.com";
- const base::Time expiry = base::Time::Now() + base::Seconds(1000);
- const GURL report_uri = GURL("https://example.com/foo/bar");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::Value::Dict state;
- {
- base::RunLoop run_loop;
- network_context->GetHSTSState(
- kTestDomain,
- base::BindOnce(&StoreValue, &state, run_loop.QuitClosure()));
- run_loop.Run();
- }
- absl::optional<bool> result = state.FindBool("result");
- ASSERT_TRUE(result.has_value());
- EXPECT_FALSE(*result);
- {
- base::RunLoop run_loop;
- network_context->AddHSTS(kTestDomain, expiry, false /*include_subdomains*/,
- run_loop.QuitClosure());
- run_loop.Run();
- }
- {
- base::RunLoop run_loop;
- network_context->GetHSTSState(
- kTestDomain,
- base::BindOnce(&StoreValue, &state, run_loop.QuitClosure()));
- run_loop.Run();
- }
- result = state.FindBool("result");
- ASSERT_TRUE(result.has_value());
- EXPECT_TRUE(*result);
- // Not checking all values - only enough to ensure the underlying call
- // was made.
- const std::string* dynamic_sts_domain =
- state.FindString("dynamic_sts_domain");
- ASSERT_TRUE(dynamic_sts_domain);
- EXPECT_EQ(kTestDomain, *dynamic_sts_domain);
- absl::optional<double> dynamic_sts_expiry =
- state.FindDouble("dynamic_sts_expiry");
- EXPECT_EQ(expiry.ToDoubleT(), dynamic_sts_expiry);
- }
- TEST_F(NetworkContextTest, ForceReloadProxyConfig) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- auto net_log_exporter =
- std::make_unique<network::NetLogExporter>(network_context.get());
- base::FilePath net_log_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&net_log_path));
- {
- base::File net_log_file(
- net_log_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- EXPECT_TRUE(net_log_file.IsValid());
- base::RunLoop run_loop;
- int32_t start_param = 0;
- auto start_callback = base::BindLambdaForTesting([&](int32_t result) {
- start_param = result;
- run_loop.Quit();
- });
- net_log_exporter->Start(std::move(net_log_file),
- /*extra_constants=*/base::Value::Dict(),
- net::NetLogCaptureMode::kDefault,
- network::mojom::NetLogExporter::kUnlimitedFileSize,
- start_callback);
- run_loop.Run();
- EXPECT_EQ(net::OK, start_param);
- }
- {
- base::RunLoop run_loop;
- network_context->ForceReloadProxyConfig(run_loop.QuitClosure());
- run_loop.Run();
- }
- {
- base::RunLoop run_loop;
- int32_t stop_param = 0;
- auto stop_callback = base::BindLambdaForTesting([&](int32_t result) {
- stop_param = result;
- run_loop.Quit();
- });
- net_log_exporter->Stop(
- /*polled_data=*/base::Value::Dict(), stop_callback);
- run_loop.Run();
- EXPECT_EQ(net::OK, stop_param);
- }
- std::string log_contents;
- EXPECT_TRUE(base::ReadFileToString(net_log_path, &log_contents));
- EXPECT_NE(std::string::npos, log_contents.find("\"new_config\""))
- << log_contents;
- base::DeleteFile(net_log_path);
- }
- TEST_F(NetworkContextTest, ClearBadProxiesCache) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::ProxyResolutionService* proxy_resolution_service =
- network_context->url_request_context()->proxy_resolution_service();
- // Very starting conditions: zero bad proxies.
- EXPECT_EQ(0UL, proxy_resolution_service->proxy_retry_info().size());
- // Simulate network error to add one proxy to the bad proxy list.
- net::ProxyInfo proxy_info;
- proxy_info.UseNamedProxy("http://foo1.com");
- proxy_resolution_service->ReportSuccess(proxy_info);
- std::vector<net::ProxyServer> proxies;
- proxies.push_back(net::ProxyUriToProxyServer("http://foo1.com",
- net::ProxyServer::SCHEME_HTTP));
- proxy_resolution_service->MarkProxiesAsBadUntil(
- proxy_info, base::Days(1), proxies, net::NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1UL, proxy_resolution_service->proxy_retry_info().size());
- // Clear the bad proxies.
- base::RunLoop run_loop;
- network_context->ClearBadProxiesCache(run_loop.QuitClosure());
- run_loop.Run();
- // Verify all cleared.
- EXPECT_EQ(0UL, proxy_resolution_service->proxy_retry_info().size());
- }
- // This is a test ProxyErrorClient that records the sequence of calls made to
- // OnPACScriptError() and OnRequestMaybeFailedDueToProxySettings().
- class TestProxyErrorClient final : public mojom::ProxyErrorClient {
- public:
- struct PacScriptError {
- int line = -1;
- std::string details;
- };
- TestProxyErrorClient() = default;
- TestProxyErrorClient(const TestProxyErrorClient&) = delete;
- TestProxyErrorClient& operator=(const TestProxyErrorClient&) = delete;
- ~TestProxyErrorClient() override {}
- void OnPACScriptError(int32_t line_number,
- const std::string& details) override {
- on_pac_script_error_calls_.push_back({line_number, details});
- }
- void OnRequestMaybeFailedDueToProxySettings(int32_t net_error) override {
- on_request_maybe_failed_calls_.push_back(net_error);
- }
- const std::vector<int>& on_request_maybe_failed_calls() const {
- return on_request_maybe_failed_calls_;
- }
- const std::vector<PacScriptError>& on_pac_script_error_calls() const {
- return on_pac_script_error_calls_;
- }
- // Creates an mojo::PendingRemote, binds it to |*this| and returns it.
- mojo::PendingRemote<mojom::ProxyErrorClient> CreateRemote() {
- mojo::PendingRemote<mojom::ProxyErrorClient> client_remote =
- receiver_.BindNewPipeAndPassRemote();
- receiver_.set_disconnect_handler(base::BindOnce(
- &TestProxyErrorClient::OnMojoPipeError, base::Unretained(this)));
- return client_remote;
- }
- // Runs until the message pipe is closed due to an error.
- void RunUntilMojoPipeError() {
- if (has_received_mojo_pipe_error_)
- return;
- base::RunLoop run_loop;
- quit_closure_for_on_mojo_pipe_error_ = run_loop.QuitClosure();
- run_loop.Run();
- }
- private:
- void OnMojoPipeError() {
- if (has_received_mojo_pipe_error_)
- return;
- has_received_mojo_pipe_error_ = true;
- if (quit_closure_for_on_mojo_pipe_error_)
- std::move(quit_closure_for_on_mojo_pipe_error_).Run();
- }
- mojo::Receiver<mojom::ProxyErrorClient> receiver_{this};
- base::OnceClosure quit_closure_for_on_mojo_pipe_error_;
- bool has_received_mojo_pipe_error_ = false;
- std::vector<int> on_request_maybe_failed_calls_;
- std::vector<PacScriptError> on_pac_script_error_calls_;
- };
- // While in scope, all host resolutions will fail with ERR_NAME_NOT_RESOLVED,
- // including localhost (so this precludes the use of embedded test server).
- class ScopedFailAllHostResolutions {
- public:
- ScopedFailAllHostResolutions()
- : mock_resolver_proc_(new net::RuleBasedHostResolverProc(nullptr)),
- default_resolver_proc_(mock_resolver_proc_.get()) {
- mock_resolver_proc_->AddSimulatedFailure("*");
- }
- private:
- scoped_refptr<net::RuleBasedHostResolverProc> mock_resolver_proc_;
- net::ScopedDefaultHostResolverProc default_resolver_proc_;
- };
- // Tests that when a ProxyErrorClient is provided to NetworkContextParams, this
- // client's OnRequestMaybeFailedDueToProxySettings() method is called exactly
- // once when a request fails due to a proxy server connectivity failure.
- TEST_F(NetworkContextTest, ProxyErrorClientNotifiedOfProxyConnection) {
- // Avoid the test having a network dependency on DNS.
- ScopedFailAllHostResolutions fail_dns;
- // Set up the NetworkContext, such that it uses an unreachable proxy
- // (proxy and is configured to send "proxy errors" to
- // |proxy_error_client|.
- TestProxyErrorClient proxy_error_client;
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->proxy_error_client = proxy_error_client.CreateRemote();
- net::ProxyConfig proxy_config;
- // Set the proxy to an unreachable address (host resolution fails).
- proxy_config.proxy_rules().ParseFromString("proxy.bad.dns");
- context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
- proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Issue an HTTP request. It doesn't matter exactly what the URL is, since it
- // will be sent to the proxy.
- ResourceRequest request;
- request.url = GURL("http://example.test");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr loader_params =
- mojom::URLLoaderFactoryParams::New();
- loader_params->process_id = mojom::kBrowserProcessId;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(loader_params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- // Confirm the the resource request failed due to an unreachable proxy.
- client.RunUntilComplete();
- EXPECT_THAT(client.completion_status().error_code,
- net::test::IsError(net::ERR_PROXY_CONNECTION_FAILED));
- // Tear down the network context and wait for a pipe error to ensure
- // that all queued messages on |proxy_error_client| have been processed.
- network_context.reset();
- proxy_error_client.RunUntilMojoPipeError();
- // Confirm that the ProxyErrorClient received the expected calls.
- const auto& request_errors =
- proxy_error_client.on_request_maybe_failed_calls();
- const auto& pac_errors = proxy_error_client.on_pac_script_error_calls();
- ASSERT_EQ(1u, request_errors.size());
- EXPECT_THAT(request_errors[0],
- net::test::IsError(net::ERR_PROXY_CONNECTION_FAILED));
- EXPECT_EQ(0u, pac_errors.size());
- }
- // Tests that when a ProxyErrorClient is provided to NetworkContextParams, this
- // client's OnRequestMaybeFailedDueToProxySettings() method is
- // NOT called when a request fails due to a non-proxy related error (in this
- // case the target host is unreachable).
- TEST_F(NetworkContextTest, ProxyErrorClientNotNotifiedOfUnreachableError) {
- // Avoid the test having a network dependency on DNS.
- ScopedFailAllHostResolutions fail_dns;
- // Set up the NetworkContext that uses the default DIRECT proxy
- // configuration.
- TestProxyErrorClient proxy_error_client;
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->proxy_error_client = proxy_error_client.CreateRemote();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Issue an HTTP request to an unreachable URL.
- ResourceRequest request;
- request.url = GURL("http://server.bad.dns/fail");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr loader_params =
- mojom::URLLoaderFactoryParams::New();
- loader_params->process_id = mojom::kBrowserProcessId;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(loader_params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- // Confirm the the resource request failed.
- client.RunUntilComplete();
- EXPECT_THAT(client.completion_status().error_code,
- net::test::IsError(net::ERR_NAME_NOT_RESOLVED));
- // Tear down the network context and wait for a pipe error to ensure
- // that all queued messages on |proxy_error_client| have been processed.
- network_context.reset();
- proxy_error_client.RunUntilMojoPipeError();
- // Confirm that the ProxyErrorClient received no calls.
- const auto& request_errors =
- proxy_error_client.on_request_maybe_failed_calls();
- const auto& pac_errors = proxy_error_client.on_pac_script_error_calls();
- EXPECT_EQ(0u, request_errors.size());
- EXPECT_EQ(0u, pac_errors.size());
- }
- // Tests that when a ProxyErrorClient is provided to NetworkContextParams, this
- // client's OnPACScriptError() method is called whenever the PAC script throws
- // an error.
- TEST_F(NetworkContextTest, ProxyErrorClientNotifiedOfPacError) {
- // Avoid the test having a network dependency on DNS.
- ScopedFailAllHostResolutions fail_dns;
- // Set up the NetworkContext so that it sends "proxy errors" to
- // |proxy_error_client|, and uses a mock ProxyResolverFactory that emits
- // script errors.
- TestProxyErrorClient proxy_error_client;
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->proxy_error_client = proxy_error_client.CreateRemote();
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- context_params->dhcp_wpad_url_client =
- network::MockMojoDhcpWpadUrlClient::CreateWithSelfOwnedReceiver(
- std::string());
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- // The PAC URL doesn't matter, since the test is configured to use a
- // mock ProxyResolverFactory which doesn't actually evaluate it. It just
- // needs to be a data: URL to ensure the network fetch doesn't fail.
- //
- // That said, the mock PAC evaluator being used behaves similarly to the
- // script embedded in the data URL below.
- net::ProxyConfig proxy_config = net::ProxyConfig::CreateFromCustomPacURL(
- GURL("data:,function FindProxyForURL(url,host){throw url}"));
- context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
- proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
- context_params->proxy_resolver_factory =
- MockMojoProxyResolverFactory::Create();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- // Issue an HTTP request. This will end up being sent DIRECT since the PAC
- // script is broken.
- ResourceRequest request;
- request.url = GURL("http://server.bad.dns");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr loader_params =
- mojom::URLLoaderFactoryParams::New();
- loader_params->process_id = mojom::kBrowserProcessId;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(loader_params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- // Confirm the the resource request failed.
- client.RunUntilComplete();
- EXPECT_THAT(client.completion_status().error_code,
- net::test::IsError(net::ERR_NAME_NOT_RESOLVED));
- // Tear down the network context and wait for a pipe error to ensure
- // that all queued messages on |proxy_error_client| have been processed.
- network_context.reset();
- proxy_error_client.RunUntilMojoPipeError();
- // Confirm that the ProxyErrorClient received the expected calls.
- const auto& request_errors =
- proxy_error_client.on_request_maybe_failed_calls();
- const auto& pac_errors = proxy_error_client.on_pac_script_error_calls();
- EXPECT_EQ(0u, request_errors.size());
- ASSERT_EQ(1u, pac_errors.size());
- EXPECT_EQ(pac_errors[0].line, 42);
- EXPECT_EQ(pac_errors[0].details,
- "Failed: FindProxyForURL(url=http://server.bad.dns/)");
- }
- // Test ensures that ProxyServer data is populated correctly across Mojo calls.
- // Basically it performs a set of URLLoader network requests, whose requests
- // configure proxies. Then it checks whether the expected proxy scheme is
- // respected.
- TEST_F(NetworkContextTest, EnsureProperProxyServerIsUsed) {
- net::test_server::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- struct ProxyConfigSet {
- net::ProxyConfig proxy_config;
- GURL url;
- net::ProxyServer::Scheme expected_proxy_config_scheme;
- } proxy_config_set[2];
- proxy_config_set[0].proxy_config.proxy_rules().ParseFromString(
- "http=" + test_server.host_port_pair().ToString());
- proxy_config_set[0].url = GURL("http://does.not.matter/echo");
- proxy_config_set[0].expected_proxy_config_scheme =
- net::ProxyServer::SCHEME_HTTP;
- proxy_config_set[1].proxy_config.proxy_rules().ParseFromString(
- "http=direct://");
- proxy_config_set[1]
- .proxy_config.proxy_rules()
- .bypass_rules.AddRulesToSubtractImplicit();
- proxy_config_set[1].url = test_server.GetURL("/echo");
- proxy_config_set[1].expected_proxy_config_scheme =
- net::ProxyServer::SCHEME_DIRECT;
- for (const auto& proxy_data : proxy_config_set) {
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
- proxy_data.proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
- mojo::Remote<mojom::ProxyConfigClient> config_client;
- context_params->proxy_config_client_receiver =
- config_client.BindNewPipeAndPassReceiver();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = 0;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- ResourceRequest request;
- request.url = proxy_data.url;
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_TRUE(client.has_received_completion());
- EXPECT_EQ(client.response_head()->proxy_server.scheme(),
- proxy_data.expected_proxy_config_scheme);
- }
- }
- class TestURLLoaderHeaderClient : public mojom::TrustedURLLoaderHeaderClient {
- public:
- class TestHeaderClient : public mojom::TrustedHeaderClient {
- public:
- TestHeaderClient() {}
- TestHeaderClient(const TestHeaderClient&) = delete;
- TestHeaderClient& operator=(const TestHeaderClient&) = delete;
- // network::mojom::TrustedHeaderClient:
- void OnBeforeSendHeaders(const net::HttpRequestHeaders& headers,
- OnBeforeSendHeadersCallback callback) override {
- auto new_headers = headers;
- new_headers.SetHeader("foo", "bar");
- std::move(callback).Run(on_before_send_headers_result_, new_headers);
- }
- void OnHeadersReceived(const std::string& headers,
- const net::IPEndPoint& endpoint,
- OnHeadersReceivedCallback callback) override {
- auto new_headers =
- base::MakeRefCounted<net::HttpResponseHeaders>(headers);
- new_headers->SetHeader("baz", "qux");
- std::move(callback).Run(on_headers_received_result_,
- new_headers->raw_headers(), GURL());
- }
- void set_on_before_send_headers_result(int result) {
- on_before_send_headers_result_ = result;
- }
- void set_on_headers_received_result(int result) {
- on_headers_received_result_ = result;
- }
- void Bind(
- mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
- receiver_.reset();
- receiver_.Bind(std::move(receiver));
- }
- private:
- int on_before_send_headers_result_ = net::OK;
- int on_headers_received_result_ = net::OK;
- mojo::Receiver<mojom::TrustedHeaderClient> receiver_{this};
- };
- explicit TestURLLoaderHeaderClient(
- mojo::PendingReceiver<mojom::TrustedURLLoaderHeaderClient> receiver)
- : receiver_(this, std::move(receiver)) {}
- TestURLLoaderHeaderClient(const TestURLLoaderHeaderClient&) = delete;
- TestURLLoaderHeaderClient& operator=(const TestURLLoaderHeaderClient&) =
- delete;
- // network::mojom::TrustedURLLoaderHeaderClient:
- void OnLoaderCreated(
- int32_t request_id,
- mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver)
- override {
- header_client_.Bind(std::move(receiver));
- }
- void OnLoaderForCorsPreflightCreated(
- const ResourceRequest& request,
- mojo::PendingReceiver<mojom::TrustedHeaderClient> receiver) override {
- header_client_.Bind(std::move(receiver));
- }
- void set_on_before_send_headers_result(int result) {
- header_client_.set_on_before_send_headers_result(result);
- }
- void set_on_headers_received_result(int result) {
- header_client_.set_on_headers_received_result(result);
- }
- private:
- TestHeaderClient header_client_;
- mojo::Receiver<mojom::TrustedURLLoaderHeaderClient> receiver_;
- };
- TEST_F(NetworkContextTest, HeaderClientModifiesHeaders) {
- net::EmbeddedTestServer test_server;
- net::test_server::RegisterDefaultHandlers(&test_server);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ResourceRequest request;
- request.url = test_server.GetURL("/echoheader?foo");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- TestURLLoaderHeaderClient header_client(
- params->header_client.InitWithNewPipeAndPassReceiver());
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- // First, do a request with kURLLoadOptionUseHeaderClient set.
- {
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionUseHeaderClient, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- // Make sure request header was modified. The value will be in the body
- // since we used the /echoheader endpoint.
- std::string response;
- EXPECT_TRUE(
- mojo::BlockingCopyToString(client.response_body_release(), &response));
- EXPECT_EQ(response, "bar");
- // Make sure response header was modified.
- EXPECT_TRUE(client.response_head()->headers->HasHeaderValue("baz", "qux"));
- }
- // Next, do a request without kURLLoadOptionUseHeaderClient set, headers
- // should not be modified.
- {
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- // Make sure request header was not set.
- std::string response;
- EXPECT_TRUE(
- mojo::BlockingCopyToString(client.response_body_release(), &response));
- EXPECT_EQ(response, "None");
- // Make sure response header was not set.
- EXPECT_FALSE(client.response_head()->headers->HasHeaderValue("foo", "bar"));
- }
- }
- TEST_F(NetworkContextTest, HeaderClientFailsRequest) {
- net::EmbeddedTestServer test_server;
- net::test_server::RegisterDefaultHandlers(&test_server);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ResourceRequest request;
- request.url = test_server.GetURL("/echo");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- TestURLLoaderHeaderClient header_client(
- params->header_client.InitWithNewPipeAndPassReceiver());
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- // First, fail request on OnBeforeSendHeaders.
- {
- header_client.set_on_before_send_headers_result(net::ERR_FAILED);
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionUseHeaderClient, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_EQ(client.completion_status().error_code, net::ERR_FAILED);
- }
- // Next, fail request on OnHeadersReceived.
- {
- header_client.set_on_before_send_headers_result(net::OK);
- header_client.set_on_headers_received_result(net::ERR_FAILED);
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionUseHeaderClient, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client.RunUntilComplete();
- EXPECT_EQ(client.completion_status().error_code, net::ERR_FAILED);
- }
- }
- class HangingTestURLLoaderHeaderClient
- : public mojom::TrustedURLLoaderHeaderClient {
- public:
- class TestHeaderClient : public mojom::TrustedHeaderClient {
- public:
- TestHeaderClient() {}
- TestHeaderClient(const TestHeaderClient&) = delete;
- TestHeaderClient& operator=(const TestHeaderClient&) = delete;
- // network::mojom::TrustedHeaderClient:
- void OnBeforeSendHeaders(const net::HttpRequestHeaders& headers,
- OnBeforeSendHeadersCallback callback) override {
- saved_request_headers_ = headers;
- saved_on_before_send_headers_callback_ = std::move(callback);
- on_before_send_headers_loop_.Quit();
- }
- void OnHeadersReceived(const std::string& headers,
- const net::IPEndPoint& endpoint,
- OnHeadersReceivedCallback callback) override {
- saved_received_headers_ = headers;
- saved_on_headers_received_callback_ = std::move(callback);
- on_headers_received_loop_.Quit();
- }
- void CallOnBeforeSendHeadersCallback() {
- net::HttpRequestHeaders new_headers = std::move(saved_request_headers_);
- new_headers.SetHeader("foo", "bar");
- std::move(saved_on_before_send_headers_callback_)
- .Run(net::OK, new_headers);
- }
- void WaitForOnBeforeSendHeaders() { on_before_send_headers_loop_.Run(); }
- void CallOnHeadersReceivedCallback() {
- auto new_headers = base::MakeRefCounted<net::HttpResponseHeaders>(
- saved_received_headers_);
- new_headers->SetHeader("baz", "qux");
- std::move(saved_on_headers_received_callback_)
- .Run(net::OK, new_headers->raw_headers(), GURL());
- }
- void WaitForOnHeadersReceived() { on_headers_received_loop_.Run(); }
- void Bind(
- mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
- receiver_.Bind(std::move(receiver));
- }
- private:
- base::RunLoop on_before_send_headers_loop_;
- net::HttpRequestHeaders saved_request_headers_;
- OnBeforeSendHeadersCallback saved_on_before_send_headers_callback_;
- base::RunLoop on_headers_received_loop_;
- std::string saved_received_headers_;
- OnHeadersReceivedCallback saved_on_headers_received_callback_;
- mojo::Receiver<mojom::TrustedHeaderClient> receiver_{this};
- };
- explicit HangingTestURLLoaderHeaderClient(
- mojo::PendingReceiver<mojom::TrustedURLLoaderHeaderClient> receiver)
- : receiver_(this, std::move(receiver)) {}
- HangingTestURLLoaderHeaderClient(const HangingTestURLLoaderHeaderClient&) =
- delete;
- HangingTestURLLoaderHeaderClient& operator=(
- const HangingTestURLLoaderHeaderClient&) = delete;
- // network::mojom::TrustedURLLoaderHeaderClient:
- void OnLoaderCreated(
- int32_t request_id,
- mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver)
- override {
- header_client_.Bind(std::move(receiver));
- }
- void OnLoaderForCorsPreflightCreated(
- const ResourceRequest& request,
- mojo::PendingReceiver<mojom::TrustedHeaderClient> receiver) override {
- header_client_.Bind(std::move(receiver));
- }
- void CallOnBeforeSendHeadersCallback() {
- header_client_.CallOnBeforeSendHeadersCallback();
- }
- void WaitForOnBeforeSendHeaders() {
- header_client_.WaitForOnBeforeSendHeaders();
- }
- void CallOnHeadersReceivedCallback() {
- header_client_.CallOnHeadersReceivedCallback();
- }
- void WaitForOnHeadersReceived() { header_client_.WaitForOnHeadersReceived(); }
- private:
- TestHeaderClient header_client_;
- mojo::Receiver<mojom::TrustedURLLoaderHeaderClient> receiver_;
- };
- // Test waiting on the OnHeadersReceived event, then proceeding to call the
- // OnHeadersReceivedCallback asynchronously. This mostly just verifies that
- // HangingTestURLLoaderHeaderClient works.
- TEST_F(NetworkContextTest, HangingHeaderClientModifiesHeadersAsynchronously) {
- net::EmbeddedTestServer test_server;
- net::test_server::RegisterDefaultHandlers(&test_server);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ResourceRequest request;
- request.url = test_server.GetURL("/echoheader?foo");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- HangingTestURLLoaderHeaderClient header_client(
- params->header_client.InitWithNewPipeAndPassReceiver());
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionUseHeaderClient, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- header_client.WaitForOnBeforeSendHeaders();
- header_client.CallOnBeforeSendHeadersCallback();
- header_client.WaitForOnHeadersReceived();
- header_client.CallOnHeadersReceivedCallback();
- client.RunUntilComplete();
- EXPECT_EQ(client.completion_status().error_code, net::OK);
- // Make sure request header was modified. The value will be in the body
- // since we used the /echoheader endpoint.
- std::string response;
- EXPECT_TRUE(
- mojo::BlockingCopyToString(client.response_body_release(), &response));
- EXPECT_EQ(response, "bar");
- // Make sure response header was modified.
- EXPECT_TRUE(client.response_head()->headers->HasHeaderValue("baz", "qux"));
- }
- // Test destroying the mojom::URLLoader after the OnBeforeSendHeaders event and
- // then calling the OnBeforeSendHeadersCallback.
- TEST_F(NetworkContextTest, HangingHeaderClientAbortDuringOnBeforeSendHeaders) {
- net::EmbeddedTestServer test_server;
- net::test_server::RegisterDefaultHandlers(&test_server);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ResourceRequest request;
- request.url = test_server.GetURL("/echoheader?foo");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- HangingTestURLLoaderHeaderClient header_client(
- params->header_client.InitWithNewPipeAndPassReceiver());
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionUseHeaderClient, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- header_client.WaitForOnBeforeSendHeaders();
- loader.reset();
- // Ensure the loader is destroyed before the callback is run.
- base::RunLoop().RunUntilIdle();
- header_client.CallOnBeforeSendHeadersCallback();
- client.RunUntilComplete();
- EXPECT_EQ(client.completion_status().error_code, net::ERR_ABORTED);
- }
- // Test destroying the mojom::URLLoader after the OnHeadersReceived event and
- // then calling the OnHeadersReceivedCallback.
- TEST_F(NetworkContextTest, HangingHeaderClientAbortDuringOnHeadersReceived) {
- net::EmbeddedTestServer test_server;
- net::test_server::RegisterDefaultHandlers(&test_server);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- ResourceRequest request;
- request.url = test_server.GetURL("/echoheader?foo");
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- HangingTestURLLoaderHeaderClient header_client(
- params->header_client.InitWithNewPipeAndPassReceiver());
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- mojo::PendingRemote<mojom::URLLoader> loader;
- TestURLLoaderClient client;
- loader_factory->CreateLoaderAndStart(
- loader.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionUseHeaderClient, request, client.CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- header_client.WaitForOnBeforeSendHeaders();
- header_client.CallOnBeforeSendHeadersCallback();
- header_client.WaitForOnHeadersReceived();
- loader.reset();
- // Ensure the loader is destroyed before the callback is run.
- base::RunLoop().RunUntilIdle();
- header_client.CallOnHeadersReceivedCallback();
- client.RunUntilComplete();
- EXPECT_EQ(client.completion_status().error_code, net::ERR_ABORTED);
- }
- // Custom proxy does not apply to localhost, so resolve kMockHost to localhost,
- // and use that instead.
- class NetworkContextMockHostTest : public NetworkContextTest {
- public:
- NetworkContextMockHostTest() {
- net::MockHostResolverBase::RuleResolver rules;
- rules.AddRule(kMockHost, "127.0.0.1");
- network_service_->set_host_resolver_factory_for_testing(
- std::make_unique<net::MockHostResolverFactory>(std::move(rules)));
- }
- protected:
- GURL GetURLWithMockHost(const net::EmbeddedTestServer& server,
- const std::string& relative_url) {
- GURL server_base_url = server.base_url();
- GURL base_url =
- GURL(base::StrCat({server_base_url.scheme(), "://", kMockHost, ":",
- server_base_url.port()}));
- EXPECT_TRUE(base_url.is_valid()) << base_url.possibly_invalid_spec();
- return base_url.Resolve(relative_url);
- }
- net::ProxyServer ConvertToProxyServer(const net::EmbeddedTestServer& server) {
- std::string base_url = server.base_url().spec();
- // Remove slash from URL.
- base_url.pop_back();
- auto proxy_server =
- net::ProxyUriToProxyServer(base_url, net::ProxyServer::SCHEME_HTTP);
- EXPECT_TRUE(proxy_server.is_valid()) << base_url;
- return proxy_server;
- }
- };
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- // Flaky crashes on Linux: https://crbug.com/1115201
- #define MAYBE_CustomProxyUsesSpecifiedProxyList \
- DISABLED_CustomProxyUsesSpecifiedProxyList
- #else
- #define MAYBE_CustomProxyUsesSpecifiedProxyList \
- CustomProxyUsesSpecifiedProxyList
- #endif
- TEST_F(NetworkContextMockHostTest, MAYBE_CustomProxyUsesSpecifiedProxyList) {
- net::EmbeddedTestServer proxy_test_server;
- net::test_server::RegisterDefaultHandlers(&proxy_test_server);
- ASSERT_TRUE(proxy_test_server.Start());
- mojo::Remote<mojom::CustomProxyConfigClient> proxy_config_client;
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- context_params->custom_proxy_config_client_receiver =
- proxy_config_client.BindNewPipeAndPassReceiver();
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(context_params));
- auto config = mojom::CustomProxyConfig::New();
- config->rules.ParseFromString(
- "http=" +
- net::ProxyServerToProxyUri(ConvertToProxyServer(proxy_test_server)));
- base::RunLoop loop;
- proxy_config_client->OnCustomProxyConfigUpdated(std::move(config),
- loop.QuitClosure());
- loop.Run();
- ResourceRequest request;
- request.url = GURL("http://does.not.resolve/echo");
- std::unique_ptr<TestURLLoaderClient> client =
- FetchRequest(request, network_context.get());
- std::string response;
- EXPECT_TRUE(
- mojo::BlockingCopyToString(client->response_body_release(), &response));
- // |invalid_server| has no handlers set up so would return an empty response.
- EXPECT_EQ(response, "Echo");
- EXPECT_EQ(client->response_head()->proxy_server,
- ConvertToProxyServer(proxy_test_server));
- }
- TEST_F(NetworkContextTest, MaximumCount) {
- net::EmbeddedTestServer test_server;
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- const char kPath1[] = "/foobar";
- const char kPath2[] = "/hung";
- const char kPath3[] = "/hello.html";
- net::test_server::ControllableHttpResponse controllable_response1(
- &test_server, kPath1);
- ASSERT_TRUE(test_server.Start());
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- network_context->set_max_loaders_per_process_for_testing(2);
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- mojom::URLLoaderFactoryParamsPtr params =
- mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- network_context->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- ResourceRequest request;
- request.url = test_server.GetURL(kPath1);
- auto client1 = std::make_unique<TestURLLoaderClient>();
- mojo::PendingRemote<mojom::URLLoader> loader1;
- loader_factory->CreateLoaderAndStart(
- loader1.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client1->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- request.url = test_server.GetURL(kPath2);
- auto client2 = std::make_unique<TestURLLoaderClient>();
- mojo::PendingRemote<mojom::URLLoader> loader2;
- loader_factory->CreateLoaderAndStart(
- loader2.InitWithNewPipeAndPassReceiver(), 0 /* request_id */,
- 0 /* options */, request, client2->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- // A third request should fail, since the first two are outstanding and the
- // limit is 2.
- request.url = test_server.GetURL(kPath3);
- auto client3 = std::make_unique<TestURLLoaderClient>();
- mojo::Remote<mojom::URLLoader> loader3;
- loader_factory->CreateLoaderAndStart(
- loader3.BindNewPipeAndPassReceiver(), 0 /* request_id */, 0 /* options */,
- request, client3->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client3->RunUntilComplete();
- ASSERT_EQ(client3->completion_status().error_code,
- net::ERR_INSUFFICIENT_RESOURCES);
- // Complete the first request and try the third again.
- controllable_response1.WaitForRequest();
- controllable_response1.Send("HTTP/1.1 200 OK\r\n");
- controllable_response1.Done();
- client1->RunUntilComplete();
- ASSERT_EQ(client1->completion_status().error_code, net::OK);
- client3 = std::make_unique<TestURLLoaderClient>();
- loader3.reset();
- loader_factory->CreateLoaderAndStart(
- loader3.BindNewPipeAndPassReceiver(), 0 /* request_id */, 0 /* options */,
- request, client3->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- client3->RunUntilComplete();
- ASSERT_EQ(client3->completion_status().error_code, net::OK);
- }
- TEST_F(NetworkContextTest, AllowAllCookies) {
- net::test_server::EmbeddedTestServer test_server(
- net::test_server::EmbeddedTestServer::TYPE_HTTPS);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- GURL server_url = test_server.GetURL("/echoheader?Cookie");
- GURL first_party_url(server_url);
- GURL third_party_url("http://www.some.other.origin.test/");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_TRUE(
- SetCookieHelper(network_context.get(), server_url, "TestCookie", "1"));
- int url_loader_options = mojom::kURLLoadOptionNone;
- ResourceRequest first_party_request;
- first_party_request.url = server_url;
- first_party_request.site_for_cookies =
- net::SiteForCookies::FromUrl(first_party_url);
- std::unique_ptr<TestURLLoaderClient> client = FetchRequest(
- first_party_request, network_context.get(), url_loader_options);
- std::string response_body;
- ASSERT_TRUE(client->response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client->response_body_release(),
- &response_body));
- EXPECT_EQ("TestCookie=1", response_body);
- ResourceRequest third_party_request;
- third_party_request.url = server_url;
- third_party_request.site_for_cookies =
- net::SiteForCookies::FromUrl(third_party_url);
- client = FetchRequest(third_party_request, network_context.get(),
- url_loader_options);
- ASSERT_TRUE(client->response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client->response_body_release(),
- &response_body));
- EXPECT_EQ("TestCookie=1", response_body);
- }
- TEST_F(NetworkContextTest, BlockThirdPartyCookies) {
- net::test_server::EmbeddedTestServer test_server(
- net::test_server::EmbeddedTestServer::TYPE_HTTPS);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- GURL server_url = test_server.GetURL("/echoheader?Cookie");
- GURL first_party_url(server_url);
- GURL third_party_url("http://www.some.other.origin.test/");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_TRUE(
- SetCookieHelper(network_context.get(), server_url, "TestCookie", "1"));
- int url_loader_options = mojom::kURLLoadOptionBlockThirdPartyCookies;
- ResourceRequest first_party_request;
- first_party_request.url = server_url;
- first_party_request.site_for_cookies =
- net::SiteForCookies::FromUrl(first_party_url);
- std::unique_ptr<TestURLLoaderClient> client = FetchRequest(
- first_party_request, network_context.get(), url_loader_options);
- std::string response_body;
- ASSERT_TRUE(client->response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client->response_body_release(),
- &response_body));
- EXPECT_EQ("TestCookie=1", response_body);
- ResourceRequest third_party_request;
- third_party_request.url = server_url;
- third_party_request.site_for_cookies =
- net::SiteForCookies::FromUrl(third_party_url);
- client = FetchRequest(third_party_request, network_context.get(),
- url_loader_options);
- ASSERT_TRUE(client->response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client->response_body_release(),
- &response_body));
- EXPECT_EQ("None", response_body);
- }
- TEST_F(NetworkContextTest, BlockAllCookies) {
- net::test_server::EmbeddedTestServer test_server(
- net::test_server::EmbeddedTestServer::TYPE_HTTPS);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- ASSERT_TRUE(test_server.Start());
- GURL server_url = test_server.GetURL("/echoheader?Cookie");
- GURL first_party_url(server_url);
- GURL third_party_url("http://www.some.other.origin.test/");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_TRUE(
- SetCookieHelper(network_context.get(), server_url, "TestCookie", "1"));
- int url_loader_options = mojom::kURLLoadOptionBlockAllCookies;
- ResourceRequest first_party_request;
- first_party_request.url = server_url;
- first_party_request.site_for_cookies =
- net::SiteForCookies::FromUrl(first_party_url);
- std::unique_ptr<TestURLLoaderClient> client = FetchRequest(
- first_party_request, network_context.get(), url_loader_options);
- std::string response_body;
- ASSERT_TRUE(client->response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client->response_body_release(),
- &response_body));
- EXPECT_EQ("None", response_body);
- ResourceRequest third_party_request;
- third_party_request.url = server_url;
- third_party_request.site_for_cookies =
- net::SiteForCookies::FromUrl(third_party_url);
- client = FetchRequest(third_party_request, network_context.get(),
- url_loader_options);
- ASSERT_TRUE(client->response_body().is_valid());
- EXPECT_TRUE(mojo::BlockingCopyToString(client->response_body_release(),
- &response_body));
- EXPECT_EQ("None", response_body);
- }
- #if BUILDFLAG(IS_CT_SUPPORTED)
- TEST_F(NetworkContextTest, CertificateTransparencyConfig) {
- // Configure CT logs in network service.
- std::vector<network::mojom::CTLogInfoPtr> log_list_mojo;
- // The log public keys do not matter for the test, so invalid keys are used.
- // However, because the log IDs are derived from the SHA-256 hash of the log
- // key, the log keys are generated such that qualified logs are in the form
- // of four digits (e.g. "0000", "1111"), while disqualified logs are in the
- // form of four letters (e.g. "AAAA", "BBBB").
- for (int i = 0; i < 6; ++i) {
- network::mojom::CTLogInfoPtr log_info = network::mojom::CTLogInfo::New();
- // Shift to ASCII '0' (0x30)
- log_info->public_key = std::string(4, 0x30 + static_cast<char>(i));
- log_info->name = std::string(4, 0x30 + static_cast<char>(i));
- log_info->operated_by_google = i % 2;
- if (log_info->operated_by_google) {
- log_info->current_operator = "Google";
- } else {
- log_info->current_operator = "Not Google";
- }
- log_list_mojo.push_back(std::move(log_info));
- }
- for (int i = 0; i < 3; ++i) {
- network::mojom::CTLogInfoPtr log_info = network::mojom::CTLogInfo::New();
- // Shift to ASCII 'A' (0x41)
- log_info->public_key = std::string(4, 0x41 + static_cast<char>(i));
- log_info->name = std::string(4, 0x41 + static_cast<char>(i));
- log_info->operated_by_google = false;
- log_info->disqualified_at = base::Time::FromTimeT(i);
- log_info->current_operator = "Not Google Either";
- log_list_mojo.push_back(std::move(log_info));
- }
- base::RunLoop run_loop;
- network_service()->UpdateCtLogList(std::move(log_list_mojo),
- base::Time::Now(), run_loop.QuitClosure());
- run_loop.Run();
- // Configure CT params in network context.
- mojom::NetworkContextParamsPtr params =
- CreateNetworkContextParamsForTesting();
- params->enforce_chrome_ct_policy = true;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- net::CTPolicyEnforcer* request_enforcer =
- network_context->url_request_context()->ct_policy_enforcer();
- ASSERT_TRUE(request_enforcer);
- // Completely unsafe if |enforce_chrome_ct_policy| is false.
- certificate_transparency::ChromeCTPolicyEnforcer* policy_enforcer =
- reinterpret_cast<certificate_transparency::ChromeCTPolicyEnforcer*>(
- request_enforcer);
- EXPECT_TRUE(std::is_sorted(
- policy_enforcer->operated_by_google_logs_for_testing().begin(),
- policy_enforcer->operated_by_google_logs_for_testing().end()));
- EXPECT_TRUE(
- std::is_sorted(policy_enforcer->disqualified_logs_for_testing().begin(),
- policy_enforcer->disqualified_logs_for_testing().end()));
- EXPECT_THAT(
- policy_enforcer->operated_by_google_logs_for_testing(),
- ::testing::UnorderedElementsAreArray({crypto::SHA256HashString("1111"),
- crypto::SHA256HashString("3333"),
- crypto::SHA256HashString("5555")}));
- EXPECT_THAT(policy_enforcer->disqualified_logs_for_testing(),
- ::testing::UnorderedElementsAre(
- ::testing::Pair(crypto::SHA256HashString("AAAA"),
- base::Time::FromTimeT(0)),
- ::testing::Pair(crypto::SHA256HashString("BBBB"),
- base::Time::FromTimeT(1)),
- ::testing::Pair(crypto::SHA256HashString("CCCC"),
- base::Time::FromTimeT(2))));
- std::map<std::string, certificate_transparency::OperatorHistoryEntry>
- operator_history = policy_enforcer->operator_history_for_testing();
- for (auto log : policy_enforcer->operated_by_google_logs_for_testing()) {
- EXPECT_EQ(operator_history[log].current_operator_, "Google");
- EXPECT_TRUE(operator_history[log].previous_operators_.empty());
- }
- for (auto log : policy_enforcer->disqualified_logs_for_testing()) {
- EXPECT_EQ(operator_history[log.first].current_operator_,
- "Not Google Either");
- EXPECT_TRUE(operator_history[log.first].previous_operators_.empty());
- }
- }
- TEST_F(NetworkContextTest, CertificateTransparencyConfigWithOperatorSwitches) {
- // Configure CT logs in network service.
- std::vector<network::mojom::CTLogInfoPtr> log_list_mojo;
- // The log public keys do not matter for the test, so invalid keys are used.
- // However, because the log IDs are derived from the SHA-256 hash of the log
- // key, the log keys are generated such that the log that never switched
- // operator is "0000", while the one that did is "AAAA".
- network::mojom::CTLogInfoPtr log_info = network::mojom::CTLogInfo::New();
- // Shift to ASCII '0' (0x30)
- log_info->public_key = std::string(4, 0x30);
- log_info->name = std::string(4, 0x30);
- log_info->current_operator = "Forever Operator";
- log_list_mojo.push_back(std::move(log_info));
- log_info = network::mojom::CTLogInfo::New();
- // Shift to ASCII 'A' (0x41)
- log_info->public_key = std::string(4, 0x41);
- log_info->name = std::string(4, 0x41);
- log_info->current_operator = "Changed Operator";
- for (int i = 0; i < 3; i++) {
- network::mojom::PreviousOperatorEntryPtr previous_operator =
- network::mojom::PreviousOperatorEntry::New();
- previous_operator->name = "Operator " + base::NumberToString(i);
- previous_operator->end_time = base::Time::FromTimeT(i);
- log_info->previous_operators.push_back(std::move(previous_operator));
- }
- log_list_mojo.push_back(std::move(log_info));
- base::RunLoop run_loop;
- network_service()->UpdateCtLogList(std::move(log_list_mojo),
- base::Time::Now(), run_loop.QuitClosure());
- run_loop.Run();
- // Configure CT params in network context.
- mojom::NetworkContextParamsPtr params =
- CreateNetworkContextParamsForTesting();
- params->enforce_chrome_ct_policy = true;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- net::CTPolicyEnforcer* request_enforcer =
- network_context->url_request_context()->ct_policy_enforcer();
- ASSERT_TRUE(request_enforcer);
- // Completely unsafe if |enforce_chrome_ct_policy| is false.
- certificate_transparency::ChromeCTPolicyEnforcer* policy_enforcer =
- reinterpret_cast<certificate_transparency::ChromeCTPolicyEnforcer*>(
- request_enforcer);
- std::map<std::string, certificate_transparency::OperatorHistoryEntry>
- operator_history = policy_enforcer->operator_history_for_testing();
- EXPECT_EQ(
- operator_history[crypto::SHA256HashString("0000")].current_operator_,
- "Forever Operator");
- EXPECT_TRUE(operator_history[crypto::SHA256HashString("0000")]
- .previous_operators_.empty());
- EXPECT_EQ(
- operator_history[crypto::SHA256HashString("AAAA")].current_operator_,
- "Changed Operator");
- EXPECT_THAT(
- operator_history[crypto::SHA256HashString("AAAA")].previous_operators_,
- ::testing::ElementsAre(
- ::testing::Pair("Operator 0", base::Time::FromTimeT(0)),
- ::testing::Pair("Operator 1", base::Time::FromTimeT(1)),
- ::testing::Pair("Operator 2", base::Time::FromTimeT(2))));
- }
- #endif
- TEST_F(NetworkContextTest, AddHttpAuthCacheEntry) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- ASSERT_TRUE(cache);
- // |key_server_entries_by_network_isolation_key| should be disabled by
- // default, so the passed in NetworkIsolationKeys don't matter.
- EXPECT_FALSE(cache->key_server_entries_by_network_isolation_key());
- // Add an AUTH_SERVER cache entry.
- url::SchemeHostPort scheme_host_port(GURL("http://example.test/"));
- net::AuthChallengeInfo challenge;
- challenge.is_proxy = false;
- challenge.challenger = scheme_host_port;
- challenge.scheme = "basic";
- challenge.realm = "testrealm";
- const char16_t kUsername[] = u"test_user";
- const char16_t kPassword[] = u"test_pass";
- ASSERT_FALSE(cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- base::RunLoop run_loop;
- network_context->AddAuthCacheEntry(challenge, net::NetworkIsolationKey(),
- net::AuthCredentials(kUsername, kPassword),
- run_loop.QuitClosure());
- run_loop.Run();
- net::HttpAuthCache::Entry* entry = cache->Lookup(
- scheme_host_port, net::HttpAuth::AUTH_SERVER, challenge.realm,
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(scheme_host_port, entry->scheme_host_port());
- EXPECT_EQ(challenge.realm, entry->realm());
- EXPECT_EQ(net::HttpAuth::StringToScheme(challenge.scheme), entry->scheme());
- EXPECT_EQ(kUsername, entry->credentials().username());
- EXPECT_EQ(kPassword, entry->credentials().password());
- // Entry should only have been added for server auth.
- EXPECT_FALSE(cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_PROXY,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- // Add an AUTH_PROXY cache entry.
- url::SchemeHostPort proxy_scheme_host_port(GURL("http://proxy.test/"));
- challenge.is_proxy = true;
- challenge.challenger = proxy_scheme_host_port;
- const char16_t kProxyUsername[] = u"test_proxy_user";
- const char16_t kProxyPassword[] = u"test_proxy_pass";
- ASSERT_FALSE(cache->Lookup(proxy_scheme_host_port, net::HttpAuth::AUTH_PROXY,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- base::RunLoop run_loop2;
- network_context->AddAuthCacheEntry(
- challenge, net::NetworkIsolationKey(),
- net::AuthCredentials(kProxyUsername, kProxyPassword),
- run_loop2.QuitClosure());
- run_loop2.Run();
- entry = cache->Lookup(proxy_scheme_host_port, net::HttpAuth::AUTH_PROXY,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(proxy_scheme_host_port, entry->scheme_host_port());
- EXPECT_EQ(challenge.realm, entry->realm());
- EXPECT_EQ(net::HttpAuth::StringToScheme(challenge.scheme), entry->scheme());
- EXPECT_EQ(kProxyUsername, entry->credentials().username());
- EXPECT_EQ(kProxyPassword, entry->credentials().password());
- // Entry should only have been added for proxy auth.
- EXPECT_FALSE(cache->Lookup(proxy_scheme_host_port, net::HttpAuth::AUTH_SERVER,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- }
- TEST_F(NetworkContextTest, AddHttpAuthCacheEntryWithNetworkIsolationKey) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- network_context->SetSplitAuthCacheByNetworkIsolationKey(true);
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- ASSERT_TRUE(cache);
- // If this isn't true, the rest of this test is pretty meaningless.
- ASSERT_TRUE(cache->key_server_entries_by_network_isolation_key());
- // Add an AUTH_SERVER cache entry.
- url::Origin origin = url::Origin::Create(GURL("http://example.test/"));
- url::SchemeHostPort scheme_host_port =
- origin.GetTupleOrPrecursorTupleIfOpaque();
- net::NetworkIsolationKey network_isolation_key(origin, origin);
- net::AuthChallengeInfo challenge;
- challenge.is_proxy = false;
- challenge.challenger = scheme_host_port;
- challenge.scheme = "basic";
- challenge.realm = "testrealm";
- const char16_t kUsername[] = u"test_user";
- const char16_t kPassword[] = u"test_pass";
- ASSERT_FALSE(cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- network_isolation_key));
- base::RunLoop run_loop;
- network_context->AddAuthCacheEntry(challenge, network_isolation_key,
- net::AuthCredentials(kUsername, kPassword),
- run_loop.QuitClosure());
- run_loop.Run();
- net::HttpAuthCache::Entry* entry = cache->Lookup(
- scheme_host_port, net::HttpAuth::AUTH_SERVER, challenge.realm,
- net::HttpAuth::AUTH_SCHEME_BASIC, network_isolation_key);
- ASSERT_TRUE(entry);
- EXPECT_EQ(scheme_host_port, entry->scheme_host_port());
- EXPECT_EQ(challenge.realm, entry->realm());
- EXPECT_EQ(net::HttpAuth::StringToScheme(challenge.scheme), entry->scheme());
- EXPECT_EQ(kUsername, entry->credentials().username());
- EXPECT_EQ(kPassword, entry->credentials().password());
- // Entry should only be accessibly when using the correct NetworkIsolationKey.
- EXPECT_FALSE(cache->Lookup(scheme_host_port, net::HttpAuth::AUTH_SERVER,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- }
- TEST_F(NetworkContextTest, CopyHttpAuthCacheProxyEntries) {
- const url::SchemeHostPort kSchemeHostPort(GURL("http://foo.com"));
- std::unique_ptr<NetworkContext> network_context1 =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::AuthChallengeInfo challenge;
- challenge.is_proxy = true;
- challenge.challenger = kSchemeHostPort;
- challenge.scheme = "basic";
- challenge.realm = "testrealm";
- const char16_t kProxyUsername[] = u"proxy_user";
- const char16_t kProxyPassword[] = u"proxy_pass";
- base::RunLoop run_loop1;
- network_context1->AddAuthCacheEntry(
- challenge, net::NetworkIsolationKey(),
- net::AuthCredentials(kProxyUsername, kProxyPassword),
- run_loop1.QuitClosure());
- run_loop1.Run();
- challenge.is_proxy = false;
- const char16_t kServerUsername[] = u"server_user";
- const char16_t kServerPassword[] = u"server_pass";
- base::RunLoop run_loop2;
- network_context1->AddAuthCacheEntry(
- challenge, net::NetworkIsolationKey(),
- net::AuthCredentials(kServerUsername, kServerPassword),
- run_loop2.QuitClosure());
- run_loop2.Run();
- base::UnguessableToken token;
- base::RunLoop run_loop3;
- network_context1->SaveHttpAuthCacheProxyEntries(base::BindLambdaForTesting(
- [&](const base::UnguessableToken& returned_token) {
- token = returned_token;
- run_loop3.Quit();
- }));
- run_loop3.Run();
- // Delete first NetworkContext, to make sure saved credentials outlast it.
- network_context1.reset();
- base::RunLoop().RunUntilIdle();
- std::unique_ptr<NetworkContext> network_context2 =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop4;
- network_context2->LoadHttpAuthCacheProxyEntries(token,
- run_loop4.QuitClosure());
- run_loop4.Run();
- // Check cached credentials directly, since there's no API to check proxy
- // credentials.
- net::HttpAuthCache* cache = network_context2->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- // The server credentials should not have been copied.
- EXPECT_FALSE(cache->Lookup(kSchemeHostPort, net::HttpAuth::AUTH_SERVER,
- challenge.realm, net::HttpAuth::AUTH_SCHEME_BASIC,
- net::NetworkIsolationKey()));
- net::HttpAuthCache::Entry* entry = cache->Lookup(
- kSchemeHostPort, net::HttpAuth::AUTH_PROXY, challenge.realm,
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(kProxyUsername, entry->credentials().username());
- EXPECT_EQ(kProxyPassword, entry->credentials().password());
- }
- TEST_F(NetworkContextTest, SplitAuthCacheByNetworkIsolationKey) {
- const url::SchemeHostPort kSchemeHostPort(GURL("http://foo.com"));
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- net::HttpAuthCache* cache = network_context->url_request_context()
- ->http_transaction_factory()
- ->GetSession()
- ->http_auth_cache();
- EXPECT_FALSE(cache->key_server_entries_by_network_isolation_key());
- // Add proxy credentials, which should never be deleted.
- net::AuthChallengeInfo challenge;
- challenge.is_proxy = true;
- challenge.challenger = kSchemeHostPort;
- challenge.scheme = "basic";
- challenge.realm = "testrealm";
- const char16_t kProxyUsername[] = u"proxy_user";
- const char16_t kProxyPassword[] = u"proxy_pass";
- base::RunLoop run_loop1;
- network_context->AddAuthCacheEntry(
- challenge, net::NetworkIsolationKey(),
- net::AuthCredentials(kProxyUsername, kProxyPassword),
- run_loop1.QuitClosure());
- run_loop1.Run();
- // Set up challenge to add server credentials.
- challenge.is_proxy = false;
- for (bool set_split_cache_by_network_isolation_key : {true, false}) {
- // In each loop iteration, the setting should change, which should clear
- // server credentials.
- EXPECT_NE(set_split_cache_by_network_isolation_key,
- cache->key_server_entries_by_network_isolation_key());
- // Add server credentials.
- const char16_t kServerUsername[] = u"server_user";
- const char16_t kServerPassword[] = u"server_pass";
- base::RunLoop run_loop2;
- network_context->AddAuthCacheEntry(
- challenge, net::NetworkIsolationKey(),
- net::AuthCredentials(kServerUsername, kServerPassword),
- run_loop2.QuitClosure());
- run_loop2.Run();
- // Toggle setting.
- network_context->SetSplitAuthCacheByNetworkIsolationKey(
- set_split_cache_by_network_isolation_key);
- EXPECT_EQ(set_split_cache_by_network_isolation_key,
- cache->key_server_entries_by_network_isolation_key());
- // The server credentials should have been deleted.
- EXPECT_FALSE(cache->Lookup(
- kSchemeHostPort, net::HttpAuth::AUTH_SERVER, challenge.realm,
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey()));
- // The proxy credentials should still be in the cache.
- net::HttpAuthCache::Entry* entry = cache->Lookup(
- kSchemeHostPort, net::HttpAuth::AUTH_PROXY, challenge.realm,
- net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey());
- ASSERT_TRUE(entry);
- EXPECT_EQ(kProxyUsername, entry->credentials().username());
- EXPECT_EQ(kProxyPassword, entry->credentials().password());
- }
- }
- TEST_F(NetworkContextTest, HSTSPolicyBypassList) {
- // The default test preload list includes "example" as a preloaded TLD
- // (including subdomains).
- net::ScopedTransportSecurityStateSource scoped_security_state_source;
- mojom::NetworkContextParamsPtr params =
- CreateNetworkContextParamsForTesting();
- params->hsts_policy_bypass_list.push_back("example");
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- net::TransportSecurityState* transport_security_state =
- network_context->url_request_context()->transport_security_state();
- // With the policy set, example should no longer upgrade to HTTPS.
- EXPECT_FALSE(transport_security_state->ShouldUpgradeToSSL("example"));
- // But the policy shouldn't apply to subdomains.
- EXPECT_TRUE(transport_security_state->ShouldUpgradeToSSL("sub.example"));
- }
- TEST_F(NetworkContextTest, FactoriesDeletedWhenBindingsCleared) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- auto loader_params = mojom::URLLoaderFactoryParams::New();
- loader_params->process_id = 1;
- mojo::Remote<mojom::URLLoaderFactory> remote1;
- network_context->CreateURLLoaderFactory(remote1.BindNewPipeAndPassReceiver(),
- std::move(loader_params));
- loader_params = mojom::URLLoaderFactoryParams::New();
- loader_params->process_id = 1;
- mojo::Remote<mojom::URLLoaderFactory> remote2;
- network_context->CreateURLLoaderFactory(remote2.BindNewPipeAndPassReceiver(),
- std::move(loader_params));
- // We should have at least 2 loader factories.
- EXPECT_GT(network_context->num_url_loader_factories_for_testing(), 1u);
- network_context->ResetURLLoaderFactories();
- EXPECT_EQ(network_context->num_url_loader_factories_for_testing(), 0u);
- }
- static ResourceRequest CreateResourceRequest(const char* method,
- const GURL& url) {
- ResourceRequest request;
- request.method = std::string(method);
- request.url = url;
- request.request_initiator =
- url::Origin::Create(url); // ensure initiator is set
- return request;
- }
- class NetworkContextSplitCacheTest : public NetworkContextTest {
- protected:
- NetworkContextSplitCacheTest() {
- feature_list_.InitAndEnableFeature(
- net::features::kSplitCacheByNetworkIsolationKey);
- test_server_.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("services/test/data")));
- EXPECT_TRUE(test_server_.Start());
- // Set up a scoped host resolver to access other origins.
- scoped_refptr<net::RuleBasedHostResolverProc> mock_resolver_proc =
- base::MakeRefCounted<net::RuleBasedHostResolverProc>(nullptr);
- mock_resolver_proc->AddRule("*", "127.0.0.1");
- mock_host_resolver_ = std::make_unique<net::ScopedDefaultHostResolverProc>(
- mock_resolver_proc.get());
- mojom::NetworkContextParamsPtr context_params =
- CreateNetworkContextParamsForTesting();
- network_context_ = CreateContextWithParams(std::move(context_params));
- }
- net::EmbeddedTestServer* test_server() { return &test_server_; }
- void LoadAndVerifyCached(const GURL& url,
- const net::IsolationInfo& isolation_info,
- bool was_cached,
- bool expect_redirect = false,
- absl::optional<GURL> new_url = absl::nullopt,
- bool automatically_assign_isolation_info = false) {
- ResourceRequest request = CreateResourceRequest("GET", url);
- request.load_flags |= net::LOAD_SKIP_CACHE_VALIDATION;
- mojo::Remote<mojom::URLLoaderFactory> loader_factory;
- auto params = mojom::URLLoaderFactoryParams::New();
- params->process_id = mojom::kBrowserProcessId;
- params->is_corb_enabled = false;
- if (isolation_info.request_type() ==
- net::IsolationInfo::RequestType::kOther) {
- params->isolation_info = isolation_info;
- } else {
- request.trusted_params = ResourceRequest::TrustedParams();
- request.trusted_params->isolation_info = isolation_info;
- params->is_trusted = true;
- // These params must be individually set, to be consistent with the
- // IsolationInfo if its request type is a main frame navigation.
- // TODO(crbug.com/1172314): Unify these to avoid inconsistencies.
- if (isolation_info.request_type() ==
- net::IsolationInfo::RequestType::kMainFrame) {
- request.is_outermost_main_frame = true;
- request.update_first_party_url_on_redirect = true;
- }
- }
- params->automatically_assign_isolation_info =
- automatically_assign_isolation_info;
- request.site_for_cookies = isolation_info.site_for_cookies();
- network_context_->CreateURLLoaderFactory(
- loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
- auto client = std::make_unique<TestURLLoaderClient>();
- mojo::Remote<mojom::URLLoader> loader;
- loader_factory->CreateLoaderAndStart(
- loader.BindNewPipeAndPassReceiver(), 0 /* request_id */,
- mojom::kURLLoadOptionNone, request, client->CreateRemote(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- if (expect_redirect) {
- client->RunUntilRedirectReceived();
- loader->FollowRedirect({}, {}, {}, new_url);
- client->ClearHasReceivedRedirect();
- }
- if (new_url) {
- client->RunUntilRedirectReceived();
- loader->FollowRedirect({}, {}, {}, absl::nullopt);
- }
- client->RunUntilComplete();
- EXPECT_EQ(net::OK, client->completion_status().error_code);
- EXPECT_EQ(was_cached, client->completion_status().exists_in_cache);
- }
- private:
- base::test::ScopedFeatureList feature_list_;
- net::EmbeddedTestServer test_server_;
- std::unique_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_;
- std::unique_ptr<NetworkContext> network_context_;
- };
- TEST_F(NetworkContextSplitCacheTest, CachedUsingNetworkIsolationKey) {
- GURL url = test_server()->GetURL("/resource");
- url::Origin origin_a = url::Origin::Create(GURL("http://a.test/"));
- net::IsolationInfo info_a =
- net::IsolationInfo::CreateForInternalRequest(origin_a);
- LoadAndVerifyCached(url, info_a, false /* was_cached */);
- // Load again with a different isolation key. The cached entry should not be
- // loaded.
- url::Origin origin_b = url::Origin::Create(GURL("http://b.test/"));
- net::IsolationInfo info_b =
- net::IsolationInfo::CreateForInternalRequest(origin_b);
- LoadAndVerifyCached(url, info_b, false /* was_cached */);
- // Load again with the same isolation key. The cached entry should be loaded.
- LoadAndVerifyCached(url, info_b, true /* was_cached */);
- }
- TEST_F(NetworkContextSplitCacheTest,
- NavigationResourceCachedUsingNetworkIsolationKey) {
- GURL url = test_server()->GetURL("othersite.test", "/main.html");
- url::Origin origin_a = url::Origin::Create(url);
- net::IsolationInfo info_a =
- net::IsolationInfo::Create(net::IsolationInfo::RequestType::kSubFrame,
- origin_a, origin_a, net::SiteForCookies());
- LoadAndVerifyCached(url, info_a, false /* was_cached */);
- // Load again with a different isolation key. The cached entry should not be
- // loaded.
- GURL url_b = test_server()->GetURL("/main.html");
- url::Origin origin_b = url::Origin::Create(url_b);
- net::IsolationInfo info_b =
- net::IsolationInfo::Create(net::IsolationInfo::RequestType::kSubFrame,
- origin_b, origin_b, net::SiteForCookies());
- LoadAndVerifyCached(url_b, info_b, false /* was_cached */);
- // Load again with the same isolation key. The cached entry should be loaded.
- LoadAndVerifyCached(url_b, info_b, true /* was_cached */);
- }
- TEST_F(NetworkContextSplitCacheTest,
- CachedUsingNetworkIsolationKeyWithFrameOrigin) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- net::features::kSplitCacheByNetworkIsolationKey);
- GURL url = test_server()->GetURL("/resource");
- url::Origin origin_a = url::Origin::Create(GURL("http://a.test/"));
- net::IsolationInfo info_a =
- net::IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
- origin_a, origin_a, net::SiteForCookies());
- LoadAndVerifyCached(url, info_a, false /* was_cached */);
- // Load again with a different isolation key. The cached entry should not be
- // loaded.
- url::Origin origin_b = url::Origin::Create(GURL("http://b.test/"));
- net::IsolationInfo info_b =
- net::IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
- origin_a, origin_b, net::SiteForCookies());
- LoadAndVerifyCached(url, info_b, false /* was_cached */);
- }
- TEST_F(NetworkContextSplitCacheTest,
- NavigationResourceRedirectNetworkIsolationKey) {
- // Create a request that redirects.
- GURL url = test_server()->GetURL(
- "/server-redirect?" +
- test_server()->GetURL("othersite.test", "/title1.html").spec());
- url::Origin origin = url::Origin::Create(url);
- net::IsolationInfo info = net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kMainFrame, origin, origin,
- net::SiteForCookies::FromOrigin(origin));
- LoadAndVerifyCached(url, info, false /* was_cached */,
- true /* expect_redirect */);
- // Now directly load with the key using the redirected URL. This should be a
- // cache hit.
- GURL redirected_url = test_server()->GetURL("othersite.test", "/title1.html");
- url::Origin redirected_origin = url::Origin::Create(redirected_url);
- LoadAndVerifyCached(redirected_url, info.CreateForRedirect(redirected_origin),
- true /* was_cached */);
- // A non-navigation resource with the same key and url should also be cached.
- net::IsolationInfo non_navigation_redirected_info =
- net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, redirected_origin,
- redirected_origin,
- net::SiteForCookies::FromOrigin(redirected_origin));
- LoadAndVerifyCached(redirected_url, non_navigation_redirected_info,
- true /* was_cached */);
- }
- TEST_F(NetworkContextSplitCacheTest, AutomaticallyAssignIsolationInfo) {
- GURL url = test_server()->GetURL("/resource");
- // Load with an automatically assigned IsolationInfo, which should populate
- // the cache using the IsolationInfo for |url|'s origin.
- LoadAndVerifyCached(url, net::IsolationInfo(), false /* was_cached */,
- false /* expect_redirect */, absl::nullopt /* new_url */,
- true /* automatically_assign_isolation_info */);
- // Load again with a different isolation info. The cached entry should not be
- // loaded.
- url::Origin other_origin = url::Origin::Create(GURL("http://other.test/"));
- net::IsolationInfo other_info =
- net::IsolationInfo::CreateForInternalRequest(other_origin);
- LoadAndVerifyCached(url, other_info, false /* was_cached */);
- // Load explicitly using the requested URL's own IsolationInfo, which should
- // use the cached entry.
- url::Origin origin = url::Origin::Create(GURL(url));
- net::IsolationInfo info =
- net::IsolationInfo::CreateForInternalRequest(origin);
- LoadAndVerifyCached(url, info, true /* was_cached */);
- }
- TEST_F(NetworkContextTest, EnableTrustTokens) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- EXPECT_TRUE(network_context->trust_token_store());
- base::RunLoop run_loop;
- bool success = false;
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- success = !!store;
- run_loop.Quit();
- }));
- run_loop.Run();
- EXPECT_TRUE(success);
- }
- TEST_F(NetworkContextTestWithMockTime, EnableTrustTokensWithStoreOnDisk) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- base::ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- base::FilePath database_name(FILE_PATH_LITERAL("my_token_store"));
- {
- auto params = CreateNetworkContextParamsForTesting();
- params->file_paths = mojom::NetworkContextFilePaths::New();
- params->file_paths->data_directory = dir.GetPath();
- params->file_paths->trust_token_database_name = database_name;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- base::RunLoop run_loop;
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- DCHECK(store);
- store->AddTokens(*SuitableTrustTokenOrigin::Create(
- GURL("https://trusttoken.com/")),
- std::vector<std::string>{"token"}, "issuing key");
- run_loop.Quit();
- }));
- // Allow the store time to initialize asynchronously and execute the
- // operation.
- run_loop.Run();
- // Allow the write time to propagate to disk.
- task_environment_.FastForwardBy(2 * kTrustTokenWriteBufferingWindow);
- }
- // Allow the context's backing store time to be torn down asynchronously.
- task_environment_.RunUntilIdle();
- {
- auto params = CreateNetworkContextParamsForTesting();
- params->file_paths = mojom::NetworkContextFilePaths::New();
- params->file_paths->data_directory = dir.GetPath();
- params->file_paths->trust_token_database_name = database_name;
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(std::move(params));
- base::RunLoop run_loop;
- absl::optional<int> obtained_num_tokens;
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting(
- [&obtained_num_tokens, &run_loop](TrustTokenStore* store) {
- DCHECK(store);
- obtained_num_tokens =
- store->CountTokens(*SuitableTrustTokenOrigin::Create(
- GURL("https://trusttoken.com/")));
- run_loop.Quit();
- }));
- // Allow the store time to initialize asynchronously.
- run_loop.Run();
- EXPECT_THAT(obtained_num_tokens, Optional(1));
- }
- // Allow the context's backing store time to be destroyed asynchronously.
- task_environment_.RunUntilIdle();
- }
- TEST_F(NetworkContextTest, DisableTrustTokens) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(network_context->trust_token_store());
- }
- class NetworkContextExpectBadMessageTest : public NetworkContextTest {
- public:
- NetworkContextExpectBadMessageTest() {
- mojo::SetDefaultProcessErrorHandler(
- base::BindLambdaForTesting([&](const std::string&) {
- EXPECT_FALSE(got_bad_message_);
- got_bad_message_ = true;
- }));
- }
- ~NetworkContextExpectBadMessageTest() override {
- mojo::SetDefaultProcessErrorHandler(base::NullCallback());
- }
- protected:
- void AssertBadMessage() { EXPECT_TRUE(got_bad_message_); }
- bool got_bad_message_ = false;
- };
- TEST_F(NetworkContextExpectBadMessageTest,
- FailsTrustTokenBearingRequestWhenTrustTokensIsDisabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(network_context->trust_token_store());
- ResourceRequest my_request;
- my_request.request_initiator =
- url::Origin::Create(GURL("https://initiator.com"));
- my_request.trust_token_params =
- OptionalTrustTokenParams(mojom::TrustTokenParams::New());
- std::unique_ptr<TestURLLoaderClient> client =
- FetchRequest(my_request, network_context.get());
- AssertBadMessage();
- }
- TEST_F(NetworkContextExpectBadMessageTest,
- FailsTrustTokenRedemptionWhenForbidden) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow |network_context|'s Trust Tokens store time to initialize
- // asynchronously, if necessary.
- task_environment_.RunUntilIdle();
- ASSERT_TRUE(network_context->trust_token_store());
- ResourceRequest my_request;
- my_request.trust_token_params =
- OptionalTrustTokenParams(mojom::TrustTokenParams::New());
- my_request.trust_token_params->type =
- mojom::TrustTokenOperationType::kRedemption;
- auto factory_params = mojom::URLLoaderFactoryParams::New();
- factory_params->trust_token_redemption_policy =
- mojom::TrustTokenRedemptionPolicy::kForbid;
- std::unique_ptr<TestURLLoaderClient> client =
- FetchRequest(my_request, network_context.get(), mojom::kURLLoadOptionNone,
- mojom::kBrowserProcessId, std::move(factory_params));
- AssertBadMessage();
- }
- TEST_F(NetworkContextExpectBadMessageTest,
- FailsTrustTokenSigningWhenForbidden) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow |network_context|'s Trust Tokens store time to initialize
- // asynchronously, if necessary.
- task_environment_.RunUntilIdle();
- ASSERT_TRUE(network_context->trust_token_store());
- ResourceRequest my_request;
- my_request.trust_token_params =
- OptionalTrustTokenParams(mojom::TrustTokenParams::New());
- my_request.trust_token_params->type =
- mojom::TrustTokenOperationType::kSigning;
- auto factory_params = mojom::URLLoaderFactoryParams::New();
- factory_params->trust_token_redemption_policy =
- mojom::TrustTokenRedemptionPolicy::kForbid;
- std::unique_ptr<TestURLLoaderClient> client =
- FetchRequest(my_request, network_context.get(), mojom::kURLLoadOptionNone,
- mojom::kBrowserProcessId, std::move(factory_params));
- AssertBadMessage();
- }
- TEST_F(NetworkContextTest,
- AttemptsTrustTokenBearingRequestWhenTrustTokensIsEnabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- task_environment_.RunUntilIdle();
- ResourceRequest my_request;
- my_request.trust_token_params =
- OptionalTrustTokenParams(mojom::TrustTokenParams::New());
- // Since the request doesn't have a destination URL suitable for use as a
- // Trust Tokens issuer, it should fail.
- std::unique_ptr<TestURLLoaderClient> client = FetchRequest(
- my_request, network_context.get(), mojom::kURLLoadOptionNone,
- mojom::kBrowserProcessId, mojom::URLLoaderFactoryParams::New());
- EXPECT_EQ(client->completion_status().error_code,
- net::ERR_TRUST_TOKEN_OPERATION_FAILED);
- EXPECT_EQ(client->completion_status().trust_token_operation_status,
- mojom::TrustTokenOperationStatus::kInvalidArgument);
- }
- TEST_F(NetworkContextTest,
- RejectsTrustTokenBearingRequestWhenThirdPartyCookiesAreDisabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- base::RunLoop run_loop;
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting(
- [&run_loop](TrustTokenStore* unused) { run_loop.Quit(); }));
- run_loop.Run();
- network_context->cookie_manager()->BlockThirdPartyCookies(true);
- ResourceRequest my_request;
- my_request.trust_token_params =
- OptionalTrustTokenParams(mojom::TrustTokenParams::New());
- std::unique_ptr<TestURLLoaderClient> client = FetchRequest(
- my_request, network_context.get(), mojom::kURLLoadOptionNone,
- mojom::kBrowserProcessId, mojom::URLLoaderFactoryParams::New());
- EXPECT_EQ(client->completion_status().error_code,
- net::ERR_TRUST_TOKEN_OPERATION_FAILED);
- EXPECT_EQ(client->completion_status().trust_token_operation_status,
- mojom::TrustTokenOperationStatus::kUnavailable);
- }
- TEST_F(NetworkContextTest, NoAvailableTrustTokensWhenTrustTokensAreDisabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- base::RunLoop run_loop;
- absl::optional<std::vector<mojom::StoredTrustTokensForIssuerPtr>>
- trust_tokens;
- network_context->GetStoredTrustTokenCounts(base::BindLambdaForTesting(
- [&trust_tokens,
- &run_loop](std::vector<mojom::StoredTrustTokensForIssuerPtr> tokens) {
- trust_tokens = std::move(tokens);
- run_loop.Quit();
- }));
- run_loop.Run();
- ASSERT_TRUE(trust_tokens.has_value());
- EXPECT_TRUE(trust_tokens->empty());
- }
- TEST_F(NetworkContextTest, GetStoredTrustTokens) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- // Query Trust Tokens before adding the mock token.
- absl::optional<std::vector<mojom::StoredTrustTokensForIssuerPtr>>
- trust_tokens_before_adding;
- network_context->GetStoredTrustTokenCounts(base::BindLambdaForTesting(
- [&](std::vector<mojom::StoredTrustTokensForIssuerPtr> tokens) {
- trust_tokens_before_adding = std::move(tokens);
- }));
- // Add a mock token.
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- DCHECK(store);
- store->AddTokens(
- *SuitableTrustTokenOrigin::Create(GURL("https://trusttoken.com")),
- std::vector<std::string>{"token"}, "issuing key");
- }));
- // Query Trust Tokens after adding the mock token.
- absl::optional<std::vector<mojom::StoredTrustTokensForIssuerPtr>>
- trust_tokens_after_adding;
- network_context->GetStoredTrustTokenCounts(base::BindLambdaForTesting(
- [&](std::vector<mojom::StoredTrustTokensForIssuerPtr> tokens) {
- trust_tokens_after_adding = std::move(tokens);
- run_loop.Quit();
- }));
- // Allow the store time to initialize asynchronously and execute the
- // operations.
- run_loop.Run();
- ASSERT_TRUE(trust_tokens_before_adding.has_value());
- EXPECT_EQ(trust_tokens_before_adding->size(), 0ul);
- ASSERT_TRUE(trust_tokens_after_adding.has_value());
- ASSERT_EQ(trust_tokens_after_adding->size(), 1ul);
- EXPECT_EQ(trust_tokens_after_adding.value()[0]->issuer.Serialize(),
- "https://trusttoken.com");
- }
- TEST_F(NetworkContextTest, GetStoredTrustTokensReentrant) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Add a mock token.
- base::RunLoop run_loop;
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- DCHECK(store);
- store->AddTokens(
- *SuitableTrustTokenOrigin::Create(GURL("https://trusttoken.com")),
- std::vector<std::string>{"token"}, "issuing key");
- }));
- absl::optional<std::vector<mojom::StoredTrustTokensForIssuerPtr>>
- trust_tokens;
- absl::optional<std::vector<mojom::StoredTrustTokensForIssuerPtr>>
- reentrant_trust_tokens;
- network_context->GetStoredTrustTokenCounts(base::BindLambdaForTesting(
- [&](std::vector<mojom::StoredTrustTokensForIssuerPtr> tokens) {
- network_context->GetStoredTrustTokenCounts(base::BindLambdaForTesting(
- [&](std::vector<mojom::StoredTrustTokensForIssuerPtr> tokens) {
- reentrant_trust_tokens = std::move(tokens);
- run_loop.Quit();
- }));
- trust_tokens = std::move(tokens);
- }));
- // Allow the store time to initialize asynchronously and execute the
- // operations.
- run_loop.Run();
- ASSERT_TRUE(trust_tokens.has_value());
- ASSERT_TRUE(reentrant_trust_tokens.has_value());
- EXPECT_EQ(trust_tokens->size(), reentrant_trust_tokens->size());
- EXPECT_EQ(trust_tokens.value()[0]->issuer,
- reentrant_trust_tokens.value()[0]->issuer);
- EXPECT_EQ(trust_tokens.value()[0]->count,
- reentrant_trust_tokens.value()[0]->count);
- }
- TEST_F(NetworkContextTest,
- DeleteStoredTrustTokensReportsErrorWhenFeatureIsDisabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- base::RunLoop run_loop;
- absl::optional<mojom::DeleteStoredTrustTokensStatus> actual_status;
- network_context->DeleteStoredTrustTokens(
- url::Origin::Create(GURL("https://example.com")),
- base::BindLambdaForTesting(
- [&](mojom::DeleteStoredTrustTokensStatus status) {
- actual_status = status;
- run_loop.Quit();
- }));
- run_loop.Run();
- EXPECT_THAT(
- actual_status,
- Optional(mojom::DeleteStoredTrustTokensStatus::kFailureFeatureDisabled));
- }
- TEST_F(NetworkContextTest,
- DeleteStoredTrustTokensReportsErrorWithInvalidOrigin) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- // Allow the store time to initialize asynchronously.
- base::RunLoop run_loop;
- absl::optional<mojom::DeleteStoredTrustTokensStatus> actual_status;
- network_context->DeleteStoredTrustTokens(
- url::Origin::Create(GURL("ws://example.com")),
- base::BindLambdaForTesting(
- [&](mojom::DeleteStoredTrustTokensStatus status) {
- actual_status = status;
- run_loop.Quit();
- }));
- run_loop.Run();
- EXPECT_THAT(
- actual_status,
- Optional(mojom::DeleteStoredTrustTokensStatus::kFailureInvalidOrigin));
- }
- TEST_F(NetworkContextTest, DeleteStoredTrustTokens) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- const SuitableTrustTokenOrigin issuer_origin_to_delete =
- *SuitableTrustTokenOrigin::Create(GURL("https://trusttoken-delete.com"));
- const SuitableTrustTokenOrigin issuer_origin_to_keep =
- *SuitableTrustTokenOrigin::Create(GURL("https://trusttoken-keep.com"));
- // Add two mock tokens from different issuers.
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- DCHECK(store);
- store->AddTokens(issuer_origin_to_delete,
- std::vector<std::string>{"token"}, "issuing key");
- store->AddTokens(issuer_origin_to_keep,
- std::vector<std::string>{"token"}, "issuing key");
- ASSERT_EQ(store->GetStoredTrustTokenCounts().size(), 2ul);
- }));
- // Delete all Trust Tokens for one of the issuers.
- absl::optional<mojom::DeleteStoredTrustTokensStatus> delete_status;
- network_context->DeleteStoredTrustTokens(
- issuer_origin_to_delete.origin(),
- base::BindLambdaForTesting(
- [&](mojom::DeleteStoredTrustTokensStatus status) {
- delete_status = status;
- }));
- // Query Trust Tokens after deleting one of the mock token.
- absl::optional<base::flat_map<SuitableTrustTokenOrigin, int>> trust_tokens;
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- trust_tokens = store->GetStoredTrustTokenCounts();
- run_loop.Quit();
- }));
- // Allow the store time to initialize asynchronously and execute the
- // operations.
- run_loop.Run();
- EXPECT_THAT(
- delete_status,
- Optional(mojom::DeleteStoredTrustTokensStatus::kSuccessTokensDeleted));
- ASSERT_TRUE(trust_tokens->contains(issuer_origin_to_keep));
- EXPECT_EQ(trust_tokens->at(issuer_origin_to_keep), 1);
- }
- TEST_F(NetworkContextTest, DeleteStoredTrustTokensReentrant) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTrustTokens);
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- base::RunLoop run_loop;
- const SuitableTrustTokenOrigin issuer_origin_foo =
- *SuitableTrustTokenOrigin::Create(GURL("https://trusttoken-foo.com"));
- const SuitableTrustTokenOrigin issuer_origin_bar =
- *SuitableTrustTokenOrigin::Create(GURL("https://trusttoken-bar.com"));
- // Add two mock tokens from different issuers.
- network_context->trust_token_store()->ExecuteOrEnqueue(
- base::BindLambdaForTesting([&](TrustTokenStore* store) {
- DCHECK(store);
- store->AddTokens(issuer_origin_foo, std::vector<std::string>{"token"},
- "issuing key");
- store->AddTokens(issuer_origin_bar, std::vector<std::string>{"token"},
- "issuing key");
- ASSERT_EQ(store->GetStoredTrustTokenCounts().size(), 2ul);
- }));
- // Delete all Trust Tokens for both issuers simultaneously.
- absl::optional<mojom::DeleteStoredTrustTokensStatus> delete_status_foo;
- absl::optional<mojom::DeleteStoredTrustTokensStatus> delete_status_bar;
- network_context->DeleteStoredTrustTokens(
- issuer_origin_foo.origin(),
- base::BindLambdaForTesting(
- [&](mojom::DeleteStoredTrustTokensStatus status) {
- delete_status_foo = status;
- network_context->DeleteStoredTrustTokens(
- issuer_origin_bar,
- base::BindLambdaForTesting(
- [&](mojom::DeleteStoredTrustTokensStatus status) {
- delete_status_bar = status;
- run_loop.Quit();
- }));
- }));
- // Allow the store time to initialize asynchronously and execute the
- // operations.
- run_loop.Run();
- EXPECT_THAT(
- delete_status_foo,
- Optional(mojom::DeleteStoredTrustTokensStatus::kSuccessTokensDeleted));
- EXPECT_THAT(
- delete_status_bar,
- Optional(mojom::DeleteStoredTrustTokensStatus::kSuccessTokensDeleted));
- }
- TEST_F(NetworkContextTest, HttpAuthUrlFilter) {
- std::unique_ptr<NetworkContext> network_context =
- CreateContextWithParams(CreateNetworkContextParamsForTesting());
- const GURL kGoogle("https://www.google.com");
- const GURL kGoogleSubdomain("https://subdomain.google.com");
- const GURL kBlocked("https://www.blocked.com");
- auto is_url_allowed_to_use_auth_schemes =
- [&network_context](const GURL& url) {
- return network_context->GetHttpAuthPreferences()
- ->IsAllowedToUseAllHttpAuthSchemes(url::SchemeHostPort(url));
- };
- network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
- network::mojom::HttpAuthDynamicParams::New();
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogle));
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogleSubdomain));
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kBlocked));
- auth_dynamic_params->patterns_allowed_to_use_all_schemes =
- std::vector<std::string>{"subdomain.google.com"};
- network_context->OnHttpAuthDynamicParamsChanged(auth_dynamic_params.get());
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kGoogle));
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogleSubdomain));
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(
- GURL("https://subdomain.blocked.com")));
- auth_dynamic_params->patterns_allowed_to_use_all_schemes =
- std::vector<std::string>{};
- network_context->OnHttpAuthDynamicParamsChanged(auth_dynamic_params.get());
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kGoogle));
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kGoogleSubdomain));
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kBlocked));
- auth_dynamic_params->patterns_allowed_to_use_all_schemes =
- std::vector<std::string>{"google.com"};
- network_context->OnHttpAuthDynamicParamsChanged(auth_dynamic_params.get());
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogle));
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogleSubdomain));
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kBlocked));
- auth_dynamic_params->patterns_allowed_to_use_all_schemes =
- std::vector<std::string>{"https://google.com/path"};
- network_context->OnHttpAuthDynamicParamsChanged(auth_dynamic_params.get());
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kGoogle));
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kGoogleSubdomain));
- EXPECT_FALSE(is_url_allowed_to_use_auth_schemes(kBlocked));
- auth_dynamic_params->patterns_allowed_to_use_all_schemes =
- std::vector<std::string>{"*"};
- network_context->OnHttpAuthDynamicParamsChanged(auth_dynamic_params.get());
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogle));
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kGoogleSubdomain));
- EXPECT_TRUE(is_url_allowed_to_use_auth_schemes(kBlocked));
- }
- } // namespace
- } // namespace network
|