spdy_network_transaction_unittest.cc 437 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <cmath>
  5. #include <utility>
  6. #include <vector>
  7. #include "base/bind.h"
  8. #include "base/callback_helpers.h"
  9. #include "base/files/file_util.h"
  10. #include "base/files/scoped_temp_dir.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/run_loop.h"
  13. #include "base/strings/string_number_conversions.h"
  14. #include "base/strings/string_piece.h"
  15. #include "base/test/metrics/histogram_tester.h"
  16. #include "base/test/scoped_feature_list.h"
  17. #include "base/test/test_file_util.h"
  18. #include "base/threading/thread_task_runner_handle.h"
  19. #include "build/build_config.h"
  20. #include "net/base/auth.h"
  21. #include "net/base/chunked_upload_data_stream.h"
  22. #include "net/base/completion_once_callback.h"
  23. #include "net/base/elements_upload_data_stream.h"
  24. #include "net/base/features.h"
  25. #include "net/base/ip_endpoint.h"
  26. #include "net/base/network_isolation_key.h"
  27. #include "net/base/proxy_delegate.h"
  28. #include "net/base/proxy_server.h"
  29. #include "net/base/proxy_string_util.h"
  30. #include "net/base/request_priority.h"
  31. #include "net/base/schemeful_site.h"
  32. #include "net/base/test_proxy_delegate.h"
  33. #include "net/base/upload_bytes_element_reader.h"
  34. #include "net/base/upload_file_element_reader.h"
  35. #include "net/dns/mock_host_resolver.h"
  36. #include "net/dns/public/secure_dns_policy.h"
  37. #include "net/http/http_auth_scheme.h"
  38. #include "net/http/http_network_session.h"
  39. #include "net/http/http_network_session_peer.h"
  40. #include "net/http/http_network_transaction.h"
  41. #include "net/http/http_proxy_connect_job.h"
  42. #include "net/http/http_response_info.h"
  43. #include "net/http/http_server_properties.h"
  44. #include "net/http/http_transaction_test_util.h"
  45. #include "net/http/test_upload_data_stream_not_allow_http1.h"
  46. #include "net/http/transport_security_state.h"
  47. #include "net/log/net_log_event_type.h"
  48. #include "net/log/net_log_with_source.h"
  49. #include "net/log/test_net_log.h"
  50. #include "net/log/test_net_log_util.h"
  51. #include "net/proxy_resolution/configured_proxy_resolution_service.h"
  52. #include "net/socket/next_proto.h"
  53. #include "net/socket/socket_tag.h"
  54. #include "net/spdy/alps_decoder.h"
  55. #include "net/spdy/buffered_spdy_framer.h"
  56. #include "net/spdy/spdy_http_stream.h"
  57. #include "net/spdy/spdy_http_utils.h"
  58. #include "net/spdy/spdy_session.h"
  59. #include "net/spdy/spdy_session_pool.h"
  60. #include "net/spdy/spdy_test_util_common.h"
  61. #include "net/ssl/ssl_connection_status_flags.h"
  62. #include "net/test/cert_test_util.h"
  63. #include "net/test/gtest_util.h"
  64. #include "net/test/test_data_directory.h"
  65. #include "net/test/test_with_task_environment.h"
  66. #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
  67. #include "net/third_party/quiche/src/quiche/spdy/test_tools/spdy_test_utils.h"
  68. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  69. #include "net/url_request/url_request_context.h"
  70. #include "net/url_request/url_request_context_builder.h"
  71. #include "net/url_request/url_request_test_util.h"
  72. #include "net/websockets/websocket_test_util.h"
  73. #include "testing/gmock/include/gmock/gmock.h"
  74. #include "testing/platform_test.h"
  75. #include "url/gurl.h"
  76. using net::test::IsError;
  77. using net::test::IsOk;
  78. //-----------------------------------------------------------------------------
  79. namespace net {
  80. namespace {
  81. using testing::Each;
  82. using testing::Eq;
  83. const int32_t kBufferSize = SpdyHttpStream::kRequestBodyBufferSize;
  84. } // namespace
  85. const char kPushedUrl[] = "https://www.example.org/foo.dat";
  86. class SpdyNetworkTransactionTest : public TestWithTaskEnvironment {
  87. protected:
  88. SpdyNetworkTransactionTest()
  89. : TestWithTaskEnvironment(
  90. base::test::TaskEnvironment::TimeSource::MOCK_TIME),
  91. default_url_(kDefaultUrl),
  92. host_port_pair_(HostPortPair::FromURL(default_url_)) {}
  93. ~SpdyNetworkTransactionTest() override {
  94. // UploadDataStream may post a deletion task back to the message loop on
  95. // destruction.
  96. upload_data_stream_.reset();
  97. base::RunLoop().RunUntilIdle();
  98. }
  99. void SetUp() override {
  100. request_.method = "GET";
  101. request_.url = GURL(kDefaultUrl);
  102. request_.traffic_annotation =
  103. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  104. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  105. }
  106. struct TransactionHelperResult {
  107. int rv;
  108. std::string status_line;
  109. std::string response_data;
  110. HttpResponseInfo response_info;
  111. };
  112. // A helper class that handles all the initial npn/ssl setup.
  113. class NormalSpdyTransactionHelper {
  114. public:
  115. NormalSpdyTransactionHelper(
  116. const HttpRequestInfo& request,
  117. RequestPriority priority,
  118. const NetLogWithSource& log,
  119. std::unique_ptr<SpdySessionDependencies> session_deps)
  120. : request_(request),
  121. priority_(priority),
  122. session_deps_(session_deps.get() == nullptr
  123. ? std::make_unique<SpdySessionDependencies>()
  124. : std::move(session_deps)),
  125. log_(log) {
  126. session_deps_->net_log = log.net_log();
  127. session_ =
  128. SpdySessionDependencies::SpdyCreateSession(session_deps_.get());
  129. }
  130. ~NormalSpdyTransactionHelper() {
  131. // Any test which doesn't close the socket by sending it an EOF will
  132. // have a valid session left open, which leaks the entire session pool.
  133. // This is just fine - in fact, some of our tests intentionally do this
  134. // so that we can check consistency of the SpdySessionPool as the test
  135. // finishes. If we had put an EOF on the socket, the SpdySession would
  136. // have closed and we wouldn't be able to check the consistency.
  137. // Forcefully close existing sessions here.
  138. session()->spdy_session_pool()->CloseAllSessions();
  139. }
  140. void RunPreTestSetup() {
  141. // We're now ready to use SSL-npn SPDY.
  142. trans_ =
  143. std::make_unique<HttpNetworkTransaction>(priority_, session_.get());
  144. }
  145. // Start the transaction, read some data, finish.
  146. void RunDefaultTest() {
  147. if (!StartDefaultTest())
  148. return;
  149. FinishDefaultTest();
  150. }
  151. bool StartDefaultTest() {
  152. output_.rv = trans_->Start(&request_, callback_.callback(), log_);
  153. // We expect an IO Pending or some sort of error.
  154. EXPECT_LT(output_.rv, 0);
  155. return output_.rv == ERR_IO_PENDING;
  156. }
  157. void FinishDefaultTest() {
  158. output_.rv = callback_.WaitForResult();
  159. // Finish async network reads/writes.
  160. base::RunLoop().RunUntilIdle();
  161. if (output_.rv != OK) {
  162. session_->spdy_session_pool()->CloseCurrentSessions(ERR_ABORTED);
  163. return;
  164. }
  165. // Verify responses.
  166. const HttpResponseInfo* response = trans_->GetResponseInfo();
  167. ASSERT_TRUE(response);
  168. ASSERT_TRUE(response->headers);
  169. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  170. response->connection_info);
  171. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  172. EXPECT_TRUE(response->was_fetched_via_spdy);
  173. EXPECT_TRUE(response->was_alpn_negotiated);
  174. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  175. EXPECT_EQ(443, response->remote_endpoint.port());
  176. output_.status_line = response->headers->GetStatusLine();
  177. output_.response_info = *response; // Make a copy so we can verify.
  178. output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
  179. }
  180. void FinishDefaultTestWithoutVerification() {
  181. output_.rv = callback_.WaitForResult();
  182. // Finish async network reads/writes.
  183. base::RunLoop().RunUntilIdle();
  184. if (output_.rv != OK)
  185. session_->spdy_session_pool()->CloseCurrentSessions(ERR_ABORTED);
  186. }
  187. void WaitForCallbackToComplete() { output_.rv = callback_.WaitForResult(); }
  188. // Most tests will want to call this function. In particular, the MockReads
  189. // should end with an empty read, and that read needs to be processed to
  190. // ensure proper deletion of the spdy_session_pool.
  191. void VerifyDataConsumed() {
  192. for (const SocketDataProvider* provider : data_vector_) {
  193. EXPECT_TRUE(provider->AllReadDataConsumed());
  194. EXPECT_TRUE(provider->AllWriteDataConsumed());
  195. }
  196. }
  197. // Occasionally a test will expect to error out before certain reads are
  198. // processed. In that case we want to explicitly ensure that the reads were
  199. // not processed.
  200. void VerifyDataNotConsumed() {
  201. for (const SocketDataProvider* provider : data_vector_) {
  202. EXPECT_FALSE(provider->AllReadDataConsumed());
  203. EXPECT_FALSE(provider->AllWriteDataConsumed());
  204. }
  205. }
  206. void RunToCompletion(SocketDataProvider* data) {
  207. RunPreTestSetup();
  208. AddData(data);
  209. RunDefaultTest();
  210. VerifyDataConsumed();
  211. }
  212. void RunToCompletionWithSSLData(
  213. SocketDataProvider* data,
  214. std::unique_ptr<SSLSocketDataProvider> ssl_provider) {
  215. RunPreTestSetup();
  216. AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider));
  217. RunDefaultTest();
  218. VerifyDataConsumed();
  219. }
  220. void AddData(SocketDataProvider* data) {
  221. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  222. ssl_provider->ssl_info.cert =
  223. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  224. AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider));
  225. }
  226. void AddDataWithSSLSocketDataProvider(
  227. SocketDataProvider* data,
  228. std::unique_ptr<SSLSocketDataProvider> ssl_provider) {
  229. data_vector_.push_back(data);
  230. if (ssl_provider->next_proto == kProtoUnknown)
  231. ssl_provider->next_proto = kProtoHTTP2;
  232. session_deps_->socket_factory->AddSSLSocketDataProvider(
  233. ssl_provider.get());
  234. ssl_vector_.push_back(std::move(ssl_provider));
  235. session_deps_->socket_factory->AddSocketDataProvider(data);
  236. }
  237. size_t GetSpdySessionCount() {
  238. std::unique_ptr<base::Value> value(
  239. session_->spdy_session_pool()->SpdySessionPoolInfoToValue());
  240. CHECK(value && value->is_list());
  241. return value->GetList().size();
  242. }
  243. HttpNetworkTransaction* trans() { return trans_.get(); }
  244. void ResetTrans() { trans_.reset(); }
  245. const TransactionHelperResult& output() { return output_; }
  246. HttpNetworkSession* session() const { return session_.get(); }
  247. SpdySessionDependencies* session_deps() { return session_deps_.get(); }
  248. private:
  249. typedef std::vector<SocketDataProvider*> DataVector;
  250. typedef std::vector<std::unique_ptr<SSLSocketDataProvider>> SSLVector;
  251. typedef std::vector<std::unique_ptr<SocketDataProvider>> AlternateVector;
  252. const HttpRequestInfo request_;
  253. const RequestPriority priority_;
  254. std::unique_ptr<SpdySessionDependencies> session_deps_;
  255. std::unique_ptr<HttpNetworkSession> session_;
  256. TransactionHelperResult output_;
  257. SSLVector ssl_vector_;
  258. TestCompletionCallback callback_;
  259. std::unique_ptr<HttpNetworkTransaction> trans_;
  260. DataVector data_vector_;
  261. const NetLogWithSource log_;
  262. };
  263. void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
  264. int expected_status);
  265. void ConnectStatusHelper(const MockRead& status);
  266. [[nodiscard]] HttpRequestInfo CreateGetPushRequest() const {
  267. HttpRequestInfo request;
  268. request.method = "GET";
  269. request.url = GURL(kPushedUrl);
  270. request.traffic_annotation =
  271. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  272. return request;
  273. }
  274. void UsePostRequest() {
  275. ASSERT_FALSE(upload_data_stream_);
  276. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  277. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  278. kUploadData, kUploadDataSize));
  279. upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
  280. std::move(element_readers), 0);
  281. request_.method = "POST";
  282. request_.upload_data_stream = upload_data_stream_.get();
  283. }
  284. void UseFilePostRequest() {
  285. ASSERT_FALSE(upload_data_stream_);
  286. base::FilePath file_path;
  287. CHECK(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
  288. CHECK_EQ(static_cast<int>(kUploadDataSize),
  289. base::WriteFile(file_path, kUploadData, kUploadDataSize));
  290. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  291. element_readers.push_back(std::make_unique<UploadFileElementReader>(
  292. base::ThreadTaskRunnerHandle::Get().get(), file_path, 0,
  293. kUploadDataSize, base::Time()));
  294. upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
  295. std::move(element_readers), 0);
  296. request_.method = "POST";
  297. request_.upload_data_stream = upload_data_stream_.get();
  298. request_.traffic_annotation =
  299. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  300. }
  301. void UseUnreadableFilePostRequest() {
  302. ASSERT_FALSE(upload_data_stream_);
  303. base::FilePath file_path;
  304. CHECK(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
  305. CHECK_EQ(static_cast<int>(kUploadDataSize),
  306. base::WriteFile(file_path, kUploadData, kUploadDataSize));
  307. CHECK(base::MakeFileUnreadable(file_path));
  308. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  309. element_readers.push_back(std::make_unique<UploadFileElementReader>(
  310. base::ThreadTaskRunnerHandle::Get().get(), file_path, 0,
  311. kUploadDataSize, base::Time()));
  312. upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
  313. std::move(element_readers), 0);
  314. request_.method = "POST";
  315. request_.upload_data_stream = upload_data_stream_.get();
  316. }
  317. void UseComplexPostRequest() {
  318. ASSERT_FALSE(upload_data_stream_);
  319. const int kFileRangeOffset = 1;
  320. const int kFileRangeLength = 3;
  321. CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
  322. base::FilePath file_path;
  323. CHECK(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
  324. CHECK_EQ(static_cast<int>(kUploadDataSize),
  325. base::WriteFile(file_path, kUploadData, kUploadDataSize));
  326. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  327. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  328. kUploadData, kFileRangeOffset));
  329. element_readers.push_back(std::make_unique<UploadFileElementReader>(
  330. base::ThreadTaskRunnerHandle::Get().get(), file_path, kFileRangeOffset,
  331. kFileRangeLength, base::Time()));
  332. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  333. kUploadData + kFileRangeOffset + kFileRangeLength,
  334. kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
  335. upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
  336. std::move(element_readers), 0);
  337. request_.method = "POST";
  338. request_.upload_data_stream = upload_data_stream_.get();
  339. }
  340. void UseChunkedPostRequest() {
  341. ASSERT_FALSE(upload_chunked_data_stream_);
  342. upload_chunked_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
  343. request_.method = "POST";
  344. request_.upload_data_stream = upload_chunked_data_stream_.get();
  345. }
  346. // Read the result of a particular transaction, knowing that we've got
  347. // multiple transactions in the read pipeline; so as we read, we may have
  348. // to skip over data destined for other transactions while we consume
  349. // the data for |trans|.
  350. int ReadResult(HttpNetworkTransaction* trans, std::string* result) {
  351. const int kSize = 3000;
  352. int bytes_read = 0;
  353. scoped_refptr<IOBufferWithSize> buf =
  354. base::MakeRefCounted<IOBufferWithSize>(kSize);
  355. TestCompletionCallback callback;
  356. while (true) {
  357. int rv = trans->Read(buf.get(), kSize, callback.callback());
  358. if (rv == ERR_IO_PENDING) {
  359. rv = callback.WaitForResult();
  360. } else if (rv <= 0) {
  361. break;
  362. }
  363. result->append(buf->data(), rv);
  364. bytes_read += rv;
  365. }
  366. return bytes_read;
  367. }
  368. void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
  369. // This lengthy block is reaching into the pool to dig out the active
  370. // session. Once we have the session, we verify that the streams are
  371. // all closed and not leaked at this point.
  372. SpdySessionKey key(HostPortPair::FromURL(request_.url),
  373. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  374. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  375. request_.network_isolation_key, SecureDnsPolicy::kAllow);
  376. HttpNetworkSession* session = helper.session();
  377. base::WeakPtr<SpdySession> spdy_session =
  378. session->spdy_session_pool()->FindAvailableSession(
  379. key, /* enable_ip_based_pooling = */ true,
  380. /* is_websocket = */ false, log_);
  381. ASSERT_TRUE(spdy_session);
  382. EXPECT_EQ(0u, num_active_streams(spdy_session));
  383. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
  384. }
  385. void RunServerPushTest(SequencedSocketData* data,
  386. HttpResponseInfo* response,
  387. HttpResponseInfo* push_response,
  388. const std::string& expected) {
  389. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  390. nullptr);
  391. helper.RunPreTestSetup();
  392. helper.AddData(data);
  393. HttpNetworkTransaction* trans = helper.trans();
  394. // Start the transaction with basic parameters.
  395. TestCompletionCallback callback;
  396. int rv = trans->Start(&request_, callback.callback(), log_);
  397. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  398. rv = callback.WaitForResult();
  399. // Finish async network reads/writes.
  400. base::RunLoop().RunUntilIdle();
  401. // Request the pushed path.
  402. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  403. HttpRequestInfo request = CreateGetPushRequest();
  404. rv = trans2.Start(&request, callback.callback(), log_);
  405. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  406. base::RunLoop().RunUntilIdle();
  407. // The data for the pushed path may be coming in more than 1 frame. Compile
  408. // the results into a single string.
  409. // Read the server push body.
  410. std::string result2;
  411. ReadResult(&trans2, &result2);
  412. // Read the response body.
  413. std::string result;
  414. ReadResult(trans, &result);
  415. // Verify that we consumed all test data.
  416. EXPECT_TRUE(data->AllReadDataConsumed());
  417. EXPECT_TRUE(data->AllWriteDataConsumed());
  418. LoadTimingInfo load_timing_info;
  419. EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
  420. EXPECT_TRUE(load_timing_info.push_start.is_null());
  421. EXPECT_TRUE(load_timing_info.push_end.is_null());
  422. LoadTimingInfo load_timing_info2;
  423. EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
  424. EXPECT_FALSE(load_timing_info2.push_start.is_null());
  425. EXPECT_FALSE(load_timing_info2.push_end.is_null());
  426. // Verify that the received push data is same as the expected push data.
  427. EXPECT_EQ(result2.compare(expected), 0) << "Received data: "
  428. << result2
  429. << "||||| Expected data: "
  430. << expected;
  431. // Verify the response HEADERS.
  432. // Copy the response info, because trans goes away.
  433. *response = *trans->GetResponseInfo();
  434. *push_response = *trans2.GetResponseInfo();
  435. VerifyStreamsClosed(helper);
  436. }
  437. void RunBrokenPushTest(SequencedSocketData* data, int expected_rv) {
  438. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  439. nullptr);
  440. helper.RunPreTestSetup();
  441. helper.AddData(data);
  442. HttpNetworkTransaction* trans = helper.trans();
  443. // Start the transaction with basic parameters.
  444. TestCompletionCallback callback;
  445. int rv = trans->Start(&request_, callback.callback(), log_);
  446. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  447. rv = callback.WaitForResult();
  448. EXPECT_EQ(expected_rv, rv);
  449. // Finish async network reads/writes.
  450. base::RunLoop().RunUntilIdle();
  451. // Verify that we consumed all test data.
  452. EXPECT_TRUE(data->AllReadDataConsumed());
  453. EXPECT_TRUE(data->AllWriteDataConsumed());
  454. if (expected_rv == OK) {
  455. // Expected main request to succeed, even if push failed.
  456. HttpResponseInfo response = *trans->GetResponseInfo();
  457. EXPECT_TRUE(response.headers);
  458. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  459. }
  460. }
  461. static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper,
  462. int result) {
  463. helper->ResetTrans();
  464. }
  465. static void StartTransactionCallback(HttpNetworkSession* session,
  466. GURL url,
  467. NetLogWithSource log,
  468. int result) {
  469. HttpRequestInfo request;
  470. HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
  471. TestCompletionCallback callback;
  472. request.method = "GET";
  473. request.url = url;
  474. request.traffic_annotation =
  475. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  476. int rv = trans.Start(&request, callback.callback(), log);
  477. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  478. callback.WaitForResult();
  479. }
  480. ChunkedUploadDataStream* upload_chunked_data_stream() {
  481. return upload_chunked_data_stream_.get();
  482. }
  483. size_t num_active_streams(base::WeakPtr<SpdySession> session) {
  484. return session->active_streams_.size();
  485. }
  486. static size_t num_unclaimed_pushed_streams(
  487. base::WeakPtr<SpdySession> session) {
  488. return session->pool_->push_promise_index()->CountStreamsForSession(
  489. session.get());
  490. }
  491. static bool has_unclaimed_pushed_stream_for_url(
  492. base::WeakPtr<SpdySession> session,
  493. const GURL& url) {
  494. return session->pool_->push_promise_index()->FindStream(
  495. url, session.get()) != kNoPushedStreamFound;
  496. }
  497. static spdy::SpdyStreamId spdy_stream_hi_water_mark(
  498. base::WeakPtr<SpdySession> session) {
  499. return session->stream_hi_water_mark_;
  500. }
  501. base::RepeatingClosure FastForwardByCallback(base::TimeDelta delta) {
  502. return base::BindRepeating(&SpdyNetworkTransactionTest::FastForwardBy,
  503. base::Unretained(this), delta);
  504. }
  505. const GURL default_url_;
  506. const HostPortPair host_port_pair_;
  507. HttpRequestInfo request_;
  508. SpdyTestUtil spdy_util_;
  509. const NetLogWithSource log_;
  510. private:
  511. std::unique_ptr<ChunkedUploadDataStream> upload_chunked_data_stream_;
  512. std::unique_ptr<UploadDataStream> upload_data_stream_;
  513. base::ScopedTempDir temp_dir_;
  514. };
  515. // Verify HttpNetworkTransaction constructor.
  516. TEST_F(SpdyNetworkTransactionTest, Constructor) {
  517. auto session_deps = std::make_unique<SpdySessionDependencies>();
  518. std::unique_ptr<HttpNetworkSession> session(
  519. SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
  520. auto trans =
  521. std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
  522. }
  523. TEST_F(SpdyNetworkTransactionTest, Get) {
  524. // Construct the request.
  525. spdy::SpdySerializedFrame req(
  526. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  527. MockWrite writes[] = {CreateMockWrite(req, 0)};
  528. spdy::SpdySerializedFrame resp(
  529. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  530. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  531. MockRead reads[] = {
  532. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  533. MockRead(ASYNC, 0, 3) // EOF
  534. };
  535. SequencedSocketData data(reads, writes);
  536. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  537. helper.RunToCompletion(&data);
  538. TransactionHelperResult out = helper.output();
  539. EXPECT_THAT(out.rv, IsOk());
  540. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  541. EXPECT_EQ("hello!", out.response_data);
  542. }
  543. TEST_F(SpdyNetworkTransactionTest, SetPriority) {
  544. for (bool set_priority_before_starting_transaction : {true, false}) {
  545. SpdyTestUtil spdy_test_util;
  546. spdy::SpdySerializedFrame req(
  547. spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  548. MockWrite writes[] = {CreateMockWrite(req, 0)};
  549. spdy::SpdySerializedFrame resp(
  550. spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1));
  551. spdy::SpdySerializedFrame body(
  552. spdy_test_util.ConstructSpdyDataFrame(1, true));
  553. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
  554. MockRead(ASYNC, 0, 3)};
  555. SequencedSocketData data(reads, writes);
  556. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
  557. helper.RunPreTestSetup();
  558. helper.AddData(&data);
  559. if (set_priority_before_starting_transaction) {
  560. helper.trans()->SetPriority(LOWEST);
  561. EXPECT_TRUE(helper.StartDefaultTest());
  562. } else {
  563. EXPECT_TRUE(helper.StartDefaultTest());
  564. helper.trans()->SetPriority(LOWEST);
  565. }
  566. helper.FinishDefaultTest();
  567. helper.VerifyDataConsumed();
  568. TransactionHelperResult out = helper.output();
  569. EXPECT_THAT(out.rv, IsOk());
  570. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  571. EXPECT_EQ("hello!", out.response_data);
  572. }
  573. }
  574. // Test that changing the request priority of an existing stream triggers
  575. // sending PRIORITY frames in case there are multiple open streams and their
  576. // relative priorities change.
  577. TEST_F(SpdyNetworkTransactionTest, SetPriorityOnExistingStream) {
  578. const char* kUrl2 = "https://www.example.org/bar";
  579. spdy::SpdySerializedFrame req1(
  580. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  581. spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(kUrl2, 3, MEDIUM));
  582. spdy::SpdySerializedFrame priority1(
  583. spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
  584. spdy::SpdySerializedFrame priority2(
  585. spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
  586. MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 2),
  587. CreateMockWrite(priority1, 4),
  588. CreateMockWrite(priority2, 5)};
  589. spdy::SpdySerializedFrame resp1(
  590. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  591. spdy::SpdySerializedFrame resp2(
  592. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  593. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  594. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  595. MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(resp2, 3),
  596. CreateMockRead(body1, 6), CreateMockRead(body2, 7),
  597. MockRead(ASYNC, 0, 8)};
  598. SequencedSocketData data(reads, writes);
  599. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
  600. helper.RunPreTestSetup();
  601. helper.AddData(&data);
  602. EXPECT_TRUE(helper.StartDefaultTest());
  603. // Open HTTP/2 connection and create first stream.
  604. base::RunLoop().RunUntilIdle();
  605. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  606. HttpRequestInfo request2;
  607. request2.url = GURL(kUrl2);
  608. request2.method = "GET";
  609. request2.traffic_annotation =
  610. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  611. TestCompletionCallback callback2;
  612. int rv = trans2.Start(&request2, callback2.callback(), log_);
  613. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  614. // Create second stream.
  615. base::RunLoop().RunUntilIdle();
  616. // First request has HIGHEST priority, second request has MEDIUM priority.
  617. // Changing the priority of the first request to LOWEST changes their order,
  618. // and therefore triggers sending PRIORITY frames.
  619. helper.trans()->SetPriority(LOWEST);
  620. helper.FinishDefaultTest();
  621. helper.VerifyDataConsumed();
  622. TransactionHelperResult out = helper.output();
  623. EXPECT_THAT(out.rv, IsOk());
  624. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  625. EXPECT_EQ("hello!", out.response_data);
  626. rv = callback2.WaitForResult();
  627. ASSERT_THAT(rv, IsOk());
  628. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  629. ASSERT_TRUE(response2);
  630. ASSERT_TRUE(response2->headers);
  631. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  632. response2->connection_info);
  633. EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
  634. }
  635. // Create two requests: a lower priority one first, then a higher priority one.
  636. // Test that the second request gets sent out first.
  637. TEST_F(SpdyNetworkTransactionTest, RequestsOrderedByPriority) {
  638. const char* kUrl2 = "https://www.example.org/foo";
  639. // First send second request on stream 1, then first request on stream 3.
  640. spdy::SpdySerializedFrame req2(
  641. spdy_util_.ConstructSpdyGet(kUrl2, 1, HIGHEST));
  642. spdy::SpdySerializedFrame req1(
  643. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOW));
  644. MockWrite writes[] = {CreateMockWrite(req2, 0), CreateMockWrite(req1, 1)};
  645. spdy::SpdySerializedFrame resp2(
  646. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  647. spdy::SpdySerializedFrame resp1(
  648. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  649. spdy::SpdySerializedFrame body2(
  650. spdy_util_.ConstructSpdyDataFrame(1, "stream 1", true));
  651. spdy::SpdySerializedFrame body1(
  652. spdy_util_.ConstructSpdyDataFrame(3, "stream 3", true));
  653. MockRead reads[] = {CreateMockRead(resp2, 2), CreateMockRead(body2, 3),
  654. CreateMockRead(resp1, 4), CreateMockRead(body1, 5),
  655. MockRead(ASYNC, 0, 6)};
  656. SequencedSocketData data(reads, writes);
  657. NormalSpdyTransactionHelper helper(request_, LOW, log_, nullptr);
  658. helper.RunPreTestSetup();
  659. helper.AddData(&data);
  660. // Create HTTP/2 connection. This is necessary because starting the first
  661. // transaction does not create the connection yet, so the second request
  662. // could not use the same connection, whereas running the message loop after
  663. // starting the first transaction would call Socket::Write() with the first
  664. // HEADERS frame, so the second transaction could not get ahead of it.
  665. SpdySessionKey key(HostPortPair("www.example.org", 443),
  666. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  667. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  668. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  669. auto spdy_session = CreateSpdySession(helper.session(), key, log_);
  670. EXPECT_TRUE(spdy_session);
  671. // Start first transaction.
  672. EXPECT_TRUE(helper.StartDefaultTest());
  673. // Start second transaction.
  674. HttpNetworkTransaction trans2(HIGHEST, helper.session());
  675. HttpRequestInfo request2;
  676. request2.url = GURL(kUrl2);
  677. request2.method = "GET";
  678. request2.traffic_annotation =
  679. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  680. TestCompletionCallback callback2;
  681. int rv = trans2.Start(&request2, callback2.callback(), log_);
  682. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  683. // Complete first transaction and verify results.
  684. helper.FinishDefaultTest();
  685. helper.VerifyDataConsumed();
  686. TransactionHelperResult out = helper.output();
  687. EXPECT_THAT(out.rv, IsOk());
  688. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  689. EXPECT_EQ("stream 3", out.response_data);
  690. // Complete second transaction and verify results.
  691. rv = callback2.WaitForResult();
  692. ASSERT_THAT(rv, IsOk());
  693. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  694. ASSERT_TRUE(response2);
  695. ASSERT_TRUE(response2->headers);
  696. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  697. response2->connection_info);
  698. EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
  699. std::string response_data;
  700. ReadTransaction(&trans2, &response_data);
  701. EXPECT_EQ("stream 1", response_data);
  702. }
  703. // Test that already enqueued HEADERS frames are reordered if their relative
  704. // priority changes.
  705. TEST_F(SpdyNetworkTransactionTest, QueuedFramesReorderedOnPriorityChange) {
  706. const char* kUrl2 = "https://www.example.org/foo";
  707. const char* kUrl3 = "https://www.example.org/bar";
  708. spdy::SpdySerializedFrame req1(
  709. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
  710. spdy::SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(kUrl3, 3, MEDIUM));
  711. spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(kUrl2, 5, LOWEST));
  712. MockWrite writes[] = {MockWrite(ASYNC, ERR_IO_PENDING, 0),
  713. CreateMockWrite(req1, 1), CreateMockWrite(req3, 2),
  714. CreateMockWrite(req2, 3)};
  715. spdy::SpdySerializedFrame resp1(
  716. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  717. spdy::SpdySerializedFrame resp3(
  718. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  719. spdy::SpdySerializedFrame resp2(
  720. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  721. spdy::SpdySerializedFrame body1(
  722. spdy_util_.ConstructSpdyDataFrame(1, "stream 1", true));
  723. spdy::SpdySerializedFrame body3(
  724. spdy_util_.ConstructSpdyDataFrame(3, "stream 3", true));
  725. spdy::SpdySerializedFrame body2(
  726. spdy_util_.ConstructSpdyDataFrame(5, "stream 5", true));
  727. MockRead reads[] = {CreateMockRead(resp1, 4), CreateMockRead(body1, 5),
  728. CreateMockRead(resp3, 6), CreateMockRead(body3, 7),
  729. CreateMockRead(resp2, 8), CreateMockRead(body2, 9),
  730. MockRead(ASYNC, 0, 10)};
  731. SequencedSocketData data(reads, writes);
  732. // Priority of first request does not matter, because Socket::Write() will be
  733. // called with its HEADERS frame before the other requests start.
  734. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  735. helper.RunPreTestSetup();
  736. helper.AddData(&data);
  737. EXPECT_TRUE(helper.StartDefaultTest());
  738. // Open HTTP/2 connection, create HEADERS frame for first request, and call
  739. // Socket::Write() with that frame. After this, no other request can get
  740. // ahead of the first one.
  741. base::RunLoop().RunUntilIdle();
  742. HttpNetworkTransaction trans2(HIGHEST, helper.session());
  743. HttpRequestInfo request2;
  744. request2.url = GURL(kUrl2);
  745. request2.method = "GET";
  746. request2.traffic_annotation =
  747. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  748. TestCompletionCallback callback2;
  749. int rv = trans2.Start(&request2, callback2.callback(), log_);
  750. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  751. HttpNetworkTransaction trans3(MEDIUM, helper.session());
  752. HttpRequestInfo request3;
  753. request3.url = GURL(kUrl3);
  754. request3.method = "GET";
  755. request3.traffic_annotation =
  756. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  757. TestCompletionCallback callback3;
  758. rv = trans3.Start(&request3, callback3.callback(), log_);
  759. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  760. // Create HEADERS frames for second and third request and enqueue them in
  761. // SpdyWriteQueue with their original priorities. Writing of the first
  762. // HEADERS frame to the socked still has not completed.
  763. base::RunLoop().RunUntilIdle();
  764. // Second request is of HIGHEST, third of MEDIUM priority. Changing second
  765. // request to LOWEST changes their relative order. This should result in
  766. // already enqueued frames being reordered within SpdyWriteQueue.
  767. trans2.SetPriority(LOWEST);
  768. // Complete async write of the first HEADERS frame.
  769. data.Resume();
  770. helper.FinishDefaultTest();
  771. TransactionHelperResult out = helper.output();
  772. EXPECT_THAT(out.rv, IsOk());
  773. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  774. EXPECT_EQ("stream 1", out.response_data);
  775. rv = callback2.WaitForResult();
  776. ASSERT_THAT(rv, IsOk());
  777. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  778. ASSERT_TRUE(response2);
  779. ASSERT_TRUE(response2->headers);
  780. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  781. response2->connection_info);
  782. EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
  783. std::string response_data;
  784. ReadTransaction(&trans2, &response_data);
  785. EXPECT_EQ("stream 5", response_data);
  786. rv = callback3.WaitForResult();
  787. ASSERT_THAT(rv, IsOk());
  788. const HttpResponseInfo* response3 = trans3.GetResponseInfo();
  789. ASSERT_TRUE(response3);
  790. ASSERT_TRUE(response3->headers);
  791. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  792. response3->connection_info);
  793. EXPECT_EQ("HTTP/1.1 200", response3->headers->GetStatusLine());
  794. ReadTransaction(&trans3, &response_data);
  795. EXPECT_EQ("stream 3", response_data);
  796. helper.VerifyDataConsumed();
  797. }
  798. TEST_F(SpdyNetworkTransactionTest, GetAtEachPriority) {
  799. for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY;
  800. p = RequestPriority(p + 1)) {
  801. SpdyTestUtil spdy_test_util;
  802. // Construct the request.
  803. spdy::SpdySerializedFrame req(
  804. spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, p));
  805. MockWrite writes[] = {CreateMockWrite(req, 0)};
  806. spdy::SpdyPriority spdy_prio = 0;
  807. EXPECT_TRUE(GetSpdyPriority(req, &spdy_prio));
  808. // this repeats the RequestPriority-->spdy::SpdyPriority mapping from
  809. // spdy::SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
  810. // sure it's being done right.
  811. switch (p) {
  812. case HIGHEST:
  813. EXPECT_EQ(0, spdy_prio);
  814. break;
  815. case MEDIUM:
  816. EXPECT_EQ(1, spdy_prio);
  817. break;
  818. case LOW:
  819. EXPECT_EQ(2, spdy_prio);
  820. break;
  821. case LOWEST:
  822. EXPECT_EQ(3, spdy_prio);
  823. break;
  824. case IDLE:
  825. EXPECT_EQ(4, spdy_prio);
  826. break;
  827. case THROTTLED:
  828. EXPECT_EQ(5, spdy_prio);
  829. break;
  830. default:
  831. FAIL();
  832. }
  833. spdy::SpdySerializedFrame resp(
  834. spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1));
  835. spdy::SpdySerializedFrame body(
  836. spdy_test_util.ConstructSpdyDataFrame(1, true));
  837. MockRead reads[] = {
  838. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  839. MockRead(ASYNC, 0, 3) // EOF
  840. };
  841. SequencedSocketData data(reads, writes);
  842. NormalSpdyTransactionHelper helper(request_, p, log_, nullptr);
  843. helper.RunToCompletion(&data);
  844. TransactionHelperResult out = helper.output();
  845. EXPECT_THAT(out.rv, IsOk());
  846. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  847. EXPECT_EQ("hello!", out.response_data);
  848. }
  849. }
  850. // Start three gets simultaniously; making sure that multiplexed
  851. // streams work properly.
  852. // This can't use the TransactionHelper method, since it only
  853. // handles a single transaction, and finishes them as soon
  854. // as it launches them.
  855. // TODO(gavinp): create a working generalized TransactionHelper that
  856. // can allow multiple streams in flight.
  857. TEST_F(SpdyNetworkTransactionTest, ThreeGets) {
  858. spdy::SpdySerializedFrame req(
  859. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  860. spdy::SpdySerializedFrame resp(
  861. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  862. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  863. spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
  864. spdy::SpdySerializedFrame req2(
  865. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  866. spdy::SpdySerializedFrame resp2(
  867. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  868. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
  869. spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
  870. spdy::SpdySerializedFrame req3(
  871. spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST));
  872. spdy::SpdySerializedFrame resp3(
  873. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  874. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, false));
  875. spdy::SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(5, true));
  876. MockWrite writes[] = {
  877. CreateMockWrite(req, 0), CreateMockWrite(req2, 3),
  878. CreateMockWrite(req3, 6),
  879. };
  880. MockRead reads[] = {
  881. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  882. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  883. CreateMockRead(resp3, 7), CreateMockRead(body3, 8),
  884. CreateMockRead(fbody, 9), CreateMockRead(fbody2, 10),
  885. CreateMockRead(fbody3, 11),
  886. MockRead(ASYNC, 0, 12), // EOF
  887. };
  888. SequencedSocketData data(reads, writes);
  889. SequencedSocketData data_placeholder1;
  890. SequencedSocketData data_placeholder2;
  891. TransactionHelperResult out;
  892. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  893. helper.RunPreTestSetup();
  894. helper.AddData(&data);
  895. // We require placeholder data because three get requests are sent out at
  896. // the same time which results in three sockets being connected. The first
  897. // on will negotiate SPDY and will be used for all requests.
  898. helper.AddData(&data_placeholder1);
  899. helper.AddData(&data_placeholder2);
  900. TestCompletionCallback callback1;
  901. TestCompletionCallback callback2;
  902. TestCompletionCallback callback3;
  903. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  904. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  905. HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session());
  906. out.rv = trans1.Start(&request_, callback1.callback(), log_);
  907. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  908. out.rv = trans2.Start(&request_, callback2.callback(), log_);
  909. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  910. out.rv = trans3.Start(&request_, callback3.callback(), log_);
  911. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  912. out.rv = callback1.WaitForResult();
  913. ASSERT_THAT(out.rv, IsOk());
  914. out.rv = callback3.WaitForResult();
  915. ASSERT_THAT(out.rv, IsOk());
  916. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  917. EXPECT_TRUE(response1->headers);
  918. EXPECT_TRUE(response1->was_fetched_via_spdy);
  919. out.status_line = response1->headers->GetStatusLine();
  920. out.response_info = *response1;
  921. trans2.GetResponseInfo();
  922. out.rv = ReadTransaction(&trans1, &out.response_data);
  923. helper.VerifyDataConsumed();
  924. EXPECT_THAT(out.rv, IsOk());
  925. EXPECT_THAT(out.rv, IsOk());
  926. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  927. EXPECT_EQ("hello!hello!", out.response_data);
  928. }
  929. TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
  930. spdy::SpdySerializedFrame req(
  931. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  932. spdy::SpdySerializedFrame resp(
  933. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  934. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  935. spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
  936. spdy::SpdySerializedFrame req2(
  937. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  938. spdy::SpdySerializedFrame resp2(
  939. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  940. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
  941. spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
  942. MockWrite writes[] = {
  943. CreateMockWrite(req, 0), CreateMockWrite(req2, 3),
  944. };
  945. MockRead reads[] = {
  946. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  947. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  948. CreateMockRead(fbody, 6), CreateMockRead(fbody2, 7),
  949. MockRead(ASYNC, 0, 8), // EOF
  950. };
  951. SequencedSocketData data(reads, writes);
  952. MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
  953. SequencedSocketData data_placeholder;
  954. data_placeholder.set_connect_data(never_finishing_connect);
  955. TransactionHelperResult out;
  956. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  957. helper.RunPreTestSetup();
  958. helper.AddData(&data);
  959. // We require placeholder data because two requests are sent out at
  960. // the same time which results in two sockets being connected. The first
  961. // on will negotiate SPDY and will be used for all requests.
  962. helper.AddData(&data_placeholder);
  963. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  964. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  965. TestCompletionCallback callback1;
  966. TestCompletionCallback callback2;
  967. out.rv = trans1.Start(&request_, callback1.callback(), log_);
  968. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  969. out.rv = trans2.Start(&request_, callback2.callback(), log_);
  970. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  971. out.rv = callback1.WaitForResult();
  972. ASSERT_THAT(out.rv, IsOk());
  973. out.rv = callback2.WaitForResult();
  974. ASSERT_THAT(out.rv, IsOk());
  975. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  976. EXPECT_TRUE(response1->headers);
  977. EXPECT_TRUE(response1->was_fetched_via_spdy);
  978. out.status_line = response1->headers->GetStatusLine();
  979. out.response_info = *response1;
  980. out.rv = ReadTransaction(&trans1, &out.response_data);
  981. EXPECT_THAT(out.rv, IsOk());
  982. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  983. EXPECT_EQ("hello!hello!", out.response_data);
  984. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  985. EXPECT_TRUE(response2->headers);
  986. EXPECT_TRUE(response2->was_fetched_via_spdy);
  987. out.status_line = response2->headers->GetStatusLine();
  988. out.response_info = *response2;
  989. out.rv = ReadTransaction(&trans2, &out.response_data);
  990. EXPECT_THAT(out.rv, IsOk());
  991. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  992. EXPECT_EQ("hello!hello!", out.response_data);
  993. helper.VerifyDataConsumed();
  994. }
  995. TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
  996. spdy::SpdySerializedFrame req(
  997. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  998. spdy::SpdySerializedFrame resp(
  999. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1000. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  1001. spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
  1002. spdy::SpdySerializedFrame req2(
  1003. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  1004. spdy::SpdySerializedFrame resp2(
  1005. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  1006. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
  1007. spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
  1008. MockWrite writes[] = {
  1009. CreateMockWrite(req, 0), CreateMockWrite(req2, 3),
  1010. };
  1011. MockRead reads[] = {
  1012. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  1013. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  1014. CreateMockRead(fbody, 6), CreateMockRead(fbody2, 7),
  1015. MockRead(ASYNC, 0, 8), // EOF
  1016. };
  1017. SequencedSocketData preconnect_data(reads, writes);
  1018. MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING);
  1019. SequencedSocketData data_placeholder;
  1020. data_placeholder.set_connect_data(never_finishing_connect);
  1021. TransactionHelperResult out;
  1022. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1023. helper.RunPreTestSetup();
  1024. helper.AddData(&preconnect_data);
  1025. // We require placeholder data because 3 connections are attempted (first is
  1026. // the preconnect, 2nd and 3rd are the never finished connections.
  1027. helper.AddData(&data_placeholder);
  1028. helper.AddData(&data_placeholder);
  1029. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  1030. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  1031. TestCompletionCallback callback1;
  1032. TestCompletionCallback callback2;
  1033. // Preconnect the first.
  1034. HttpStreamFactory* http_stream_factory =
  1035. helper.session()->http_stream_factory();
  1036. http_stream_factory->PreconnectStreams(1, request_);
  1037. out.rv = trans1.Start(&request_, callback1.callback(), log_);
  1038. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  1039. out.rv = trans2.Start(&request_, callback2.callback(), log_);
  1040. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  1041. out.rv = callback1.WaitForResult();
  1042. ASSERT_THAT(out.rv, IsOk());
  1043. out.rv = callback2.WaitForResult();
  1044. ASSERT_THAT(out.rv, IsOk());
  1045. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  1046. EXPECT_TRUE(response1->headers);
  1047. EXPECT_TRUE(response1->was_fetched_via_spdy);
  1048. out.status_line = response1->headers->GetStatusLine();
  1049. out.response_info = *response1;
  1050. out.rv = ReadTransaction(&trans1, &out.response_data);
  1051. EXPECT_THAT(out.rv, IsOk());
  1052. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1053. EXPECT_EQ("hello!hello!", out.response_data);
  1054. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  1055. EXPECT_TRUE(response2->headers);
  1056. EXPECT_TRUE(response2->was_fetched_via_spdy);
  1057. out.status_line = response2->headers->GetStatusLine();
  1058. out.response_info = *response2;
  1059. out.rv = ReadTransaction(&trans2, &out.response_data);
  1060. EXPECT_THAT(out.rv, IsOk());
  1061. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1062. EXPECT_EQ("hello!hello!", out.response_data);
  1063. helper.VerifyDataConsumed();
  1064. }
  1065. // Similar to ThreeGets above, however this test adds a SETTINGS
  1066. // frame. The SETTINGS frame is read during the IO loop waiting on
  1067. // the first transaction completion, and sets a maximum concurrent
  1068. // stream limit of 1. This means that our IO loop exists after the
  1069. // second transaction completes, so we can assert on read_index().
  1070. TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
  1071. // Construct the request.
  1072. // Each request fully completes before the next starts.
  1073. spdy::SpdySerializedFrame req(
  1074. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1075. spdy::SpdySerializedFrame resp(
  1076. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1077. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  1078. spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
  1079. spdy_util_.UpdateWithStreamDestruction(1);
  1080. spdy::SpdySerializedFrame req2(
  1081. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  1082. spdy::SpdySerializedFrame resp2(
  1083. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  1084. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
  1085. spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
  1086. spdy_util_.UpdateWithStreamDestruction(3);
  1087. spdy::SpdySerializedFrame req3(
  1088. spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST));
  1089. spdy::SpdySerializedFrame resp3(
  1090. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  1091. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, false));
  1092. spdy::SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(5, true));
  1093. spdy::SettingsMap settings;
  1094. const uint32_t max_concurrent_streams = 1;
  1095. settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
  1096. spdy::SpdySerializedFrame settings_frame(
  1097. spdy_util_.ConstructSpdySettings(settings));
  1098. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  1099. MockWrite writes[] = {
  1100. CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 5),
  1101. CreateMockWrite(req2, 6), CreateMockWrite(req3, 10),
  1102. };
  1103. MockRead reads[] = {
  1104. CreateMockRead(settings_frame, 1),
  1105. CreateMockRead(resp, 2),
  1106. CreateMockRead(body, 3),
  1107. CreateMockRead(fbody, 4),
  1108. CreateMockRead(resp2, 7),
  1109. CreateMockRead(body2, 8),
  1110. CreateMockRead(fbody2, 9),
  1111. CreateMockRead(resp3, 11),
  1112. CreateMockRead(body3, 12),
  1113. CreateMockRead(fbody3, 13),
  1114. MockRead(ASYNC, 0, 14), // EOF
  1115. };
  1116. SequencedSocketData data(reads, writes);
  1117. TransactionHelperResult out;
  1118. {
  1119. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  1120. nullptr);
  1121. helper.RunPreTestSetup();
  1122. helper.AddData(&data);
  1123. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  1124. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  1125. HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session());
  1126. TestCompletionCallback callback1;
  1127. TestCompletionCallback callback2;
  1128. TestCompletionCallback callback3;
  1129. out.rv = trans1.Start(&request_, callback1.callback(), log_);
  1130. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1131. // Run transaction 1 through quickly to force a read of our SETTINGS
  1132. // frame.
  1133. out.rv = callback1.WaitForResult();
  1134. ASSERT_THAT(out.rv, IsOk());
  1135. out.rv = trans2.Start(&request_, callback2.callback(), log_);
  1136. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1137. out.rv = trans3.Start(&request_, callback3.callback(), log_);
  1138. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1139. out.rv = callback2.WaitForResult();
  1140. ASSERT_THAT(out.rv, IsOk());
  1141. out.rv = callback3.WaitForResult();
  1142. ASSERT_THAT(out.rv, IsOk());
  1143. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  1144. ASSERT_TRUE(response1);
  1145. EXPECT_TRUE(response1->headers);
  1146. EXPECT_TRUE(response1->was_fetched_via_spdy);
  1147. out.status_line = response1->headers->GetStatusLine();
  1148. out.response_info = *response1;
  1149. out.rv = ReadTransaction(&trans1, &out.response_data);
  1150. EXPECT_THAT(out.rv, IsOk());
  1151. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1152. EXPECT_EQ("hello!hello!", out.response_data);
  1153. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  1154. out.status_line = response2->headers->GetStatusLine();
  1155. out.response_info = *response2;
  1156. out.rv = ReadTransaction(&trans2, &out.response_data);
  1157. EXPECT_THAT(out.rv, IsOk());
  1158. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1159. EXPECT_EQ("hello!hello!", out.response_data);
  1160. const HttpResponseInfo* response3 = trans3.GetResponseInfo();
  1161. out.status_line = response3->headers->GetStatusLine();
  1162. out.response_info = *response3;
  1163. out.rv = ReadTransaction(&trans3, &out.response_data);
  1164. EXPECT_THAT(out.rv, IsOk());
  1165. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1166. EXPECT_EQ("hello!hello!", out.response_data);
  1167. helper.VerifyDataConsumed();
  1168. }
  1169. EXPECT_THAT(out.rv, IsOk());
  1170. }
  1171. // Similar to ThreeGetsWithMaxConcurrent above, however this test adds
  1172. // a fourth transaction. The third and fourth transactions have
  1173. // different data ("hello!" vs "hello!hello!") and because of the
  1174. // user specified priority, we expect to see them inverted in
  1175. // the response from the server.
  1176. TEST_F(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
  1177. // Construct the request.
  1178. spdy::SpdySerializedFrame req(
  1179. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1180. spdy::SpdySerializedFrame resp(
  1181. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1182. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  1183. spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
  1184. spdy_util_.UpdateWithStreamDestruction(1);
  1185. spdy::SpdySerializedFrame req2(
  1186. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  1187. spdy::SpdySerializedFrame resp2(
  1188. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  1189. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
  1190. spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
  1191. spdy_util_.UpdateWithStreamDestruction(3);
  1192. spdy::SpdySerializedFrame req4(
  1193. spdy_util_.ConstructSpdyGet(nullptr, 0, 5, HIGHEST));
  1194. spdy::SpdySerializedFrame resp4(
  1195. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  1196. spdy::SpdySerializedFrame fbody4(spdy_util_.ConstructSpdyDataFrame(5, true));
  1197. spdy_util_.UpdateWithStreamDestruction(5);
  1198. spdy::SpdySerializedFrame req3(
  1199. spdy_util_.ConstructSpdyGet(nullptr, 0, 7, LOWEST));
  1200. spdy::SpdySerializedFrame resp3(
  1201. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 7));
  1202. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(7, false));
  1203. spdy::SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(7, true));
  1204. spdy::SettingsMap settings;
  1205. const uint32_t max_concurrent_streams = 1;
  1206. settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
  1207. spdy::SpdySerializedFrame settings_frame(
  1208. spdy_util_.ConstructSpdySettings(settings));
  1209. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  1210. MockWrite writes[] = {
  1211. CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 5),
  1212. // By making these synchronous, it guarantees that they are not *started*
  1213. // before their sequence number, which in turn verifies that only a single
  1214. // request is in-flight at a time.
  1215. CreateMockWrite(req2, 6, SYNCHRONOUS),
  1216. CreateMockWrite(req4, 10, SYNCHRONOUS),
  1217. CreateMockWrite(req3, 13, SYNCHRONOUS),
  1218. };
  1219. MockRead reads[] = {
  1220. CreateMockRead(settings_frame, 1),
  1221. CreateMockRead(resp, 2),
  1222. CreateMockRead(body, 3),
  1223. CreateMockRead(fbody, 4),
  1224. CreateMockRead(resp2, 7),
  1225. CreateMockRead(body2, 8),
  1226. CreateMockRead(fbody2, 9),
  1227. CreateMockRead(resp4, 11),
  1228. CreateMockRead(fbody4, 12),
  1229. CreateMockRead(resp3, 14),
  1230. CreateMockRead(body3, 15),
  1231. CreateMockRead(fbody3, 16),
  1232. MockRead(ASYNC, 0, 17), // EOF
  1233. };
  1234. SequencedSocketData data(reads, writes);
  1235. TransactionHelperResult out;
  1236. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1237. helper.RunPreTestSetup();
  1238. helper.AddData(&data);
  1239. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  1240. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  1241. HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session());
  1242. HttpNetworkTransaction trans4(HIGHEST, helper.session());
  1243. TestCompletionCallback callback1;
  1244. TestCompletionCallback callback2;
  1245. TestCompletionCallback callback3;
  1246. TestCompletionCallback callback4;
  1247. out.rv = trans1.Start(&request_, callback1.callback(), log_);
  1248. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  1249. // Run transaction 1 through quickly to force a read of our SETTINGS frame.
  1250. out.rv = callback1.WaitForResult();
  1251. ASSERT_THAT(out.rv, IsOk());
  1252. // Finish async network reads and writes associated with |trans1|.
  1253. base::RunLoop().RunUntilIdle();
  1254. out.rv = trans2.Start(&request_, callback2.callback(), log_);
  1255. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  1256. out.rv = trans3.Start(&request_, callback3.callback(), log_);
  1257. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  1258. out.rv = trans4.Start(&request_, callback4.callback(), log_);
  1259. ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING));
  1260. out.rv = callback2.WaitForResult();
  1261. ASSERT_THAT(out.rv, IsOk());
  1262. out.rv = callback3.WaitForResult();
  1263. ASSERT_THAT(out.rv, IsOk());
  1264. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  1265. EXPECT_TRUE(response1->headers);
  1266. EXPECT_TRUE(response1->was_fetched_via_spdy);
  1267. out.status_line = response1->headers->GetStatusLine();
  1268. out.response_info = *response1;
  1269. out.rv = ReadTransaction(&trans1, &out.response_data);
  1270. EXPECT_THAT(out.rv, IsOk());
  1271. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1272. EXPECT_EQ("hello!hello!", out.response_data);
  1273. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  1274. out.status_line = response2->headers->GetStatusLine();
  1275. out.response_info = *response2;
  1276. out.rv = ReadTransaction(&trans2, &out.response_data);
  1277. EXPECT_THAT(out.rv, IsOk());
  1278. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1279. EXPECT_EQ("hello!hello!", out.response_data);
  1280. // notice: response3 gets two hellos, response4 gets one
  1281. // hello, so we know dequeuing priority was respected.
  1282. const HttpResponseInfo* response3 = trans3.GetResponseInfo();
  1283. out.status_line = response3->headers->GetStatusLine();
  1284. out.response_info = *response3;
  1285. out.rv = ReadTransaction(&trans3, &out.response_data);
  1286. EXPECT_THAT(out.rv, IsOk());
  1287. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1288. EXPECT_EQ("hello!hello!", out.response_data);
  1289. out.rv = callback4.WaitForResult();
  1290. EXPECT_THAT(out.rv, IsOk());
  1291. const HttpResponseInfo* response4 = trans4.GetResponseInfo();
  1292. out.status_line = response4->headers->GetStatusLine();
  1293. out.response_info = *response4;
  1294. out.rv = ReadTransaction(&trans4, &out.response_data);
  1295. EXPECT_THAT(out.rv, IsOk());
  1296. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1297. EXPECT_EQ("hello!", out.response_data);
  1298. helper.VerifyDataConsumed();
  1299. EXPECT_THAT(out.rv, IsOk());
  1300. }
  1301. // Similar to ThreeGetsMaxConcurrrent above, however, this test
  1302. // deletes a session in the middle of the transaction to ensure
  1303. // that we properly remove pendingcreatestream objects from
  1304. // the spdy_session
  1305. TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
  1306. // Construct the request.
  1307. spdy::SpdySerializedFrame req(
  1308. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1309. spdy::SpdySerializedFrame resp(
  1310. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1311. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  1312. spdy::SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true));
  1313. spdy_util_.UpdateWithStreamDestruction(1);
  1314. spdy::SpdySerializedFrame req2(
  1315. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  1316. spdy::SpdySerializedFrame resp2(
  1317. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  1318. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false));
  1319. spdy::SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true));
  1320. spdy::SettingsMap settings;
  1321. const uint32_t max_concurrent_streams = 1;
  1322. settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
  1323. spdy::SpdySerializedFrame settings_frame(
  1324. spdy_util_.ConstructSpdySettings(settings));
  1325. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  1326. MockWrite writes[] = {
  1327. CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 5),
  1328. CreateMockWrite(req2, 6),
  1329. };
  1330. MockRead reads[] = {
  1331. CreateMockRead(settings_frame, 1), CreateMockRead(resp, 2),
  1332. CreateMockRead(body, 3), CreateMockRead(fbody, 4),
  1333. CreateMockRead(resp2, 7), CreateMockRead(body2, 8),
  1334. CreateMockRead(fbody2, 9), MockRead(ASYNC, 0, 10), // EOF
  1335. };
  1336. SequencedSocketData data(reads, writes);
  1337. TransactionHelperResult out;
  1338. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1339. helper.RunPreTestSetup();
  1340. helper.AddData(&data);
  1341. auto trans1 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  1342. helper.session());
  1343. auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  1344. helper.session());
  1345. auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  1346. helper.session());
  1347. TestCompletionCallback callback1;
  1348. TestCompletionCallback callback2;
  1349. TestCompletionCallback callback3;
  1350. out.rv = trans1->Start(&request_, callback1.callback(), log_);
  1351. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1352. // Run transaction 1 through quickly to force a read of our SETTINGS frame.
  1353. out.rv = callback1.WaitForResult();
  1354. ASSERT_THAT(out.rv, IsOk());
  1355. out.rv = trans2->Start(&request_, callback2.callback(), log_);
  1356. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1357. out.rv = trans3->Start(&request_, callback3.callback(), log_);
  1358. trans3.reset();
  1359. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1360. out.rv = callback2.WaitForResult();
  1361. ASSERT_THAT(out.rv, IsOk());
  1362. const HttpResponseInfo* response1 = trans1->GetResponseInfo();
  1363. ASSERT_TRUE(response1);
  1364. EXPECT_TRUE(response1->headers);
  1365. EXPECT_TRUE(response1->was_fetched_via_spdy);
  1366. out.status_line = response1->headers->GetStatusLine();
  1367. out.response_info = *response1;
  1368. out.rv = ReadTransaction(trans1.get(), &out.response_data);
  1369. EXPECT_THAT(out.rv, IsOk());
  1370. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1371. EXPECT_EQ("hello!hello!", out.response_data);
  1372. const HttpResponseInfo* response2 = trans2->GetResponseInfo();
  1373. ASSERT_TRUE(response2);
  1374. out.status_line = response2->headers->GetStatusLine();
  1375. out.response_info = *response2;
  1376. out.rv = ReadTransaction(trans2.get(), &out.response_data);
  1377. EXPECT_THAT(out.rv, IsOk());
  1378. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1379. EXPECT_EQ("hello!hello!", out.response_data);
  1380. helper.VerifyDataConsumed();
  1381. EXPECT_THAT(out.rv, IsOk());
  1382. }
  1383. namespace {
  1384. // A helper class that will delete |transaction| on error when the callback is
  1385. // invoked.
  1386. class KillerCallback : public TestCompletionCallbackBase {
  1387. public:
  1388. explicit KillerCallback(std::unique_ptr<HttpNetworkTransaction> transaction)
  1389. : transaction_(std::move(transaction)) {}
  1390. ~KillerCallback() override = default;
  1391. CompletionOnceCallback callback() {
  1392. return base::BindOnce(&KillerCallback::OnComplete, base::Unretained(this));
  1393. }
  1394. private:
  1395. void OnComplete(int result) {
  1396. if (result < 0)
  1397. transaction_.reset();
  1398. SetResult(result);
  1399. }
  1400. std::unique_ptr<HttpNetworkTransaction> transaction_;
  1401. };
  1402. } // namespace
  1403. // Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
  1404. // closes the socket while we have a pending transaction waiting for
  1405. // a pending stream creation. http://crbug.com/52901
  1406. TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
  1407. // Construct the request. Each stream uses a different priority to provide
  1408. // more useful failure information if the requests are made in an unexpected
  1409. // order.
  1410. spdy::SpdySerializedFrame req(
  1411. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  1412. spdy::SpdySerializedFrame resp(
  1413. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1414. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false));
  1415. spdy::SpdySerializedFrame fin_body(
  1416. spdy_util_.ConstructSpdyDataFrame(1, true));
  1417. spdy_util_.UpdateWithStreamDestruction(1);
  1418. spdy::SpdySerializedFrame req2(
  1419. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  1420. spdy::SpdySerializedFrame resp2(
  1421. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  1422. spdy::SettingsMap settings;
  1423. const uint32_t max_concurrent_streams = 1;
  1424. settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = max_concurrent_streams;
  1425. spdy::SpdySerializedFrame settings_frame(
  1426. spdy_util_.ConstructSpdySettings(settings));
  1427. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  1428. MockWrite writes[] = {CreateMockWrite(req, 0),
  1429. CreateMockWrite(settings_ack, 6),
  1430. CreateMockWrite(req2, 7)};
  1431. MockRead reads[] = {
  1432. CreateMockRead(settings_frame, 1), CreateMockRead(resp, 2),
  1433. CreateMockRead(body, 3),
  1434. // Delay the request here. For this test to pass, the three HTTP streams
  1435. // have to be created in order, but SpdySession doesn't actually guarantee
  1436. // that (See note in SpdySession::ProcessPendingStreamRequests). As a
  1437. // workaround, delay finishing up the first stream until the second and
  1438. // third streams are waiting in the SPDY stream request queue.
  1439. MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(fin_body, 5),
  1440. CreateMockRead(resp2, 8),
  1441. // The exact error does not matter, but some errors, such as
  1442. // ERR_CONNECTION_RESET, may trigger a retry, which this test does not
  1443. // account for.
  1444. MockRead(ASYNC, ERR_SSL_BAD_RECORD_MAC_ALERT, 9), // Abort!
  1445. };
  1446. SequencedSocketData data(reads, writes);
  1447. SequencedSocketData data_placeholder;
  1448. TransactionHelperResult out;
  1449. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
  1450. helper.RunPreTestSetup();
  1451. helper.AddData(&data);
  1452. // We require placeholder data because three get requests are sent out, so
  1453. // there needs to be three sets of SSL connection data.
  1454. helper.AddData(&data_placeholder);
  1455. helper.AddData(&data_placeholder);
  1456. HttpNetworkTransaction trans1(HIGHEST, helper.session());
  1457. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  1458. auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  1459. helper.session());
  1460. auto* trans3_ptr = trans3.get();
  1461. TestCompletionCallback callback1;
  1462. TestCompletionCallback callback2;
  1463. KillerCallback callback3(std::move(trans3));
  1464. out.rv = trans1.Start(&request_, callback1.callback(), log_);
  1465. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1466. // Run transaction 1 through quickly to force a read of our SETTINGS frame.
  1467. out.rv = callback1.WaitForResult();
  1468. ASSERT_THAT(out.rv, IsOk());
  1469. out.rv = trans2.Start(&request_, callback2.callback(), log_);
  1470. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1471. out.rv = trans3_ptr->Start(&request_, callback3.callback(), log_);
  1472. ASSERT_EQ(out.rv, ERR_IO_PENDING);
  1473. // Run until both transactions are in the SpdySession's queue, waiting for the
  1474. // final request to complete.
  1475. base::RunLoop().RunUntilIdle();
  1476. data.Resume();
  1477. out.rv = callback3.WaitForResult();
  1478. EXPECT_THAT(out.rv, IsError(ERR_SSL_BAD_RECORD_MAC_ALERT));
  1479. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  1480. ASSERT_TRUE(response1);
  1481. EXPECT_TRUE(response1->headers);
  1482. EXPECT_TRUE(response1->was_fetched_via_spdy);
  1483. out.status_line = response1->headers->GetStatusLine();
  1484. out.response_info = *response1;
  1485. out.rv = ReadTransaction(&trans1, &out.response_data);
  1486. EXPECT_THAT(out.rv, IsOk());
  1487. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  1488. ASSERT_TRUE(response2);
  1489. out.status_line = response2->headers->GetStatusLine();
  1490. out.response_info = *response2;
  1491. out.rv = ReadTransaction(&trans2, &out.response_data);
  1492. EXPECT_THAT(out.rv, IsError(ERR_SSL_BAD_RECORD_MAC_ALERT));
  1493. helper.VerifyDataConsumed();
  1494. }
  1495. // Test that a simple PUT request works.
  1496. TEST_F(SpdyNetworkTransactionTest, Put) {
  1497. // Setup the request.
  1498. request_.method = "PUT";
  1499. spdy::Http2HeaderBlock put_headers(
  1500. spdy_util_.ConstructPutHeaderBlock(kDefaultUrl, 0));
  1501. spdy::SpdySerializedFrame req(
  1502. spdy_util_.ConstructSpdyHeaders(1, std::move(put_headers), LOWEST, true));
  1503. MockWrite writes[] = {
  1504. CreateMockWrite(req, 0),
  1505. };
  1506. spdy::SpdySerializedFrame resp(
  1507. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1508. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1509. MockRead reads[] = {
  1510. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  1511. MockRead(ASYNC, 0, 3) // EOF
  1512. };
  1513. SequencedSocketData data(reads, writes);
  1514. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1515. helper.RunToCompletion(&data);
  1516. TransactionHelperResult out = helper.output();
  1517. EXPECT_THAT(out.rv, IsOk());
  1518. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1519. }
  1520. // Test that a simple HEAD request works.
  1521. TEST_F(SpdyNetworkTransactionTest, Head) {
  1522. // Setup the request.
  1523. request_.method = "HEAD";
  1524. spdy::Http2HeaderBlock head_headers(
  1525. spdy_util_.ConstructHeadHeaderBlock(kDefaultUrl, 0));
  1526. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyHeaders(
  1527. 1, std::move(head_headers), LOWEST, true));
  1528. MockWrite writes[] = {
  1529. CreateMockWrite(req, 0),
  1530. };
  1531. spdy::SpdySerializedFrame resp(
  1532. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1533. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1534. MockRead reads[] = {
  1535. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  1536. MockRead(ASYNC, 0, 3) // EOF
  1537. };
  1538. SequencedSocketData data(reads, writes);
  1539. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1540. helper.RunToCompletion(&data);
  1541. TransactionHelperResult out = helper.output();
  1542. EXPECT_THAT(out.rv, IsOk());
  1543. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1544. }
  1545. // Test that a simple POST works.
  1546. TEST_F(SpdyNetworkTransactionTest, Post) {
  1547. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  1548. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  1549. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1550. MockWrite writes[] = {
  1551. CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
  1552. };
  1553. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1554. MockRead reads[] = {
  1555. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  1556. MockRead(ASYNC, 0, 4) // EOF
  1557. };
  1558. SequencedSocketData data(reads, writes);
  1559. UsePostRequest();
  1560. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1561. helper.RunToCompletion(&data);
  1562. TransactionHelperResult out = helper.output();
  1563. EXPECT_THAT(out.rv, IsOk());
  1564. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1565. EXPECT_EQ("hello!", out.response_data);
  1566. }
  1567. // Test that a POST with a file works.
  1568. TEST_F(SpdyNetworkTransactionTest, FilePost) {
  1569. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  1570. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  1571. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1572. MockWrite writes[] = {
  1573. CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
  1574. };
  1575. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1576. MockRead reads[] = {
  1577. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  1578. MockRead(ASYNC, 0, 4) // EOF
  1579. };
  1580. SequencedSocketData data(reads, writes);
  1581. UseFilePostRequest();
  1582. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1583. helper.RunToCompletion(&data);
  1584. TransactionHelperResult out = helper.output();
  1585. EXPECT_THAT(out.rv, IsOk());
  1586. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1587. EXPECT_EQ("hello!", out.response_data);
  1588. }
  1589. // Test that a POST with a unreadable file fails.
  1590. TEST_F(SpdyNetworkTransactionTest, UnreadableFilePost) {
  1591. MockWrite writes[] = {
  1592. MockWrite(ASYNC, 0, 0) // EOF
  1593. };
  1594. MockRead reads[] = {
  1595. MockRead(ASYNC, 0, 1) // EOF
  1596. };
  1597. SequencedSocketData data(reads, writes);
  1598. UseUnreadableFilePostRequest();
  1599. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1600. helper.RunPreTestSetup();
  1601. helper.AddData(&data);
  1602. helper.RunDefaultTest();
  1603. base::RunLoop().RunUntilIdle();
  1604. helper.VerifyDataNotConsumed();
  1605. EXPECT_THAT(helper.output().rv, IsError(ERR_ACCESS_DENIED));
  1606. }
  1607. // Test that a complex POST works.
  1608. TEST_F(SpdyNetworkTransactionTest, ComplexPost) {
  1609. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  1610. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  1611. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1612. MockWrite writes[] = {
  1613. CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
  1614. };
  1615. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1616. MockRead reads[] = {
  1617. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  1618. MockRead(ASYNC, 0, 4) // EOF
  1619. };
  1620. SequencedSocketData data(reads, writes);
  1621. UseComplexPostRequest();
  1622. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1623. helper.RunToCompletion(&data);
  1624. TransactionHelperResult out = helper.output();
  1625. EXPECT_THAT(out.rv, IsOk());
  1626. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1627. EXPECT_EQ("hello!", out.response_data);
  1628. }
  1629. // Test that a chunked POST works.
  1630. TEST_F(SpdyNetworkTransactionTest, ChunkedPost) {
  1631. spdy::SpdySerializedFrame req(
  1632. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  1633. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1634. MockWrite writes[] = {
  1635. CreateMockWrite(req, 0), CreateMockWrite(body, 1),
  1636. };
  1637. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1638. MockRead reads[] = {
  1639. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  1640. MockRead(ASYNC, 0, 4) // EOF
  1641. };
  1642. SequencedSocketData data(reads, writes);
  1643. UseChunkedPostRequest();
  1644. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1645. // These chunks get merged into a single frame when being sent.
  1646. const int kFirstChunkSize = kUploadDataSize/2;
  1647. upload_chunked_data_stream()->AppendData(kUploadData, kFirstChunkSize, false);
  1648. upload_chunked_data_stream()->AppendData(
  1649. kUploadData + kFirstChunkSize, kUploadDataSize - kFirstChunkSize, true);
  1650. helper.RunToCompletion(&data);
  1651. TransactionHelperResult out = helper.output();
  1652. EXPECT_THAT(out.rv, IsOk());
  1653. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1654. EXPECT_EQ(kUploadData, out.response_data);
  1655. }
  1656. // Test that a chunked POST works with chunks appended after transaction starts.
  1657. TEST_F(SpdyNetworkTransactionTest, DelayedChunkedPost) {
  1658. spdy::SpdySerializedFrame req(
  1659. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  1660. spdy::SpdySerializedFrame chunk1(spdy_util_.ConstructSpdyDataFrame(1, false));
  1661. spdy::SpdySerializedFrame chunk2(spdy_util_.ConstructSpdyDataFrame(1, false));
  1662. spdy::SpdySerializedFrame chunk3(spdy_util_.ConstructSpdyDataFrame(1, true));
  1663. MockWrite writes[] = {
  1664. CreateMockWrite(req, 0), CreateMockWrite(chunk1, 1),
  1665. CreateMockWrite(chunk2, 2), CreateMockWrite(chunk3, 3),
  1666. };
  1667. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1668. MockRead reads[] = {
  1669. CreateMockRead(resp, 4), CreateMockRead(chunk1, 5),
  1670. CreateMockRead(chunk2, 6), CreateMockRead(chunk3, 7),
  1671. MockRead(ASYNC, 0, 8) // EOF
  1672. };
  1673. SequencedSocketData data(reads, writes);
  1674. UseChunkedPostRequest();
  1675. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1676. upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, false);
  1677. helper.RunPreTestSetup();
  1678. helper.AddData(&data);
  1679. ASSERT_TRUE(helper.StartDefaultTest());
  1680. base::RunLoop().RunUntilIdle();
  1681. upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, false);
  1682. base::RunLoop().RunUntilIdle();
  1683. upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, true);
  1684. helper.FinishDefaultTest();
  1685. helper.VerifyDataConsumed();
  1686. std::string expected_response;
  1687. expected_response += kUploadData;
  1688. expected_response += kUploadData;
  1689. expected_response += kUploadData;
  1690. TransactionHelperResult out = helper.output();
  1691. EXPECT_THAT(out.rv, IsOk());
  1692. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1693. EXPECT_EQ(expected_response, out.response_data);
  1694. }
  1695. // Test that a POST without any post data works.
  1696. TEST_F(SpdyNetworkTransactionTest, NullPost) {
  1697. // Setup the request.
  1698. request_.method = "POST";
  1699. // Create an empty UploadData.
  1700. request_.upload_data_stream = nullptr;
  1701. // When request.upload_data_stream is NULL for post, content-length is
  1702. // expected to be 0.
  1703. spdy::Http2HeaderBlock req_block(
  1704. spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
  1705. spdy::SpdySerializedFrame req(
  1706. spdy_util_.ConstructSpdyHeaders(1, std::move(req_block), LOWEST, true));
  1707. MockWrite writes[] = {
  1708. CreateMockWrite(req, 0),
  1709. };
  1710. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1711. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1712. MockRead reads[] = {
  1713. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  1714. MockRead(ASYNC, 0, 3) // EOF
  1715. };
  1716. SequencedSocketData data(reads, writes);
  1717. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1718. helper.RunToCompletion(&data);
  1719. TransactionHelperResult out = helper.output();
  1720. EXPECT_THAT(out.rv, IsOk());
  1721. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1722. EXPECT_EQ("hello!", out.response_data);
  1723. }
  1724. // Test that a simple POST works.
  1725. TEST_F(SpdyNetworkTransactionTest, EmptyPost) {
  1726. // Create an empty UploadDataStream.
  1727. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  1728. ElementsUploadDataStream stream(std::move(element_readers), 0);
  1729. // Setup the request.
  1730. request_.method = "POST";
  1731. request_.upload_data_stream = &stream;
  1732. const uint64_t kContentLength = 0;
  1733. spdy::Http2HeaderBlock req_block(
  1734. spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kContentLength));
  1735. spdy::SpdySerializedFrame req(
  1736. spdy_util_.ConstructSpdyHeaders(1, std::move(req_block), LOWEST, true));
  1737. MockWrite writes[] = {
  1738. CreateMockWrite(req, 0),
  1739. };
  1740. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1741. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1742. MockRead reads[] = {
  1743. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  1744. MockRead(ASYNC, 0, 3) // EOF
  1745. };
  1746. SequencedSocketData data(reads, writes);
  1747. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1748. helper.RunToCompletion(&data);
  1749. TransactionHelperResult out = helper.output();
  1750. EXPECT_THAT(out.rv, IsOk());
  1751. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1752. EXPECT_EQ("hello!", out.response_data);
  1753. }
  1754. // While we're doing a post, the server sends the reply before upload completes.
  1755. TEST_F(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) {
  1756. spdy::SpdySerializedFrame req(
  1757. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  1758. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1759. MockWrite writes[] = {
  1760. CreateMockWrite(req, 0), CreateMockWrite(body, 3),
  1761. };
  1762. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  1763. MockRead reads[] = {
  1764. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  1765. MockRead(ASYNC, 0, 4) // EOF
  1766. };
  1767. // Write the request headers, and read the complete response
  1768. // while still waiting for chunked request data.
  1769. SequencedSocketData data(reads, writes);
  1770. UseChunkedPostRequest();
  1771. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1772. helper.RunPreTestSetup();
  1773. helper.AddData(&data);
  1774. ASSERT_TRUE(helper.StartDefaultTest());
  1775. base::RunLoop().RunUntilIdle();
  1776. // Process the request headers, response headers, and response body.
  1777. // The request body is still in flight.
  1778. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  1779. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  1780. // Finish sending the request body.
  1781. upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, true);
  1782. helper.WaitForCallbackToComplete();
  1783. EXPECT_THAT(helper.output().rv, IsOk());
  1784. std::string response_body;
  1785. EXPECT_THAT(ReadTransaction(helper.trans(), &response_body), IsOk());
  1786. EXPECT_EQ(kUploadData, response_body);
  1787. // Finish async network reads/writes.
  1788. base::RunLoop().RunUntilIdle();
  1789. helper.VerifyDataConsumed();
  1790. }
  1791. // The client upon cancellation tries to send a RST_STREAM frame. The mock
  1792. // socket causes the TCP write to return zero. This test checks that the client
  1793. // tries to queue up the RST_STREAM frame again.
  1794. TEST_F(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
  1795. spdy::SpdySerializedFrame req(
  1796. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1797. spdy::SpdySerializedFrame rst(
  1798. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1799. MockWrite writes[] = {
  1800. CreateMockWrite(req, 0, SYNCHRONOUS),
  1801. MockWrite(SYNCHRONOUS, nullptr, 0, 2),
  1802. CreateMockWrite(rst, 3, SYNCHRONOUS),
  1803. };
  1804. spdy::SpdySerializedFrame resp(
  1805. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1806. MockRead reads[] = {
  1807. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, nullptr, 0, 4) // EOF
  1808. };
  1809. SequencedSocketData data(reads, writes);
  1810. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1811. helper.RunPreTestSetup();
  1812. helper.AddData(&data);
  1813. helper.StartDefaultTest();
  1814. EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
  1815. helper.WaitForCallbackToComplete();
  1816. EXPECT_THAT(helper.output().rv, IsOk());
  1817. helper.ResetTrans();
  1818. base::RunLoop().RunUntilIdle();
  1819. helper.VerifyDataConsumed();
  1820. }
  1821. // Test that the transaction doesn't crash when we don't have a reply.
  1822. TEST_F(SpdyNetworkTransactionTest, ResponseWithoutHeaders) {
  1823. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1824. MockRead reads[] = {
  1825. CreateMockRead(body, 1), MockRead(ASYNC, 0, 3) // EOF
  1826. };
  1827. spdy::SpdySerializedFrame req(
  1828. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1829. spdy::SpdySerializedFrame rst(
  1830. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  1831. MockWrite writes[] = {
  1832. CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
  1833. };
  1834. SequencedSocketData data(reads, writes);
  1835. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1836. helper.RunToCompletion(&data);
  1837. TransactionHelperResult out = helper.output();
  1838. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  1839. }
  1840. // Test that the transaction doesn't crash when we get two replies on the same
  1841. // stream ID. See http://crbug.com/45639.
  1842. TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
  1843. spdy::SpdySerializedFrame req(
  1844. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1845. spdy::SpdySerializedFrame rst(
  1846. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  1847. MockWrite writes[] = {
  1848. CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
  1849. };
  1850. spdy::SpdySerializedFrame resp0(
  1851. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1852. spdy::SpdySerializedFrame resp1(
  1853. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1854. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1855. MockRead reads[] = {
  1856. CreateMockRead(resp0, 1), CreateMockRead(resp1, 2),
  1857. CreateMockRead(body, 3), MockRead(ASYNC, 0, 5) // EOF
  1858. };
  1859. SequencedSocketData data(reads, writes);
  1860. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1861. helper.RunPreTestSetup();
  1862. helper.AddData(&data);
  1863. HttpNetworkTransaction* trans = helper.trans();
  1864. TestCompletionCallback callback;
  1865. int rv = trans->Start(&request_, callback.callback(), log_);
  1866. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  1867. rv = callback.WaitForResult();
  1868. EXPECT_THAT(rv, IsOk());
  1869. const HttpResponseInfo* response = trans->GetResponseInfo();
  1870. ASSERT_TRUE(response);
  1871. EXPECT_TRUE(response->headers);
  1872. EXPECT_TRUE(response->was_fetched_via_spdy);
  1873. std::string response_data;
  1874. rv = ReadTransaction(trans, &response_data);
  1875. EXPECT_THAT(rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  1876. helper.VerifyDataConsumed();
  1877. }
  1878. TEST_F(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) {
  1879. // Construct the request.
  1880. spdy::SpdySerializedFrame req(
  1881. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1882. spdy::SpdySerializedFrame rst(
  1883. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  1884. MockWrite writes[] = {
  1885. CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
  1886. };
  1887. const char* const headers[] = {
  1888. "transfer-encoding", "chunked"
  1889. };
  1890. spdy::SpdySerializedFrame resp(
  1891. spdy_util_.ConstructSpdyGetReply(headers, 1, 1));
  1892. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1893. MockRead reads[] = {
  1894. CreateMockRead(resp, 1), CreateMockRead(body, 3),
  1895. MockRead(ASYNC, 0, 4) // EOF
  1896. };
  1897. SequencedSocketData data(reads, writes);
  1898. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1899. helper.RunToCompletion(&data);
  1900. TransactionHelperResult out = helper.output();
  1901. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  1902. helper.session()->spdy_session_pool()->CloseAllSessions();
  1903. helper.VerifyDataConsumed();
  1904. }
  1905. TEST_F(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) {
  1906. // Construct the request.
  1907. spdy::SpdySerializedFrame req(
  1908. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1909. spdy::SpdySerializedFrame priority(
  1910. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  1911. spdy::SpdySerializedFrame rst(
  1912. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
  1913. MockWrite writes[] = {
  1914. CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
  1915. CreateMockWrite(rst, 5),
  1916. };
  1917. spdy::SpdySerializedFrame resp(
  1918. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1919. const char* const headers[] = {
  1920. "transfer-encoding", "chunked"
  1921. };
  1922. spdy::SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
  1923. headers, std::size(headers) / 2, 2, 1, "https://www.example.org/1"));
  1924. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  1925. MockRead reads[] = {
  1926. CreateMockRead(resp, 1), CreateMockRead(push, 2), CreateMockRead(body, 4),
  1927. MockRead(ASYNC, 0, 6) // EOF
  1928. };
  1929. SequencedSocketData data(reads, writes);
  1930. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1931. helper.RunToCompletion(&data);
  1932. TransactionHelperResult out = helper.output();
  1933. EXPECT_THAT(out.rv, IsOk());
  1934. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  1935. EXPECT_EQ("hello!", out.response_data);
  1936. helper.session()->spdy_session_pool()->CloseAllSessions();
  1937. helper.VerifyDataConsumed();
  1938. }
  1939. TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) {
  1940. // Construct the request.
  1941. spdy::SpdySerializedFrame req(
  1942. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1943. MockWrite writes[] = {
  1944. CreateMockWrite(req),
  1945. };
  1946. spdy::SpdySerializedFrame resp(
  1947. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1948. MockRead reads[] = {
  1949. CreateMockRead(resp),
  1950. // This following read isn't used by the test, except during the
  1951. // RunUntilIdle() call at the end since the SpdySession survives the
  1952. // HttpNetworkTransaction and still tries to continue Read()'ing. Any
  1953. // MockRead will do here.
  1954. MockRead(ASYNC, 0, 0) // EOF
  1955. };
  1956. StaticSocketDataProvider data(reads, writes);
  1957. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1958. helper.RunPreTestSetup();
  1959. helper.AddData(&data);
  1960. HttpNetworkTransaction* trans = helper.trans();
  1961. TestCompletionCallback callback;
  1962. int rv = trans->Start(&request_, callback.callback(), log_);
  1963. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  1964. helper.ResetTrans(); // Cancel the transaction.
  1965. // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
  1966. // MockClientSocketFactory) are still alive.
  1967. base::RunLoop().RunUntilIdle();
  1968. helper.VerifyDataNotConsumed();
  1969. }
  1970. // Verify that the client sends a Rst Frame upon cancelling the stream.
  1971. TEST_F(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
  1972. spdy::SpdySerializedFrame req(
  1973. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  1974. spdy::SpdySerializedFrame rst(
  1975. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1976. MockWrite writes[] = {
  1977. CreateMockWrite(req, 0, SYNCHRONOUS),
  1978. CreateMockWrite(rst, 2, SYNCHRONOUS),
  1979. };
  1980. spdy::SpdySerializedFrame resp(
  1981. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  1982. MockRead reads[] = {
  1983. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, nullptr, 0, 3) // EOF
  1984. };
  1985. SequencedSocketData data(reads, writes);
  1986. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  1987. helper.RunPreTestSetup();
  1988. helper.AddData(&data);
  1989. HttpNetworkTransaction* trans = helper.trans();
  1990. TestCompletionCallback callback;
  1991. int rv = trans->Start(&request_, callback.callback(), log_);
  1992. EXPECT_THAT(callback.GetResult(rv), IsOk());
  1993. helper.ResetTrans();
  1994. base::RunLoop().RunUntilIdle();
  1995. helper.VerifyDataConsumed();
  1996. }
  1997. // Verify that the client can correctly deal with the user callback attempting
  1998. // to start another transaction on a session that is closing down. See
  1999. // http://crbug.com/47455
  2000. TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
  2001. spdy::SpdySerializedFrame req(
  2002. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2003. MockWrite writes[] = {CreateMockWrite(req)};
  2004. MockWrite writes2[] = {CreateMockWrite(req, 0),
  2005. MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3)};
  2006. // The indicated length of this frame is longer than its actual length. When
  2007. // the session receives an empty frame after this one, it shuts down the
  2008. // session, and calls the read callback with the incomplete data.
  2009. const uint8_t kGetBodyFrame2[] = {
  2010. 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
  2011. 0x07, 'h', 'e', 'l', 'l', 'o', '!',
  2012. };
  2013. spdy::SpdySerializedFrame resp(
  2014. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2015. MockRead reads[] = {
  2016. CreateMockRead(resp, 1),
  2017. MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause
  2018. MockRead(ASYNC, reinterpret_cast<const char*>(kGetBodyFrame2),
  2019. std::size(kGetBodyFrame2), 3),
  2020. MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause
  2021. MockRead(ASYNC, nullptr, 0, 5), // EOF
  2022. };
  2023. MockRead reads2[] = {
  2024. CreateMockRead(resp, 1), MockRead(ASYNC, nullptr, 0, 2), // EOF
  2025. };
  2026. SequencedSocketData data(reads, writes);
  2027. SequencedSocketData data2(reads2, writes2);
  2028. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2029. helper.RunPreTestSetup();
  2030. helper.AddData(&data);
  2031. helper.AddData(&data2);
  2032. HttpNetworkTransaction* trans = helper.trans();
  2033. // Start the transaction with basic parameters.
  2034. TestCompletionCallback callback;
  2035. int rv = trans->Start(&request_, callback.callback(), log_);
  2036. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  2037. rv = callback.WaitForResult();
  2038. const int kSize = 3000;
  2039. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kSize);
  2040. rv = trans->Read(
  2041. buf.get(), kSize,
  2042. base::BindOnce(&SpdyNetworkTransactionTest::StartTransactionCallback,
  2043. helper.session(), default_url_, log_));
  2044. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  2045. // This forces an err_IO_pending, which sets the callback.
  2046. data.Resume();
  2047. data.RunUntilPaused();
  2048. // This finishes the read.
  2049. data.Resume();
  2050. base::RunLoop().RunUntilIdle();
  2051. helper.VerifyDataConsumed();
  2052. }
  2053. // Verify that the client can correctly deal with the user callback deleting
  2054. // the transaction. Failures will usually be flagged by thread and/or memory
  2055. // checking tools. See http://crbug.com/46925
  2056. TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
  2057. spdy::SpdySerializedFrame req(
  2058. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2059. MockWrite writes[] = {CreateMockWrite(req, 0)};
  2060. spdy::SpdySerializedFrame resp(
  2061. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2062. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  2063. MockRead reads[] = {
  2064. CreateMockRead(resp, 1),
  2065. MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause
  2066. CreateMockRead(body, 3), MockRead(ASYNC, nullptr, 0, 4), // EOF
  2067. };
  2068. SequencedSocketData data(reads, writes);
  2069. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2070. helper.RunPreTestSetup();
  2071. helper.AddData(&data);
  2072. HttpNetworkTransaction* trans = helper.trans();
  2073. // Start the transaction with basic parameters.
  2074. TestCompletionCallback callback;
  2075. int rv = trans->Start(&request_, callback.callback(), log_);
  2076. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  2077. rv = callback.WaitForResult();
  2078. // Setup a user callback which will delete the session, and clear out the
  2079. // memory holding the stream object. Note that the callback deletes trans.
  2080. const int kSize = 3000;
  2081. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kSize);
  2082. rv = trans->Read(
  2083. buf.get(), kSize,
  2084. base::BindOnce(&SpdyNetworkTransactionTest::DeleteSessionCallback,
  2085. base::Unretained(&helper)));
  2086. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  2087. data.Resume();
  2088. // Finish running rest of tasks.
  2089. base::RunLoop().RunUntilIdle();
  2090. helper.VerifyDataConsumed();
  2091. }
  2092. TEST_F(SpdyNetworkTransactionTest, RedirectGetRequest) {
  2093. MockClientSocketFactory socket_factory;
  2094. auto context_builder =
  2095. CreateSpdyTestURLRequestContextBuilder(&socket_factory);
  2096. auto spdy_url_request_context = context_builder->Build();
  2097. SpdySessionPoolPeer pool_peer(
  2098. spdy_url_request_context->http_transaction_factory()
  2099. ->GetSession()
  2100. ->spdy_session_pool());
  2101. pool_peer.SetEnableSendingInitialData(false);
  2102. // Use a different port to avoid trying to reuse the initial H2 session.
  2103. const char kRedirectUrl[] = "https://www.foo.com:8080/index.php";
  2104. SSLSocketDataProvider ssl_provider0(ASYNC, OK);
  2105. ssl_provider0.next_proto = kProtoHTTP2;
  2106. socket_factory.AddSSLSocketDataProvider(&ssl_provider0);
  2107. spdy::Http2HeaderBlock headers0(
  2108. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  2109. headers0["user-agent"] = "";
  2110. headers0["accept-encoding"] = "gzip, deflate";
  2111. spdy::SpdySerializedFrame req0(
  2112. spdy_util_.ConstructSpdyHeaders(1, std::move(headers0), LOWEST, true));
  2113. spdy::SpdySerializedFrame rst(
  2114. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  2115. MockWrite writes0[] = {CreateMockWrite(req0, 0), CreateMockWrite(rst, 2)};
  2116. const char* const kExtraHeaders[] = {"location", kRedirectUrl};
  2117. spdy::SpdySerializedFrame resp0(spdy_util_.ConstructSpdyReplyError(
  2118. "301", kExtraHeaders, std::size(kExtraHeaders) / 2, 1));
  2119. MockRead reads0[] = {CreateMockRead(resp0, 1), MockRead(ASYNC, 0, 3)};
  2120. SequencedSocketData data0(reads0, writes0);
  2121. socket_factory.AddSocketDataProvider(&data0);
  2122. SSLSocketDataProvider ssl_provider1(ASYNC, OK);
  2123. ssl_provider1.next_proto = kProtoHTTP2;
  2124. socket_factory.AddSSLSocketDataProvider(&ssl_provider1);
  2125. SpdyTestUtil spdy_util1;
  2126. spdy::Http2HeaderBlock headers1(
  2127. spdy_util1.ConstructGetHeaderBlock(kRedirectUrl));
  2128. headers1["user-agent"] = "";
  2129. headers1["accept-encoding"] = "gzip, deflate";
  2130. spdy::SpdySerializedFrame req1(
  2131. spdy_util1.ConstructSpdyHeaders(1, std::move(headers1), LOWEST, true));
  2132. MockWrite writes1[] = {CreateMockWrite(req1, 0)};
  2133. spdy::SpdySerializedFrame resp1(
  2134. spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
  2135. spdy::SpdySerializedFrame body1(spdy_util1.ConstructSpdyDataFrame(1, true));
  2136. MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  2137. MockRead(ASYNC, 0, 3)};
  2138. SequencedSocketData data1(reads1, writes1);
  2139. socket_factory.AddSocketDataProvider(&data1);
  2140. TestDelegate delegate;
  2141. std::unique_ptr<URLRequest> request = spdy_url_request_context->CreateRequest(
  2142. default_url_, DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  2143. request->Start();
  2144. delegate.RunUntilRedirect();
  2145. EXPECT_EQ(1, delegate.received_redirect_count());
  2146. request->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
  2147. absl::nullopt /* modified_headers */);
  2148. delegate.RunUntilComplete();
  2149. EXPECT_EQ(1, delegate.response_started_count());
  2150. EXPECT_FALSE(delegate.received_data_before_response());
  2151. EXPECT_THAT(delegate.request_status(), IsOk());
  2152. EXPECT_EQ("hello!", delegate.data_received());
  2153. // Pump the message loop to allow read data to be consumed.
  2154. base::RunLoop().RunUntilIdle();
  2155. EXPECT_TRUE(data0.AllReadDataConsumed());
  2156. EXPECT_TRUE(data0.AllWriteDataConsumed());
  2157. EXPECT_TRUE(data1.AllReadDataConsumed());
  2158. EXPECT_TRUE(data1.AllWriteDataConsumed());
  2159. }
  2160. TEST_F(SpdyNetworkTransactionTest, RedirectServerPush) {
  2161. const char redirected_url[] = "https://www.foo.com/index.php";
  2162. MockClientSocketFactory socket_factory;
  2163. auto context_builder =
  2164. CreateSpdyTestURLRequestContextBuilder(&socket_factory);
  2165. auto spdy_url_request_context = context_builder->Build();
  2166. SpdySessionPoolPeer pool_peer(
  2167. spdy_url_request_context->http_transaction_factory()
  2168. ->GetSession()
  2169. ->spdy_session_pool());
  2170. pool_peer.SetEnableSendingInitialData(false);
  2171. SSLSocketDataProvider ssl_provider0(ASYNC, OK);
  2172. ssl_provider0.next_proto = kProtoHTTP2;
  2173. ssl_provider0.ssl_info.cert =
  2174. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  2175. ASSERT_TRUE(ssl_provider0.ssl_info.cert);
  2176. socket_factory.AddSSLSocketDataProvider(&ssl_provider0);
  2177. spdy::Http2HeaderBlock headers0(
  2178. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  2179. headers0["user-agent"] = "";
  2180. headers0["accept-encoding"] = "gzip, deflate";
  2181. spdy::SpdySerializedFrame req0(
  2182. spdy_util_.ConstructSpdyHeaders(1, std::move(headers0), LOWEST, true));
  2183. spdy::SpdySerializedFrame priority(
  2184. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2185. spdy::SpdySerializedFrame rst(
  2186. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL));
  2187. MockWrite writes[] = {CreateMockWrite(req0, 0), CreateMockWrite(priority, 3),
  2188. CreateMockWrite(rst, 5)};
  2189. spdy::SpdySerializedFrame resp0(
  2190. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2191. spdy::SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
  2192. nullptr, 0, 2, 1, kPushedUrl, "301", redirected_url));
  2193. spdy::SpdySerializedFrame body0(spdy_util_.ConstructSpdyDataFrame(1, true));
  2194. MockRead reads[] = {CreateMockRead(resp0, 1), CreateMockRead(push, 2),
  2195. CreateMockRead(body0, 4), MockRead(ASYNC, 0, 6)};
  2196. SequencedSocketData data0(reads, writes);
  2197. socket_factory.AddSocketDataProvider(&data0);
  2198. SSLSocketDataProvider ssl_provider1(ASYNC, OK);
  2199. ssl_provider1.next_proto = kProtoHTTP2;
  2200. socket_factory.AddSSLSocketDataProvider(&ssl_provider1);
  2201. SpdyTestUtil spdy_util1;
  2202. spdy::Http2HeaderBlock headers1(
  2203. spdy_util1.ConstructGetHeaderBlock(redirected_url));
  2204. headers1["user-agent"] = "";
  2205. headers1["accept-encoding"] = "gzip, deflate";
  2206. spdy::SpdySerializedFrame req1(
  2207. spdy_util1.ConstructSpdyHeaders(1, std::move(headers1), LOWEST, true));
  2208. MockWrite writes1[] = {CreateMockWrite(req1, 0)};
  2209. spdy::SpdySerializedFrame resp1(
  2210. spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
  2211. spdy::SpdySerializedFrame body1(spdy_util1.ConstructSpdyDataFrame(1, true));
  2212. MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  2213. MockRead(ASYNC, 0, 3)};
  2214. SequencedSocketData data1(reads1, writes1);
  2215. socket_factory.AddSocketDataProvider(&data1);
  2216. TestDelegate delegate0;
  2217. std::unique_ptr<URLRequest> request = spdy_url_request_context->CreateRequest(
  2218. default_url_, DEFAULT_PRIORITY, &delegate0, TRAFFIC_ANNOTATION_FOR_TESTS);
  2219. request->Start();
  2220. delegate0.RunUntilComplete();
  2221. EXPECT_EQ(0, delegate0.received_redirect_count());
  2222. EXPECT_EQ("hello!", delegate0.data_received());
  2223. TestDelegate delegate1;
  2224. std::unique_ptr<URLRequest> request1 =
  2225. spdy_url_request_context->CreateRequest(GURL(kPushedUrl),
  2226. DEFAULT_PRIORITY, &delegate1,
  2227. TRAFFIC_ANNOTATION_FOR_TESTS);
  2228. request1->Start();
  2229. delegate1.RunUntilRedirect();
  2230. EXPECT_EQ(1, delegate1.received_redirect_count());
  2231. request1->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
  2232. absl::nullopt /* modified_headers */);
  2233. delegate1.RunUntilComplete();
  2234. EXPECT_EQ(1, delegate1.response_started_count());
  2235. EXPECT_FALSE(delegate1.received_data_before_response());
  2236. EXPECT_EQ(OK, delegate1.request_status());
  2237. EXPECT_EQ("hello!", delegate1.data_received());
  2238. // Pump the message loop to allow read data to be consumed.
  2239. base::RunLoop().RunUntilIdle();
  2240. EXPECT_TRUE(data0.AllReadDataConsumed());
  2241. EXPECT_TRUE(data0.AllWriteDataConsumed());
  2242. EXPECT_TRUE(data1.AllReadDataConsumed());
  2243. EXPECT_TRUE(data1.AllWriteDataConsumed());
  2244. }
  2245. TEST_F(SpdyNetworkTransactionTest, RedirectMultipleLocations) {
  2246. const spdy::SpdyStreamId kStreamId = 1;
  2247. // Construct the request and the RST frame.
  2248. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(
  2249. /*extra_headers=*/nullptr, /*extra_header_count=*/0, kStreamId, LOWEST));
  2250. spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
  2251. kStreamId, spdy::ERROR_CODE_PROTOCOL_ERROR));
  2252. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 4)};
  2253. // Construct the response.
  2254. const char* const kExtraResponseHeaders[] = {
  2255. "location",
  2256. "https://example1.test",
  2257. "location",
  2258. "https://example2.test",
  2259. };
  2260. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
  2261. "301", kExtraResponseHeaders, std::size(kExtraResponseHeaders) / 2,
  2262. kStreamId));
  2263. spdy::SpdySerializedFrame body(
  2264. spdy_util_.ConstructSpdyDataFrame(kStreamId, /*fin=*/true));
  2265. MockRead reads[] = {
  2266. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  2267. MockRead(ASYNC, 0, 3) // EOF
  2268. };
  2269. SequencedSocketData data(reads, writes);
  2270. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2271. helper.RunToCompletion(&data);
  2272. TransactionHelperResult out = helper.output();
  2273. EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
  2274. }
  2275. TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
  2276. spdy::SpdySerializedFrame stream1_syn(
  2277. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2278. spdy::SpdySerializedFrame stream2_priority(
  2279. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2280. MockWrite writes[] = {
  2281. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2282. };
  2283. spdy::SpdySerializedFrame stream1_reply(
  2284. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2285. spdy::SpdySerializedFrame stream2_syn(
  2286. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2287. spdy::SpdySerializedFrame stream1_body(
  2288. spdy_util_.ConstructSpdyDataFrame(1, true));
  2289. const char kPushedData[] = "pushed";
  2290. spdy::SpdySerializedFrame stream2_body(
  2291. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  2292. MockRead reads[] = {
  2293. CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
  2294. CreateMockRead(stream1_body, 4), CreateMockRead(stream2_body, 5),
  2295. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a pause
  2296. };
  2297. HttpResponseInfo response;
  2298. HttpResponseInfo response2;
  2299. std::string expected_push_result("pushed");
  2300. SequencedSocketData data(reads, writes);
  2301. RunServerPushTest(&data,
  2302. &response,
  2303. &response2,
  2304. expected_push_result);
  2305. // Verify the response headers.
  2306. EXPECT_TRUE(response.headers);
  2307. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2308. // Verify the pushed stream.
  2309. EXPECT_TRUE(response2.headers);
  2310. EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
  2311. }
  2312. // When server push is disabled by
  2313. // HttpNetworkSession::initial_settings[SETTINGS_ENABLE_PUSH] = 0, verify that
  2314. // such a setting is sent out in the initial SETTINGS frame, and if the server
  2315. // creates a pushed stream despite of this, it is immediately reset.
  2316. TEST_F(SpdyNetworkTransactionTest, ServerPushDisabled) {
  2317. base::HistogramTester histogram_tester;
  2318. spdy::SpdySerializedFrame preface(
  2319. const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
  2320. spdy::kHttp2ConnectionHeaderPrefixSize,
  2321. /* owns_buffer = */ false);
  2322. spdy::SettingsMap initial_settings;
  2323. initial_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
  2324. initial_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
  2325. initial_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
  2326. kSpdyMaxConcurrentPushedStreams;
  2327. initial_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
  2328. kSpdyMaxHeaderListSize;
  2329. spdy::SpdySerializedFrame initial_settings_frame(
  2330. spdy_util_.ConstructSpdySettings(initial_settings));
  2331. spdy::SpdySerializedFrame req(
  2332. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2333. spdy::SpdySerializedFrame rst(
  2334. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  2335. MockWrite writes[] = {CreateMockWrite(preface, 0),
  2336. CreateMockWrite(initial_settings_frame, 1),
  2337. CreateMockWrite(req, 2), CreateMockWrite(rst, 5)};
  2338. spdy::SpdySerializedFrame reply(
  2339. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2340. spdy::SpdySerializedFrame push(
  2341. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2342. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  2343. MockRead reads[] = {CreateMockRead(reply, 3), CreateMockRead(push, 4),
  2344. CreateMockRead(body, 6), MockRead(ASYNC, OK, 7)};
  2345. SequencedSocketData data(reads, writes);
  2346. auto session_deps = std::make_unique<SpdySessionDependencies>();
  2347. session_deps->http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
  2348. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  2349. std::move(session_deps));
  2350. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  2351. SpdySessionPoolPeer pool_peer(spdy_session_pool);
  2352. pool_peer.SetEnableSendingInitialData(true);
  2353. helper.RunToCompletion(&data);
  2354. histogram_tester.ExpectBucketCount(
  2355. "Net.SpdyPushedStreamFate",
  2356. static_cast<int>(SpdyPushedStreamFate::kPushDisabled), 1);
  2357. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  2358. }
  2359. TEST_F(SpdyNetworkTransactionTest, ServerPushHeadMethod) {
  2360. spdy::SpdySerializedFrame req(
  2361. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2362. spdy::SpdySerializedFrame priority(
  2363. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2364. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 2)};
  2365. spdy::Http2HeaderBlock push_promise_header_block;
  2366. push_promise_header_block[spdy::kHttp2MethodHeader] = "HEAD";
  2367. spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_promise_header_block);
  2368. spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
  2369. 1, 2, std::move(push_promise_header_block)));
  2370. spdy::Http2HeaderBlock push_response_headers;
  2371. push_response_headers[spdy::kHttp2StatusHeader] = "200";
  2372. push_response_headers["foo"] = "bar";
  2373. spdy::SpdyHeadersIR headers_ir(2, std::move(push_response_headers));
  2374. spdy::SpdySerializedFrame push_headers(spdy_util_.SerializeFrame(headers_ir));
  2375. spdy::SpdySerializedFrame resp(
  2376. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2377. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  2378. MockRead reads[] = {
  2379. CreateMockRead(push_promise, 1), CreateMockRead(push_headers, 3),
  2380. CreateMockRead(resp, 4), CreateMockRead(body, 5),
  2381. // Do not close the connection after first request is done.
  2382. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
  2383. SequencedSocketData data(reads, writes);
  2384. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2385. helper.RunPreTestSetup();
  2386. helper.AddData(&data);
  2387. // Run first request. This reads PUSH_PROMISE.
  2388. helper.RunDefaultTest();
  2389. // Request the pushed resource.
  2390. HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
  2391. HttpRequestInfo request = CreateGetPushRequest();
  2392. request.method = "HEAD";
  2393. request.traffic_annotation =
  2394. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  2395. TestCompletionCallback callback;
  2396. int rv = trans.Start(&request, callback.callback(), log_);
  2397. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  2398. rv = callback.WaitForResult();
  2399. EXPECT_THAT(rv, IsOk());
  2400. const HttpResponseInfo* response = trans.GetResponseInfo();
  2401. ASSERT_TRUE(response);
  2402. EXPECT_TRUE(response->was_fetched_via_spdy);
  2403. EXPECT_TRUE(response->was_alpn_negotiated);
  2404. ASSERT_TRUE(response->headers);
  2405. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  2406. std::string value;
  2407. EXPECT_TRUE(response->headers->GetNormalizedHeader("foo", &value));
  2408. EXPECT_EQ("bar", value);
  2409. helper.VerifyDataConsumed();
  2410. }
  2411. TEST_F(SpdyNetworkTransactionTest, ServerPushHeadDoesNotMatchGetRequest) {
  2412. spdy::SpdySerializedFrame req1(
  2413. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2414. spdy::SpdySerializedFrame priority(
  2415. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2416. spdy_util_.UpdateWithStreamDestruction(1);
  2417. spdy::SpdySerializedFrame req2(
  2418. spdy_util_.ConstructSpdyGet(kPushedUrl, 3, LOWEST));
  2419. MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(priority, 2),
  2420. CreateMockWrite(req2, 6)};
  2421. spdy::Http2HeaderBlock push_promise_header_block;
  2422. push_promise_header_block[spdy::kHttp2MethodHeader] = "HEAD";
  2423. spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_promise_header_block);
  2424. spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
  2425. 1, 2, std::move(push_promise_header_block)));
  2426. spdy::Http2HeaderBlock push_response_headers;
  2427. push_response_headers[spdy::kHttp2StatusHeader] = "200";
  2428. push_response_headers["foo"] = "bar";
  2429. spdy::SpdyHeadersIR headers_ir(2, std::move(push_response_headers));
  2430. spdy::SpdySerializedFrame push_headers(spdy_util_.SerializeFrame(headers_ir));
  2431. spdy::SpdySerializedFrame resp1(
  2432. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2433. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  2434. spdy::SpdySerializedFrame resp2(
  2435. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  2436. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  2437. MockRead reads[] = {CreateMockRead(push_promise, 1),
  2438. CreateMockRead(push_headers, 3),
  2439. CreateMockRead(resp1, 4),
  2440. CreateMockRead(body1, 5),
  2441. CreateMockRead(resp2, 7),
  2442. CreateMockRead(body2, 8),
  2443. MockRead(ASYNC, 0, 9)};
  2444. SequencedSocketData data(reads, writes);
  2445. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2446. helper.RunPreTestSetup();
  2447. helper.AddData(&data);
  2448. // Run first request. This reads PUSH_PROMISE.
  2449. helper.RunDefaultTest();
  2450. // Request the pushed resource.
  2451. HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
  2452. HttpRequestInfo request = CreateGetPushRequest();
  2453. TestCompletionCallback callback;
  2454. int rv = trans.Start(&request, callback.callback(), log_);
  2455. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  2456. rv = callback.WaitForResult();
  2457. EXPECT_THAT(rv, IsOk());
  2458. const HttpResponseInfo* response = trans.GetResponseInfo();
  2459. ASSERT_TRUE(response);
  2460. EXPECT_TRUE(response->was_fetched_via_spdy);
  2461. EXPECT_TRUE(response->was_alpn_negotiated);
  2462. ASSERT_TRUE(response->headers);
  2463. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  2464. std::string value;
  2465. EXPECT_FALSE(response->headers->GetNormalizedHeader("foo", &value));
  2466. std::string result;
  2467. ReadResult(&trans, &result);
  2468. EXPECT_EQ("hello!", result);
  2469. // Read EOF.
  2470. base::RunLoop().RunUntilIdle();
  2471. helper.VerifyDataConsumed();
  2472. }
  2473. TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
  2474. spdy::SpdySerializedFrame stream1_syn(
  2475. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2476. spdy::SpdySerializedFrame stream2_priority(
  2477. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2478. MockWrite writes[] = {
  2479. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2480. };
  2481. spdy::SpdySerializedFrame stream1_reply(
  2482. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2483. spdy::SpdySerializedFrame stream2_syn(
  2484. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2485. const char kPushedData[] = "pushed";
  2486. spdy::SpdySerializedFrame stream2_body(
  2487. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  2488. spdy::SpdySerializedFrame stream1_body(
  2489. spdy_util_.ConstructSpdyDataFrame(1, true));
  2490. MockRead reads[] = {
  2491. CreateMockRead(stream1_reply, 1),
  2492. CreateMockRead(stream2_syn, 2),
  2493. CreateMockRead(stream2_body, 4),
  2494. CreateMockRead(stream1_body, 5, SYNCHRONOUS),
  2495. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a pause
  2496. };
  2497. HttpResponseInfo response;
  2498. HttpResponseInfo response2;
  2499. std::string expected_push_result("pushed");
  2500. SequencedSocketData data(reads, writes);
  2501. RunServerPushTest(&data,
  2502. &response,
  2503. &response2,
  2504. expected_push_result);
  2505. // Verify the response headers.
  2506. EXPECT_TRUE(response.headers);
  2507. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2508. // Verify the pushed stream.
  2509. EXPECT_TRUE(response2.headers);
  2510. EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
  2511. }
  2512. TEST_F(SpdyNetworkTransactionTest, ServerPushUpdatesPriority) {
  2513. spdy::SpdySerializedFrame stream1_headers(
  2514. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  2515. spdy::SpdySerializedFrame stream3_headers(
  2516. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  2517. spdy::SpdySerializedFrame stream5_headers(
  2518. spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM));
  2519. // Stream 1 pushes two streams that are initially prioritized below stream 5.
  2520. // Stream 2 is later prioritized below stream 1 after it matches a request.
  2521. spdy::SpdySerializedFrame stream2_priority(
  2522. spdy_util_.ConstructSpdyPriority(2, 5, IDLE, true));
  2523. spdy::SpdySerializedFrame stream4_priority(
  2524. spdy_util_.ConstructSpdyPriority(4, 2, IDLE, true));
  2525. spdy::SpdySerializedFrame stream4_priority_update(
  2526. spdy_util_.ConstructSpdyPriority(4, 5, IDLE, true));
  2527. spdy::SpdySerializedFrame stream2_priority_update(
  2528. spdy_util_.ConstructSpdyPriority(2, 1, HIGHEST, true));
  2529. MockWrite writes[] = {
  2530. CreateMockWrite(stream1_headers, 0),
  2531. CreateMockWrite(stream3_headers, 1),
  2532. CreateMockWrite(stream5_headers, 2),
  2533. CreateMockWrite(stream2_priority, 7),
  2534. CreateMockWrite(stream4_priority, 9),
  2535. CreateMockWrite(stream4_priority_update, 11),
  2536. CreateMockWrite(stream2_priority_update, 12),
  2537. };
  2538. spdy::SpdySerializedFrame stream1_reply(
  2539. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2540. spdy::SpdySerializedFrame stream3_reply(
  2541. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  2542. spdy::SpdySerializedFrame stream5_reply(
  2543. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  2544. spdy::SpdySerializedFrame stream2_push(
  2545. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2546. spdy::SpdySerializedFrame stream4_push(spdy_util_.ConstructSpdyPush(
  2547. nullptr, 0, 4, 1, "https://www.example.org/bar.dat"));
  2548. spdy::SpdySerializedFrame stream1_body(
  2549. spdy_util_.ConstructSpdyDataFrame(1, true));
  2550. spdy::SpdySerializedFrame stream2_body(
  2551. spdy_util_.ConstructSpdyDataFrame(2, true));
  2552. spdy::SpdySerializedFrame stream3_body(
  2553. spdy_util_.ConstructSpdyDataFrame(3, true));
  2554. spdy::SpdySerializedFrame stream5_body(
  2555. spdy_util_.ConstructSpdyDataFrame(5, true));
  2556. MockRead reads[] = {
  2557. CreateMockRead(stream1_reply, 3),
  2558. CreateMockRead(stream3_reply, 4),
  2559. CreateMockRead(stream5_reply, 5),
  2560. CreateMockRead(stream2_push, 6),
  2561. CreateMockRead(stream4_push, 8),
  2562. MockRead(ASYNC, ERR_IO_PENDING, 10),
  2563. CreateMockRead(stream1_body, 13),
  2564. CreateMockRead(stream2_body, 14),
  2565. CreateMockRead(stream3_body, 15),
  2566. CreateMockRead(stream5_body, 16),
  2567. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 17), // Force a pause
  2568. };
  2569. SequencedSocketData data(reads, writes);
  2570. SequencedSocketData data_placeholder1;
  2571. SequencedSocketData data_placeholder2;
  2572. SequencedSocketData data_placeholder3;
  2573. NormalSpdyTransactionHelper helper(request_, LOWEST, log_, nullptr);
  2574. helper.RunPreTestSetup();
  2575. helper.AddData(&data);
  2576. helper.AddData(&data_placeholder1); // other requests reuse the same socket
  2577. helper.AddData(&data_placeholder2);
  2578. helper.AddData(&data_placeholder3);
  2579. HttpNetworkTransaction trans1(HIGHEST, helper.session());
  2580. HttpNetworkTransaction trans3(MEDIUM, helper.session());
  2581. HttpNetworkTransaction trans5(MEDIUM, helper.session());
  2582. TestCompletionCallback callback1;
  2583. TestCompletionCallback callback3;
  2584. TestCompletionCallback callback5;
  2585. // Start the ordinary requests.
  2586. ASSERT_THAT(trans1.Start(&request_, callback1.callback(), log_),
  2587. IsError(ERR_IO_PENDING));
  2588. ASSERT_THAT(trans3.Start(&request_, callback3.callback(), log_),
  2589. IsError(ERR_IO_PENDING));
  2590. ASSERT_THAT(trans5.Start(&request_, callback5.callback(), log_),
  2591. IsError(ERR_IO_PENDING));
  2592. data.RunUntilPaused();
  2593. // Start a request that matches the push.
  2594. HttpRequestInfo push_req = CreateGetPushRequest();
  2595. HttpNetworkTransaction trans2(HIGHEST, helper.session());
  2596. TestCompletionCallback callback2;
  2597. ASSERT_THAT(trans2.Start(&push_req, callback2.callback(), log_),
  2598. IsError(ERR_IO_PENDING));
  2599. data.Resume();
  2600. base::RunLoop().RunUntilIdle();
  2601. ASSERT_THAT(callback1.WaitForResult(), IsOk());
  2602. ASSERT_THAT(callback2.WaitForResult(), IsOk());
  2603. ASSERT_THAT(callback3.WaitForResult(), IsOk());
  2604. ASSERT_THAT(callback5.WaitForResult(), IsOk());
  2605. helper.VerifyDataConsumed();
  2606. }
  2607. TEST_F(SpdyNetworkTransactionTest, ServerPushServerAborted) {
  2608. spdy::SpdySerializedFrame stream1_syn(
  2609. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2610. spdy::SpdySerializedFrame stream2_priority(
  2611. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2612. MockWrite writes[] = {
  2613. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2614. };
  2615. spdy::SpdySerializedFrame stream1_reply(
  2616. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2617. spdy::SpdySerializedFrame stream2_syn(
  2618. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2619. spdy::SpdySerializedFrame stream2_rst(
  2620. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_PROTOCOL_ERROR));
  2621. spdy::SpdySerializedFrame stream1_body(
  2622. spdy_util_.ConstructSpdyDataFrame(1, true));
  2623. MockRead reads[] = {
  2624. CreateMockRead(stream1_reply, 1),
  2625. CreateMockRead(stream2_syn, 2, SYNCHRONOUS),
  2626. CreateMockRead(stream2_rst, 4),
  2627. CreateMockRead(stream1_body, 5, SYNCHRONOUS),
  2628. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a pause
  2629. };
  2630. SequencedSocketData data(reads, writes);
  2631. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2632. helper.RunPreTestSetup();
  2633. helper.AddData(&data);
  2634. HttpNetworkTransaction* trans = helper.trans();
  2635. // Start the transaction with basic parameters.
  2636. TestCompletionCallback callback;
  2637. int rv = trans->Start(&request_, callback.callback(), log_);
  2638. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  2639. rv = callback.WaitForResult();
  2640. EXPECT_THAT(rv, IsOk());
  2641. // Verify that we consumed all test data.
  2642. base::RunLoop().RunUntilIdle();
  2643. EXPECT_TRUE(data.AllReadDataConsumed());
  2644. EXPECT_TRUE(data.AllWriteDataConsumed());
  2645. // Verify the response headers.
  2646. HttpResponseInfo response = *trans->GetResponseInfo();
  2647. EXPECT_TRUE(response.headers);
  2648. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2649. }
  2650. // Verify that we don't leak streams and that we properly send a reset
  2651. // if the server pushes the same stream twice.
  2652. TEST_F(SpdyNetworkTransactionTest, ServerPushDuplicate) {
  2653. base::HistogramTester histogram_tester;
  2654. spdy::SpdySerializedFrame stream1_syn(
  2655. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2656. spdy::SpdySerializedFrame stream2_priority(
  2657. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2658. spdy::SpdySerializedFrame stream3_rst(
  2659. spdy_util_.ConstructSpdyRstStream(4, spdy::ERROR_CODE_REFUSED_STREAM));
  2660. MockWrite writes[] = {
  2661. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2662. CreateMockWrite(stream3_rst, 5),
  2663. };
  2664. spdy::SpdySerializedFrame stream1_reply(
  2665. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2666. spdy::SpdySerializedFrame stream2_syn(
  2667. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2668. spdy::SpdySerializedFrame stream3_syn(
  2669. spdy_util_.ConstructSpdyPush(nullptr, 0, 4, 1, kPushedUrl));
  2670. const char kPushedData[] = "pushed";
  2671. spdy::SpdySerializedFrame stream1_body(
  2672. spdy_util_.ConstructSpdyDataFrame(1, true));
  2673. spdy::SpdySerializedFrame stream2_body(
  2674. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  2675. MockRead reads[] = {
  2676. CreateMockRead(stream1_reply, 1),
  2677. CreateMockRead(stream2_syn, 2),
  2678. CreateMockRead(stream3_syn, 4),
  2679. CreateMockRead(stream1_body, 6),
  2680. CreateMockRead(stream2_body, 7),
  2681. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8), // Force a pause
  2682. };
  2683. HttpResponseInfo response;
  2684. HttpResponseInfo response2;
  2685. std::string expected_push_result("pushed");
  2686. SequencedSocketData data(reads, writes);
  2687. RunServerPushTest(&data,
  2688. &response,
  2689. &response2,
  2690. expected_push_result);
  2691. // Verify the response headers.
  2692. EXPECT_TRUE(response.headers);
  2693. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2694. // Verify the pushed stream.
  2695. EXPECT_TRUE(response2.headers);
  2696. EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
  2697. histogram_tester.ExpectBucketCount(
  2698. "Net.SpdyPushedStreamFate",
  2699. static_cast<int>(SpdyPushedStreamFate::kAcceptedNoVary), 1);
  2700. histogram_tester.ExpectBucketCount(
  2701. "Net.SpdyPushedStreamFate",
  2702. static_cast<int>(SpdyPushedStreamFate::kDuplicateUrl), 1);
  2703. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 2);
  2704. }
  2705. TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
  2706. spdy::SpdySerializedFrame stream1_syn(
  2707. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2708. spdy::SpdySerializedFrame stream2_priority(
  2709. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2710. MockWrite writes[] = {
  2711. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2712. };
  2713. spdy::SpdySerializedFrame stream1_reply(
  2714. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2715. spdy::SpdySerializedFrame stream2_syn(
  2716. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2717. static const char kPushedData[] = "pushed payload for chunked test";
  2718. spdy::SpdySerializedFrame stream2_body_base(
  2719. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  2720. const size_t kChunkSize = strlen(kPushedData) / 4;
  2721. spdy::SpdySerializedFrame stream2_body1(stream2_body_base.data(), kChunkSize,
  2722. false);
  2723. spdy::SpdySerializedFrame stream2_body2(stream2_body_base.data() + kChunkSize,
  2724. kChunkSize, false);
  2725. spdy::SpdySerializedFrame stream2_body3(
  2726. stream2_body_base.data() + 2 * kChunkSize, kChunkSize, false);
  2727. spdy::SpdySerializedFrame stream2_body4(
  2728. stream2_body_base.data() + 3 * kChunkSize,
  2729. stream2_body_base.size() - 3 * kChunkSize, false);
  2730. spdy::SpdySerializedFrame stream1_body(
  2731. spdy_util_.ConstructSpdyDataFrame(1, true));
  2732. MockRead reads[] = {
  2733. CreateMockRead(stream1_reply, 1),
  2734. CreateMockRead(stream2_syn, 2),
  2735. CreateMockRead(stream2_body1, 4),
  2736. CreateMockRead(stream2_body2, 5),
  2737. CreateMockRead(stream2_body3, 6),
  2738. CreateMockRead(stream2_body4, 7),
  2739. CreateMockRead(stream1_body, 8, SYNCHRONOUS),
  2740. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 9), // Force a pause
  2741. };
  2742. HttpResponseInfo response;
  2743. HttpResponseInfo response2;
  2744. std::string expected_push_result(kPushedData);
  2745. SequencedSocketData data(reads, writes);
  2746. RunServerPushTest(&data, &response, &response2, kPushedData);
  2747. // Verify the response headers.
  2748. EXPECT_TRUE(response.headers);
  2749. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2750. // Verify the pushed stream.
  2751. EXPECT_TRUE(response2.headers);
  2752. EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
  2753. }
  2754. TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
  2755. spdy::SpdySerializedFrame stream1_syn(
  2756. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2757. spdy::SpdySerializedFrame stream2_priority(
  2758. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2759. MockWrite writes[] = {
  2760. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2761. };
  2762. spdy::SpdySerializedFrame stream1_reply(
  2763. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2764. spdy::SpdySerializedFrame stream2_syn(
  2765. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2766. static const char kPushedData[] = "pushed payload for chunked test";
  2767. spdy::SpdySerializedFrame stream2_body_base(
  2768. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  2769. const size_t kChunkSize = strlen(kPushedData) / 4;
  2770. spdy::SpdySerializedFrame stream2_body1(stream2_body_base.data(), kChunkSize,
  2771. false);
  2772. spdy::SpdySerializedFrame stream2_body2(stream2_body_base.data() + kChunkSize,
  2773. kChunkSize, false);
  2774. spdy::SpdySerializedFrame stream2_body3(
  2775. stream2_body_base.data() + 2 * kChunkSize, kChunkSize, false);
  2776. spdy::SpdySerializedFrame stream2_body4(
  2777. stream2_body_base.data() + 3 * kChunkSize,
  2778. stream2_body_base.size() - 3 * kChunkSize, false);
  2779. spdy::SpdySerializedFrame stream1_body(
  2780. spdy_util_.ConstructSpdyDataFrame(1, true));
  2781. MockRead reads[] = {
  2782. CreateMockRead(stream1_reply, 1),
  2783. CreateMockRead(stream2_syn, 2),
  2784. CreateMockRead(stream2_body1, 4),
  2785. CreateMockRead(stream2_body2, 5),
  2786. CreateMockRead(stream2_body3, 6),
  2787. CreateMockRead(stream2_body4, 7),
  2788. CreateMockRead(stream1_body, 8, SYNCHRONOUS),
  2789. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 9) // Force a pause.
  2790. };
  2791. HttpResponseInfo response;
  2792. HttpResponseInfo response2;
  2793. SequencedSocketData data(reads, writes);
  2794. RunServerPushTest(&data, &response, &response2, kPushedData);
  2795. // Verify the response headers.
  2796. EXPECT_TRUE(response.headers);
  2797. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2798. // Verify the pushed stream.
  2799. EXPECT_TRUE(response2.headers);
  2800. EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
  2801. }
  2802. TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidUrl) {
  2803. base::HistogramTester histogram_tester;
  2804. // Coverage on how a non-empty invalid GURL in a PUSH_PROMISE is handled.
  2805. spdy::Http2HeaderBlock headers(
  2806. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  2807. spdy::SpdySerializedFrame req(
  2808. spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
  2809. // Can't use ConstructSpdyPush here since it wants to parse a URL and
  2810. // split it into the appropriate :header pieces. So we have to hand-fill
  2811. // those pieces in.
  2812. spdy::Http2HeaderBlock push_promise_header_block;
  2813. push_promise_header_block[spdy::kHttp2AuthorityHeader] = "";
  2814. push_promise_header_block[spdy::kHttp2SchemeHeader] = "";
  2815. push_promise_header_block[spdy::kHttp2PathHeader] = "/index.html";
  2816. spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
  2817. 1, 2, std::move(push_promise_header_block)));
  2818. spdy::SpdySerializedFrame stream2_rst(
  2819. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  2820. MockWrite writes[] = {CreateMockWrite(req, 0),
  2821. CreateMockWrite(stream2_rst, 2)};
  2822. MockRead reads[] = {
  2823. CreateMockRead(push_promise, 1), MockRead(ASYNC, 0, 3) /* EOF */
  2824. };
  2825. SequencedSocketData data(reads, writes);
  2826. RunBrokenPushTest(&data, ERR_CONNECTION_CLOSED);
  2827. histogram_tester.ExpectBucketCount(
  2828. "Net.SpdyPushedStreamFate",
  2829. static_cast<int>(SpdyPushedStreamFate::kInvalidUrl), 1);
  2830. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  2831. }
  2832. TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
  2833. spdy::SpdySerializedFrame stream1_syn(
  2834. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2835. spdy::SpdySerializedFrame goaway(
  2836. spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_PROTOCOL_ERROR,
  2837. "Framer error: 1 (INVALID_STREAM_ID)."));
  2838. MockWrite writes[] = {
  2839. CreateMockWrite(stream1_syn, 0), CreateMockWrite(goaway, 3),
  2840. };
  2841. spdy::SpdySerializedFrame stream1_reply(
  2842. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2843. spdy::SpdySerializedFrame stream2_syn(
  2844. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 0, kPushedUrl));
  2845. MockRead reads[] = {
  2846. CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
  2847. };
  2848. SequencedSocketData data(reads, writes);
  2849. RunBrokenPushTest(&data, OK);
  2850. }
  2851. TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
  2852. base::HistogramTester histogram_tester;
  2853. spdy::SpdySerializedFrame stream1_syn(
  2854. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2855. spdy::SpdySerializedFrame stream1_body(
  2856. spdy_util_.ConstructSpdyDataFrame(1, true));
  2857. spdy::SpdySerializedFrame stream2_rst(
  2858. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_STREAM_CLOSED));
  2859. MockWrite writes[] = {
  2860. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_rst, 3),
  2861. };
  2862. spdy::SpdySerializedFrame stream1_reply(
  2863. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2864. spdy::SpdySerializedFrame stream2_syn(
  2865. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 9, kPushedUrl));
  2866. MockRead reads[] = {
  2867. CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
  2868. CreateMockRead(stream1_body, 4),
  2869. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a pause
  2870. };
  2871. SequencedSocketData data(reads, writes);
  2872. RunBrokenPushTest(&data, OK);
  2873. histogram_tester.ExpectBucketCount(
  2874. "Net.SpdyPushedStreamFate",
  2875. static_cast<int>(SpdyPushedStreamFate::kInactiveAssociatedStream), 1);
  2876. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  2877. }
  2878. TEST_F(SpdyNetworkTransactionTest, ServerPushNoURL) {
  2879. base::HistogramTester histogram_tester;
  2880. spdy::SpdySerializedFrame stream1_syn(
  2881. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2882. spdy::SpdySerializedFrame stream1_body(
  2883. spdy_util_.ConstructSpdyDataFrame(1, true));
  2884. spdy::SpdySerializedFrame stream2_rst(
  2885. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  2886. MockWrite writes[] = {
  2887. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_rst, 3),
  2888. };
  2889. spdy::SpdySerializedFrame stream1_reply(
  2890. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2891. spdy::Http2HeaderBlock incomplete_headers;
  2892. incomplete_headers[spdy::kHttp2StatusHeader] = "200 OK";
  2893. incomplete_headers["hello"] = "bye";
  2894. spdy::SpdySerializedFrame stream2_syn(
  2895. spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(incomplete_headers)));
  2896. MockRead reads[] = {
  2897. CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
  2898. CreateMockRead(stream1_body, 4),
  2899. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5) // Force a pause
  2900. };
  2901. SequencedSocketData data(reads, writes);
  2902. RunBrokenPushTest(&data, OK);
  2903. histogram_tester.ExpectBucketCount(
  2904. "Net.SpdyPushedStreamFate",
  2905. static_cast<int>(SpdyPushedStreamFate::kInvalidUrl), 1);
  2906. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  2907. }
  2908. // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY.
  2909. TEST_F(SpdyNetworkTransactionTest, ServerPushOnPushedStream) {
  2910. base::HistogramTester histogram_tester;
  2911. spdy::SpdySerializedFrame stream1_syn(
  2912. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2913. spdy::SpdySerializedFrame stream2_priority(
  2914. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2915. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  2916. 2, spdy::ERROR_CODE_PROTOCOL_ERROR,
  2917. "Received pushed stream id 4 on invalid stream id 2 (must be odd)."));
  2918. MockWrite writes[] = {
  2919. CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
  2920. CreateMockWrite(goaway, 5),
  2921. };
  2922. spdy::SpdySerializedFrame stream1_reply(
  2923. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2924. spdy::SpdySerializedFrame stream2_syn(
  2925. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2926. spdy::SpdySerializedFrame stream3_syn(spdy_util_.ConstructSpdyPush(
  2927. nullptr, 0, 4, 2, "https://www.example.org/bar.dat"));
  2928. MockRead reads[] = {
  2929. CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
  2930. CreateMockRead(stream3_syn, 4),
  2931. };
  2932. SequencedSocketData data(reads, writes);
  2933. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2934. helper.RunToCompletion(&data);
  2935. histogram_tester.ExpectBucketCount(
  2936. "Net.SpdyPushedStreamFate",
  2937. static_cast<int>(SpdyPushedStreamFate::kAssociatedStreamIdParityError),
  2938. 1);
  2939. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  2940. }
  2941. // PUSH_PROMISE on a closed client-initiated stream should trigger RST_STREAM.
  2942. TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedStream) {
  2943. base::HistogramTester histogram_tester;
  2944. spdy::SpdySerializedFrame stream1_syn(
  2945. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2946. spdy::SpdySerializedFrame rst(
  2947. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_STREAM_CLOSED));
  2948. MockWrite writes[] = {
  2949. CreateMockWrite(stream1_syn, 0), CreateMockWrite(rst, 5),
  2950. };
  2951. spdy::SpdySerializedFrame stream1_reply(
  2952. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  2953. spdy::SpdySerializedFrame stream1_body(
  2954. spdy_util_.ConstructSpdyDataFrame(1, true));
  2955. spdy::SpdySerializedFrame stream2_syn(
  2956. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2957. MockRead reads[] = {
  2958. CreateMockRead(stream1_reply, 1), CreateMockRead(stream1_body, 2),
  2959. CreateMockRead(stream2_syn, 3), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  2960. };
  2961. SequencedSocketData data(reads, writes);
  2962. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  2963. helper.RunPreTestSetup();
  2964. helper.AddData(&data);
  2965. HttpNetworkTransaction* trans = helper.trans();
  2966. TestCompletionCallback callback;
  2967. int rv = trans->Start(&request_, callback.callback(), log_);
  2968. rv = callback.GetResult(rv);
  2969. EXPECT_THAT(rv, IsOk());
  2970. // Finish async network reads/writes.
  2971. base::RunLoop().RunUntilIdle();
  2972. HttpResponseInfo response = *trans->GetResponseInfo();
  2973. EXPECT_TRUE(response.headers);
  2974. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  2975. EXPECT_TRUE(data.AllReadDataConsumed());
  2976. EXPECT_TRUE(data.AllWriteDataConsumed());
  2977. VerifyStreamsClosed(helper);
  2978. histogram_tester.ExpectBucketCount(
  2979. "Net.SpdyPushedStreamFate",
  2980. static_cast<int>(SpdyPushedStreamFate::kInactiveAssociatedStream), 1);
  2981. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  2982. }
  2983. // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY even if
  2984. // stream is closed.
  2985. TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) {
  2986. base::HistogramTester histogram_tester;
  2987. spdy::SpdySerializedFrame stream1_syn(
  2988. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  2989. spdy::SpdySerializedFrame stream2_priority(
  2990. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  2991. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  2992. 2, spdy::ERROR_CODE_PROTOCOL_ERROR,
  2993. "Received pushed stream id 4 on invalid stream id 2 (must be odd)."));
  2994. MockWrite writes[] = {CreateMockWrite(stream1_syn, 0),
  2995. CreateMockWrite(stream2_priority, 3),
  2996. CreateMockWrite(goaway, 8)};
  2997. spdy::SpdySerializedFrame stream2_syn(
  2998. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  2999. spdy::SpdySerializedFrame stream1_reply(
  3000. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3001. spdy::SpdySerializedFrame stream1_body(
  3002. spdy_util_.ConstructSpdyDataFrame(1, true));
  3003. const char kPushedData[] = "pushed";
  3004. spdy::SpdySerializedFrame stream2_body(
  3005. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  3006. spdy::SpdySerializedFrame stream3_syn(spdy_util_.ConstructSpdyPush(
  3007. nullptr, 0, 4, 2, "https://www.example.org/bar.dat"));
  3008. MockRead reads[] = {
  3009. CreateMockRead(stream2_syn, 1), CreateMockRead(stream1_reply, 2),
  3010. CreateMockRead(stream1_body, 4), CreateMockRead(stream2_body, 5),
  3011. MockRead(ASYNC, ERR_IO_PENDING, 6), CreateMockRead(stream3_syn, 7)};
  3012. SequencedSocketData data(reads, writes);
  3013. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  3014. helper.RunPreTestSetup();
  3015. helper.AddData(&data);
  3016. HttpNetworkTransaction* trans1 = helper.trans();
  3017. TestCompletionCallback callback1;
  3018. int rv = trans1->Start(&request_, callback1.callback(), log_);
  3019. rv = callback1.GetResult(rv);
  3020. EXPECT_THAT(rv, IsOk());
  3021. HttpResponseInfo response = *trans1->GetResponseInfo();
  3022. EXPECT_TRUE(response.headers);
  3023. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  3024. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  3025. TestCompletionCallback callback2;
  3026. HttpRequestInfo request = CreateGetPushRequest();
  3027. rv = trans2.Start(&request, callback2.callback(), log_);
  3028. rv = callback2.GetResult(rv);
  3029. EXPECT_THAT(rv, IsOk());
  3030. response = *trans2.GetResponseInfo();
  3031. EXPECT_TRUE(response.headers);
  3032. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  3033. std::string result;
  3034. ReadResult(&trans2, &result);
  3035. EXPECT_EQ(kPushedData, result);
  3036. data.Resume();
  3037. base::RunLoop().RunUntilIdle();
  3038. EXPECT_TRUE(data.AllReadDataConsumed());
  3039. EXPECT_TRUE(data.AllWriteDataConsumed());
  3040. histogram_tester.ExpectBucketCount(
  3041. "Net.SpdyPushedStreamFate",
  3042. static_cast<int>(SpdyPushedStreamFate::kAssociatedStreamIdParityError),
  3043. 1);
  3044. histogram_tester.ExpectBucketCount(
  3045. "Net.SpdyPushedStreamFate",
  3046. static_cast<int>(SpdyPushedStreamFate::kAcceptedNoVary), 1);
  3047. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 2);
  3048. }
  3049. TEST_F(SpdyNetworkTransactionTest, ServerCancelsPush) {
  3050. spdy::SpdySerializedFrame req1(
  3051. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  3052. spdy::SpdySerializedFrame priority(
  3053. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  3054. spdy_util_.UpdateWithStreamDestruction(1);
  3055. spdy::SpdySerializedFrame req2(
  3056. spdy_util_.ConstructSpdyGet(kPushedUrl, 3, LOWEST));
  3057. MockWrite writes1[] = {CreateMockWrite(req1, 0), CreateMockWrite(priority, 3),
  3058. CreateMockWrite(req2, 6)};
  3059. spdy::SpdySerializedFrame reply1(
  3060. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3061. spdy::SpdySerializedFrame push(
  3062. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  3063. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3064. spdy::SpdySerializedFrame rst(
  3065. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_INTERNAL_ERROR));
  3066. spdy::SpdySerializedFrame reply2(
  3067. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  3068. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  3069. MockRead reads1[] = {CreateMockRead(reply1, 1), CreateMockRead(push, 2),
  3070. CreateMockRead(body1, 4), CreateMockRead(rst, 5),
  3071. CreateMockRead(reply2, 7), CreateMockRead(body2, 8),
  3072. MockRead(ASYNC, 0, 9)};
  3073. SequencedSocketData data(reads1, writes1);
  3074. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  3075. helper.RunPreTestSetup();
  3076. helper.AddData(&data);
  3077. // First request opens up connection.
  3078. HttpNetworkTransaction* trans1 = helper.trans();
  3079. TestCompletionCallback callback1;
  3080. int rv = trans1->Start(&request_, callback1.callback(), log_);
  3081. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  3082. // Read until response body arrives. PUSH_PROMISE comes earlier.
  3083. rv = callback1.WaitForResult();
  3084. EXPECT_THAT(rv, IsOk());
  3085. const HttpResponseInfo* response = trans1->GetResponseInfo();
  3086. EXPECT_TRUE(response->headers);
  3087. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3088. std::string result1;
  3089. ReadResult(trans1, &result1);
  3090. EXPECT_EQ("hello!", result1);
  3091. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  3092. SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
  3093. PRIVACY_MODE_DISABLED,
  3094. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3095. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3096. base::WeakPtr<SpdySession> spdy_session =
  3097. spdy_session_pool->FindAvailableSession(
  3098. key, /* enable_ip_based_pooling = */ true,
  3099. /* is_websocket = */ false, log_);
  3100. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
  3101. // Create request matching pushed stream.
  3102. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  3103. HttpRequestInfo request2 = CreateGetPushRequest();
  3104. TestCompletionCallback callback2;
  3105. rv = trans2.Start(&request2, callback2.callback(), log_);
  3106. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  3107. // Pushed stream is now claimed by second request.
  3108. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
  3109. // Second request receives RST_STREAM and is retried on the same connection.
  3110. rv = callback2.WaitForResult();
  3111. EXPECT_THAT(rv, IsOk());
  3112. response = trans2.GetResponseInfo();
  3113. EXPECT_TRUE(response->headers);
  3114. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3115. std::string result2;
  3116. ReadResult(&trans2, &result2);
  3117. EXPECT_EQ("hello!", result2);
  3118. // Read EOF.
  3119. base::RunLoop().RunUntilIdle();
  3120. helper.VerifyDataConsumed();
  3121. }
  3122. // Regression test for https://crbug.com/776415.
  3123. // A client-initiated request can only pool to an existing HTTP/2 connection if
  3124. // the IP address matches. However, a resource can be pushed by the server on a
  3125. // connection even if the IP address does not match. This test verifies that if
  3126. // the request binds to such a pushed stream, and after that the server resets
  3127. // the stream before SpdySession::GetPushedStream() is called, then the retry
  3128. // (using a client-initiated stream) does not pool to this connection.
  3129. TEST_F(SpdyNetworkTransactionTest, ServerCancelsCrossOriginPush) {
  3130. const char* kUrl1 = "https://www.example.org";
  3131. const char* kUrl2 = "https://mail.example.org";
  3132. auto resolver = std::make_unique<MockHostResolver>();
  3133. resolver->rules()->ClearRules();
  3134. resolver->rules()->AddRule("www.example.org", "127.0.0.1");
  3135. resolver->rules()->AddRule("mail.example.org", "127.0.0.2");
  3136. auto session_deps = std::make_unique<SpdySessionDependencies>();
  3137. session_deps->host_resolver = std::move(resolver);
  3138. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  3139. std::move(session_deps));
  3140. spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(kUrl1, 1, LOWEST));
  3141. spdy::SpdySerializedFrame priority(
  3142. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  3143. MockWrite writes1[] = {CreateMockWrite(req1, 0),
  3144. CreateMockWrite(priority, 3)};
  3145. spdy::SpdySerializedFrame reply1(
  3146. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3147. spdy::SpdySerializedFrame push(
  3148. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kUrl2));
  3149. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3150. spdy::SpdySerializedFrame rst(
  3151. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_INTERNAL_ERROR));
  3152. MockRead reads1[] = {
  3153. CreateMockRead(reply1, 1), CreateMockRead(push, 2),
  3154. CreateMockRead(body1, 4), CreateMockRead(rst, 5),
  3155. MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7)};
  3156. SequencedSocketData data1(reads1, writes1);
  3157. SpdyTestUtil spdy_util2;
  3158. spdy::SpdySerializedFrame req2(spdy_util2.ConstructSpdyGet(kUrl2, 1, LOWEST));
  3159. MockWrite writes2[] = {CreateMockWrite(req2, 0)};
  3160. spdy::SpdySerializedFrame reply2(
  3161. spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
  3162. spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(
  3163. 1, "Response on the second connection.", true));
  3164. MockRead reads2[] = {CreateMockRead(reply2, 1), CreateMockRead(body2, 2),
  3165. MockRead(ASYNC, 0, 3)};
  3166. SequencedSocketData data2(reads2, writes2);
  3167. helper.RunPreTestSetup();
  3168. helper.AddData(&data1);
  3169. helper.AddData(&data2);
  3170. // First request opens up connection to www.example.org.
  3171. HttpNetworkTransaction* trans1 = helper.trans();
  3172. HttpRequestInfo request1;
  3173. request1.method = "GET";
  3174. request1.url = GURL(kUrl1);
  3175. request1.traffic_annotation =
  3176. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3177. TestCompletionCallback callback1;
  3178. int rv = trans1->Start(&request1, callback1.callback(), log_);
  3179. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  3180. // Read until response body arrives. PUSH_PROMISE comes earlier.
  3181. rv = callback1.WaitForResult();
  3182. EXPECT_THAT(rv, IsOk());
  3183. const HttpResponseInfo* response = trans1->GetResponseInfo();
  3184. EXPECT_TRUE(response->headers);
  3185. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3186. std::string result1;
  3187. ReadResult(trans1, &result1);
  3188. EXPECT_EQ("hello!", result1);
  3189. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  3190. SpdySessionKey key1(HostPortPair::FromURL(GURL(kUrl1)), ProxyServer::Direct(),
  3191. PRIVACY_MODE_DISABLED,
  3192. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3193. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3194. base::WeakPtr<SpdySession> spdy_session1 =
  3195. spdy_session_pool->FindAvailableSession(
  3196. key1, /* enable_ip_based_pooling = */ true,
  3197. /* is_websocket = */ false, log_);
  3198. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session1));
  3199. // While cross-origin push for kUrl2 is allowed on spdy_session1,
  3200. // a client-initiated request would not pool to this connection,
  3201. // because the IP address does not match.
  3202. SpdySessionKey key2(HostPortPair::FromURL(GURL(kUrl2)), ProxyServer::Direct(),
  3203. PRIVACY_MODE_DISABLED,
  3204. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3205. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3206. EXPECT_FALSE(spdy_session_pool->FindAvailableSession(
  3207. key2, /* enable_ip_based_pooling = */ true,
  3208. /* is_websocket = */ false, log_));
  3209. // Create request matching pushed stream.
  3210. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  3211. HttpRequestInfo request2;
  3212. request2.method = "GET";
  3213. request2.url = GURL(kUrl2);
  3214. request2.traffic_annotation =
  3215. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3216. TestCompletionCallback callback2;
  3217. rv = trans2.Start(&request2, callback2.callback(), log_);
  3218. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  3219. // Pushed stream is now claimed by second request.
  3220. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session1));
  3221. // Second request receives RST_STREAM and is retried on a new connection.
  3222. rv = callback2.WaitForResult();
  3223. EXPECT_THAT(rv, IsOk());
  3224. response = trans2.GetResponseInfo();
  3225. EXPECT_TRUE(response->headers);
  3226. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3227. std::string result2;
  3228. ReadResult(&trans2, &result2);
  3229. EXPECT_EQ("Response on the second connection.", result2);
  3230. // Make sure that the first connection is still open. This is important in
  3231. // order to test that the retry created its own connection (because the IP
  3232. // address does not match), instead of using the connection of the cancelled
  3233. // pushed stream.
  3234. EXPECT_TRUE(spdy_session1);
  3235. // Read EOF.
  3236. data1.Resume();
  3237. base::RunLoop().RunUntilIdle();
  3238. helper.VerifyDataConsumed();
  3239. }
  3240. TEST_F(SpdyNetworkTransactionTest, NoConnectionPoolingOverTunnel) {
  3241. // Use port 443 for two reasons: This makes the endpoint is port 443 check in
  3242. // NormalSpdyTransactionHelper pass, and this means that the tunnel uses the
  3243. // same port as the servers, to further confuse things.
  3244. const char kPacString[] = "PROXY myproxy:443";
  3245. auto session_deps = std::make_unique<SpdySessionDependencies>(
  3246. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  3247. kPacString, TRAFFIC_ANNOTATION_FOR_TESTS));
  3248. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  3249. std::move(session_deps));
  3250. // Only one request uses the first connection.
  3251. spdy::SpdySerializedFrame req1(
  3252. spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
  3253. MockWrite writes1[] = {
  3254. MockWrite(ASYNC, 0,
  3255. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  3256. "Host: www.example.org:443\r\n"
  3257. "Proxy-Connection: keep-alive\r\n\r\n"),
  3258. CreateMockWrite(req1, 2),
  3259. };
  3260. spdy::SpdySerializedFrame resp1(
  3261. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3262. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3263. MockRead reads1[] = {MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
  3264. CreateMockRead(resp1, 3), CreateMockRead(body1, 4),
  3265. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
  3266. MockConnect connect1(ASYNC, OK);
  3267. SequencedSocketData data1(connect1, reads1, writes1);
  3268. // Run a transaction to completion to set up a SPDY session.
  3269. helper.RunToCompletion(&data1);
  3270. TransactionHelperResult out = helper.output();
  3271. EXPECT_THAT(out.rv, IsOk());
  3272. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  3273. EXPECT_EQ("hello!", out.response_data);
  3274. // A new SPDY session should have been created.
  3275. SpdySessionKey key1(HostPortPair("www.example.org", 443),
  3276. PacResultElementToProxyServer(kPacString),
  3277. PRIVACY_MODE_DISABLED,
  3278. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3279. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3280. base::WeakPtr<SpdySession> session1 =
  3281. helper.session()->spdy_session_pool()->FindAvailableSession(
  3282. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3283. NetLogWithSource());
  3284. ASSERT_TRUE(session1);
  3285. // The second request uses a second connection.
  3286. SpdyTestUtil spdy_util2;
  3287. spdy::SpdySerializedFrame req2(
  3288. spdy_util2.ConstructSpdyGet("https://example.test", 1, LOWEST));
  3289. MockWrite writes2[] = {
  3290. MockWrite(ASYNC, 0,
  3291. "CONNECT example.test:443 HTTP/1.1\r\n"
  3292. "Host: example.test:443\r\n"
  3293. "Proxy-Connection: keep-alive\r\n\r\n"),
  3294. CreateMockWrite(req2, 2),
  3295. };
  3296. spdy::SpdySerializedFrame resp2(
  3297. spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
  3298. spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(1, true));
  3299. MockRead reads2[] = {MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
  3300. CreateMockRead(resp2, 3), CreateMockRead(body2, 4),
  3301. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
  3302. MockConnect connect2(ASYNC, OK);
  3303. SequencedSocketData data2(connect2, reads2, writes2);
  3304. helper.AddData(&data2);
  3305. HttpRequestInfo request2;
  3306. request2.method = "GET";
  3307. request2.url = GURL("https://example.test/");
  3308. request2.load_flags = 0;
  3309. request2.traffic_annotation =
  3310. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3311. auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3312. helper.session());
  3313. TestCompletionCallback callback;
  3314. EXPECT_THAT(trans2->Start(&request2, callback.callback(), NetLogWithSource()),
  3315. IsError(ERR_IO_PENDING));
  3316. // Wait for the second request to get headers. It should create a new H2
  3317. // session to do so.
  3318. EXPECT_THAT(callback.WaitForResult(), IsOk());
  3319. const HttpResponseInfo* response = trans2->GetResponseInfo();
  3320. ASSERT_TRUE(response);
  3321. ASSERT_TRUE(response->headers);
  3322. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3323. EXPECT_TRUE(response->was_fetched_via_spdy);
  3324. EXPECT_TRUE(response->was_alpn_negotiated);
  3325. std::string response_data;
  3326. ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
  3327. EXPECT_EQ("hello!", response_data);
  3328. // Inspect the new session.
  3329. SpdySessionKey key2(HostPortPair("example.test", 443),
  3330. PacResultElementToProxyServer(kPacString),
  3331. PRIVACY_MODE_DISABLED,
  3332. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3333. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3334. base::WeakPtr<SpdySession> session2 =
  3335. helper.session()->spdy_session_pool()->FindAvailableSession(
  3336. key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3337. NetLogWithSource());
  3338. ASSERT_TRUE(session2);
  3339. ASSERT_TRUE(session1);
  3340. EXPECT_NE(session1.get(), session2.get());
  3341. }
  3342. // Check that if a session is found after host resolution, but is closed before
  3343. // the task to try to use it executes, the request will continue to create a new
  3344. // socket and use it.
  3345. TEST_F(SpdyNetworkTransactionTest, ConnectionPoolingSessionClosedBeforeUse) {
  3346. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  3347. // Only one request uses the first connection.
  3348. spdy::SpdySerializedFrame req1(
  3349. spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
  3350. MockWrite writes1[] = {
  3351. CreateMockWrite(req1, 0),
  3352. };
  3353. spdy::SpdySerializedFrame resp1(
  3354. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3355. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3356. MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  3357. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
  3358. MockConnect connect1(ASYNC, OK);
  3359. SequencedSocketData data1(connect1, reads1, writes1);
  3360. // Run a transaction to completion to set up a SPDY session.
  3361. helper.RunToCompletion(&data1);
  3362. TransactionHelperResult out = helper.output();
  3363. EXPECT_THAT(out.rv, IsOk());
  3364. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  3365. EXPECT_EQ("hello!", out.response_data);
  3366. // A new SPDY session should have been created.
  3367. SpdySessionKey key1(HostPortPair("www.example.org", 443),
  3368. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  3369. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3370. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3371. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3372. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3373. NetLogWithSource()));
  3374. // The second request uses a second connection.
  3375. SpdyTestUtil spdy_util2;
  3376. spdy::SpdySerializedFrame req2(
  3377. spdy_util2.ConstructSpdyGet("https://example.test", 1, LOWEST));
  3378. MockWrite writes2[] = {
  3379. CreateMockWrite(req2, 0),
  3380. };
  3381. spdy::SpdySerializedFrame resp2(
  3382. spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
  3383. spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(1, true));
  3384. MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
  3385. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
  3386. MockConnect connect2(ASYNC, OK);
  3387. SequencedSocketData data2(connect2, reads2, writes2);
  3388. helper.AddData(&data2);
  3389. HttpRequestInfo request2;
  3390. request2.method = "GET";
  3391. request2.url = GURL("https://example.test/");
  3392. request2.load_flags = 0;
  3393. request2.traffic_annotation =
  3394. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3395. auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3396. helper.session());
  3397. // Set on-demand mode and run the second request to the DNS lookup.
  3398. helper.session_deps()->host_resolver->set_ondemand_mode(true);
  3399. TestCompletionCallback callback;
  3400. EXPECT_THAT(trans2->Start(&request2, callback.callback(), NetLogWithSource()),
  3401. IsError(ERR_IO_PENDING));
  3402. base::RunLoop().RunUntilIdle();
  3403. ASSERT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
  3404. // Resolve the request now, which should create an alias for the SpdySession
  3405. // immediately, but the task to use the session for the second request should
  3406. // run asynchronously, so it hasn't run yet.
  3407. helper.session_deps()->host_resolver->ResolveOnlyRequestNow();
  3408. SpdySessionKey key2(HostPortPair("example.test", 443), ProxyServer::Direct(),
  3409. PRIVACY_MODE_DISABLED,
  3410. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3411. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3412. base::WeakPtr<SpdySession> session1 =
  3413. helper.session()->spdy_session_pool()->FindAvailableSession(
  3414. key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3415. NetLogWithSource());
  3416. ASSERT_TRUE(session1);
  3417. EXPECT_EQ(key1, session1->spdy_session_key());
  3418. // Remove the session before the second request can try to use it.
  3419. helper.session()->spdy_session_pool()->CloseAllSessions();
  3420. // Wait for the second request to get headers. It should create a new H2
  3421. // session to do so.
  3422. EXPECT_THAT(callback.WaitForResult(), IsOk());
  3423. const HttpResponseInfo* response = trans2->GetResponseInfo();
  3424. ASSERT_TRUE(response);
  3425. ASSERT_TRUE(response->headers);
  3426. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3427. EXPECT_TRUE(response->was_fetched_via_spdy);
  3428. EXPECT_TRUE(response->was_alpn_negotiated);
  3429. std::string response_data;
  3430. ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
  3431. EXPECT_EQ("hello!", response_data);
  3432. // Inspect the new session.
  3433. base::WeakPtr<SpdySession> session2 =
  3434. helper.session()->spdy_session_pool()->FindAvailableSession(
  3435. key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3436. NetLogWithSource());
  3437. ASSERT_TRUE(session2);
  3438. EXPECT_EQ(key2, session2->spdy_session_key());
  3439. helper.VerifyDataConsumed();
  3440. }
  3441. #if BUILDFLAG(IS_ANDROID)
  3442. // Test this if two HttpNetworkTransactions try to repurpose the same
  3443. // SpdySession with two different SocketTags, only one request gets the session,
  3444. // while the other makes a new SPDY session.
  3445. TEST_F(SpdyNetworkTransactionTest, ConnectionPoolingMultipleSocketTags) {
  3446. const SocketTag kSocketTag1(SocketTag::UNSET_UID, 1);
  3447. const SocketTag kSocketTag2(SocketTag::UNSET_UID, 2);
  3448. const SocketTag kSocketTag3(SocketTag::UNSET_UID, 3);
  3449. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  3450. // The first and third requests use the first connection.
  3451. spdy::SpdySerializedFrame req1(
  3452. spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
  3453. spdy_util_.UpdateWithStreamDestruction(1);
  3454. spdy::SpdySerializedFrame req3(
  3455. spdy_util_.ConstructSpdyGet("https://example.test/request3", 3, LOWEST));
  3456. MockWrite writes1[] = {
  3457. CreateMockWrite(req1, 0),
  3458. CreateMockWrite(req3, 3),
  3459. };
  3460. spdy::SpdySerializedFrame resp1(
  3461. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3462. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3463. spdy::SpdySerializedFrame resp3(
  3464. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  3465. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(3, true));
  3466. MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  3467. CreateMockRead(resp3, 4), CreateMockRead(body3, 5),
  3468. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
  3469. SequencedSocketData data1(MockConnect(ASYNC, OK), reads1, writes1);
  3470. helper.AddData(&data1);
  3471. // Due to the vagaries of how the socket pools work, in this particular case,
  3472. // the second ConnectJob will be cancelled, but only after it tries to start
  3473. // connecting. This does not happen in the general case of a bunch of requests
  3474. // using the same socket tag.
  3475. SequencedSocketData data2(MockConnect(SYNCHRONOUS, ERR_IO_PENDING),
  3476. base::span<const MockRead>(),
  3477. base::span<const MockWrite>());
  3478. helper.AddData(&data2);
  3479. // The second request uses a second connection.
  3480. SpdyTestUtil spdy_util2;
  3481. spdy::SpdySerializedFrame req2(
  3482. spdy_util2.ConstructSpdyGet("https://example.test/request2", 1, LOWEST));
  3483. MockWrite writes2[] = {
  3484. CreateMockWrite(req2, 0),
  3485. };
  3486. spdy::SpdySerializedFrame resp2(
  3487. spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
  3488. spdy::SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame(1, true));
  3489. MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
  3490. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
  3491. SequencedSocketData data3(MockConnect(ASYNC, OK), reads2, writes2);
  3492. helper.AddData(&data3);
  3493. // Run a transaction to completion to set up a SPDY session. This can't use
  3494. // RunToCompletion(), since it can't call VerifyDataConsumed() yet.
  3495. helper.RunPreTestSetup();
  3496. helper.RunDefaultTest();
  3497. TransactionHelperResult out = helper.output();
  3498. EXPECT_THAT(out.rv, IsOk());
  3499. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  3500. EXPECT_EQ("hello!", out.response_data);
  3501. // A new SPDY session should have been created.
  3502. SpdySessionKey key1(HostPortPair("www.example.org", 443),
  3503. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  3504. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  3505. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3506. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3507. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3508. NetLogWithSource()));
  3509. // Set on-demand mode for the next two requests.
  3510. helper.session_deps()->host_resolver->set_ondemand_mode(true);
  3511. HttpRequestInfo request2;
  3512. request2.socket_tag = kSocketTag2;
  3513. request2.method = "GET";
  3514. request2.url = GURL("https://example.test/request2");
  3515. request2.load_flags = 0;
  3516. request2.traffic_annotation =
  3517. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3518. auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3519. helper.session());
  3520. TestCompletionCallback callback2;
  3521. EXPECT_THAT(
  3522. trans2->Start(&request2, callback2.callback(), NetLogWithSource()),
  3523. IsError(ERR_IO_PENDING));
  3524. HttpRequestInfo request3;
  3525. request3.socket_tag = kSocketTag3;
  3526. request3.method = "GET";
  3527. request3.url = GURL("https://example.test/request3");
  3528. request3.load_flags = 0;
  3529. request3.traffic_annotation =
  3530. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3531. auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3532. helper.session());
  3533. TestCompletionCallback callback3;
  3534. EXPECT_THAT(
  3535. trans3->Start(&request3, callback3.callback(), NetLogWithSource()),
  3536. IsError(ERR_IO_PENDING));
  3537. // Run the message loop until both requests are waiting on the host resolver.
  3538. base::RunLoop().RunUntilIdle();
  3539. ASSERT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
  3540. // Complete the second requests's DNS lookup now, which should create an alias
  3541. // for the SpdySession immediately, but the task to use the session for the
  3542. // second request should run asynchronously, so it hasn't run yet.
  3543. helper.session_deps()->host_resolver->ResolveNow(2);
  3544. SpdySessionKey key2(HostPortPair("example.test", 443), ProxyServer::Direct(),
  3545. PRIVACY_MODE_DISABLED,
  3546. SpdySessionKey::IsProxySession::kFalse, kSocketTag2,
  3547. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3548. // Complete the third requests's DNS lookup now, which should hijack the
  3549. // SpdySession from the second request.
  3550. helper.session_deps()->host_resolver->ResolveNow(3);
  3551. SpdySessionKey key3(HostPortPair("example.test", 443), ProxyServer::Direct(),
  3552. PRIVACY_MODE_DISABLED,
  3553. SpdySessionKey::IsProxySession::kFalse, kSocketTag3,
  3554. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3555. // Wait for the second request to get headers. It should create a new H2
  3556. // session to do so.
  3557. EXPECT_THAT(callback2.WaitForResult(), IsOk());
  3558. const HttpResponseInfo* response = trans2->GetResponseInfo();
  3559. ASSERT_TRUE(response);
  3560. ASSERT_TRUE(response->headers);
  3561. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3562. EXPECT_TRUE(response->was_fetched_via_spdy);
  3563. EXPECT_TRUE(response->was_alpn_negotiated);
  3564. std::string response_data;
  3565. ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
  3566. EXPECT_EQ("hello!", response_data);
  3567. // Wait for the third request to get headers. It should have reused the first
  3568. // session.
  3569. EXPECT_THAT(callback3.WaitForResult(), IsOk());
  3570. response = trans3->GetResponseInfo();
  3571. ASSERT_TRUE(response);
  3572. ASSERT_TRUE(response->headers);
  3573. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3574. EXPECT_TRUE(response->was_fetched_via_spdy);
  3575. EXPECT_TRUE(response->was_alpn_negotiated);
  3576. ASSERT_THAT(ReadTransaction(trans3.get(), &response_data), IsOk());
  3577. EXPECT_EQ("hello!", response_data);
  3578. helper.VerifyDataConsumed();
  3579. }
  3580. TEST_F(SpdyNetworkTransactionTest, SocketTagChangeSessionTagWithDnsAliases) {
  3581. SocketTag socket_tag_1(SocketTag::UNSET_UID, 1);
  3582. SocketTag socket_tag_2(SocketTag::UNSET_UID, 2);
  3583. request_.socket_tag = socket_tag_1;
  3584. std::unique_ptr<SpdySessionDependencies> session_deps =
  3585. std::make_unique<SpdySessionDependencies>();
  3586. std::unique_ptr<MockCachingHostResolver> host_resolver =
  3587. std::make_unique<MockCachingHostResolver>(2 /* cache_invalidation_num */);
  3588. session_deps->host_resolver = std::move(host_resolver);
  3589. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  3590. std::move(session_deps));
  3591. GURL url = request_.url;
  3592. std::set<std::string> dns_aliases({"alias1", "alias2", "alias3"});
  3593. helper.session_deps()->host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
  3594. url.host(), "127.0.0.1", dns_aliases);
  3595. spdy::SpdySerializedFrame req1(
  3596. spdy_util_.ConstructSpdyGet(url.spec().c_str(), 1, DEFAULT_PRIORITY));
  3597. spdy_util_.UpdateWithStreamDestruction(1);
  3598. spdy::SpdySerializedFrame req2(
  3599. spdy_util_.ConstructSpdyGet(url.spec().c_str(), 3, DEFAULT_PRIORITY));
  3600. MockWrite writes[] = {
  3601. CreateMockWrite(req1, 0),
  3602. CreateMockWrite(req2, 3),
  3603. };
  3604. spdy::SpdySerializedFrame resp1(
  3605. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3606. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3607. spdy::SpdySerializedFrame resp2(
  3608. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  3609. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  3610. MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  3611. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  3612. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
  3613. SequencedSocketData data(MockConnect(ASYNC, OK), reads, writes);
  3614. helper.AddData(&data);
  3615. // Run a transaction to completion to set up a SPDY session. This can't use
  3616. // RunToCompletion(), since it can't call VerifyDataConsumed() yet because
  3617. // there are still further requests expected.
  3618. helper.RunPreTestSetup();
  3619. helper.RunDefaultTest();
  3620. TransactionHelperResult out = helper.output();
  3621. EXPECT_THAT(out.rv, IsOk());
  3622. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  3623. EXPECT_EQ("hello!", out.response_data);
  3624. // A new SPDY session should have been created.
  3625. EXPECT_EQ(1u, helper.GetSpdySessionCount());
  3626. SpdySessionKey key1(HostPortPair(url.host(), 443), ProxyServer::Direct(),
  3627. PRIVACY_MODE_DISABLED,
  3628. SpdySessionKey::IsProxySession::kFalse, socket_tag_1,
  3629. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3630. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3631. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3632. NetLogWithSource()));
  3633. EXPECT_EQ(
  3634. dns_aliases,
  3635. helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key1));
  3636. // Clear host resolver rules to ensure that cached values for DNS aliases
  3637. // are used.
  3638. helper.session_deps()->host_resolver->rules()->ClearRules();
  3639. HttpRequestInfo request2;
  3640. request2.socket_tag = socket_tag_2;
  3641. request2.method = "GET";
  3642. request2.url = url;
  3643. request2.load_flags = 0;
  3644. request2.traffic_annotation =
  3645. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3646. SpdySessionKey key2(HostPortPair(url.host(), 443), ProxyServer::Direct(),
  3647. PRIVACY_MODE_DISABLED,
  3648. SpdySessionKey::IsProxySession::kFalse, socket_tag_2,
  3649. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3650. auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3651. helper.session());
  3652. TestCompletionCallback callback2;
  3653. EXPECT_THAT(
  3654. trans2->Start(&request2, callback2.callback(), NetLogWithSource()),
  3655. IsError(ERR_IO_PENDING));
  3656. // Wait for the second request to get headers. It should have reused the
  3657. // first session but changed the tag.
  3658. EXPECT_THAT(callback2.WaitForResult(), IsOk());
  3659. EXPECT_EQ(1u, helper.GetSpdySessionCount());
  3660. EXPECT_FALSE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3661. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3662. NetLogWithSource()));
  3663. EXPECT_TRUE(helper.session()
  3664. ->spdy_session_pool()
  3665. ->GetDnsAliasesForSessionKey(key1)
  3666. .empty());
  3667. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3668. key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3669. NetLogWithSource()));
  3670. EXPECT_EQ(
  3671. dns_aliases,
  3672. helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key2));
  3673. const HttpResponseInfo* response = trans2->GetResponseInfo();
  3674. ASSERT_TRUE(response);
  3675. ASSERT_TRUE(response->headers);
  3676. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3677. EXPECT_TRUE(response->was_fetched_via_spdy);
  3678. EXPECT_TRUE(response->was_alpn_negotiated);
  3679. std::string response_data;
  3680. ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
  3681. EXPECT_EQ("hello!", response_data);
  3682. helper.VerifyDataConsumed();
  3683. }
  3684. TEST_F(SpdyNetworkTransactionTest,
  3685. SocketTagChangeFromIPAliasedSessionWithDnsAliases) {
  3686. SocketTag socket_tag_1(SocketTag::UNSET_UID, 1);
  3687. SocketTag socket_tag_2(SocketTag::UNSET_UID, 2);
  3688. request_.socket_tag = socket_tag_1;
  3689. std::unique_ptr<SpdySessionDependencies> session_deps =
  3690. std::make_unique<SpdySessionDependencies>();
  3691. std::unique_ptr<MockCachingHostResolver> host_resolver =
  3692. std::make_unique<MockCachingHostResolver>(2 /* cache_invalidation_num */);
  3693. session_deps->host_resolver = std::move(host_resolver);
  3694. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  3695. std::move(session_deps));
  3696. GURL url1 = request_.url;
  3697. std::set<std::string> dns_aliases1({"alias1", "alias2", "alias3"});
  3698. GURL url2("https://example.test/");
  3699. std::set<std::string> dns_aliases2({"example.net", "example.com"});
  3700. helper.session_deps()->host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
  3701. url1.host(), "127.0.0.1", dns_aliases1);
  3702. helper.session_deps()->host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
  3703. url2.host(), "127.0.0.1", dns_aliases2);
  3704. spdy::SpdySerializedFrame req1(
  3705. spdy_util_.ConstructSpdyGet(url1.spec().c_str(), 1, DEFAULT_PRIORITY));
  3706. spdy_util_.UpdateWithStreamDestruction(1);
  3707. spdy::SpdySerializedFrame req2(
  3708. spdy_util_.ConstructSpdyGet(url2.spec().c_str(), 3, DEFAULT_PRIORITY));
  3709. spdy_util_.UpdateWithStreamDestruction(3);
  3710. spdy::SpdySerializedFrame req3(
  3711. spdy_util_.ConstructSpdyGet(url2.spec().c_str(), 5, DEFAULT_PRIORITY));
  3712. spdy_util_.UpdateWithStreamDestruction(5);
  3713. spdy::SpdySerializedFrame req4(
  3714. spdy_util_.ConstructSpdyGet(url1.spec().c_str(), 7, DEFAULT_PRIORITY));
  3715. MockWrite writes[] = {
  3716. CreateMockWrite(req1, 0),
  3717. CreateMockWrite(req2, 3),
  3718. CreateMockWrite(req3, 6),
  3719. CreateMockWrite(req4, 9),
  3720. };
  3721. spdy::SpdySerializedFrame resp1(
  3722. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3723. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  3724. spdy::SpdySerializedFrame resp2(
  3725. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  3726. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  3727. spdy::SpdySerializedFrame resp3(
  3728. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  3729. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, true));
  3730. spdy::SpdySerializedFrame resp4(
  3731. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 7));
  3732. spdy::SpdySerializedFrame body4(spdy_util_.ConstructSpdyDataFrame(7, true));
  3733. MockRead reads[] = {CreateMockRead(resp1, 1),
  3734. CreateMockRead(body1, 2),
  3735. CreateMockRead(resp2, 4),
  3736. CreateMockRead(body2, 5),
  3737. CreateMockRead(resp3, 7),
  3738. CreateMockRead(body3, 8),
  3739. CreateMockRead(resp4, 10),
  3740. CreateMockRead(body4, 11),
  3741. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 12)};
  3742. SequencedSocketData data(MockConnect(ASYNC, OK), reads, writes);
  3743. helper.AddData(&data);
  3744. // Run a transaction to completion to set up a SPDY session. This can't use
  3745. // RunToCompletion(), since it can't call VerifyDataConsumed() yet.
  3746. helper.RunPreTestSetup();
  3747. helper.RunDefaultTest();
  3748. TransactionHelperResult out = helper.output();
  3749. EXPECT_THAT(out.rv, IsOk());
  3750. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  3751. EXPECT_EQ("hello!", out.response_data);
  3752. // A new SPDY session should have been created.
  3753. EXPECT_EQ(1u, helper.GetSpdySessionCount());
  3754. SpdySessionKey key1(HostPortPair(url1.host(), 443), ProxyServer::Direct(),
  3755. PRIVACY_MODE_DISABLED,
  3756. SpdySessionKey::IsProxySession::kFalse, socket_tag_1,
  3757. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3758. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3759. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3760. NetLogWithSource()));
  3761. EXPECT_EQ(
  3762. dns_aliases1,
  3763. helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key1));
  3764. HttpRequestInfo request2;
  3765. request2.socket_tag = socket_tag_1;
  3766. request2.method = "GET";
  3767. request2.url = url2;
  3768. request2.load_flags = 0;
  3769. request2.traffic_annotation =
  3770. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3771. SpdySessionKey key2(HostPortPair(url2.host(), 443), ProxyServer::Direct(),
  3772. PRIVACY_MODE_DISABLED,
  3773. SpdySessionKey::IsProxySession::kFalse, socket_tag_1,
  3774. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3775. auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3776. helper.session());
  3777. TestCompletionCallback callback2;
  3778. EXPECT_THAT(
  3779. trans2->Start(&request2, callback2.callback(), NetLogWithSource()),
  3780. IsError(ERR_IO_PENDING));
  3781. // Wait for the second request to get headers. It should have reused the
  3782. // first session.
  3783. EXPECT_THAT(callback2.WaitForResult(), IsOk());
  3784. EXPECT_EQ(1u, helper.GetSpdySessionCount());
  3785. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3786. key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3787. NetLogWithSource()));
  3788. EXPECT_EQ(
  3789. dns_aliases2,
  3790. helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key2));
  3791. const HttpResponseInfo* response = trans2->GetResponseInfo();
  3792. ASSERT_TRUE(response);
  3793. ASSERT_TRUE(response->headers);
  3794. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3795. EXPECT_TRUE(response->was_fetched_via_spdy);
  3796. EXPECT_TRUE(response->was_alpn_negotiated);
  3797. std::string response_data;
  3798. ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
  3799. EXPECT_EQ("hello!", response_data);
  3800. // Clear host resolver rules to ensure that cached values for DNS aliases
  3801. // are used.
  3802. helper.session_deps()->host_resolver->rules()->ClearRules();
  3803. trans2.reset();
  3804. HttpRequestInfo request3;
  3805. request3.socket_tag = socket_tag_2;
  3806. request3.method = "GET";
  3807. request3.url = url2;
  3808. request3.load_flags = 0;
  3809. request3.traffic_annotation =
  3810. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3811. SpdySessionKey key3(HostPortPair(url2.host(), 443), ProxyServer::Direct(),
  3812. PRIVACY_MODE_DISABLED,
  3813. SpdySessionKey::IsProxySession::kFalse, socket_tag_2,
  3814. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3815. auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3816. helper.session());
  3817. TestCompletionCallback callback3;
  3818. EXPECT_THAT(
  3819. trans3->Start(&request3, callback3.callback(), NetLogWithSource()),
  3820. IsError(ERR_IO_PENDING));
  3821. // Wait for the third request to get headers. It should have reused the
  3822. // first session but changed the socket tag.
  3823. EXPECT_THAT(callback3.WaitForResult(), IsOk());
  3824. EXPECT_EQ(1u, helper.GetSpdySessionCount());
  3825. EXPECT_FALSE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3826. key2, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3827. NetLogWithSource()));
  3828. EXPECT_TRUE(helper.session()
  3829. ->spdy_session_pool()
  3830. ->GetDnsAliasesForSessionKey(key2)
  3831. .empty());
  3832. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3833. key3, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3834. NetLogWithSource()));
  3835. EXPECT_EQ(
  3836. dns_aliases2,
  3837. helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key3));
  3838. response = trans3->GetResponseInfo();
  3839. ASSERT_TRUE(response);
  3840. ASSERT_TRUE(response->headers);
  3841. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3842. EXPECT_TRUE(response->was_fetched_via_spdy);
  3843. EXPECT_TRUE(response->was_alpn_negotiated);
  3844. ASSERT_THAT(ReadTransaction(trans3.get(), &response_data), IsOk());
  3845. EXPECT_EQ("hello!", response_data);
  3846. trans3.reset();
  3847. HttpRequestInfo request4;
  3848. request4.socket_tag = socket_tag_2;
  3849. request4.method = "GET";
  3850. request4.url = url1;
  3851. request4.load_flags = 0;
  3852. request4.traffic_annotation =
  3853. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  3854. SpdySessionKey key4(HostPortPair(url1.host(), 443), ProxyServer::Direct(),
  3855. PRIVACY_MODE_DISABLED,
  3856. SpdySessionKey::IsProxySession::kFalse, socket_tag_2,
  3857. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  3858. auto trans4 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
  3859. helper.session());
  3860. TestCompletionCallback callback4;
  3861. EXPECT_THAT(
  3862. trans4->Start(&request4, callback4.callback(), NetLogWithSource()),
  3863. IsError(ERR_IO_PENDING));
  3864. // Wait for the third request to get headers. It should have reused the
  3865. // first session but changed the socket tag.
  3866. EXPECT_THAT(callback4.WaitForResult(), IsOk());
  3867. EXPECT_EQ(1u, helper.GetSpdySessionCount());
  3868. EXPECT_FALSE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3869. key1, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3870. NetLogWithSource()));
  3871. EXPECT_TRUE(helper.session()
  3872. ->spdy_session_pool()
  3873. ->GetDnsAliasesForSessionKey(key1)
  3874. .empty());
  3875. EXPECT_TRUE(helper.session()->spdy_session_pool()->FindAvailableSession(
  3876. key4, true /* enable_ip_based_pooling */, false /* is_websocket */,
  3877. NetLogWithSource()));
  3878. EXPECT_EQ(
  3879. dns_aliases1,
  3880. helper.session()->spdy_session_pool()->GetDnsAliasesForSessionKey(key4));
  3881. response = trans4->GetResponseInfo();
  3882. ASSERT_TRUE(response);
  3883. ASSERT_TRUE(response->headers);
  3884. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  3885. EXPECT_TRUE(response->was_fetched_via_spdy);
  3886. EXPECT_TRUE(response->was_alpn_negotiated);
  3887. ASSERT_THAT(ReadTransaction(trans4.get(), &response_data), IsOk());
  3888. EXPECT_EQ("hello!", response_data);
  3889. helper.VerifyDataConsumed();
  3890. }
  3891. #endif // BUILDFLAG(IS_ANDROID)
  3892. // Regression test for https://crbug.com/727653.
  3893. TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithNoMethod) {
  3894. base::HistogramTester histogram_tester;
  3895. spdy::SpdySerializedFrame req(
  3896. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  3897. spdy::SpdySerializedFrame rst(
  3898. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  3899. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 3)};
  3900. spdy::SpdySerializedFrame reply(
  3901. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3902. spdy::Http2HeaderBlock push_promise_header_block;
  3903. spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_promise_header_block);
  3904. spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
  3905. 1, 2, std::move(push_promise_header_block)));
  3906. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  3907. MockRead reads[] = {CreateMockRead(reply, 1), CreateMockRead(push_promise, 2),
  3908. CreateMockRead(body, 4),
  3909. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
  3910. SequencedSocketData data(reads, writes);
  3911. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  3912. helper.RunToCompletion(&data);
  3913. histogram_tester.ExpectBucketCount(
  3914. "Net.SpdyPushedStreamFate",
  3915. static_cast<int>(SpdyPushedStreamFate::kInvalidUrl), 1);
  3916. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  3917. }
  3918. // Regression test for https://crbug.com/727653.
  3919. TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithInvalidMethod) {
  3920. base::HistogramTester histogram_tester;
  3921. spdy::SpdySerializedFrame req(
  3922. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  3923. spdy::SpdySerializedFrame rst(
  3924. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  3925. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 3)};
  3926. spdy::SpdySerializedFrame reply(
  3927. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  3928. spdy::Http2HeaderBlock push_promise_header_block;
  3929. push_promise_header_block[":method"] = "POST";
  3930. spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_promise_header_block);
  3931. spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
  3932. 1, 2, std::move(push_promise_header_block)));
  3933. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  3934. MockRead reads[] = {CreateMockRead(reply, 1), CreateMockRead(push_promise, 2),
  3935. CreateMockRead(body, 4),
  3936. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
  3937. SequencedSocketData data(reads, writes);
  3938. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  3939. helper.RunToCompletion(&data);
  3940. histogram_tester.ExpectBucketCount(
  3941. "Net.SpdyPushedStreamFate",
  3942. static_cast<int>(SpdyPushedStreamFate::kInvalidUrl), 1);
  3943. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  3944. }
  3945. // Verify that various response headers parse correctly through the HTTP layer.
  3946. TEST_F(SpdyNetworkTransactionTest, ResponseHeaders) {
  3947. struct ResponseHeadersTests {
  3948. int extra_header_count;
  3949. const char* extra_headers[4];
  3950. size_t expected_header_count;
  3951. base::StringPiece expected_headers[8];
  3952. } test_cases[] = {
  3953. // No extra headers.
  3954. {0, {}, 1, {"hello", "bye"}},
  3955. // Comma-separated header value.
  3956. {1,
  3957. {"cookie", "val1, val2"},
  3958. 2,
  3959. {"hello", "bye", "cookie", "val1, val2"}},
  3960. // Multiple headers are preserved: they are joined with \0 separator in
  3961. // spdy::Http2HeaderBlock.AppendValueOrAddHeader(), then split up in
  3962. // HpackEncoder, then joined with \0 separator when
  3963. // spdy::HpackDecoderAdapter::ListenerAdapter::OnHeader() calls
  3964. // spdy::Http2HeaderBlock.AppendValueOrAddHeader(), then split up again in
  3965. // HttpResponseHeaders.
  3966. {2,
  3967. {"content-encoding", "val1", "content-encoding", "val2"},
  3968. 3,
  3969. {"hello", "bye", "content-encoding", "val1", "content-encoding",
  3970. "val2"}},
  3971. // Cookie header is not split up by HttpResponseHeaders.
  3972. {2,
  3973. {"cookie", "val1", "cookie", "val2"},
  3974. 2,
  3975. {"hello", "bye", "cookie", "val1; val2"}}};
  3976. for (size_t i = 0; i < std::size(test_cases); ++i) {
  3977. SCOPED_TRACE(i);
  3978. SpdyTestUtil spdy_test_util;
  3979. spdy::SpdySerializedFrame req(
  3980. spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  3981. MockWrite writes[] = {CreateMockWrite(req, 0)};
  3982. spdy::SpdySerializedFrame resp(spdy_test_util.ConstructSpdyGetReply(
  3983. test_cases[i].extra_headers, test_cases[i].extra_header_count, 1));
  3984. spdy::SpdySerializedFrame body(
  3985. spdy_test_util.ConstructSpdyDataFrame(1, true));
  3986. MockRead reads[] = {
  3987. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  3988. MockRead(ASYNC, 0, 3) // EOF
  3989. };
  3990. SequencedSocketData data(reads, writes);
  3991. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  3992. nullptr);
  3993. helper.RunToCompletion(&data);
  3994. TransactionHelperResult out = helper.output();
  3995. EXPECT_THAT(out.rv, IsOk());
  3996. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  3997. EXPECT_EQ("hello!", out.response_data);
  3998. scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
  3999. ASSERT_TRUE(headers);
  4000. EXPECT_EQ("HTTP/1.1 200", headers->GetStatusLine());
  4001. size_t iter = 0;
  4002. std::string name, value;
  4003. size_t expected_header_index = 0;
  4004. while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
  4005. ASSERT_LT(expected_header_index, test_cases[i].expected_header_count);
  4006. EXPECT_EQ(name,
  4007. test_cases[i].expected_headers[2 * expected_header_index]);
  4008. EXPECT_EQ(value,
  4009. test_cases[i].expected_headers[2 * expected_header_index + 1]);
  4010. ++expected_header_index;
  4011. }
  4012. EXPECT_EQ(expected_header_index, test_cases[i].expected_header_count);
  4013. }
  4014. }
  4015. // Verify that we don't crash on invalid response headers.
  4016. TEST_F(SpdyNetworkTransactionTest, InvalidResponseHeaders) {
  4017. struct InvalidResponseHeadersTests {
  4018. int num_headers;
  4019. const char* headers[10];
  4020. } test_cases[] = {// Response headers missing status header
  4021. {2, {"cookie", "val1", "cookie", "val2", nullptr}},
  4022. // Response headers with no headers
  4023. {0, {nullptr}}};
  4024. for (size_t i = 0; i < std::size(test_cases); ++i) {
  4025. SCOPED_TRACE(i);
  4026. SpdyTestUtil spdy_test_util;
  4027. spdy::SpdySerializedFrame req(
  4028. spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4029. spdy::SpdySerializedFrame rst(spdy_test_util.ConstructSpdyRstStream(
  4030. 1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  4031. MockWrite writes[] = {
  4032. CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
  4033. };
  4034. // Construct the reply.
  4035. spdy::Http2HeaderBlock reply_headers;
  4036. AppendToHeaderBlock(
  4037. test_cases[i].headers, test_cases[i].num_headers, &reply_headers);
  4038. spdy::SpdySerializedFrame resp(
  4039. spdy_test_util.ConstructSpdyReply(1, std::move(reply_headers)));
  4040. MockRead reads[] = {
  4041. CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3) // EOF
  4042. };
  4043. SequencedSocketData data(reads, writes);
  4044. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  4045. nullptr);
  4046. helper.RunToCompletion(&data);
  4047. TransactionHelperResult out = helper.output();
  4048. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  4049. }
  4050. }
  4051. TEST_F(SpdyNetworkTransactionTest, CorruptFrameSessionError) {
  4052. spdy::SpdySerializedFrame req(
  4053. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4054. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  4055. 0, spdy::ERROR_CODE_COMPRESSION_ERROR,
  4056. "Framer error: 24 (HPACK_TRUNCATED_BLOCK)."));
  4057. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(goaway, 2)};
  4058. // This is the length field that's too short.
  4059. spdy::SpdySerializedFrame reply_wrong_length(
  4060. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4061. size_t right_size = reply_wrong_length.size() - spdy::kFrameHeaderSize;
  4062. size_t wrong_size = right_size - 4;
  4063. spdy::test::SetFrameLength(&reply_wrong_length, wrong_size);
  4064. MockRead reads[] = {
  4065. MockRead(ASYNC, reply_wrong_length.data(), reply_wrong_length.size() - 4,
  4066. 1),
  4067. };
  4068. SequencedSocketData data(reads, writes);
  4069. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4070. helper.RunToCompletion(&data);
  4071. TransactionHelperResult out = helper.output();
  4072. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_COMPRESSION_ERROR));
  4073. }
  4074. TEST_F(SpdyNetworkTransactionTest, GoAwayOnDecompressionFailure) {
  4075. spdy::SpdySerializedFrame req(
  4076. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4077. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  4078. 0, spdy::ERROR_CODE_COMPRESSION_ERROR,
  4079. "Framer error: 24 (HPACK_TRUNCATED_BLOCK)."));
  4080. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(goaway, 2)};
  4081. // Read HEADERS with corrupted payload.
  4082. spdy::SpdySerializedFrame resp(
  4083. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4084. memset(resp.data() + 12, 0xcf, resp.size() - 12);
  4085. MockRead reads[] = {CreateMockRead(resp, 1)};
  4086. SequencedSocketData data(reads, writes);
  4087. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4088. helper.RunToCompletion(&data);
  4089. TransactionHelperResult out = helper.output();
  4090. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_COMPRESSION_ERROR));
  4091. }
  4092. TEST_F(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) {
  4093. spdy::SpdySerializedFrame req(
  4094. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4095. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  4096. 0, spdy::ERROR_CODE_FRAME_SIZE_ERROR,
  4097. "Framer error: 9 (INVALID_CONTROL_FRAME_SIZE)."));
  4098. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(goaway, 2)};
  4099. // Read WINDOW_UPDATE with incorrectly-sized payload.
  4100. spdy::SpdySerializedFrame bad_window_update(
  4101. spdy_util_.ConstructSpdyWindowUpdate(1, 1));
  4102. spdy::test::SetFrameLength(&bad_window_update, bad_window_update.size() - 1);
  4103. MockRead reads[] = {CreateMockRead(bad_window_update, 1)};
  4104. SequencedSocketData data(reads, writes);
  4105. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4106. helper.RunToCompletion(&data);
  4107. TransactionHelperResult out = helper.output();
  4108. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_FRAME_SIZE_ERROR));
  4109. }
  4110. // Test that we shutdown correctly on write errors.
  4111. TEST_F(SpdyNetworkTransactionTest, WriteError) {
  4112. spdy::SpdySerializedFrame req(
  4113. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4114. MockWrite writes[] = {
  4115. // We'll write 10 bytes successfully
  4116. MockWrite(ASYNC, req.data(), 10, 1),
  4117. // Followed by ERROR!
  4118. MockWrite(ASYNC, ERR_FAILED, 2),
  4119. // Session drains and attempts to write a GOAWAY: Another ERROR!
  4120. MockWrite(ASYNC, ERR_FAILED, 3),
  4121. };
  4122. MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
  4123. SequencedSocketData data(reads, writes);
  4124. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4125. helper.RunPreTestSetup();
  4126. helper.AddData(&data);
  4127. EXPECT_TRUE(helper.StartDefaultTest());
  4128. helper.FinishDefaultTest();
  4129. EXPECT_TRUE(data.AllWriteDataConsumed());
  4130. EXPECT_TRUE(data.AllReadDataConsumed());
  4131. TransactionHelperResult out = helper.output();
  4132. EXPECT_THAT(out.rv, IsError(ERR_FAILED));
  4133. }
  4134. // Test that partial writes work.
  4135. TEST_F(SpdyNetworkTransactionTest, PartialWrite) {
  4136. // Chop the HEADERS frame into 5 chunks.
  4137. spdy::SpdySerializedFrame req(
  4138. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4139. const int kChunks = 5;
  4140. std::unique_ptr<MockWrite[]> writes = ChopWriteFrame(req, kChunks);
  4141. for (int i = 0; i < kChunks; ++i) {
  4142. writes[i].sequence_number = i;
  4143. }
  4144. spdy::SpdySerializedFrame resp(
  4145. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4146. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  4147. MockRead reads[] = {
  4148. CreateMockRead(resp, kChunks), CreateMockRead(body, kChunks + 1),
  4149. MockRead(ASYNC, 0, kChunks + 2) // EOF
  4150. };
  4151. SequencedSocketData data(reads, base::make_span(writes.get(), kChunks));
  4152. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4153. helper.RunToCompletion(&data);
  4154. TransactionHelperResult out = helper.output();
  4155. EXPECT_THAT(out.rv, IsOk());
  4156. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  4157. EXPECT_EQ("hello!", out.response_data);
  4158. }
  4159. // Test that the NetLog contains good data for a simple GET request.
  4160. TEST_F(SpdyNetworkTransactionTest, NetLog) {
  4161. static const char* const kExtraHeaders[] = {
  4162. "user-agent", "Chrome",
  4163. };
  4164. spdy::SpdySerializedFrame req(
  4165. spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, 1, LOWEST));
  4166. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4167. spdy::SpdySerializedFrame resp(
  4168. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4169. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  4170. MockRead reads[] = {
  4171. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  4172. MockRead(ASYNC, 0, 3) // EOF
  4173. };
  4174. RecordingNetLogObserver net_log_observer;
  4175. SequencedSocketData data(reads, writes);
  4176. request_.extra_headers.SetHeader("User-Agent", "Chrome");
  4177. NormalSpdyTransactionHelper helper(
  4178. request_, DEFAULT_PRIORITY,
  4179. NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
  4180. helper.RunToCompletion(&data);
  4181. TransactionHelperResult out = helper.output();
  4182. EXPECT_THAT(out.rv, IsOk());
  4183. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  4184. EXPECT_EQ("hello!", out.response_data);
  4185. // Check that the NetLog was filled reasonably.
  4186. // This test is intentionally non-specific about the exact ordering of the
  4187. // log; instead we just check to make sure that certain events exist, and that
  4188. // they are in the right order.
  4189. auto entries = net_log_observer.GetEntries();
  4190. EXPECT_LT(0u, entries.size());
  4191. int pos = 0;
  4192. pos = ExpectLogContainsSomewhere(
  4193. entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST,
  4194. NetLogEventPhase::BEGIN);
  4195. pos = ExpectLogContainsSomewhere(
  4196. entries, pos + 1, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST,
  4197. NetLogEventPhase::END);
  4198. pos = ExpectLogContainsSomewhere(
  4199. entries, pos + 1, NetLogEventType::HTTP_TRANSACTION_READ_HEADERS,
  4200. NetLogEventPhase::BEGIN);
  4201. pos = ExpectLogContainsSomewhere(
  4202. entries, pos + 1, NetLogEventType::HTTP_TRANSACTION_READ_HEADERS,
  4203. NetLogEventPhase::END);
  4204. pos = ExpectLogContainsSomewhere(entries, pos + 1,
  4205. NetLogEventType::HTTP_TRANSACTION_READ_BODY,
  4206. NetLogEventPhase::BEGIN);
  4207. pos = ExpectLogContainsSomewhere(entries, pos + 1,
  4208. NetLogEventType::HTTP_TRANSACTION_READ_BODY,
  4209. NetLogEventPhase::END);
  4210. // Check that we logged all the headers correctly
  4211. pos = ExpectLogContainsSomewhere(entries, 0,
  4212. NetLogEventType::HTTP2_SESSION_SEND_HEADERS,
  4213. NetLogEventPhase::NONE);
  4214. ASSERT_TRUE(entries[pos].HasParams());
  4215. auto* header_list = entries[pos].params.GetDict().FindList("headers");
  4216. ASSERT_TRUE(header_list);
  4217. ASSERT_EQ(5u, header_list->size());
  4218. ASSERT_TRUE((*header_list)[0].is_string());
  4219. EXPECT_EQ(":method: GET", (*header_list)[0].GetString());
  4220. ASSERT_TRUE((*header_list)[1].is_string());
  4221. EXPECT_EQ(":authority: www.example.org", (*header_list)[1].GetString());
  4222. ASSERT_TRUE((*header_list)[2].is_string());
  4223. EXPECT_EQ(":scheme: https", (*header_list)[2].GetString());
  4224. ASSERT_TRUE((*header_list)[3].is_string());
  4225. EXPECT_EQ(":path: /", (*header_list)[3].GetString());
  4226. ASSERT_TRUE((*header_list)[4].is_string());
  4227. EXPECT_EQ("user-agent: Chrome", (*header_list)[4].GetString());
  4228. }
  4229. // Since we buffer the IO from the stream to the renderer, this test verifies
  4230. // that when we read out the maximum amount of data (e.g. we received 50 bytes
  4231. // on the network, but issued a Read for only 5 of those bytes) that the data
  4232. // flow still works correctly.
  4233. TEST_F(SpdyNetworkTransactionTest, BufferFull) {
  4234. spdy::SpdySerializedFrame req(
  4235. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4236. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4237. // 2 data frames in a single read.
  4238. spdy::SpdySerializedFrame data_frame_1(
  4239. spdy_util_.ConstructSpdyDataFrame(1, "goodby", /*fin=*/false));
  4240. spdy::SpdySerializedFrame data_frame_2(
  4241. spdy_util_.ConstructSpdyDataFrame(1, "e worl", /*fin=*/false));
  4242. spdy::SpdySerializedFrame combined_data_frames =
  4243. CombineFrames({&data_frame_1, &data_frame_2});
  4244. spdy::SpdySerializedFrame last_frame(
  4245. spdy_util_.ConstructSpdyDataFrame(1, "d", /*fin=*/true));
  4246. spdy::SpdySerializedFrame resp(
  4247. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4248. MockRead reads[] = {
  4249. CreateMockRead(resp, 1),
  4250. MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause
  4251. CreateMockRead(combined_data_frames, 3),
  4252. MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause
  4253. CreateMockRead(last_frame, 5),
  4254. MockRead(ASYNC, 0, 6) // EOF
  4255. };
  4256. SequencedSocketData data(reads, writes);
  4257. TestCompletionCallback callback;
  4258. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4259. helper.RunPreTestSetup();
  4260. helper.AddData(&data);
  4261. HttpNetworkTransaction* trans = helper.trans();
  4262. int rv = trans->Start(&request_, callback.callback(), log_);
  4263. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  4264. TransactionHelperResult out = helper.output();
  4265. out.rv = callback.WaitForResult();
  4266. EXPECT_EQ(out.rv, OK);
  4267. const HttpResponseInfo* response = trans->GetResponseInfo();
  4268. EXPECT_TRUE(response->headers);
  4269. EXPECT_TRUE(response->was_fetched_via_spdy);
  4270. out.status_line = response->headers->GetStatusLine();
  4271. out.response_info = *response; // Make a copy so we can verify.
  4272. // Read Data
  4273. TestCompletionCallback read_callback;
  4274. std::string content;
  4275. do {
  4276. // Read small chunks at a time.
  4277. const int kSmallReadSize = 3;
  4278. scoped_refptr<IOBuffer> buf =
  4279. base::MakeRefCounted<IOBuffer>(kSmallReadSize);
  4280. rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
  4281. if (rv == ERR_IO_PENDING) {
  4282. data.Resume();
  4283. rv = read_callback.WaitForResult();
  4284. }
  4285. if (rv > 0) {
  4286. content.append(buf->data(), rv);
  4287. } else if (rv < 0) {
  4288. NOTREACHED();
  4289. }
  4290. } while (rv > 0);
  4291. out.response_data.swap(content);
  4292. // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
  4293. // MockClientSocketFactory) are still alive.
  4294. base::RunLoop().RunUntilIdle();
  4295. // Verify that we consumed all test data.
  4296. helper.VerifyDataConsumed();
  4297. EXPECT_THAT(out.rv, IsOk());
  4298. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  4299. EXPECT_EQ("goodbye world", out.response_data);
  4300. }
  4301. // Verify that basic buffering works; when multiple data frames arrive
  4302. // at the same time, ensure that we don't notify a read completion for
  4303. // each data frame individually.
  4304. TEST_F(SpdyNetworkTransactionTest, Buffering) {
  4305. spdy::SpdySerializedFrame req(
  4306. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4307. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4308. // 4 data frames in a single read.
  4309. spdy::SpdySerializedFrame data_frame(
  4310. spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
  4311. spdy::SpdySerializedFrame data_frame_fin(
  4312. spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/true));
  4313. spdy::SpdySerializedFrame combined_data_frames =
  4314. CombineFrames({&data_frame, &data_frame, &data_frame, &data_frame_fin});
  4315. spdy::SpdySerializedFrame resp(
  4316. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4317. MockRead reads[] = {
  4318. CreateMockRead(resp, 1),
  4319. MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause
  4320. CreateMockRead(combined_data_frames, 3), MockRead(ASYNC, 0, 4) // EOF
  4321. };
  4322. SequencedSocketData data(reads, writes);
  4323. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4324. helper.RunPreTestSetup();
  4325. helper.AddData(&data);
  4326. HttpNetworkTransaction* trans = helper.trans();
  4327. TestCompletionCallback callback;
  4328. int rv = trans->Start(&request_, callback.callback(), log_);
  4329. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  4330. TransactionHelperResult out = helper.output();
  4331. out.rv = callback.WaitForResult();
  4332. EXPECT_EQ(out.rv, OK);
  4333. const HttpResponseInfo* response = trans->GetResponseInfo();
  4334. EXPECT_TRUE(response->headers);
  4335. EXPECT_TRUE(response->was_fetched_via_spdy);
  4336. out.status_line = response->headers->GetStatusLine();
  4337. out.response_info = *response; // Make a copy so we can verify.
  4338. // Read Data
  4339. TestCompletionCallback read_callback;
  4340. std::string content;
  4341. int reads_completed = 0;
  4342. do {
  4343. // Read small chunks at a time.
  4344. const int kSmallReadSize = 14;
  4345. scoped_refptr<IOBuffer> buf =
  4346. base::MakeRefCounted<IOBuffer>(kSmallReadSize);
  4347. rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
  4348. if (rv == ERR_IO_PENDING) {
  4349. data.Resume();
  4350. rv = read_callback.WaitForResult();
  4351. }
  4352. if (rv > 0) {
  4353. EXPECT_EQ(kSmallReadSize, rv);
  4354. content.append(buf->data(), rv);
  4355. } else if (rv < 0) {
  4356. FAIL() << "Unexpected read error: " << rv;
  4357. }
  4358. reads_completed++;
  4359. } while (rv > 0);
  4360. EXPECT_EQ(3, reads_completed); // Reads are: 14 bytes, 14 bytes, 0 bytes.
  4361. out.response_data.swap(content);
  4362. // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
  4363. // MockClientSocketFactory) are still alive.
  4364. base::RunLoop().RunUntilIdle();
  4365. // Verify that we consumed all test data.
  4366. helper.VerifyDataConsumed();
  4367. EXPECT_THAT(out.rv, IsOk());
  4368. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  4369. EXPECT_EQ("messagemessagemessagemessage", out.response_data);
  4370. }
  4371. // Verify the case where we buffer data but read it after it has been buffered.
  4372. TEST_F(SpdyNetworkTransactionTest, BufferedAll) {
  4373. spdy::SpdySerializedFrame req(
  4374. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4375. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4376. // 5 data frames in a single read.
  4377. spdy::SpdySerializedFrame reply(
  4378. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4379. spdy::SpdySerializedFrame data_frame(
  4380. spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
  4381. spdy::SpdySerializedFrame data_frame_fin(
  4382. spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/true));
  4383. spdy::SpdySerializedFrame combined_frames = CombineFrames(
  4384. {&reply, &data_frame, &data_frame, &data_frame, &data_frame_fin});
  4385. MockRead reads[] = {
  4386. CreateMockRead(combined_frames, 1), MockRead(ASYNC, 0, 2) // EOF
  4387. };
  4388. SequencedSocketData data(reads, writes);
  4389. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4390. helper.RunPreTestSetup();
  4391. helper.AddData(&data);
  4392. HttpNetworkTransaction* trans = helper.trans();
  4393. TestCompletionCallback callback;
  4394. int rv = trans->Start(&request_, callback.callback(), log_);
  4395. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  4396. TransactionHelperResult out = helper.output();
  4397. out.rv = callback.WaitForResult();
  4398. EXPECT_EQ(out.rv, OK);
  4399. const HttpResponseInfo* response = trans->GetResponseInfo();
  4400. EXPECT_TRUE(response->headers);
  4401. EXPECT_TRUE(response->was_fetched_via_spdy);
  4402. out.status_line = response->headers->GetStatusLine();
  4403. out.response_info = *response; // Make a copy so we can verify.
  4404. // Read Data
  4405. TestCompletionCallback read_callback;
  4406. std::string content;
  4407. int reads_completed = 0;
  4408. do {
  4409. // Read small chunks at a time.
  4410. const int kSmallReadSize = 14;
  4411. scoped_refptr<IOBuffer> buf =
  4412. base::MakeRefCounted<IOBuffer>(kSmallReadSize);
  4413. rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
  4414. if (rv > 0) {
  4415. EXPECT_EQ(kSmallReadSize, rv);
  4416. content.append(buf->data(), rv);
  4417. } else if (rv < 0) {
  4418. FAIL() << "Unexpected read error: " << rv;
  4419. }
  4420. reads_completed++;
  4421. } while (rv > 0);
  4422. EXPECT_EQ(3, reads_completed);
  4423. out.response_data.swap(content);
  4424. // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
  4425. // MockClientSocketFactory) are still alive.
  4426. base::RunLoop().RunUntilIdle();
  4427. // Verify that we consumed all test data.
  4428. helper.VerifyDataConsumed();
  4429. EXPECT_THAT(out.rv, IsOk());
  4430. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  4431. EXPECT_EQ("messagemessagemessagemessage", out.response_data);
  4432. }
  4433. // Verify the case where we buffer data and close the connection.
  4434. TEST_F(SpdyNetworkTransactionTest, BufferedClosed) {
  4435. spdy::SpdySerializedFrame req(
  4436. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4437. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4438. // All data frames in a single read.
  4439. // NOTE: We don't FIN the stream.
  4440. spdy::SpdySerializedFrame data_frame(
  4441. spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
  4442. spdy::SpdySerializedFrame combined_data_frames =
  4443. CombineFrames({&data_frame, &data_frame, &data_frame, &data_frame});
  4444. spdy::SpdySerializedFrame resp(
  4445. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4446. MockRead reads[] = {
  4447. CreateMockRead(resp, 1),
  4448. MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a wait
  4449. CreateMockRead(combined_data_frames, 3), MockRead(ASYNC, 0, 4) // EOF
  4450. };
  4451. SequencedSocketData data(reads, writes);
  4452. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4453. helper.RunPreTestSetup();
  4454. helper.AddData(&data);
  4455. HttpNetworkTransaction* trans = helper.trans();
  4456. TestCompletionCallback callback;
  4457. int rv = trans->Start(&request_, callback.callback(), log_);
  4458. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  4459. TransactionHelperResult out = helper.output();
  4460. rv = callback.WaitForResult();
  4461. EXPECT_EQ(rv, OK);
  4462. const HttpResponseInfo* response = trans->GetResponseInfo();
  4463. EXPECT_TRUE(response->headers);
  4464. EXPECT_TRUE(response->was_fetched_via_spdy);
  4465. // Read Data
  4466. TestCompletionCallback read_callback;
  4467. std::string content;
  4468. int reads_completed = 0;
  4469. do {
  4470. // Allocate a large buffer to allow buffering. If a single read fills the
  4471. // buffer, no buffering happens.
  4472. const int kLargeReadSize = 1000;
  4473. scoped_refptr<IOBuffer> buf =
  4474. base::MakeRefCounted<IOBuffer>(kLargeReadSize);
  4475. rv = trans->Read(buf.get(), kLargeReadSize, read_callback.callback());
  4476. if (rv == ERR_IO_PENDING) {
  4477. data.Resume();
  4478. rv = read_callback.WaitForResult();
  4479. }
  4480. if (rv < 0) {
  4481. // This test intentionally closes the connection, and will get an error.
  4482. EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
  4483. break;
  4484. }
  4485. reads_completed++;
  4486. } while (rv > 0);
  4487. EXPECT_EQ(0, reads_completed);
  4488. // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
  4489. // MockClientSocketFactory) are still alive.
  4490. base::RunLoop().RunUntilIdle();
  4491. // Verify that we consumed all test data.
  4492. helper.VerifyDataConsumed();
  4493. }
  4494. // Verify the case where we buffer data and cancel the transaction.
  4495. TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) {
  4496. spdy::SpdySerializedFrame req(
  4497. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4498. spdy::SpdySerializedFrame rst(
  4499. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  4500. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 4)};
  4501. // NOTE: We don't FIN the stream.
  4502. spdy::SpdySerializedFrame data_frame(
  4503. spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false));
  4504. spdy::SpdySerializedFrame resp(
  4505. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4506. MockRead reads[] = {
  4507. CreateMockRead(resp, 1),
  4508. MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a wait
  4509. CreateMockRead(data_frame, 3), MockRead(ASYNC, 0, 5) // EOF
  4510. };
  4511. SequencedSocketData data(reads, writes);
  4512. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4513. helper.RunPreTestSetup();
  4514. helper.AddData(&data);
  4515. HttpNetworkTransaction* trans = helper.trans();
  4516. TestCompletionCallback callback;
  4517. int rv = trans->Start(&request_, callback.callback(), log_);
  4518. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  4519. TransactionHelperResult out = helper.output();
  4520. out.rv = callback.WaitForResult();
  4521. EXPECT_EQ(out.rv, OK);
  4522. const HttpResponseInfo* response = trans->GetResponseInfo();
  4523. EXPECT_TRUE(response->headers);
  4524. EXPECT_TRUE(response->was_fetched_via_spdy);
  4525. out.status_line = response->headers->GetStatusLine();
  4526. out.response_info = *response; // Make a copy so we can verify.
  4527. // Read Data
  4528. TestCompletionCallback read_callback;
  4529. const int kReadSize = 256;
  4530. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kReadSize);
  4531. rv = trans->Read(buf.get(), kReadSize, read_callback.callback());
  4532. ASSERT_EQ(ERR_IO_PENDING, rv) << "Unexpected read: " << rv;
  4533. // Complete the read now, which causes buffering to start.
  4534. data.Resume();
  4535. base::RunLoop().RunUntilIdle();
  4536. // Destroy the transaction, causing the stream to get cancelled
  4537. // and orphaning the buffered IO task.
  4538. helper.ResetTrans();
  4539. // Flush the MessageLoop; this will cause the buffered IO task
  4540. // to run for the final time.
  4541. base::RunLoop().RunUntilIdle();
  4542. // Verify that we consumed all test data.
  4543. helper.VerifyDataConsumed();
  4544. }
  4545. // Request should fail upon receiving a GOAWAY frame
  4546. // with Last-Stream-ID lower than the stream id corresponding to the request
  4547. // and with error code other than NO_ERROR.
  4548. TEST_F(SpdyNetworkTransactionTest, FailOnGoAway) {
  4549. spdy::SpdySerializedFrame req(
  4550. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4551. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4552. spdy::SpdySerializedFrame go_away(
  4553. spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_INTERNAL_ERROR, ""));
  4554. MockRead reads[] = {
  4555. CreateMockRead(go_away, 1),
  4556. };
  4557. SequencedSocketData data(reads, writes);
  4558. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4559. helper.RunToCompletion(&data);
  4560. TransactionHelperResult out = helper.output();
  4561. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  4562. }
  4563. // Request should be retried on a new connection upon receiving a GOAWAY frame
  4564. // with Last-Stream-ID lower than the stream id corresponding to the request
  4565. // and with error code NO_ERROR.
  4566. TEST_F(SpdyNetworkTransactionTest, RetryOnGoAway) {
  4567. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4568. // First connection.
  4569. spdy::SpdySerializedFrame req(
  4570. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4571. MockWrite writes1[] = {CreateMockWrite(req, 0)};
  4572. spdy::SpdySerializedFrame go_away(
  4573. spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_NO_ERROR, ""));
  4574. MockRead reads1[] = {CreateMockRead(go_away, 1)};
  4575. SequencedSocketData data1(reads1, writes1);
  4576. helper.AddData(&data1);
  4577. // Second connection.
  4578. MockWrite writes2[] = {CreateMockWrite(req, 0)};
  4579. spdy::SpdySerializedFrame resp(
  4580. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4581. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  4582. MockRead reads2[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
  4583. MockRead(ASYNC, 0, 3)};
  4584. SequencedSocketData data2(reads2, writes2);
  4585. helper.AddData(&data2);
  4586. helper.RunPreTestSetup();
  4587. helper.RunDefaultTest();
  4588. TransactionHelperResult out = helper.output();
  4589. EXPECT_THAT(out.rv, IsOk());
  4590. helper.VerifyDataConsumed();
  4591. }
  4592. // A server can gracefully shut down by sending a GOAWAY frame
  4593. // with maximum last-stream-id value.
  4594. // Transactions started before receiving such a GOAWAY frame should succeed,
  4595. // but SpdySession should be unavailable for new streams.
  4596. TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) {
  4597. spdy::SpdySerializedFrame req1(
  4598. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4599. spdy_util_.UpdateWithStreamDestruction(1);
  4600. spdy::SpdySerializedFrame req2(
  4601. spdy_util_.ConstructSpdyGet("https://www.example.org/foo", 3, LOWEST));
  4602. MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 3)};
  4603. spdy::SpdySerializedFrame resp1(
  4604. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4605. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  4606. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  4607. 0x7fffffff, spdy::ERROR_CODE_NO_ERROR, "Graceful shutdown."));
  4608. spdy::SpdySerializedFrame resp2(
  4609. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  4610. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  4611. MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  4612. CreateMockRead(goaway, 4), CreateMockRead(resp2, 5),
  4613. CreateMockRead(body2, 6), MockRead(ASYNC, 0, 7)};
  4614. // Run first transaction.
  4615. SequencedSocketData data(reads, writes);
  4616. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4617. helper.RunPreTestSetup();
  4618. helper.AddData(&data);
  4619. helper.RunDefaultTest();
  4620. // Verify first response.
  4621. TransactionHelperResult out = helper.output();
  4622. EXPECT_THAT(out.rv, IsOk());
  4623. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  4624. EXPECT_EQ("hello!", out.response_data);
  4625. // GOAWAY frame has not yet been received, SpdySession should be available.
  4626. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  4627. SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
  4628. PRIVACY_MODE_DISABLED,
  4629. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  4630. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  4631. EXPECT_TRUE(
  4632. spdy_session_pool->HasAvailableSession(key, /* is_websocket = */ false));
  4633. base::WeakPtr<SpdySession> spdy_session =
  4634. spdy_session_pool->FindAvailableSession(
  4635. key, /* enable_ip_based_pooling = */ true,
  4636. /* is_websocket = */ false, log_);
  4637. EXPECT_TRUE(spdy_session);
  4638. // Start second transaction.
  4639. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  4640. TestCompletionCallback callback;
  4641. HttpRequestInfo request2;
  4642. request2.method = "GET";
  4643. request2.url = GURL("https://www.example.org/foo");
  4644. request2.traffic_annotation =
  4645. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  4646. int rv = trans2.Start(&request2, callback.callback(), log_);
  4647. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  4648. rv = callback.WaitForResult();
  4649. EXPECT_THAT(rv, IsOk());
  4650. // Verify second response.
  4651. const HttpResponseInfo* response = trans2.GetResponseInfo();
  4652. ASSERT_TRUE(response);
  4653. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2, response->connection_info);
  4654. ASSERT_TRUE(response->headers);
  4655. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  4656. EXPECT_TRUE(response->was_fetched_via_spdy);
  4657. EXPECT_TRUE(response->was_alpn_negotiated);
  4658. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  4659. EXPECT_EQ(443, response->remote_endpoint.port());
  4660. std::string response_data;
  4661. rv = ReadTransaction(&trans2, &response_data);
  4662. EXPECT_THAT(rv, IsOk());
  4663. EXPECT_EQ("hello!", response_data);
  4664. // Graceful GOAWAY was received, SpdySession should be unavailable.
  4665. EXPECT_FALSE(
  4666. spdy_session_pool->HasAvailableSession(key, /* is_websocket = */ false));
  4667. spdy_session = spdy_session_pool->FindAvailableSession(
  4668. key, /* enable_ip_based_pooling = */ true,
  4669. /* is_websocket = */ false, log_);
  4670. EXPECT_FALSE(spdy_session);
  4671. helper.VerifyDataConsumed();
  4672. }
  4673. TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) {
  4674. spdy::SpdySerializedFrame req(
  4675. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  4676. MockWrite writes[] = {CreateMockWrite(req, 0)};
  4677. spdy::SpdySerializedFrame resp(
  4678. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  4679. MockRead reads[] = {
  4680. CreateMockRead(resp, 1), MockRead(SYNCHRONOUS, 0, 2) // EOF
  4681. };
  4682. SequencedSocketData data(reads, writes);
  4683. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4684. helper.RunPreTestSetup();
  4685. helper.AddData(&data);
  4686. helper.StartDefaultTest();
  4687. EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
  4688. helper.WaitForCallbackToComplete();
  4689. EXPECT_THAT(helper.output().rv, IsError(ERR_CONNECTION_CLOSED));
  4690. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  4691. EXPECT_TRUE(response->headers);
  4692. EXPECT_TRUE(response->was_fetched_via_spdy);
  4693. // Verify that we consumed all test data.
  4694. helper.VerifyDataConsumed();
  4695. }
  4696. TEST_F(SpdyNetworkTransactionTest, GoAwayImmediately) {
  4697. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  4698. MockRead reads[] = {CreateMockRead(goaway, 0, SYNCHRONOUS)};
  4699. SequencedSocketData data(reads, base::span<MockWrite>());
  4700. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4701. helper.RunPreTestSetup();
  4702. helper.AddData(&data);
  4703. helper.StartDefaultTest();
  4704. EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
  4705. helper.WaitForCallbackToComplete();
  4706. EXPECT_THAT(helper.output().rv, IsError(ERR_CONNECTION_CLOSED));
  4707. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  4708. EXPECT_FALSE(response->headers);
  4709. EXPECT_TRUE(response->was_fetched_via_spdy);
  4710. // Verify that we consumed all test data.
  4711. helper.VerifyDataConsumed();
  4712. }
  4713. // Retry with HTTP/1.1 when receiving HTTP_1_1_REQUIRED. Note that no actual
  4714. // protocol negotiation happens, instead this test forces protocols for both
  4715. // sockets.
  4716. TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
  4717. request_.method = "GET";
  4718. // Do not force SPDY so that second socket can negotiate HTTP/1.1.
  4719. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4720. // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
  4721. spdy::Http2HeaderBlock headers(
  4722. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  4723. spdy::SpdySerializedFrame req(
  4724. spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
  4725. MockWrite writes0[] = {CreateMockWrite(req, 0)};
  4726. spdy::SpdySerializedFrame rst(
  4727. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
  4728. MockRead reads0[] = {CreateMockRead(rst, 1)};
  4729. SequencedSocketData data0(reads0, writes0);
  4730. auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4731. // Expect HTTP/2 protocols too in SSLConfig.
  4732. ssl_provider0->next_protos_expected_in_ssl_config =
  4733. NextProtoVector{kProtoHTTP2, kProtoHTTP11};
  4734. // Force SPDY.
  4735. ssl_provider0->next_proto = kProtoHTTP2;
  4736. helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
  4737. // Second socket: falling back to HTTP/1.1.
  4738. MockWrite writes1[] = {MockWrite(ASYNC, 0,
  4739. "GET / HTTP/1.1\r\n"
  4740. "Host: www.example.org\r\n"
  4741. "Connection: keep-alive\r\n\r\n")};
  4742. MockRead reads1[] = {MockRead(ASYNC, 1,
  4743. "HTTP/1.1 200 OK\r\n"
  4744. "Content-Length: 5\r\n\r\n"
  4745. "hello")};
  4746. SequencedSocketData data1(reads1, writes1);
  4747. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4748. // Expect only HTTP/1.1 protocol in SSLConfig.
  4749. ssl_provider1->next_protos_expected_in_ssl_config =
  4750. NextProtoVector{kProtoHTTP11};
  4751. // Force HTTP/1.1.
  4752. ssl_provider1->next_proto = kProtoHTTP11;
  4753. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  4754. HttpServerProperties* http_server_properties =
  4755. helper.session()->spdy_session_pool()->http_server_properties();
  4756. EXPECT_FALSE(http_server_properties->RequiresHTTP11(
  4757. url::SchemeHostPort(request_.url), NetworkIsolationKey()));
  4758. helper.RunPreTestSetup();
  4759. helper.StartDefaultTest();
  4760. helper.FinishDefaultTestWithoutVerification();
  4761. helper.VerifyDataConsumed();
  4762. EXPECT_TRUE(http_server_properties->RequiresHTTP11(
  4763. url::SchemeHostPort(request_.url), NetworkIsolationKey()));
  4764. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  4765. ASSERT_TRUE(response);
  4766. ASSERT_TRUE(response->headers);
  4767. EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
  4768. EXPECT_FALSE(response->was_fetched_via_spdy);
  4769. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
  4770. response->connection_info);
  4771. EXPECT_TRUE(response->was_alpn_negotiated);
  4772. EXPECT_TRUE(request_.url.SchemeIs("https"));
  4773. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  4774. EXPECT_EQ(443, response->remote_endpoint.port());
  4775. std::string response_data;
  4776. ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
  4777. EXPECT_EQ("hello", response_data);
  4778. }
  4779. // Same as above test, but checks that NetworkIsolationKeys are respected.
  4780. TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetryWithNetworkIsolationKey) {
  4781. const SchemefulSite kSite1(GURL("https://foo.test/"));
  4782. const SchemefulSite kSite2(GURL("https://bar.test/"));
  4783. const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
  4784. const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
  4785. const NetworkIsolationKey kNetworkIsolationKeys[] = {
  4786. kNetworkIsolationKey1, kNetworkIsolationKey2, NetworkIsolationKey()};
  4787. base::test::ScopedFeatureList feature_list;
  4788. feature_list.InitWithFeatures(
  4789. // enabled_features
  4790. {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
  4791. // Need to partition connections by NetworkIsolationKey for
  4792. // SpdySessionKeys to include NetworkIsolationKeys.
  4793. features::kPartitionConnectionsByNetworkIsolationKey},
  4794. // disabled_features
  4795. {});
  4796. // Do not force SPDY so that sockets can negotiate HTTP/1.1.
  4797. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  4798. // For each server, set up and tear down a QUIC session cleanly, and check
  4799. // that stats have been added to HttpServerProperties using the correct
  4800. // NetworkIsolationKey.
  4801. for (size_t i = 0; i < std::size(kNetworkIsolationKeys); ++i) {
  4802. SCOPED_TRACE(i);
  4803. request_.method = "GET";
  4804. request_.network_isolation_key = kNetworkIsolationKeys[i];
  4805. // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
  4806. SpdyTestUtil spdy_util;
  4807. spdy::Http2HeaderBlock headers(
  4808. spdy_util.ConstructGetHeaderBlock(kDefaultUrl));
  4809. spdy::SpdySerializedFrame req(
  4810. spdy_util.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
  4811. MockWrite writes0[] = {CreateMockWrite(req, 0)};
  4812. spdy::SpdySerializedFrame rst(spdy_util.ConstructSpdyRstStream(
  4813. 1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
  4814. MockRead reads0[] = {CreateMockRead(rst, 1)};
  4815. SequencedSocketData data0(reads0, writes0);
  4816. auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4817. // Expect HTTP/2 protocols too in SSLConfig.
  4818. ssl_provider0->next_protos_expected_in_ssl_config =
  4819. NextProtoVector{kProtoHTTP2, kProtoHTTP11};
  4820. // Force SPDY.
  4821. ssl_provider0->next_proto = kProtoHTTP2;
  4822. helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
  4823. // Second socket: falling back to HTTP/1.1.
  4824. MockWrite writes1[] = {MockWrite(ASYNC, 0,
  4825. "GET / HTTP/1.1\r\n"
  4826. "Host: www.example.org\r\n"
  4827. "Connection: keep-alive\r\n\r\n")};
  4828. MockRead reads1[] = {MockRead(ASYNC, 1,
  4829. "HTTP/1.1 200 OK\r\n"
  4830. "Content-Length: 5\r\n\r\n"
  4831. "hello")};
  4832. SequencedSocketData data1(reads1, writes1);
  4833. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4834. // Expect only HTTP/1.1 protocol in SSLConfig.
  4835. ssl_provider1->next_protos_expected_in_ssl_config =
  4836. NextProtoVector{kProtoHTTP11};
  4837. // Force HTTP/1.1.
  4838. ssl_provider1->next_proto = kProtoHTTP11;
  4839. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  4840. HttpServerProperties* http_server_properties =
  4841. helper.session()->spdy_session_pool()->http_server_properties();
  4842. EXPECT_FALSE(http_server_properties->RequiresHTTP11(
  4843. url::SchemeHostPort(request_.url), kNetworkIsolationKeys[i]));
  4844. HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
  4845. TestCompletionCallback callback;
  4846. int rv = trans.Start(&request_, callback.callback(), log_);
  4847. EXPECT_THAT(callback.GetResult(rv), IsOk());
  4848. const HttpResponseInfo* response = trans.GetResponseInfo();
  4849. ASSERT_TRUE(response);
  4850. ASSERT_TRUE(response->headers);
  4851. EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
  4852. EXPECT_FALSE(response->was_fetched_via_spdy);
  4853. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
  4854. response->connection_info);
  4855. EXPECT_TRUE(response->was_alpn_negotiated);
  4856. EXPECT_TRUE(request_.url.SchemeIs("https"));
  4857. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  4858. EXPECT_EQ(443, response->remote_endpoint.port());
  4859. std::string response_data;
  4860. ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
  4861. EXPECT_EQ("hello", response_data);
  4862. for (size_t j = 0; j < std::size(kNetworkIsolationKeys); ++j) {
  4863. // NetworkIsolationKeys up to kNetworkIsolationKeys[j] are known to
  4864. // require HTTP/1.1, others are not.
  4865. if (j <= i) {
  4866. EXPECT_TRUE(http_server_properties->RequiresHTTP11(
  4867. url::SchemeHostPort(request_.url), kNetworkIsolationKeys[j]));
  4868. } else {
  4869. EXPECT_FALSE(http_server_properties->RequiresHTTP11(
  4870. url::SchemeHostPort(request_.url), kNetworkIsolationKeys[j]));
  4871. }
  4872. }
  4873. }
  4874. }
  4875. // Retry with HTTP/1.1 to the proxy when receiving HTTP_1_1_REQUIRED from the
  4876. // proxy. Note that no actual protocol negotiation happens, instead this test
  4877. // forces protocols for both sockets.
  4878. TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
  4879. request_.method = "GET";
  4880. auto session_deps = std::make_unique<SpdySessionDependencies>(
  4881. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  4882. "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  4883. // Do not force SPDY so that second socket can negotiate HTTP/1.1.
  4884. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  4885. std::move(session_deps));
  4886. // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
  4887. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
  4888. nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
  4889. HostPortPair("www.example.org", 443)));
  4890. MockWrite writes0[] = {CreateMockWrite(req, 0)};
  4891. spdy::SpdySerializedFrame rst(
  4892. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
  4893. MockRead reads0[] = {CreateMockRead(rst, 1)};
  4894. SequencedSocketData data0(reads0, writes0);
  4895. auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4896. // Expect HTTP/2 protocols too in SSLConfig.
  4897. ssl_provider0->next_protos_expected_in_ssl_config =
  4898. NextProtoVector{kProtoHTTP2, kProtoHTTP11};
  4899. // Force SPDY.
  4900. ssl_provider0->next_proto = kProtoHTTP2;
  4901. helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
  4902. // Second socket: retry using HTTP/1.1.
  4903. MockWrite writes1[] = {
  4904. MockWrite(ASYNC, 0,
  4905. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  4906. "Host: www.example.org:443\r\n"
  4907. "Proxy-Connection: keep-alive\r\n\r\n"),
  4908. MockWrite(ASYNC, 2,
  4909. "GET / HTTP/1.1\r\n"
  4910. "Host: www.example.org\r\n"
  4911. "Connection: keep-alive\r\n\r\n"),
  4912. };
  4913. MockRead reads1[] = {
  4914. MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
  4915. MockRead(ASYNC, 3,
  4916. "HTTP/1.1 200 OK\r\n"
  4917. "Content-Length: 5\r\n\r\n"
  4918. "hello"),
  4919. };
  4920. SequencedSocketData data1(reads1, writes1);
  4921. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4922. // Expect only HTTP/1.1 protocol in SSLConfig.
  4923. ssl_provider1->next_protos_expected_in_ssl_config =
  4924. NextProtoVector{kProtoHTTP11};
  4925. // Force HTTP/1.1.
  4926. ssl_provider1->next_proto = kProtoHTTP11;
  4927. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  4928. // A third socket is needed for the tunnelled connection.
  4929. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4930. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  4931. ssl_provider2.get());
  4932. HttpServerProperties* http_server_properties =
  4933. helper.session()->spdy_session_pool()->http_server_properties();
  4934. url::SchemeHostPort proxy_scheme_host_port(url::kHttpsScheme, "myproxy", 70);
  4935. EXPECT_FALSE(http_server_properties->RequiresHTTP11(proxy_scheme_host_port,
  4936. NetworkIsolationKey()));
  4937. helper.RunPreTestSetup();
  4938. helper.StartDefaultTest();
  4939. helper.FinishDefaultTestWithoutVerification();
  4940. helper.VerifyDataConsumed();
  4941. EXPECT_TRUE(http_server_properties->RequiresHTTP11(proxy_scheme_host_port,
  4942. NetworkIsolationKey()));
  4943. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  4944. ASSERT_TRUE(response);
  4945. ASSERT_TRUE(response->headers);
  4946. EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
  4947. EXPECT_FALSE(response->was_fetched_via_spdy);
  4948. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
  4949. response->connection_info);
  4950. EXPECT_FALSE(response->was_alpn_negotiated);
  4951. EXPECT_TRUE(request_.url.SchemeIs("https"));
  4952. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  4953. EXPECT_EQ(70, response->remote_endpoint.port());
  4954. std::string response_data;
  4955. ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
  4956. EXPECT_EQ("hello", response_data);
  4957. }
  4958. // Same as above, but also test that NetworkIsolationKeys are respected.
  4959. TEST_F(SpdyNetworkTransactionTest,
  4960. HTTP11RequiredProxyRetryWithNetworkIsolationKey) {
  4961. const SchemefulSite kSite1(GURL("https://foo.test/"));
  4962. const SchemefulSite kSite2(GURL("https://bar.test/"));
  4963. const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
  4964. const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
  4965. const NetworkIsolationKey kNetworkIsolationKeys[] = {
  4966. kNetworkIsolationKey1, kNetworkIsolationKey2, NetworkIsolationKey()};
  4967. base::test::ScopedFeatureList feature_list;
  4968. feature_list.InitWithFeatures(
  4969. // enabled_features
  4970. {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
  4971. // Need to partition connections by NetworkIsolationKey for
  4972. // SpdySessionKeys to include NetworkIsolationKeys.
  4973. features::kPartitionConnectionsByNetworkIsolationKey},
  4974. // disabled_features
  4975. {});
  4976. request_.method = "GET";
  4977. auto session_deps = std::make_unique<SpdySessionDependencies>(
  4978. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  4979. "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  4980. // Do not force SPDY so that second socket can negotiate HTTP/1.1.
  4981. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  4982. std::move(session_deps));
  4983. helper.RunPreTestSetup();
  4984. for (size_t i = 0; i < std::size(kNetworkIsolationKeys); ++i) {
  4985. // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
  4986. SpdyTestUtil spdy_util;
  4987. spdy::SpdySerializedFrame req(spdy_util.ConstructSpdyConnect(
  4988. nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
  4989. HostPortPair("www.example.org", 443)));
  4990. MockWrite writes0[] = {CreateMockWrite(req, 0)};
  4991. spdy::SpdySerializedFrame rst(spdy_util.ConstructSpdyRstStream(
  4992. 1, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
  4993. MockRead reads0[] = {CreateMockRead(rst, 1)};
  4994. SequencedSocketData data0(reads0, writes0);
  4995. auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  4996. // Expect HTTP/2 protocols too in SSLConfig.
  4997. ssl_provider0->next_protos_expected_in_ssl_config =
  4998. NextProtoVector{kProtoHTTP2, kProtoHTTP11};
  4999. // Force SPDY.
  5000. ssl_provider0->next_proto = kProtoHTTP2;
  5001. helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
  5002. // Second socket: retry using HTTP/1.1.
  5003. MockWrite writes1[] = {
  5004. MockWrite(ASYNC, 0,
  5005. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  5006. "Host: www.example.org:443\r\n"
  5007. "Proxy-Connection: keep-alive\r\n\r\n"),
  5008. MockWrite(ASYNC, 2,
  5009. "GET / HTTP/1.1\r\n"
  5010. "Host: www.example.org\r\n"
  5011. "Connection: keep-alive\r\n\r\n"),
  5012. };
  5013. MockRead reads1[] = {
  5014. MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
  5015. MockRead(ASYNC, 3,
  5016. "HTTP/1.1 200 OK\r\n"
  5017. "Content-Length: 5\r\n\r\n"
  5018. "hello"),
  5019. };
  5020. SequencedSocketData data1(reads1, writes1);
  5021. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  5022. // Expect only HTTP/1.1 protocol in SSLConfig.
  5023. ssl_provider1->next_protos_expected_in_ssl_config =
  5024. NextProtoVector{kProtoHTTP11};
  5025. // Force HTTP/1.1.
  5026. ssl_provider1->next_proto = kProtoHTTP11;
  5027. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  5028. // A third socket is needed for the tunnelled connection.
  5029. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  5030. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  5031. ssl_provider2.get());
  5032. HttpServerProperties* http_server_properties =
  5033. helper.session()->spdy_session_pool()->http_server_properties();
  5034. url::SchemeHostPort proxy_scheme_host_port(url::kHttpsScheme, "myproxy",
  5035. 70);
  5036. EXPECT_FALSE(http_server_properties->RequiresHTTP11(
  5037. proxy_scheme_host_port, kNetworkIsolationKeys[i]));
  5038. request_.network_isolation_key = kNetworkIsolationKeys[i];
  5039. HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
  5040. TestCompletionCallback callback;
  5041. int rv = trans.Start(&request_, callback.callback(), log_);
  5042. EXPECT_THAT(callback.GetResult(rv), IsOk());
  5043. helper.VerifyDataConsumed();
  5044. const HttpResponseInfo* response = trans.GetResponseInfo();
  5045. ASSERT_TRUE(response);
  5046. ASSERT_TRUE(response->headers);
  5047. EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
  5048. EXPECT_FALSE(response->was_fetched_via_spdy);
  5049. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
  5050. response->connection_info);
  5051. EXPECT_FALSE(response->was_alpn_negotiated);
  5052. EXPECT_TRUE(request_.url.SchemeIs("https"));
  5053. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  5054. EXPECT_EQ(70, response->remote_endpoint.port());
  5055. std::string response_data;
  5056. ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
  5057. EXPECT_EQ("hello", response_data);
  5058. for (size_t j = 0; j < std::size(kNetworkIsolationKeys); ++j) {
  5059. // The proxy SchemeHostPort URL should not be marked as requiring HTTP/1.1
  5060. // using the current NetworkIsolationKey, and the state of others should
  5061. // be unchanged since the last loop iteration..
  5062. if (j <= i) {
  5063. EXPECT_TRUE(http_server_properties->RequiresHTTP11(
  5064. proxy_scheme_host_port, kNetworkIsolationKeys[j]));
  5065. } else {
  5066. EXPECT_FALSE(http_server_properties->RequiresHTTP11(
  5067. proxy_scheme_host_port, kNetworkIsolationKeys[j]));
  5068. }
  5069. }
  5070. // The destination SchemeHostPort should not be marked as requiring
  5071. // HTTP/1.1.
  5072. EXPECT_FALSE(http_server_properties->RequiresHTTP11(
  5073. url::SchemeHostPort(request_.url), kNetworkIsolationKeys[i]));
  5074. }
  5075. }
  5076. // Test to make sure we can correctly connect through a proxy.
  5077. TEST_F(SpdyNetworkTransactionTest, ProxyConnect) {
  5078. auto session_deps = std::make_unique<SpdySessionDependencies>(
  5079. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  5080. "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  5081. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  5082. std::move(session_deps));
  5083. helper.RunPreTestSetup();
  5084. HttpNetworkTransaction* trans = helper.trans();
  5085. const char kConnect443[] = {
  5086. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  5087. "Host: www.example.org:443\r\n"
  5088. "Proxy-Connection: keep-alive\r\n\r\n"};
  5089. const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
  5090. spdy::SpdySerializedFrame req(
  5091. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5092. spdy::SpdySerializedFrame resp(
  5093. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5094. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  5095. MockWrite writes[] = {
  5096. MockWrite(SYNCHRONOUS, kConnect443, std::size(kConnect443) - 1, 0),
  5097. CreateMockWrite(req, 2),
  5098. };
  5099. MockRead reads[] = {
  5100. MockRead(SYNCHRONOUS, kHTTP200, std::size(kHTTP200) - 1, 1),
  5101. CreateMockRead(resp, 3),
  5102. CreateMockRead(body, 4),
  5103. MockRead(ASYNC, nullptr, 0, 5),
  5104. };
  5105. SequencedSocketData data(reads, writes);
  5106. helper.AddData(&data);
  5107. TestCompletionCallback callback;
  5108. int rv = trans->Start(&request_, callback.callback(), log_);
  5109. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5110. rv = callback.WaitForResult();
  5111. EXPECT_EQ(0, rv);
  5112. // Verify the response headers.
  5113. HttpResponseInfo response = *trans->GetResponseInfo();
  5114. ASSERT_TRUE(response.headers);
  5115. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  5116. std::string response_data;
  5117. ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
  5118. EXPECT_EQ("hello!", response_data);
  5119. helper.VerifyDataConsumed();
  5120. }
  5121. // Test to make sure we can correctly connect through a proxy to
  5122. // www.example.org, if there already exists a direct spdy connection to
  5123. // www.example.org. See https://crbug.com/49874.
  5124. TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
  5125. // Use a proxy service which returns a proxy fallback list from DIRECT to
  5126. // myproxy:70. For this test there will be no fallback, so it is equivalent
  5127. // to simply DIRECT. The reason for appending the second proxy is to verify
  5128. // that the session pool key used does is just "DIRECT".
  5129. auto session_deps = std::make_unique<SpdySessionDependencies>(
  5130. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  5131. "DIRECT; PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  5132. // When setting up the first transaction, we store the SpdySessionPool so that
  5133. // we can use the same pool in the second transaction.
  5134. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  5135. std::move(session_deps));
  5136. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  5137. helper.RunPreTestSetup();
  5138. // Construct and send a simple GET request.
  5139. spdy::SpdySerializedFrame req(
  5140. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5141. MockWrite writes[] = {
  5142. CreateMockWrite(req, 0),
  5143. };
  5144. spdy::SpdySerializedFrame resp(
  5145. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5146. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  5147. MockRead reads[] = {
  5148. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  5149. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3), // Force a pause
  5150. };
  5151. SequencedSocketData data(reads, writes);
  5152. helper.AddData(&data);
  5153. HttpNetworkTransaction* trans = helper.trans();
  5154. TestCompletionCallback callback;
  5155. TransactionHelperResult out;
  5156. out.rv = trans->Start(&request_, callback.callback(), log_);
  5157. EXPECT_EQ(out.rv, ERR_IO_PENDING);
  5158. out.rv = callback.WaitForResult();
  5159. EXPECT_EQ(out.rv, OK);
  5160. const HttpResponseInfo* response = trans->GetResponseInfo();
  5161. EXPECT_TRUE(response->headers);
  5162. EXPECT_TRUE(response->was_fetched_via_spdy);
  5163. out.rv = ReadTransaction(trans, &out.response_data);
  5164. EXPECT_THAT(out.rv, IsOk());
  5165. out.status_line = response->headers->GetStatusLine();
  5166. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  5167. EXPECT_EQ("hello!", out.response_data);
  5168. // Check that the SpdySession is still in the SpdySessionPool.
  5169. SpdySessionKey session_pool_key_direct(
  5170. host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  5171. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  5172. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  5173. EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct));
  5174. SpdySessionKey session_pool_key_proxy(
  5175. host_port_pair_,
  5176. ProxyUriToProxyServer("www.foo.com", ProxyServer::SCHEME_HTTP),
  5177. PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse,
  5178. SocketTag(), NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  5179. EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy));
  5180. // New SpdyTestUtil instance for the session that will be used for the
  5181. // proxy connection.
  5182. SpdyTestUtil spdy_util_2;
  5183. // Set up data for the proxy connection.
  5184. const char kConnect443[] = {
  5185. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  5186. "Host: www.example.org:443\r\n"
  5187. "Proxy-Connection: keep-alive\r\n\r\n"};
  5188. const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
  5189. spdy::SpdySerializedFrame req2(
  5190. spdy_util_2.ConstructSpdyGet(kPushedUrl, 1, LOWEST));
  5191. spdy::SpdySerializedFrame resp2(
  5192. spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
  5193. spdy::SpdySerializedFrame body2(spdy_util_2.ConstructSpdyDataFrame(1, true));
  5194. MockWrite writes2[] = {
  5195. MockWrite(SYNCHRONOUS, kConnect443, std::size(kConnect443) - 1, 0),
  5196. CreateMockWrite(req2, 2),
  5197. };
  5198. MockRead reads2[] = {
  5199. MockRead(SYNCHRONOUS, kHTTP200, std::size(kHTTP200) - 1, 1),
  5200. CreateMockRead(resp2, 3), CreateMockRead(body2, 4),
  5201. MockRead(ASYNC, 0, 5) // EOF
  5202. };
  5203. SequencedSocketData data_proxy(reads2, writes2);
  5204. // Create another request to www.example.org, but this time through a proxy.
  5205. request_.method = "GET";
  5206. request_.url = GURL(kPushedUrl);
  5207. auto session_deps_proxy = std::make_unique<SpdySessionDependencies>(
  5208. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  5209. "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  5210. NormalSpdyTransactionHelper helper_proxy(request_, DEFAULT_PRIORITY, log_,
  5211. std::move(session_deps_proxy));
  5212. helper_proxy.RunPreTestSetup();
  5213. helper_proxy.AddData(&data_proxy);
  5214. HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
  5215. TestCompletionCallback callback_proxy;
  5216. int rv = trans_proxy->Start(&request_, callback_proxy.callback(), log_);
  5217. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5218. rv = callback_proxy.WaitForResult();
  5219. EXPECT_EQ(0, rv);
  5220. HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
  5221. ASSERT_TRUE(response_proxy.headers);
  5222. EXPECT_EQ("HTTP/1.1 200", response_proxy.headers->GetStatusLine());
  5223. std::string response_data;
  5224. ASSERT_THAT(ReadTransaction(trans_proxy, &response_data), IsOk());
  5225. EXPECT_EQ("hello!", response_data);
  5226. helper_proxy.VerifyDataConsumed();
  5227. }
  5228. // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
  5229. // on a new connection, if the connection was previously known to be good.
  5230. // This can happen when a server reboots without saying goodbye, or when
  5231. // we're behind a NAT that masked the RST.
  5232. TEST_F(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
  5233. spdy::SpdySerializedFrame resp(
  5234. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5235. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  5236. MockRead reads[] = {
  5237. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  5238. MockRead(ASYNC, ERR_IO_PENDING, 3),
  5239. MockRead(ASYNC, ERR_CONNECTION_RESET, 4),
  5240. };
  5241. MockRead reads2[] = {
  5242. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  5243. MockRead(ASYNC, 0, 3) // EOF
  5244. };
  5245. spdy::SpdySerializedFrame req(
  5246. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5247. // In all cases the connection will be reset before req3 can be
  5248. // dispatched, destroying both streams.
  5249. spdy_util_.UpdateWithStreamDestruction(1);
  5250. spdy::SpdySerializedFrame req3(
  5251. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  5252. MockWrite writes1[] = {CreateMockWrite(req, 0), CreateMockWrite(req3, 5)};
  5253. MockWrite writes2[] = {CreateMockWrite(req, 0)};
  5254. // This test has a couple of variants.
  5255. enum {
  5256. // Induce the RST while waiting for our transaction to send.
  5257. VARIANT_RST_DURING_SEND_COMPLETION = 0,
  5258. // Induce the RST while waiting for our transaction to read.
  5259. // In this case, the send completed - everything copied into the SNDBUF.
  5260. VARIANT_RST_DURING_READ_COMPLETION = 1
  5261. };
  5262. for (int variant = VARIANT_RST_DURING_SEND_COMPLETION;
  5263. variant <= VARIANT_RST_DURING_READ_COMPLETION;
  5264. ++variant) {
  5265. SequencedSocketData data1(reads,
  5266. base::make_span(writes1).first(1 + variant));
  5267. SequencedSocketData data2(reads2, writes2);
  5268. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  5269. nullptr);
  5270. helper.AddData(&data1);
  5271. helper.AddData(&data2);
  5272. helper.RunPreTestSetup();
  5273. for (int i = 0; i < 2; ++i) {
  5274. HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
  5275. TestCompletionCallback callback;
  5276. int rv = trans.Start(&request_, callback.callback(), log_);
  5277. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5278. // On the second transaction, we trigger the RST.
  5279. if (i == 1) {
  5280. if (variant == VARIANT_RST_DURING_READ_COMPLETION) {
  5281. // Writes to the socket complete asynchronously on SPDY by running
  5282. // through the message loop. Complete the write here.
  5283. base::RunLoop().RunUntilIdle();
  5284. }
  5285. // Now schedule the ERR_CONNECTION_RESET.
  5286. data1.Resume();
  5287. }
  5288. rv = callback.WaitForResult();
  5289. EXPECT_THAT(rv, IsOk());
  5290. const HttpResponseInfo* response = trans.GetResponseInfo();
  5291. ASSERT_TRUE(response);
  5292. EXPECT_TRUE(response->headers);
  5293. EXPECT_TRUE(response->was_fetched_via_spdy);
  5294. std::string response_data;
  5295. rv = ReadTransaction(&trans, &response_data);
  5296. EXPECT_THAT(rv, IsOk());
  5297. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  5298. EXPECT_EQ("hello!", response_data);
  5299. base::RunLoop().RunUntilIdle();
  5300. }
  5301. helper.VerifyDataConsumed();
  5302. base::RunLoop().RunUntilIdle();
  5303. }
  5304. }
  5305. // Tests that Basic authentication works over SPDY
  5306. TEST_F(SpdyNetworkTransactionTest, SpdyBasicAuth) {
  5307. // The first request will be a bare GET, the second request will be a
  5308. // GET with an Authorization header.
  5309. spdy::SpdySerializedFrame req_get(
  5310. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5311. // Will be refused for lack of auth.
  5312. spdy_util_.UpdateWithStreamDestruction(1);
  5313. const char* const kExtraAuthorizationHeaders[] = {
  5314. "authorization", "Basic Zm9vOmJhcg=="
  5315. };
  5316. spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
  5317. kExtraAuthorizationHeaders, std::size(kExtraAuthorizationHeaders) / 2, 3,
  5318. LOWEST));
  5319. MockWrite spdy_writes[] = {
  5320. CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
  5321. };
  5322. // The first response is a 401 authentication challenge, and the second
  5323. // response will be a 200 response since the second request includes a valid
  5324. // Authorization header.
  5325. const char* const kExtraAuthenticationHeaders[] = {
  5326. "www-authenticate",
  5327. "Basic realm=\"MyRealm\""
  5328. };
  5329. spdy::SpdySerializedFrame resp_authentication(
  5330. spdy_util_.ConstructSpdyReplyError(
  5331. "401", kExtraAuthenticationHeaders,
  5332. std::size(kExtraAuthenticationHeaders) / 2, 1));
  5333. spdy::SpdySerializedFrame body_authentication(
  5334. spdy_util_.ConstructSpdyDataFrame(1, true));
  5335. spdy::SpdySerializedFrame resp_data(
  5336. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  5337. spdy::SpdySerializedFrame body_data(
  5338. spdy_util_.ConstructSpdyDataFrame(3, true));
  5339. MockRead spdy_reads[] = {
  5340. CreateMockRead(resp_authentication, 1),
  5341. CreateMockRead(body_authentication, 2, SYNCHRONOUS),
  5342. CreateMockRead(resp_data, 4),
  5343. CreateMockRead(body_data, 5),
  5344. MockRead(ASYNC, 0, 6),
  5345. };
  5346. SequencedSocketData data(spdy_reads, spdy_writes);
  5347. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  5348. helper.RunPreTestSetup();
  5349. helper.AddData(&data);
  5350. helper.StartDefaultTest();
  5351. EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
  5352. helper.WaitForCallbackToComplete();
  5353. EXPECT_THAT(helper.output().rv, IsOk());
  5354. // Make sure the response has an auth challenge.
  5355. HttpNetworkTransaction* trans = helper.trans();
  5356. const HttpResponseInfo* const response_start = trans->GetResponseInfo();
  5357. ASSERT_TRUE(response_start);
  5358. ASSERT_TRUE(response_start->headers);
  5359. EXPECT_EQ(401, response_start->headers->response_code());
  5360. EXPECT_TRUE(response_start->was_fetched_via_spdy);
  5361. const absl::optional<AuthChallengeInfo>& auth_challenge =
  5362. response_start->auth_challenge;
  5363. ASSERT_TRUE(auth_challenge);
  5364. EXPECT_FALSE(auth_challenge->is_proxy);
  5365. EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
  5366. EXPECT_EQ("MyRealm", auth_challenge->realm);
  5367. // Restart with a username/password.
  5368. AuthCredentials credentials(u"foo", u"bar");
  5369. TestCompletionCallback callback_restart;
  5370. const int rv_restart = trans->RestartWithAuth(
  5371. credentials, callback_restart.callback());
  5372. EXPECT_THAT(rv_restart, IsError(ERR_IO_PENDING));
  5373. const int rv_restart_complete = callback_restart.WaitForResult();
  5374. EXPECT_THAT(rv_restart_complete, IsOk());
  5375. // TODO(cbentzel): This is actually the same response object as before, but
  5376. // data has changed.
  5377. const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
  5378. ASSERT_TRUE(response_restart);
  5379. ASSERT_TRUE(response_restart->headers);
  5380. EXPECT_EQ(200, response_restart->headers->response_code());
  5381. EXPECT_FALSE(response_restart->auth_challenge);
  5382. }
  5383. struct PushHeaderTestParams {
  5384. std::vector<std::pair<std::string, std::string>> extra_request_headers;
  5385. std::vector<std::pair<std::string, std::string>> extra_pushed_request_headers;
  5386. std::vector<std::pair<std::string, std::string>>
  5387. extra_pushed_response_headers;
  5388. std::string pushed_status_code;
  5389. bool push_accepted;
  5390. SpdyPushedStreamFate expected_fate;
  5391. } push_header_test_cases[] = {
  5392. // Base case: no extra headers.
  5393. {{}, {}, {}, "200", true, SpdyPushedStreamFate::kAcceptedNoVary},
  5394. // Cookie headers match.
  5395. {{{"cookie", "value=foo"}},
  5396. {{"cookie", "value=foo"}},
  5397. {{"vary", "Cookie"}},
  5398. "200",
  5399. true,
  5400. SpdyPushedStreamFate::kAcceptedMatchingVary},
  5401. // Cookie headers mismatch.
  5402. {{{"cookie", "value=foo"}},
  5403. {{"cookie", "value=bar"}},
  5404. {{"vary", "Cookie"}},
  5405. "200",
  5406. false,
  5407. SpdyPushedStreamFate::kVaryMismatch},
  5408. // Partial Content response, no Range headers.
  5409. {{}, {}, {}, "206", false, SpdyPushedStreamFate::kClientRequestNotRange},
  5410. // Partial Content response, no Range headers in pushed request.
  5411. {{{"range", "0-42"}},
  5412. {},
  5413. {},
  5414. "206",
  5415. false,
  5416. SpdyPushedStreamFate::kPushedRequestNotRange},
  5417. // Partial Content response, no Range headers in client request.
  5418. {{},
  5419. {{"range", "0-42"}},
  5420. {},
  5421. "206",
  5422. false,
  5423. SpdyPushedStreamFate::kClientRequestNotRange},
  5424. // Partial Content response, mismatching Range headers.
  5425. {{{"range", "0-42"}},
  5426. {{"range", "10-42"}},
  5427. {},
  5428. "206",
  5429. false,
  5430. SpdyPushedStreamFate::kRangeMismatch},
  5431. // Partial Content response, matching Range headers.
  5432. {{{"range", "0-42"}},
  5433. {{"range", "0-42"}},
  5434. {},
  5435. "206",
  5436. true,
  5437. SpdyPushedStreamFate::kAcceptedNoVary},
  5438. };
  5439. class SpdyNetworkTransactionPushHeaderTest
  5440. : public SpdyNetworkTransactionTest,
  5441. public ::testing::WithParamInterface<PushHeaderTestParams> {
  5442. protected:
  5443. void RunTest(bool pushed_response_headers_received_before_request) {
  5444. base::HistogramTester histogram_tester;
  5445. int seq = 0;
  5446. std::vector<MockWrite> writes;
  5447. std::vector<MockRead> reads;
  5448. spdy::SpdySerializedFrame req1(
  5449. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5450. writes.push_back(CreateMockWrite(req1, seq++));
  5451. spdy::Http2HeaderBlock pushed_request_headers;
  5452. pushed_request_headers[spdy::kHttp2MethodHeader] = "GET";
  5453. for (const auto& header : GetParam().extra_pushed_request_headers) {
  5454. pushed_request_headers.insert(header);
  5455. }
  5456. spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &pushed_request_headers);
  5457. spdy::SpdySerializedFrame pushed_request(
  5458. spdy_util_.ConstructSpdyPushPromise(1, 2,
  5459. std::move(pushed_request_headers)));
  5460. reads.push_back(CreateMockRead(pushed_request, seq++));
  5461. spdy::SpdySerializedFrame priority(
  5462. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  5463. writes.push_back(CreateMockWrite(priority, seq++));
  5464. reads.emplace_back(ASYNC, ERR_IO_PENDING, seq++);
  5465. spdy::Http2HeaderBlock pushed_response_headers;
  5466. pushed_response_headers[spdy::kHttp2StatusHeader] =
  5467. GetParam().pushed_status_code;
  5468. for (const auto& header : GetParam().extra_pushed_response_headers) {
  5469. pushed_response_headers.insert(header);
  5470. }
  5471. spdy::SpdySerializedFrame pushed_response(
  5472. spdy_util_.ConstructSpdyReply(2, std::move(pushed_response_headers)));
  5473. reads.push_back(CreateMockRead(pushed_response, seq++));
  5474. spdy::SpdySerializedFrame resp1(
  5475. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5476. reads.push_back(CreateMockRead(resp1, seq++));
  5477. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  5478. reads.push_back(CreateMockRead(body1, seq++));
  5479. spdy_util_.UpdateWithStreamDestruction(1);
  5480. spdy::SpdySerializedFrame pushed_body(
  5481. spdy_util_.ConstructSpdyDataFrame(2, "This is pushed.", true));
  5482. reads.push_back(CreateMockRead(pushed_body, seq++));
  5483. // If push is not accepted, a new request is sent on the wire.
  5484. spdy::SpdySerializedFrame rst;
  5485. spdy::SpdySerializedFrame req2;
  5486. spdy::SpdySerializedFrame resp2;
  5487. spdy::SpdySerializedFrame body2;
  5488. if (!GetParam().push_accepted) {
  5489. rst = spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL);
  5490. writes.push_back(CreateMockWrite(rst, seq++));
  5491. spdy::Http2HeaderBlock request_headers2(
  5492. spdy_util_.ConstructGetHeaderBlock(kPushedUrl));
  5493. for (const auto& header : GetParam().extra_request_headers) {
  5494. request_headers2.insert(header);
  5495. }
  5496. req2 = spdy_util_.ConstructSpdyHeaders(3, std::move(request_headers2),
  5497. LOWEST, true);
  5498. writes.push_back(CreateMockWrite(req2, seq++));
  5499. resp2 = spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3);
  5500. reads.push_back(CreateMockRead(resp2, seq++));
  5501. body2 = spdy_util_.ConstructSpdyDataFrame(3, "This is not pushed.", true);
  5502. reads.push_back(CreateMockRead(body2, seq++));
  5503. }
  5504. reads.emplace_back(ASYNC, ERR_IO_PENDING, seq++);
  5505. reads.emplace_back(ASYNC, 0, seq++);
  5506. SequencedSocketData data(reads, writes);
  5507. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  5508. nullptr);
  5509. helper.RunPreTestSetup();
  5510. helper.AddData(&data);
  5511. HttpNetworkTransaction* trans = helper.trans();
  5512. TestCompletionCallback callback1;
  5513. int rv = trans->Start(&request_, callback1.callback(), log_);
  5514. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5515. // Open connection.
  5516. base::RunLoop().RunUntilIdle();
  5517. if (pushed_response_headers_received_before_request) {
  5518. // Read pushed response headers.
  5519. data.Resume();
  5520. base::RunLoop().RunUntilIdle();
  5521. }
  5522. HttpRequestInfo request2 = CreateGetPushRequest();
  5523. for (const auto& header : GetParam().extra_request_headers) {
  5524. request2.extra_headers.SetHeader(header.first, header.second);
  5525. }
  5526. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  5527. TestCompletionCallback callback2;
  5528. rv = trans2.Start(&request2, callback2.callback(), log_);
  5529. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5530. base::RunLoop().RunUntilIdle();
  5531. if (!pushed_response_headers_received_before_request) {
  5532. // Read pushed response headers.
  5533. data.Resume();
  5534. base::RunLoop().RunUntilIdle();
  5535. }
  5536. rv = callback1.WaitForResult();
  5537. EXPECT_THAT(rv, IsOk());
  5538. const HttpResponseInfo* const response1 = trans->GetResponseInfo();
  5539. EXPECT_TRUE(response1->headers);
  5540. EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
  5541. std::string result1;
  5542. ReadResult(trans, &result1);
  5543. EXPECT_EQ(result1, "hello!");
  5544. rv = callback2.WaitForResult();
  5545. EXPECT_THAT(rv, IsOk());
  5546. std::string result2;
  5547. ReadResult(&trans2, &result2);
  5548. EXPECT_EQ(result2, GetParam().push_accepted ? "This is pushed."
  5549. : "This is not pushed.");
  5550. data.Resume();
  5551. base::RunLoop().RunUntilIdle();
  5552. helper.VerifyDataConsumed();
  5553. histogram_tester.ExpectBucketCount(
  5554. "Net.SpdyPushedStreamFate", static_cast<int>(GetParam().expected_fate),
  5555. 1);
  5556. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  5557. }
  5558. };
  5559. INSTANTIATE_TEST_SUITE_P(All,
  5560. SpdyNetworkTransactionPushHeaderTest,
  5561. ::testing::ValuesIn(push_header_test_cases));
  5562. TEST_P(SpdyNetworkTransactionPushHeaderTest,
  5563. PushedResponseHeadersReceivedBeforeRequest) {
  5564. RunTest(/* pushed_response_headers_received_before_request = */ true);
  5565. }
  5566. TEST_P(SpdyNetworkTransactionPushHeaderTest,
  5567. PushedResponseHeadersReceivedAfterRequest) {
  5568. RunTest(/* pushed_response_headers_received_before_request = */ false);
  5569. }
  5570. TEST_F(SpdyNetworkTransactionTest, ResponseHeadersTwice) {
  5571. spdy::SpdySerializedFrame req(
  5572. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5573. spdy::SpdySerializedFrame rst(
  5574. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  5575. MockWrite writes[] = {
  5576. CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
  5577. };
  5578. spdy::SpdySerializedFrame stream1_reply(
  5579. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5580. spdy::Http2HeaderBlock late_headers;
  5581. late_headers["hello"] = "bye";
  5582. spdy::SpdySerializedFrame stream1_headers(
  5583. spdy_util_.ConstructSpdyResponseHeaders(1, std::move(late_headers),
  5584. false));
  5585. spdy::SpdySerializedFrame stream1_body(
  5586. spdy_util_.ConstructSpdyDataFrame(1, true));
  5587. MockRead reads[] = {
  5588. CreateMockRead(stream1_reply, 1), CreateMockRead(stream1_headers, 2),
  5589. CreateMockRead(stream1_body, 3), MockRead(ASYNC, 0, 5) // EOF
  5590. };
  5591. SequencedSocketData data(reads, writes);
  5592. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  5593. helper.RunToCompletion(&data);
  5594. TransactionHelperResult out = helper.output();
  5595. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  5596. }
  5597. // Tests that receiving HEADERS, DATA, HEADERS, and DATA in that sequence will
  5598. // trigger a ERR_HTTP2_PROTOCOL_ERROR because trailing HEADERS must not be
  5599. // followed by any DATA frames.
  5600. TEST_F(SpdyNetworkTransactionTest, SyncReplyDataAfterTrailers) {
  5601. spdy::SpdySerializedFrame req(
  5602. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  5603. spdy::SpdySerializedFrame rst(
  5604. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  5605. MockWrite writes[] = {
  5606. CreateMockWrite(req, 0), CreateMockWrite(rst, 5),
  5607. };
  5608. spdy::SpdySerializedFrame stream1_reply(
  5609. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5610. spdy::SpdySerializedFrame stream1_body(
  5611. spdy_util_.ConstructSpdyDataFrame(1, false));
  5612. spdy::Http2HeaderBlock late_headers;
  5613. late_headers["hello"] = "bye";
  5614. spdy::SpdySerializedFrame stream1_headers(
  5615. spdy_util_.ConstructSpdyResponseHeaders(1, std::move(late_headers),
  5616. false));
  5617. spdy::SpdySerializedFrame stream1_body2(
  5618. spdy_util_.ConstructSpdyDataFrame(1, true));
  5619. MockRead reads[] = {
  5620. CreateMockRead(stream1_reply, 1), CreateMockRead(stream1_body, 2),
  5621. CreateMockRead(stream1_headers, 3), CreateMockRead(stream1_body2, 4),
  5622. MockRead(ASYNC, 0, 6) // EOF
  5623. };
  5624. SequencedSocketData data(reads, writes);
  5625. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  5626. helper.RunToCompletion(&data);
  5627. TransactionHelperResult out = helper.output();
  5628. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  5629. }
  5630. struct PushUrlTestParams {
  5631. const char* url_to_fetch;
  5632. const char* url_to_push;
  5633. bool client_cert_sent;
  5634. bool expect_ct_error;
  5635. SpdyPushedStreamFate expected_fate;
  5636. } push_url_test_cases[] = {
  5637. // http scheme cannot be pushed (except by trusted proxy).
  5638. {"https://www.example.org/foo.html", "http://www.example.org/foo.js",
  5639. false /* client_cert_sent */, false /* expect_ct_error */,
  5640. SpdyPushedStreamFate::kNonHttpsPushedScheme},
  5641. // ftp scheme cannot be pushed.
  5642. {"https://www.example.org/foo.html", "ftp://www.example.org/foo.js",
  5643. false /* client_cert_sent */, false /* expect_ct_error */,
  5644. SpdyPushedStreamFate::kInvalidUrl},
  5645. // Cross subdomain, certificate not valid.
  5646. {"https://www.example.org/foo.html", "https://blat.www.example.org/foo.js",
  5647. false /* client_cert_sent */, false /* expect_ct_error */,
  5648. SpdyPushedStreamFate::kCertificateMismatch},
  5649. // Cross domain, certificate not valid.
  5650. {"https://www.example.org/foo.html", "https://www.foo.com/foo.js",
  5651. false /* client_cert_sent */, false /* expect_ct_error */,
  5652. SpdyPushedStreamFate::kCertificateMismatch},
  5653. // Cross domain, certificate valid, but cross-origin push is rejected on a
  5654. // connection with client certificate.
  5655. {"https://www.example.org/foo.html", "https://mail.example.org/foo.js",
  5656. true /* client_cert_sent */, false /* expect_ct_error */,
  5657. SpdyPushedStreamFate::kCertificateMismatch},
  5658. // Cross domain, certificate valid, but cross-origin push is rejected on a
  5659. // connection with an Expect-CT error.
  5660. {"https://www.example.org/foo.html", "https://mail.example.org/foo.js",
  5661. false /* client_cert_sent */, true /* expect_ct_error */,
  5662. SpdyPushedStreamFate::kCertificateMismatch}};
  5663. class SpdyNetworkTransactionPushUrlTest
  5664. : public SpdyNetworkTransactionTest,
  5665. public ::testing::WithParamInterface<PushUrlTestParams> {
  5666. public:
  5667. SpdyNetworkTransactionPushUrlTest() {
  5668. // Set features needed for the |expect_ct_error| case, where it's important
  5669. // to check that NetworkIsolationKeys are respected.
  5670. feature_list_.InitWithFeatures(
  5671. /* enabled_features */
  5672. {TransportSecurityState::kDynamicExpectCTFeature,
  5673. features::kPartitionExpectCTStateByNetworkIsolationKey,
  5674. features::kPartitionConnectionsByNetworkIsolationKey,
  5675. features::kPartitionSSLSessionsByNetworkIsolationKey},
  5676. /* disabled_features */
  5677. {});
  5678. }
  5679. protected:
  5680. // In this test we want to verify that we can't accidentally push content
  5681. // which can't be pushed by this content server.
  5682. // This test assumes that:
  5683. // - if we're requesting http://www.foo.com/barbaz
  5684. // - the browser has made a connection to "www.foo.com".
  5685. void RunTest() {
  5686. base::HistogramTester histogram_tester;
  5687. SpdyTestUtil spdy_test_util;
  5688. spdy::SpdySerializedFrame stream1_syn(
  5689. spdy_test_util.ConstructSpdyGet(GetParam().url_to_fetch, 1, LOWEST));
  5690. spdy::SpdySerializedFrame stream1_body(
  5691. spdy_test_util.ConstructSpdyDataFrame(1, true));
  5692. spdy::SpdySerializedFrame push_rst(spdy_test_util.ConstructSpdyRstStream(
  5693. 2, spdy::ERROR_CODE_REFUSED_STREAM));
  5694. MockWrite writes[] = {
  5695. CreateMockWrite(stream1_syn, 0), CreateMockWrite(push_rst, 3),
  5696. };
  5697. spdy::SpdySerializedFrame stream1_reply(
  5698. spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1));
  5699. spdy::SpdySerializedFrame stream2_syn(spdy_test_util.ConstructSpdyPush(
  5700. nullptr, 0, 2, 1, GetParam().url_to_push));
  5701. const char kPushedData[] = "pushed";
  5702. spdy::SpdySerializedFrame stream2_body(
  5703. spdy_test_util.ConstructSpdyDataFrame(2, kPushedData, true));
  5704. spdy::SpdySerializedFrame rst(
  5705. spdy_test_util.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL));
  5706. MockRead reads[] = {
  5707. CreateMockRead(stream1_reply, 1),
  5708. CreateMockRead(stream2_syn, 2),
  5709. CreateMockRead(stream1_body, 4),
  5710. CreateMockRead(stream2_body, 5),
  5711. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a pause
  5712. };
  5713. HttpResponseInfo response;
  5714. SequencedSocketData data(reads, writes);
  5715. request_.url = GURL(GetParam().url_to_fetch);
  5716. // Set a NetworkIsolationKey for the |expect_ct_error| case, to make sure
  5717. // NetworkIsolationKeys are respected.
  5718. request_.network_isolation_key = NetworkIsolationKey::CreateTransient();
  5719. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  5720. ssl_provider->ssl_info.client_cert_sent = GetParam().client_cert_sent;
  5721. ssl_provider->ssl_info.cert =
  5722. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  5723. auto session_deps = std::make_unique<SpdySessionDependencies>();
  5724. if (GetParam().expect_ct_error) {
  5725. ssl_provider->ssl_info.ct_policy_compliance =
  5726. ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
  5727. ssl_provider->ssl_info.is_issued_by_known_root = true;
  5728. session_deps->transport_security_state->AddExpectCT(
  5729. "mail.example.org", base::Time::Now() + base::Days(1) /* expiry */,
  5730. true, GURL(), request_.network_isolation_key);
  5731. }
  5732. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  5733. std::move(session_deps));
  5734. helper.RunPreTestSetup();
  5735. if (GetParam().expect_ct_error) {
  5736. ssl_provider->ssl_info.ct_policy_compliance =
  5737. ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
  5738. ssl_provider->ssl_info.is_issued_by_known_root = true;
  5739. }
  5740. helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
  5741. HttpNetworkTransaction* trans = helper.trans();
  5742. // Start the transaction with basic parameters.
  5743. TestCompletionCallback callback;
  5744. int rv = trans->Start(&request_, callback.callback(), log_);
  5745. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5746. rv = callback.WaitForResult();
  5747. // Finish async network reads/writes.
  5748. base::RunLoop().RunUntilIdle();
  5749. // Read the response body.
  5750. std::string result;
  5751. ReadResult(trans, &result);
  5752. // Verify that we consumed all test data.
  5753. EXPECT_TRUE(data.AllReadDataConsumed());
  5754. EXPECT_TRUE(data.AllWriteDataConsumed());
  5755. // Verify the response headers.
  5756. // Copy the response info, because trans goes away.
  5757. response = *trans->GetResponseInfo();
  5758. VerifyStreamsClosed(helper);
  5759. // Verify the response headers.
  5760. EXPECT_TRUE(response.headers);
  5761. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  5762. histogram_tester.ExpectBucketCount(
  5763. "Net.SpdyPushedStreamFate", static_cast<int>(GetParam().expected_fate),
  5764. 1);
  5765. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  5766. }
  5767. base::test::ScopedFeatureList feature_list_;
  5768. };
  5769. INSTANTIATE_TEST_SUITE_P(All,
  5770. SpdyNetworkTransactionPushUrlTest,
  5771. ::testing::ValuesIn(push_url_test_cases));
  5772. TEST_P(SpdyNetworkTransactionPushUrlTest, PushUrlTest) {
  5773. RunTest();
  5774. }
  5775. // Verify that push works cross origin as long as the certificate is valid for
  5776. // the pushed authority.
  5777. TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) {
  5778. // "spdy_pooling.pem" is valid for both www.example.org and mail.example.org.
  5779. const char* url_to_fetch = "https://www.example.org";
  5780. const char* url_to_push = "https://mail.example.org";
  5781. spdy::SpdySerializedFrame headers(
  5782. spdy_util_.ConstructSpdyGet(url_to_fetch, 1, LOWEST));
  5783. spdy::SpdySerializedFrame push_priority(
  5784. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  5785. MockWrite writes[] = {
  5786. CreateMockWrite(headers, 0), CreateMockWrite(push_priority, 3),
  5787. };
  5788. spdy::SpdySerializedFrame reply(
  5789. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5790. spdy::SpdySerializedFrame push(
  5791. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
  5792. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  5793. const char kPushedData[] = "pushed";
  5794. spdy::SpdySerializedFrame pushed_body(
  5795. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  5796. MockRead reads[] = {
  5797. CreateMockRead(reply, 1),
  5798. CreateMockRead(push, 2, SYNCHRONOUS),
  5799. CreateMockRead(body, 4),
  5800. CreateMockRead(pushed_body, 5, SYNCHRONOUS),
  5801. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
  5802. };
  5803. SequencedSocketData data(reads, writes);
  5804. request_.url = GURL(url_to_fetch);
  5805. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  5806. helper.RunPreTestSetup();
  5807. helper.AddData(&data);
  5808. HttpNetworkTransaction* trans0 = helper.trans();
  5809. TestCompletionCallback callback0;
  5810. int rv = trans0->Start(&request_, callback0.callback(), log_);
  5811. rv = callback0.GetResult(rv);
  5812. EXPECT_THAT(rv, IsOk());
  5813. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  5814. SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
  5815. PRIVACY_MODE_DISABLED,
  5816. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  5817. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  5818. base::WeakPtr<SpdySession> spdy_session =
  5819. spdy_session_pool->FindAvailableSession(
  5820. key, /* enable_ip_based_pooling = */ true,
  5821. /* is_websocket = */ false, log_);
  5822. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
  5823. EXPECT_TRUE(
  5824. has_unclaimed_pushed_stream_for_url(spdy_session, GURL(url_to_push)));
  5825. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  5826. HttpRequestInfo push_request;
  5827. push_request.method = "GET";
  5828. push_request.url = GURL(url_to_push);
  5829. push_request.traffic_annotation =
  5830. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  5831. TestCompletionCallback callback1;
  5832. rv = trans1.Start(&push_request, callback1.callback(), log_);
  5833. rv = callback1.GetResult(rv);
  5834. EXPECT_THAT(rv, IsOk());
  5835. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
  5836. HttpResponseInfo response = *trans0->GetResponseInfo();
  5837. EXPECT_TRUE(response.headers);
  5838. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  5839. std::string result0;
  5840. ReadResult(trans0, &result0);
  5841. EXPECT_EQ("hello!", result0);
  5842. HttpResponseInfo push_response = *trans1.GetResponseInfo();
  5843. EXPECT_TRUE(push_response.headers);
  5844. EXPECT_EQ("HTTP/1.1 200", push_response.headers->GetStatusLine());
  5845. std::string result1;
  5846. ReadResult(&trans1, &result1);
  5847. EXPECT_EQ(kPushedData, result1);
  5848. base::RunLoop().RunUntilIdle();
  5849. helper.VerifyDataConsumed();
  5850. VerifyStreamsClosed(helper);
  5851. }
  5852. // Verify that push does not work cross origin when NetworkIsolationKeys don't
  5853. // match.
  5854. TEST_F(SpdyNetworkTransactionTest,
  5855. ServerPushCrossOriginNetworkIsolationKeyMistmatch) {
  5856. base::test::ScopedFeatureList feature_list;
  5857. feature_list.InitWithFeatures(
  5858. // enabled_features
  5859. {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
  5860. // Need to partition connections by NetworkIsolationKey for
  5861. // SpdySessionKeys to include NetworkIsolationKeys.
  5862. features::kPartitionConnectionsByNetworkIsolationKey},
  5863. // disabled_features
  5864. {});
  5865. // "spdy_pooling.pem" is valid for both www.example.org and mail.example.org.
  5866. const char* url_to_fetch = "https://www.example.org";
  5867. const char* url_to_push = "https://mail.example.org";
  5868. spdy::SpdySerializedFrame headers(
  5869. spdy_util_.ConstructSpdyGet(url_to_fetch, 1, LOWEST));
  5870. spdy::SpdySerializedFrame push_priority(
  5871. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  5872. MockWrite writes[] = {
  5873. CreateMockWrite(headers, 0),
  5874. CreateMockWrite(push_priority, 3),
  5875. };
  5876. spdy::SpdySerializedFrame reply(
  5877. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5878. spdy::SpdySerializedFrame push(
  5879. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
  5880. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  5881. const char kPushedData[] = "pushed";
  5882. spdy::SpdySerializedFrame pushed_body(
  5883. spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true));
  5884. MockRead reads[] = {
  5885. CreateMockRead(reply, 1),
  5886. CreateMockRead(push, 2, SYNCHRONOUS),
  5887. CreateMockRead(body, 4),
  5888. CreateMockRead(pushed_body, 5, SYNCHRONOUS),
  5889. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
  5890. };
  5891. SequencedSocketData data(reads, writes);
  5892. request_.url = GURL(url_to_fetch);
  5893. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  5894. helper.RunPreTestSetup();
  5895. helper.AddData(&data);
  5896. SequencedSocketData data2(net::MockConnect(ASYNC, net::ERR_FAILED),
  5897. base::span<MockRead>(), base::span<MockWrite>());
  5898. helper.AddData(&data2);
  5899. HttpNetworkTransaction* trans0 = helper.trans();
  5900. TestCompletionCallback callback0;
  5901. int rv = trans0->Start(&request_, callback0.callback(), log_);
  5902. rv = callback0.GetResult(rv);
  5903. EXPECT_THAT(rv, IsOk());
  5904. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  5905. SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
  5906. PRIVACY_MODE_DISABLED,
  5907. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  5908. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  5909. base::WeakPtr<SpdySession> spdy_session =
  5910. spdy_session_pool->FindAvailableSession(
  5911. key, /* enable_ip_based_pooling = */ true,
  5912. /* is_websocket = */ false, log_);
  5913. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
  5914. EXPECT_TRUE(
  5915. has_unclaimed_pushed_stream_for_url(spdy_session, GURL(url_to_push)));
  5916. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  5917. HttpRequestInfo push_request;
  5918. // Use a different NetworkIsolationKey than |spdy_session| (which uses an
  5919. // empty one).
  5920. push_request.network_isolation_key = NetworkIsolationKey::CreateTransient();
  5921. push_request.method = "GET";
  5922. push_request.url = GURL(url_to_push);
  5923. push_request.traffic_annotation =
  5924. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  5925. TestCompletionCallback callback1;
  5926. rv = trans1.Start(&push_request, callback1.callback(), log_);
  5927. // This transaction should try and use a new socket, which fails.
  5928. EXPECT_THAT(callback1.GetResult(rv), IsError(net::ERR_FAILED));
  5929. // The pushed stream should still be pending.
  5930. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
  5931. // Try again, this time with an empty NetworkIsolationKey, matching the
  5932. // SpdySession's. This request should successfully get the pushed stream.
  5933. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  5934. push_request.network_isolation_key = NetworkIsolationKey();
  5935. TestCompletionCallback callback2;
  5936. rv = trans1.Start(&push_request, callback2.callback(), log_);
  5937. EXPECT_THAT(callback2.GetResult(rv), IsOk());
  5938. HttpResponseInfo response = *trans0->GetResponseInfo();
  5939. EXPECT_TRUE(response.headers);
  5940. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  5941. std::string result0;
  5942. ReadResult(trans0, &result0);
  5943. EXPECT_EQ("hello!", result0);
  5944. HttpResponseInfo push_response = *trans1.GetResponseInfo();
  5945. EXPECT_TRUE(push_response.headers);
  5946. EXPECT_EQ("HTTP/1.1 200", push_response.headers->GetStatusLine());
  5947. std::string result1;
  5948. ReadResult(&trans1, &result1);
  5949. EXPECT_EQ(kPushedData, result1);
  5950. base::RunLoop().RunUntilIdle();
  5951. helper.VerifyDataConsumed();
  5952. VerifyStreamsClosed(helper);
  5953. }
  5954. // Regression test for https://crbug.com/832859: Server push is accepted on a
  5955. // connection with client certificate, as long as SpdySessionKey matches.
  5956. TEST_F(SpdyNetworkTransactionTest, ServerPushWithClientCert) {
  5957. spdy::SpdySerializedFrame req(
  5958. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
  5959. spdy::SpdySerializedFrame priority(
  5960. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  5961. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3)};
  5962. spdy::SpdySerializedFrame resp(
  5963. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  5964. spdy::SpdySerializedFrame push(
  5965. spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  5966. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  5967. spdy::SpdySerializedFrame body2(
  5968. spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
  5969. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(push, 2),
  5970. CreateMockRead(body1, 4), CreateMockRead(body2, 5),
  5971. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
  5972. SequencedSocketData data(reads, writes);
  5973. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  5974. ssl_provider->ssl_info.client_cert_sent = true;
  5975. ssl_provider->ssl_info.cert =
  5976. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  5977. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  5978. helper.RunPreTestSetup();
  5979. helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
  5980. EXPECT_TRUE(helper.StartDefaultTest());
  5981. helper.FinishDefaultTest();
  5982. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  5983. HttpRequestInfo request = CreateGetPushRequest();
  5984. TestCompletionCallback callback;
  5985. int rv = trans2.Start(&request, callback.callback(), log_);
  5986. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  5987. rv = callback.WaitForResult();
  5988. EXPECT_THAT(rv, IsOk());
  5989. const HttpResponseInfo* const response = trans2.GetResponseInfo();
  5990. EXPECT_TRUE(response->headers);
  5991. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  5992. std::string result;
  5993. ReadResult(&trans2, &result);
  5994. EXPECT_EQ("pushed", result);
  5995. EXPECT_TRUE(data.AllReadDataConsumed());
  5996. EXPECT_TRUE(data.AllWriteDataConsumed());
  5997. VerifyStreamsClosed(helper);
  5998. }
  5999. // Verify that push works cross origin, even if there is already a connection
  6000. // open to origin of pushed resource.
  6001. TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) {
  6002. const char* url_to_fetch0 = "https://mail.example.org/foo";
  6003. const char* url_to_fetch1 = "https://docs.example.org";
  6004. const char* url_to_push = "https://mail.example.org/bar";
  6005. SpdyTestUtil spdy_util_0;
  6006. spdy::SpdySerializedFrame headers0(
  6007. spdy_util_0.ConstructSpdyGet(url_to_fetch0, 1, LOWEST));
  6008. MockWrite writes0[] = {
  6009. CreateMockWrite(headers0, 0),
  6010. };
  6011. spdy::SpdySerializedFrame reply0(
  6012. spdy_util_0.ConstructSpdyGetReply(nullptr, 0, 1));
  6013. const char kData0[] = "first";
  6014. spdy::SpdySerializedFrame body0(
  6015. spdy_util_0.ConstructSpdyDataFrame(1, kData0, true));
  6016. MockRead reads0[] = {CreateMockRead(reply0, 1), CreateMockRead(body0, 2),
  6017. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
  6018. SequencedSocketData data0(reads0, writes0);
  6019. SpdyTestUtil spdy_util_1;
  6020. spdy::SpdySerializedFrame headers1(
  6021. spdy_util_1.ConstructSpdyGet(url_to_fetch1, 1, LOWEST));
  6022. spdy::SpdySerializedFrame push_priority(
  6023. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  6024. MockWrite writes1[] = {
  6025. CreateMockWrite(headers1, 0),
  6026. CreateMockWrite(push_priority, 3, SYNCHRONOUS),
  6027. };
  6028. spdy::SpdySerializedFrame reply1(
  6029. spdy_util_1.ConstructSpdyGetReply(nullptr, 0, 1));
  6030. spdy::SpdySerializedFrame push(
  6031. spdy_util_1.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
  6032. const char kData1[] = "second";
  6033. spdy::SpdySerializedFrame body1(
  6034. spdy_util_1.ConstructSpdyDataFrame(1, kData1, true));
  6035. const char kPushedData[] = "pushed";
  6036. spdy::SpdySerializedFrame pushed_body(
  6037. spdy_util_1.ConstructSpdyDataFrame(2, kPushedData, true));
  6038. MockRead reads1[] = {
  6039. CreateMockRead(reply1, 1),
  6040. CreateMockRead(push, 2, SYNCHRONOUS),
  6041. CreateMockRead(body1, 4),
  6042. CreateMockRead(pushed_body, 5, SYNCHRONOUS),
  6043. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
  6044. };
  6045. SequencedSocketData data1(reads1, writes1);
  6046. // Request |url_to_fetch0| to open connection to mail.example.org.
  6047. request_.url = GURL(url_to_fetch0);
  6048. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6049. helper.RunPreTestSetup();
  6050. // "spdy_pooling.pem" is valid for www.example.org, but not for
  6051. // docs.example.org.
  6052. auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  6053. ssl_provider0->ssl_info.cert =
  6054. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  6055. ASSERT_TRUE(ssl_provider0->ssl_info.cert);
  6056. helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
  6057. // "wildcard.pem" is valid for both www.example.org and docs.example.org.
  6058. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  6059. ssl_provider1->ssl_info.cert =
  6060. ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
  6061. ASSERT_TRUE(ssl_provider1->ssl_info.cert);
  6062. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  6063. HttpNetworkTransaction* trans0 = helper.trans();
  6064. TestCompletionCallback callback0;
  6065. int rv = trans0->Start(&request_, callback0.callback(), log_);
  6066. rv = callback0.GetResult(rv);
  6067. EXPECT_THAT(rv, IsOk());
  6068. // Request |url_to_fetch1|, during which docs.example.org pushes
  6069. // |url_to_push|, which happens to be for www.example.org, to which there is
  6070. // already an open connection.
  6071. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  6072. HttpRequestInfo request1;
  6073. request1.method = "GET";
  6074. request1.url = GURL(url_to_fetch1);
  6075. request1.traffic_annotation =
  6076. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  6077. TestCompletionCallback callback1;
  6078. rv = trans1.Start(&request1, callback1.callback(), log_);
  6079. rv = callback1.GetResult(rv);
  6080. EXPECT_THAT(rv, IsOk());
  6081. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  6082. HostPortPair host_port_pair0("mail.example.org", 443);
  6083. SpdySessionKey key0(host_port_pair0, ProxyServer::Direct(),
  6084. PRIVACY_MODE_DISABLED,
  6085. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  6086. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  6087. base::WeakPtr<SpdySession> spdy_session0 =
  6088. spdy_session_pool->FindAvailableSession(
  6089. key0, /* enable_ip_based_pooling = */ true,
  6090. /* is_websocket = */ false, log_);
  6091. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session0));
  6092. HostPortPair host_port_pair1("docs.example.org", 443);
  6093. SpdySessionKey key1(host_port_pair1, ProxyServer::Direct(),
  6094. PRIVACY_MODE_DISABLED,
  6095. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  6096. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  6097. base::WeakPtr<SpdySession> spdy_session1 =
  6098. spdy_session_pool->FindAvailableSession(
  6099. key1, /* enable_ip_based_pooling = */ true,
  6100. /* is_websocket = */ false, log_);
  6101. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session1));
  6102. EXPECT_TRUE(
  6103. has_unclaimed_pushed_stream_for_url(spdy_session1, GURL(url_to_push)));
  6104. // Request |url_to_push|, which should be served from the pushed resource.
  6105. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  6106. HttpRequestInfo push_request;
  6107. push_request.method = "GET";
  6108. push_request.url = GURL(url_to_push);
  6109. push_request.traffic_annotation =
  6110. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  6111. TestCompletionCallback callback2;
  6112. rv = trans2.Start(&push_request, callback2.callback(), log_);
  6113. rv = callback2.GetResult(rv);
  6114. EXPECT_THAT(rv, IsOk());
  6115. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session0));
  6116. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session1));
  6117. HttpResponseInfo response0 = *trans0->GetResponseInfo();
  6118. EXPECT_TRUE(response0.headers);
  6119. EXPECT_EQ("HTTP/1.1 200", response0.headers->GetStatusLine());
  6120. std::string result0;
  6121. ReadResult(trans0, &result0);
  6122. EXPECT_EQ(kData0, result0);
  6123. HttpResponseInfo response1 = *trans1.GetResponseInfo();
  6124. EXPECT_TRUE(response1.headers);
  6125. EXPECT_EQ("HTTP/1.1 200", response1.headers->GetStatusLine());
  6126. std::string result1;
  6127. ReadResult(&trans1, &result1);
  6128. EXPECT_EQ(kData1, result1);
  6129. HttpResponseInfo push_response = *trans2.GetResponseInfo();
  6130. EXPECT_TRUE(push_response.headers);
  6131. EXPECT_EQ("HTTP/1.1 200", push_response.headers->GetStatusLine());
  6132. std::string result2;
  6133. ReadResult(&trans2, &result2);
  6134. EXPECT_EQ(kPushedData, result2);
  6135. base::RunLoop().RunUntilIdle();
  6136. helper.VerifyDataConsumed();
  6137. VerifyStreamsClosed(helper);
  6138. }
  6139. TEST_F(SpdyNetworkTransactionTest, RetryAfterRefused) {
  6140. // Construct the request.
  6141. spdy::SpdySerializedFrame req(
  6142. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  6143. // Will be destroyed by the RST before stream 3 starts.
  6144. spdy_util_.UpdateWithStreamDestruction(1);
  6145. spdy::SpdySerializedFrame req2(
  6146. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  6147. MockWrite writes[] = {
  6148. CreateMockWrite(req, 0), CreateMockWrite(req2, 2),
  6149. };
  6150. spdy::SpdySerializedFrame refused(
  6151. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
  6152. spdy::SpdySerializedFrame resp(
  6153. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  6154. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(3, true));
  6155. MockRead reads[] = {
  6156. CreateMockRead(refused, 1), CreateMockRead(resp, 3),
  6157. CreateMockRead(body, 4), MockRead(ASYNC, 0, 5) // EOF
  6158. };
  6159. SequencedSocketData data(reads, writes);
  6160. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6161. helper.RunPreTestSetup();
  6162. helper.AddData(&data);
  6163. HttpNetworkTransaction* trans = helper.trans();
  6164. // Start the transaction with basic parameters.
  6165. TestCompletionCallback callback;
  6166. int rv = trans->Start(&request_, callback.callback(), log_);
  6167. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6168. rv = callback.WaitForResult();
  6169. EXPECT_THAT(rv, IsOk());
  6170. // Finish async network reads.
  6171. base::RunLoop().RunUntilIdle();
  6172. // Verify that we consumed all test data.
  6173. EXPECT_TRUE(data.AllReadDataConsumed());
  6174. EXPECT_TRUE(data.AllWriteDataConsumed());
  6175. // Verify the response headers.
  6176. HttpResponseInfo response = *trans->GetResponseInfo();
  6177. EXPECT_TRUE(response.headers);
  6178. EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
  6179. }
  6180. TEST_F(SpdyNetworkTransactionTest, OutOfOrderHeaders) {
  6181. // This first request will start to establish the SpdySession.
  6182. // Then we will start the second (MEDIUM priority) and then third
  6183. // (HIGHEST priority) request in such a way that the third will actually
  6184. // start before the second, causing the second to be numbered differently
  6185. // than the order they were created.
  6186. //
  6187. // Note that the requests and responses created below are expectations
  6188. // of what the above will produce on the wire, and hence are in the
  6189. // initial->HIGHEST->LOWEST priority.
  6190. //
  6191. // Frames are created by SpdySession just before the write associated
  6192. // with the frame is attempted, so stream dependencies will be based
  6193. // on the streams alive at the point of the request write attempt. Thus
  6194. // req1 is alive when req2 is attempted (during but not after the
  6195. // |data.RunFor(2);| statement below) but not when req3 is attempted.
  6196. // The call to spdy_util_.UpdateWithStreamDestruction() reflects this.
  6197. spdy::SpdySerializedFrame req1(
  6198. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  6199. spdy::SpdySerializedFrame req2(
  6200. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, HIGHEST));
  6201. spdy_util_.UpdateWithStreamDestruction(1);
  6202. spdy::SpdySerializedFrame req3(
  6203. spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM));
  6204. MockWrite writes[] = {
  6205. MockWrite(ASYNC, ERR_IO_PENDING, 0), CreateMockWrite(req1, 1),
  6206. CreateMockWrite(req2, 5), CreateMockWrite(req3, 6),
  6207. };
  6208. spdy::SpdySerializedFrame resp1(
  6209. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  6210. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  6211. spdy::SpdySerializedFrame resp2(
  6212. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  6213. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  6214. spdy::SpdySerializedFrame resp3(
  6215. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  6216. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, true));
  6217. MockRead reads[] = {
  6218. CreateMockRead(resp1, 2), MockRead(ASYNC, ERR_IO_PENDING, 3),
  6219. CreateMockRead(body1, 4), CreateMockRead(resp2, 7),
  6220. CreateMockRead(body2, 8), CreateMockRead(resp3, 9),
  6221. CreateMockRead(body3, 10), MockRead(ASYNC, 0, 11) // EOF
  6222. };
  6223. SequencedSocketData data(reads, writes);
  6224. NormalSpdyTransactionHelper helper(request_, LOWEST, log_, nullptr);
  6225. helper.RunPreTestSetup();
  6226. helper.AddData(&data);
  6227. // Start the first transaction to set up the SpdySession
  6228. HttpNetworkTransaction* trans = helper.trans();
  6229. TestCompletionCallback callback;
  6230. int rv = trans->Start(&request_, callback.callback(), log_);
  6231. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6232. // Run the message loop, but do not allow the write to complete.
  6233. // This leaves the SpdySession with a write pending, which prevents
  6234. // SpdySession from attempting subsequent writes until this write completes.
  6235. base::RunLoop().RunUntilIdle();
  6236. // Now, start both new transactions
  6237. TestCompletionCallback callback2;
  6238. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  6239. rv = trans2.Start(&request_, callback2.callback(), log_);
  6240. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6241. base::RunLoop().RunUntilIdle();
  6242. TestCompletionCallback callback3;
  6243. HttpNetworkTransaction trans3(HIGHEST, helper.session());
  6244. rv = trans3.Start(&request_, callback3.callback(), log_);
  6245. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6246. base::RunLoop().RunUntilIdle();
  6247. // We now have two HEADERS frames queued up which will be
  6248. // dequeued only once the first write completes, which we
  6249. // now allow to happen.
  6250. ASSERT_TRUE(data.IsPaused());
  6251. data.Resume();
  6252. EXPECT_THAT(callback.WaitForResult(), IsOk());
  6253. // And now we can allow everything else to run to completion.
  6254. data.Resume();
  6255. base::RunLoop().RunUntilIdle();
  6256. EXPECT_THAT(callback2.WaitForResult(), IsOk());
  6257. EXPECT_THAT(callback3.WaitForResult(), IsOk());
  6258. helper.VerifyDataConsumed();
  6259. // At this point the test is completed and we need to safely destroy
  6260. // all allocated structures. Helper stores a transaction that has a
  6261. // reference to a stack allocated request, which has a short lifetime,
  6262. // and is accessed during the transaction destruction. We need to delete
  6263. // the transaction while the request is still a valid object.
  6264. helper.ResetTrans();
  6265. }
  6266. // Test that sent data frames and received WINDOW_UPDATE frames change
  6267. // the send_window_size_ correctly.
  6268. // WINDOW_UPDATE is different than most other frames in that it can arrive
  6269. // while the client is still sending the request body. In order to enforce
  6270. // this scenario, we feed a couple of dummy frames and give a delay of 0 to
  6271. // socket data provider, so that initial read that is done as soon as the
  6272. // stream is created, succeeds and schedules another read. This way reads
  6273. // and writes are interleaved; after doing a full frame write, SpdyStream
  6274. // will break out of DoLoop and will read and process a WINDOW_UPDATE.
  6275. // Once our WINDOW_UPDATE is read, we cannot send HEADERS right away
  6276. // since request has not been completely written, therefore we feed
  6277. // enough number of WINDOW_UPDATEs to finish the first read and cause a
  6278. // write, leading to a complete write of request body; after that we send
  6279. // a reply with a body, to cause a graceful shutdown.
  6280. // TODO(agayev): develop a socket data provider where both, reads and
  6281. // writes are ordered so that writing tests like these are easy and rewrite
  6282. // all these tests using it. Right now we are working around the
  6283. // limitations as described above and it's not deterministic, tests may
  6284. // fail under specific circumstances.
  6285. TEST_F(SpdyNetworkTransactionTest, WindowUpdateReceived) {
  6286. static int kFrameCount = 2;
  6287. std::string content(kMaxSpdyFrameChunkSize, 'a');
  6288. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  6289. kDefaultUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, nullptr,
  6290. 0));
  6291. spdy::SpdySerializedFrame body(
  6292. spdy_util_.ConstructSpdyDataFrame(1, content, false));
  6293. spdy::SpdySerializedFrame body_end(
  6294. spdy_util_.ConstructSpdyDataFrame(1, content, true));
  6295. MockWrite writes[] = {
  6296. CreateMockWrite(req, 0), CreateMockWrite(body, 1),
  6297. CreateMockWrite(body_end, 2),
  6298. };
  6299. static const int32_t kDeltaWindowSize = 0xff;
  6300. static const int kDeltaCount = 4;
  6301. spdy::SpdySerializedFrame window_update(
  6302. spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
  6303. spdy::SpdySerializedFrame window_update_dummy(
  6304. spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
  6305. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  6306. MockRead reads[] = {
  6307. CreateMockRead(window_update_dummy, 3),
  6308. CreateMockRead(window_update_dummy, 4),
  6309. CreateMockRead(window_update_dummy, 5),
  6310. CreateMockRead(window_update, 6), // Four updates, therefore window
  6311. CreateMockRead(window_update, 7), // size should increase by
  6312. CreateMockRead(window_update, 8), // kDeltaWindowSize * 4
  6313. CreateMockRead(window_update, 9),
  6314. CreateMockRead(resp, 10),
  6315. MockRead(ASYNC, ERR_IO_PENDING, 11),
  6316. CreateMockRead(body_end, 12),
  6317. MockRead(ASYNC, 0, 13) // EOF
  6318. };
  6319. SequencedSocketData data(reads, writes);
  6320. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  6321. for (int i = 0; i < kFrameCount; ++i) {
  6322. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  6323. content.data(), content.size()));
  6324. }
  6325. ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
  6326. // Setup the request.
  6327. request_.method = "POST";
  6328. request_.upload_data_stream = &upload_data_stream;
  6329. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6330. helper.AddData(&data);
  6331. helper.RunPreTestSetup();
  6332. HttpNetworkTransaction* trans = helper.trans();
  6333. TestCompletionCallback callback;
  6334. int rv = trans->Start(&request_, callback.callback(), log_);
  6335. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6336. data.RunUntilPaused();
  6337. base::RunLoop().RunUntilIdle();
  6338. SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
  6339. ASSERT_TRUE(stream);
  6340. ASSERT_TRUE(stream->stream());
  6341. EXPECT_EQ(static_cast<int>(kDefaultInitialWindowSize) +
  6342. kDeltaWindowSize * kDeltaCount -
  6343. kMaxSpdyFrameChunkSize * kFrameCount,
  6344. stream->stream()->send_window_size());
  6345. data.Resume();
  6346. base::RunLoop().RunUntilIdle();
  6347. rv = callback.WaitForResult();
  6348. EXPECT_THAT(rv, IsOk());
  6349. helper.VerifyDataConsumed();
  6350. }
  6351. // Test that received data frames and sent WINDOW_UPDATE frames change
  6352. // the recv_window_size_ correctly.
  6353. TEST_F(SpdyNetworkTransactionTest, WindowUpdateSent) {
  6354. // Session level maximum window size that is more than twice the default
  6355. // initial window size so that an initial window update is sent.
  6356. const int32_t session_max_recv_window_size = 5 * 64 * 1024;
  6357. ASSERT_LT(2 * kDefaultInitialWindowSize, session_max_recv_window_size);
  6358. // Stream level maximum window size that is less than the session level
  6359. // maximum window size so that we test for confusion between the two.
  6360. const int32_t stream_max_recv_window_size = 4 * 64 * 1024;
  6361. ASSERT_GT(session_max_recv_window_size, stream_max_recv_window_size);
  6362. // Size of body to be sent. Has to be less than or equal to both window sizes
  6363. // so that we do not run out of receiving window. Also has to be greater than
  6364. // half of them so that it triggers both a session level and a stream level
  6365. // window update frame.
  6366. const int32_t kTargetSize = 3 * 64 * 1024;
  6367. ASSERT_GE(session_max_recv_window_size, kTargetSize);
  6368. ASSERT_GE(stream_max_recv_window_size, kTargetSize);
  6369. ASSERT_LT(session_max_recv_window_size / 2, kTargetSize);
  6370. ASSERT_LT(stream_max_recv_window_size / 2, kTargetSize);
  6371. // Size of each DATA frame.
  6372. const int32_t kChunkSize = 4096;
  6373. // Size of window updates.
  6374. ASSERT_EQ(0, session_max_recv_window_size / 2 % kChunkSize);
  6375. const int32_t session_window_update_delta =
  6376. session_max_recv_window_size / 2 + kChunkSize;
  6377. ASSERT_EQ(0, stream_max_recv_window_size / 2 % kChunkSize);
  6378. const int32_t stream_window_update_delta =
  6379. stream_max_recv_window_size / 2 + kChunkSize;
  6380. spdy::SpdySerializedFrame preface(
  6381. const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
  6382. spdy::kHttp2ConnectionHeaderPrefixSize,
  6383. /* owns_buffer = */ false);
  6384. spdy::SettingsMap initial_settings;
  6385. initial_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
  6386. initial_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
  6387. kSpdyMaxConcurrentPushedStreams;
  6388. initial_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
  6389. stream_max_recv_window_size;
  6390. initial_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
  6391. kSpdyMaxHeaderListSize;
  6392. spdy::SpdySerializedFrame initial_settings_frame(
  6393. spdy_util_.ConstructSpdySettings(initial_settings));
  6394. spdy::SpdySerializedFrame initial_window_update(
  6395. spdy_util_.ConstructSpdyWindowUpdate(
  6396. spdy::kSessionFlowControlStreamId,
  6397. session_max_recv_window_size - kDefaultInitialWindowSize));
  6398. spdy::SpdySerializedFrame combined_frames = CombineFrames(
  6399. {&preface, &initial_settings_frame, &initial_window_update});
  6400. std::vector<MockWrite> writes;
  6401. writes.push_back(CreateMockWrite(combined_frames));
  6402. spdy::SpdySerializedFrame req(
  6403. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  6404. writes.push_back(CreateMockWrite(req, writes.size()));
  6405. std::vector<MockRead> reads;
  6406. spdy::SpdySerializedFrame resp(
  6407. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  6408. reads.push_back(CreateMockRead(resp, writes.size() + reads.size()));
  6409. std::vector<spdy::SpdySerializedFrame> body_frames;
  6410. const std::string body_data(kChunkSize, 'x');
  6411. for (size_t remaining = kTargetSize; remaining != 0;) {
  6412. size_t frame_size = std::min(remaining, body_data.size());
  6413. body_frames.push_back(spdy_util_.ConstructSpdyDataFrame(
  6414. 1, base::StringPiece(body_data.data(), frame_size), false));
  6415. reads.push_back(
  6416. CreateMockRead(body_frames.back(), writes.size() + reads.size()));
  6417. remaining -= frame_size;
  6418. }
  6419. // Yield.
  6420. reads.emplace_back(SYNCHRONOUS, ERR_IO_PENDING, writes.size() + reads.size());
  6421. spdy::SpdySerializedFrame session_window_update(
  6422. spdy_util_.ConstructSpdyWindowUpdate(0, session_window_update_delta));
  6423. writes.push_back(
  6424. CreateMockWrite(session_window_update, writes.size() + reads.size()));
  6425. spdy::SpdySerializedFrame stream_window_update(
  6426. spdy_util_.ConstructSpdyWindowUpdate(1, stream_window_update_delta));
  6427. writes.push_back(
  6428. CreateMockWrite(stream_window_update, writes.size() + reads.size()));
  6429. SequencedSocketData data(reads, writes);
  6430. auto session_deps = std::make_unique<SpdySessionDependencies>();
  6431. session_deps->session_max_recv_window_size = session_max_recv_window_size;
  6432. session_deps->http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
  6433. stream_max_recv_window_size;
  6434. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  6435. std::move(session_deps));
  6436. helper.AddData(&data);
  6437. helper.RunPreTestSetup();
  6438. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  6439. SpdySessionPoolPeer pool_peer(spdy_session_pool);
  6440. pool_peer.SetEnableSendingInitialData(true);
  6441. HttpNetworkTransaction* trans = helper.trans();
  6442. TestCompletionCallback callback;
  6443. int rv = trans->Start(&request_, callback.callback(), log_);
  6444. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6445. rv = callback.WaitForResult();
  6446. EXPECT_THAT(rv, IsOk());
  6447. // Finish async network reads.
  6448. base::RunLoop().RunUntilIdle();
  6449. SpdyHttpStream* stream =
  6450. static_cast<SpdyHttpStream*>(trans->stream_.get());
  6451. ASSERT_TRUE(stream);
  6452. ASSERT_TRUE(stream->stream());
  6453. // All data has been read, but not consumed. The window reflects this.
  6454. EXPECT_EQ(static_cast<int>(stream_max_recv_window_size - kTargetSize),
  6455. stream->stream()->recv_window_size());
  6456. const HttpResponseInfo* response = trans->GetResponseInfo();
  6457. ASSERT_TRUE(response);
  6458. ASSERT_TRUE(response->headers);
  6459. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  6460. EXPECT_TRUE(response->was_fetched_via_spdy);
  6461. // Issue a read which will cause a WINDOW_UPDATE to be sent and window
  6462. // size increased to default.
  6463. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kTargetSize);
  6464. EXPECT_EQ(static_cast<int>(kTargetSize),
  6465. trans->Read(buf.get(), kTargetSize, CompletionOnceCallback()));
  6466. EXPECT_EQ(static_cast<int>(stream_max_recv_window_size),
  6467. stream->stream()->recv_window_size());
  6468. EXPECT_THAT(base::StringPiece(buf->data(), kTargetSize), Each(Eq('x')));
  6469. // Allow scheduled WINDOW_UPDATE frames to write.
  6470. base::RunLoop().RunUntilIdle();
  6471. helper.VerifyDataConsumed();
  6472. }
  6473. // Test that WINDOW_UPDATE frame causing overflow is handled correctly.
  6474. TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
  6475. // Number of full frames we hope to write (but will not, used to
  6476. // set content-length header correctly)
  6477. static int kFrameCount = 3;
  6478. std::string content(kMaxSpdyFrameChunkSize, 'a');
  6479. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  6480. kDefaultUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, nullptr,
  6481. 0));
  6482. spdy::SpdySerializedFrame body(
  6483. spdy_util_.ConstructSpdyDataFrame(1, content, false));
  6484. spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
  6485. 1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
  6486. // We're not going to write a data frame with FIN, we'll receive a bad
  6487. // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
  6488. MockWrite writes[] = {
  6489. CreateMockWrite(req, 0), CreateMockWrite(body, 2),
  6490. CreateMockWrite(rst, 3),
  6491. };
  6492. static const int32_t kDeltaWindowSize = 0x7fffffff; // cause an overflow
  6493. spdy::SpdySerializedFrame window_update(
  6494. spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
  6495. MockRead reads[] = {
  6496. CreateMockRead(window_update, 1), MockRead(ASYNC, 0, 4) // EOF
  6497. };
  6498. SequencedSocketData data(reads, writes);
  6499. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  6500. for (int i = 0; i < kFrameCount; ++i) {
  6501. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  6502. content.data(), content.size()));
  6503. }
  6504. ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
  6505. // Setup the request.
  6506. request_.method = "POST";
  6507. request_.upload_data_stream = &upload_data_stream;
  6508. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6509. helper.RunPreTestSetup();
  6510. helper.AddData(&data);
  6511. HttpNetworkTransaction* trans = helper.trans();
  6512. TestCompletionCallback callback;
  6513. int rv = trans->Start(&request_, callback.callback(), log_);
  6514. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  6515. base::RunLoop().RunUntilIdle();
  6516. ASSERT_TRUE(callback.have_result());
  6517. EXPECT_THAT(callback.WaitForResult(), IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
  6518. helper.VerifyDataConsumed();
  6519. }
  6520. // Regression test for https://crbug.com/732019.
  6521. // RFC7540 Section 6.9.2: A spdy::SETTINGS_INITIAL_WINDOW_SIZE change that
  6522. // causes any stream flow control window to overflow MUST be treated as a
  6523. // connection error.
  6524. TEST_F(SpdyNetworkTransactionTest, InitialWindowSizeOverflow) {
  6525. spdy::SpdySerializedFrame window_update(
  6526. spdy_util_.ConstructSpdyWindowUpdate(1, 0x60000000));
  6527. spdy::SettingsMap settings;
  6528. settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 0x60000000;
  6529. spdy::SpdySerializedFrame settings_frame(
  6530. spdy_util_.ConstructSpdySettings(settings));
  6531. MockRead reads[] = {CreateMockRead(window_update, 1),
  6532. CreateMockRead(settings_frame, 2)};
  6533. spdy::SpdySerializedFrame req(
  6534. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  6535. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  6536. spdy::SpdySerializedFrame goaway(
  6537. spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
  6538. "New spdy::SETTINGS_INITIAL_WINDOW_SIZE "
  6539. "value overflows flow control window of "
  6540. "stream 1."));
  6541. MockWrite writes[] = {CreateMockWrite(req, 0),
  6542. CreateMockWrite(settings_ack, 3),
  6543. CreateMockWrite(goaway, 4)};
  6544. SequencedSocketData data(reads, writes);
  6545. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6546. helper.RunToCompletion(&data);
  6547. TransactionHelperResult out = helper.output();
  6548. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_FLOW_CONTROL_ERROR));
  6549. }
  6550. // Tests that we close the connection if we try to enqueue more frames than
  6551. // the cap allows.
  6552. TEST_F(SpdyNetworkTransactionTest, SessionMaxQueuedCappedFramesExceeded) {
  6553. const int kTestSessionMaxQueuedCappedFrames = 5;
  6554. const int kTestNumPings = kTestSessionMaxQueuedCappedFrames + 1;
  6555. spdy::SettingsMap settings;
  6556. settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 0xffff;
  6557. spdy::SpdySerializedFrame settings_frame(
  6558. spdy_util_.ConstructSpdySettings(settings));
  6559. std::vector<spdy::SpdySerializedFrame> ping_frames;
  6560. spdy::SpdySerializedFrame req(
  6561. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  6562. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  6563. std::vector<MockWrite> writes;
  6564. std::vector<MockRead> reads;
  6565. // Send request, receive SETTINGS and send a SETTINGS ACK.
  6566. writes.push_back(CreateMockWrite(req, writes.size() + reads.size()));
  6567. reads.push_back(CreateMockRead(settings_frame, writes.size() + reads.size()));
  6568. writes.push_back(CreateMockWrite(settings_ack, writes.size() + reads.size()));
  6569. // Receive more pings than our limit allows.
  6570. for (int i = 1; i <= kTestNumPings; ++i) {
  6571. ping_frames.push_back(
  6572. spdy_util_.ConstructSpdyPing(/*ping_id=*/i, /*is_ack=*/false));
  6573. reads.push_back(
  6574. CreateMockRead(ping_frames.back(), writes.size() + reads.size()));
  6575. }
  6576. // Only write PING ACKs after receiving all of them to ensure they are all in
  6577. // the write queue.
  6578. for (int i = 1; i <= kTestNumPings; ++i) {
  6579. ping_frames.push_back(
  6580. spdy_util_.ConstructSpdyPing(/*ping_id=*/i, /*is_ack=*/true));
  6581. writes.push_back(
  6582. CreateMockWrite(ping_frames.back(), writes.size() + reads.size()));
  6583. }
  6584. // Stop reading.
  6585. reads.emplace_back(ASYNC, 0, writes.size() + reads.size());
  6586. SequencedSocketData data(reads, writes);
  6587. auto session_deps = std::make_unique<SpdySessionDependencies>();
  6588. session_deps->session_max_queued_capped_frames =
  6589. kTestSessionMaxQueuedCappedFrames;
  6590. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  6591. std::move(session_deps));
  6592. helper.RunToCompletion(&data);
  6593. TransactionHelperResult out = helper.output();
  6594. EXPECT_THAT(out.rv, IsError(ERR_CONNECTION_CLOSED));
  6595. }
  6596. // Test that after hitting a send window size of 0, the write process
  6597. // stalls and upon receiving WINDOW_UPDATE frame write resumes.
  6598. // This test constructs a POST request followed by enough data frames
  6599. // containing 'a' that would make the window size 0, followed by another
  6600. // data frame containing default content (which is "hello!") and this frame
  6601. // also contains a FIN flag. SequencedSocketData is used to enforce all
  6602. // writes, save the last, go through before a read could happen. The last frame
  6603. // ("hello!") is not permitted to go through since by the time its turn
  6604. // arrives, window size is 0. At this point MessageLoop::Run() called via
  6605. // callback would block. Therefore we call MessageLoop::RunUntilIdle()
  6606. // which returns after performing all possible writes. We use DCHECKS to
  6607. // ensure that last data frame is still there and stream has stalled.
  6608. // After that, next read is artifically enforced, which causes a
  6609. // WINDOW_UPDATE to be read and I/O process resumes.
  6610. TEST_F(SpdyNetworkTransactionTest, FlowControlStallResume) {
  6611. const int32_t initial_window_size = kDefaultInitialWindowSize;
  6612. // Number of upload data buffers we need to send to zero out the window size
  6613. // is the minimal number of upload buffers takes to be bigger than
  6614. // |initial_window_size|.
  6615. size_t num_upload_buffers =
  6616. ceil(static_cast<double>(initial_window_size) / kBufferSize);
  6617. // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
  6618. // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
  6619. // which has kBufferSize % kMaxSpdyChunkSize bytes.
  6620. size_t num_frames_in_one_upload_buffer =
  6621. ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
  6622. // Construct content for a data frame of maximum size.
  6623. std::string content(kMaxSpdyFrameChunkSize, 'a');
  6624. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  6625. kDefaultUrl, 1,
  6626. /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
  6627. LOWEST, nullptr, 0));
  6628. // Full frames.
  6629. spdy::SpdySerializedFrame body1(
  6630. spdy_util_.ConstructSpdyDataFrame(1, content, false));
  6631. // Last frame in each upload data buffer.
  6632. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(
  6633. 1,
  6634. base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize),
  6635. false));
  6636. // The very last frame before the stalled frames.
  6637. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(
  6638. 1,
  6639. base::StringPiece(content.data(), initial_window_size % kBufferSize %
  6640. kMaxSpdyFrameChunkSize),
  6641. false));
  6642. // Data frames to be sent once WINDOW_UPDATE frame is received.
  6643. // If kBufferSize * num_upload_buffers > initial_window_size,
  6644. // we need one additional frame to send the rest of 'a'.
  6645. std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
  6646. 'a');
  6647. spdy::SpdySerializedFrame body4(
  6648. spdy_util_.ConstructSpdyDataFrame(1, last_body, false));
  6649. // Also send a "hello!" after WINDOW_UPDATE.
  6650. spdy::SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true));
  6651. // Fill in mock writes.
  6652. size_t i = 0;
  6653. std::vector<MockWrite> writes;
  6654. writes.push_back(CreateMockWrite(req, i++));
  6655. for (size_t j = 0; j < num_upload_buffers; j++) {
  6656. for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
  6657. if (j == num_upload_buffers - 1 &&
  6658. (initial_window_size % kBufferSize != 0)) {
  6659. writes.push_back(CreateMockWrite(body3, i++));
  6660. } else if (k == num_frames_in_one_upload_buffer - 1 &&
  6661. kBufferSize % kMaxSpdyFrameChunkSize != 0) {
  6662. writes.push_back(CreateMockWrite(body2, i++));
  6663. } else {
  6664. writes.push_back(CreateMockWrite(body1, i++));
  6665. }
  6666. }
  6667. }
  6668. // Fill in mock reads.
  6669. std::vector<MockRead> reads;
  6670. // Force a pause.
  6671. reads.emplace_back(ASYNC, ERR_IO_PENDING, i++);
  6672. // Construct read frame for window updates that gives enough space to upload
  6673. // the rest of the data.
  6674. spdy::SpdySerializedFrame session_window_update(
  6675. spdy_util_.ConstructSpdyWindowUpdate(0,
  6676. kUploadDataSize + last_body.size()));
  6677. spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
  6678. 1, kUploadDataSize + last_body.size()));
  6679. reads.push_back(CreateMockRead(session_window_update, i++));
  6680. reads.push_back(CreateMockRead(window_update, i++));
  6681. // Stalled frames which can be sent after receiving window updates.
  6682. if (last_body.size() > 0)
  6683. writes.push_back(CreateMockWrite(body4, i++));
  6684. writes.push_back(CreateMockWrite(body5, i++));
  6685. spdy::SpdySerializedFrame reply(
  6686. spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  6687. reads.push_back(CreateMockRead(reply, i++));
  6688. reads.push_back(CreateMockRead(body2, i++));
  6689. reads.push_back(CreateMockRead(body5, i++));
  6690. reads.emplace_back(ASYNC, 0, i++); // EOF
  6691. SequencedSocketData data(reads, writes);
  6692. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  6693. std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
  6694. upload_data_string.append(kUploadData, kUploadDataSize);
  6695. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  6696. upload_data_string.c_str(), upload_data_string.size()));
  6697. ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
  6698. request_.method = "POST";
  6699. request_.upload_data_stream = &upload_data_stream;
  6700. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6701. helper.AddData(&data);
  6702. helper.RunPreTestSetup();
  6703. HttpNetworkTransaction* trans = helper.trans();
  6704. TestCompletionCallback callback;
  6705. int rv = trans->Start(&request_, callback.callback(), log_);
  6706. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6707. base::RunLoop().RunUntilIdle(); // Write as much as we can.
  6708. SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
  6709. ASSERT_TRUE(stream);
  6710. ASSERT_TRUE(stream->stream());
  6711. EXPECT_EQ(0, stream->stream()->send_window_size());
  6712. if (initial_window_size % kBufferSize != 0) {
  6713. // If it does not take whole number of full upload buffer to zero out
  6714. // initial window size, then the upload data is not at EOF, because the
  6715. // last read must be stalled.
  6716. EXPECT_FALSE(upload_data_stream.IsEOF());
  6717. } else {
  6718. // All the body data should have been read.
  6719. // TODO(satorux): This is because of the weirdness in reading the request
  6720. // body in OnSendBodyComplete(). See crbug.com/113107.
  6721. EXPECT_TRUE(upload_data_stream.IsEOF());
  6722. }
  6723. // But the body is not yet fully sent (kUploadData is not yet sent)
  6724. // since we're send-stalled.
  6725. EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
  6726. data.Resume(); // Read in WINDOW_UPDATE frame.
  6727. rv = callback.WaitForResult();
  6728. EXPECT_THAT(rv, IsOk());
  6729. // Finish async network reads.
  6730. base::RunLoop().RunUntilIdle();
  6731. helper.VerifyDataConsumed();
  6732. }
  6733. // Test we correctly handle the case where the SETTINGS frame results in
  6734. // unstalling the send window.
  6735. TEST_F(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
  6736. const int32_t initial_window_size = kDefaultInitialWindowSize;
  6737. // Number of upload data buffers we need to send to zero out the window size
  6738. // is the minimal number of upload buffers takes to be bigger than
  6739. // |initial_window_size|.
  6740. size_t num_upload_buffers =
  6741. ceil(static_cast<double>(initial_window_size) / kBufferSize);
  6742. // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
  6743. // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
  6744. // which has kBufferSize % kMaxSpdyChunkSize bytes.
  6745. size_t num_frames_in_one_upload_buffer =
  6746. ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
  6747. // Construct content for a data frame of maximum size.
  6748. std::string content(kMaxSpdyFrameChunkSize, 'a');
  6749. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  6750. kDefaultUrl, 1,
  6751. /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
  6752. LOWEST, nullptr, 0));
  6753. // Full frames.
  6754. spdy::SpdySerializedFrame body1(
  6755. spdy_util_.ConstructSpdyDataFrame(1, content, false));
  6756. // Last frame in each upload data buffer.
  6757. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(
  6758. 1,
  6759. base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize),
  6760. false));
  6761. // The very last frame before the stalled frames.
  6762. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(
  6763. 1,
  6764. base::StringPiece(content.data(), initial_window_size % kBufferSize %
  6765. kMaxSpdyFrameChunkSize),
  6766. false));
  6767. // Data frames to be sent once WINDOW_UPDATE frame is received.
  6768. // If kBufferSize * num_upload_buffers > initial_window_size,
  6769. // we need one additional frame to send the rest of 'a'.
  6770. std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
  6771. 'a');
  6772. spdy::SpdySerializedFrame body4(
  6773. spdy_util_.ConstructSpdyDataFrame(1, last_body, false));
  6774. // Also send a "hello!" after WINDOW_UPDATE.
  6775. spdy::SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true));
  6776. // Fill in mock writes.
  6777. size_t i = 0;
  6778. std::vector<MockWrite> writes;
  6779. writes.push_back(CreateMockWrite(req, i++));
  6780. for (size_t j = 0; j < num_upload_buffers; j++) {
  6781. for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
  6782. if (j == num_upload_buffers - 1 &&
  6783. (initial_window_size % kBufferSize != 0)) {
  6784. writes.push_back(CreateMockWrite(body3, i++));
  6785. } else if (k == num_frames_in_one_upload_buffer - 1 &&
  6786. kBufferSize % kMaxSpdyFrameChunkSize != 0) {
  6787. writes.push_back(CreateMockWrite(body2, i++));
  6788. } else {
  6789. writes.push_back(CreateMockWrite(body1, i++));
  6790. }
  6791. }
  6792. }
  6793. // Fill in mock reads.
  6794. std::vector<MockRead> reads;
  6795. // Force a pause.
  6796. reads.emplace_back(ASYNC, ERR_IO_PENDING, i++);
  6797. // Construct read frame for SETTINGS that gives enough space to upload the
  6798. // rest of the data.
  6799. spdy::SettingsMap settings;
  6800. settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = initial_window_size * 2;
  6801. spdy::SpdySerializedFrame settings_frame_large(
  6802. spdy_util_.ConstructSpdySettings(settings));
  6803. reads.push_back(CreateMockRead(settings_frame_large, i++));
  6804. spdy::SpdySerializedFrame session_window_update(
  6805. spdy_util_.ConstructSpdyWindowUpdate(0,
  6806. last_body.size() + kUploadDataSize));
  6807. reads.push_back(CreateMockRead(session_window_update, i++));
  6808. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  6809. writes.push_back(CreateMockWrite(settings_ack, i++));
  6810. // Stalled frames which can be sent after |settings_ack|.
  6811. if (last_body.size() > 0)
  6812. writes.push_back(CreateMockWrite(body4, i++));
  6813. writes.push_back(CreateMockWrite(body5, i++));
  6814. spdy::SpdySerializedFrame reply(
  6815. spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  6816. reads.push_back(CreateMockRead(reply, i++));
  6817. reads.push_back(CreateMockRead(body2, i++));
  6818. reads.push_back(CreateMockRead(body5, i++));
  6819. reads.emplace_back(ASYNC, 0, i++); // EOF
  6820. // Force all writes to happen before any read, last write will not
  6821. // actually queue a frame, due to window size being 0.
  6822. SequencedSocketData data(reads, writes);
  6823. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  6824. std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
  6825. upload_data_string.append(kUploadData, kUploadDataSize);
  6826. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  6827. upload_data_string.c_str(), upload_data_string.size()));
  6828. ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
  6829. request_.method = "POST";
  6830. request_.upload_data_stream = &upload_data_stream;
  6831. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6832. helper.RunPreTestSetup();
  6833. helper.AddData(&data);
  6834. HttpNetworkTransaction* trans = helper.trans();
  6835. TestCompletionCallback callback;
  6836. int rv = trans->Start(&request_, callback.callback(), log_);
  6837. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6838. data.RunUntilPaused(); // Write as much as we can.
  6839. base::RunLoop().RunUntilIdle();
  6840. SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
  6841. ASSERT_TRUE(stream);
  6842. ASSERT_TRUE(stream->stream());
  6843. EXPECT_EQ(0, stream->stream()->send_window_size());
  6844. if (initial_window_size % kBufferSize != 0) {
  6845. // If it does not take whole number of full upload buffer to zero out
  6846. // initial window size, then the upload data is not at EOF, because the
  6847. // last read must be stalled.
  6848. EXPECT_FALSE(upload_data_stream.IsEOF());
  6849. } else {
  6850. // All the body data should have been read.
  6851. // TODO(satorux): This is because of the weirdness in reading the request
  6852. // body in OnSendBodyComplete(). See crbug.com/113107.
  6853. EXPECT_TRUE(upload_data_stream.IsEOF());
  6854. }
  6855. // But the body is not yet fully sent (kUploadData is not yet sent)
  6856. // since we're send-stalled.
  6857. EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
  6858. // Read in SETTINGS frame to unstall.
  6859. data.Resume();
  6860. base::RunLoop().RunUntilIdle();
  6861. rv = callback.WaitForResult();
  6862. helper.VerifyDataConsumed();
  6863. // If stream is nullptr, that means it was unstalled and closed.
  6864. EXPECT_TRUE(stream->stream() == nullptr);
  6865. }
  6866. // Test we correctly handle the case where the SETTINGS frame results in a
  6867. // negative send window size.
  6868. TEST_F(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
  6869. const int32_t initial_window_size = kDefaultInitialWindowSize;
  6870. // Number of upload data buffers we need to send to zero out the window size
  6871. // is the minimal number of upload buffers takes to be bigger than
  6872. // |initial_window_size|.
  6873. size_t num_upload_buffers =
  6874. ceil(static_cast<double>(initial_window_size) / kBufferSize);
  6875. // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
  6876. // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
  6877. // which has kBufferSize % kMaxSpdyChunkSize bytes.
  6878. size_t num_frames_in_one_upload_buffer =
  6879. ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
  6880. // Construct content for a data frame of maximum size.
  6881. std::string content(kMaxSpdyFrameChunkSize, 'a');
  6882. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  6883. kDefaultUrl, 1,
  6884. /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
  6885. LOWEST, nullptr, 0));
  6886. // Full frames.
  6887. spdy::SpdySerializedFrame body1(
  6888. spdy_util_.ConstructSpdyDataFrame(1, content, false));
  6889. // Last frame in each upload data buffer.
  6890. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(
  6891. 1,
  6892. base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize),
  6893. false));
  6894. // The very last frame before the stalled frames.
  6895. spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(
  6896. 1,
  6897. base::StringPiece(content.data(), initial_window_size % kBufferSize %
  6898. kMaxSpdyFrameChunkSize),
  6899. false));
  6900. // Data frames to be sent once WINDOW_UPDATE frame is received.
  6901. // If kBufferSize * num_upload_buffers > initial_window_size,
  6902. // we need one additional frame to send the rest of 'a'.
  6903. std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
  6904. 'a');
  6905. spdy::SpdySerializedFrame body4(
  6906. spdy_util_.ConstructSpdyDataFrame(1, last_body, false));
  6907. // Also send a "hello!" after WINDOW_UPDATE.
  6908. spdy::SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true));
  6909. // Fill in mock writes.
  6910. size_t i = 0;
  6911. std::vector<MockWrite> writes;
  6912. writes.push_back(CreateMockWrite(req, i++));
  6913. for (size_t j = 0; j < num_upload_buffers; j++) {
  6914. for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
  6915. if (j == num_upload_buffers - 1 &&
  6916. (initial_window_size % kBufferSize != 0)) {
  6917. writes.push_back(CreateMockWrite(body3, i++));
  6918. } else if (k == num_frames_in_one_upload_buffer - 1 &&
  6919. kBufferSize % kMaxSpdyFrameChunkSize != 0) {
  6920. writes.push_back(CreateMockWrite(body2, i++));
  6921. } else {
  6922. writes.push_back(CreateMockWrite(body1, i++));
  6923. }
  6924. }
  6925. }
  6926. // Fill in mock reads.
  6927. std::vector<MockRead> reads;
  6928. // Force a pause.
  6929. reads.emplace_back(ASYNC, ERR_IO_PENDING, i++);
  6930. // Construct read frame for SETTINGS that makes the send_window_size
  6931. // negative.
  6932. spdy::SettingsMap new_settings;
  6933. new_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = initial_window_size / 2;
  6934. spdy::SpdySerializedFrame settings_frame_small(
  6935. spdy_util_.ConstructSpdySettings(new_settings));
  6936. // Construct read frames for WINDOW_UPDATE that makes the send_window_size
  6937. // positive.
  6938. spdy::SpdySerializedFrame session_window_update_init_size(
  6939. spdy_util_.ConstructSpdyWindowUpdate(0, initial_window_size));
  6940. spdy::SpdySerializedFrame window_update_init_size(
  6941. spdy_util_.ConstructSpdyWindowUpdate(1, initial_window_size));
  6942. reads.push_back(CreateMockRead(settings_frame_small, i++));
  6943. reads.push_back(CreateMockRead(session_window_update_init_size, i++));
  6944. reads.push_back(CreateMockRead(window_update_init_size, i++));
  6945. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  6946. writes.push_back(CreateMockWrite(settings_ack, i++));
  6947. // Stalled frames which can be sent after |settings_ack|.
  6948. if (last_body.size() > 0)
  6949. writes.push_back(CreateMockWrite(body4, i++));
  6950. writes.push_back(CreateMockWrite(body5, i++));
  6951. spdy::SpdySerializedFrame reply(
  6952. spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  6953. reads.push_back(CreateMockRead(reply, i++));
  6954. reads.push_back(CreateMockRead(body2, i++));
  6955. reads.push_back(CreateMockRead(body5, i++));
  6956. reads.emplace_back(ASYNC, 0, i++); // EOF
  6957. // Force all writes to happen before any read, last write will not
  6958. // actually queue a frame, due to window size being 0.
  6959. SequencedSocketData data(reads, writes);
  6960. std::vector<std::unique_ptr<UploadElementReader>> element_readers;
  6961. std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
  6962. upload_data_string.append(kUploadData, kUploadDataSize);
  6963. element_readers.push_back(std::make_unique<UploadBytesElementReader>(
  6964. upload_data_string.c_str(), upload_data_string.size()));
  6965. ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
  6966. request_.method = "POST";
  6967. request_.upload_data_stream = &upload_data_stream;
  6968. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  6969. helper.RunPreTestSetup();
  6970. helper.AddData(&data);
  6971. HttpNetworkTransaction* trans = helper.trans();
  6972. TestCompletionCallback callback;
  6973. int rv = trans->Start(&request_, callback.callback(), log_);
  6974. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  6975. data.RunUntilPaused(); // Write as much as we can.
  6976. base::RunLoop().RunUntilIdle();
  6977. SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
  6978. ASSERT_TRUE(stream);
  6979. ASSERT_TRUE(stream->stream());
  6980. EXPECT_EQ(0, stream->stream()->send_window_size());
  6981. if (initial_window_size % kBufferSize != 0) {
  6982. // If it does not take whole number of full upload buffer to zero out
  6983. // initial window size, then the upload data is not at EOF, because the
  6984. // last read must be stalled.
  6985. EXPECT_FALSE(upload_data_stream.IsEOF());
  6986. } else {
  6987. // All the body data should have been read.
  6988. // TODO(satorux): This is because of the weirdness in reading the request
  6989. // body in OnSendBodyComplete(). See crbug.com/113107.
  6990. EXPECT_TRUE(upload_data_stream.IsEOF());
  6991. }
  6992. // Read in WINDOW_UPDATE or SETTINGS frame.
  6993. data.Resume();
  6994. base::RunLoop().RunUntilIdle();
  6995. rv = callback.WaitForResult();
  6996. helper.VerifyDataConsumed();
  6997. }
  6998. TEST_F(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) {
  6999. base::HistogramTester histogram_tester;
  7000. spdy::Http2HeaderBlock push_headers;
  7001. spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat", &push_headers);
  7002. spdy::SpdySerializedFrame push(
  7003. spdy_util_.ConstructSpdyPushPromise(1, 3, std::move(push_headers)));
  7004. MockRead reads[] = {CreateMockRead(push, 1)};
  7005. spdy::SpdySerializedFrame req(
  7006. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  7007. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  7008. 0, spdy::ERROR_CODE_PROTOCOL_ERROR,
  7009. "Received invalid pushed stream id 3 (must be even) on stream id 1."));
  7010. MockWrite writes[] = {
  7011. CreateMockWrite(req, 0), CreateMockWrite(goaway, 2),
  7012. };
  7013. SequencedSocketData data(reads, writes);
  7014. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7015. helper.RunToCompletion(&data);
  7016. TransactionHelperResult out = helper.output();
  7017. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  7018. histogram_tester.ExpectBucketCount(
  7019. "Net.SpdyPushedStreamFate",
  7020. static_cast<int>(SpdyPushedStreamFate::kPromisedStreamIdParityError), 1);
  7021. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  7022. }
  7023. TEST_F(SpdyNetworkTransactionTest,
  7024. GoAwayOnPushStreamIdLesserOrEqualThanLastAccepted) {
  7025. base::HistogramTester histogram_tester;
  7026. spdy::SpdySerializedFrame push_a(spdy_util_.ConstructSpdyPush(
  7027. nullptr, 0, 4, 1, "https://www.example.org/a.dat"));
  7028. spdy::Http2HeaderBlock push_b_headers;
  7029. spdy_util_.AddUrlToHeaderBlock("https://www.example.org/b.dat",
  7030. &push_b_headers);
  7031. spdy::SpdySerializedFrame push_b(
  7032. spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_b_headers)));
  7033. MockRead reads[] = {
  7034. CreateMockRead(push_a, 1), CreateMockRead(push_b, 3),
  7035. };
  7036. spdy::SpdySerializedFrame req(
  7037. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  7038. spdy::SpdySerializedFrame priority_a(
  7039. spdy_util_.ConstructSpdyPriority(4, 1, IDLE, true));
  7040. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  7041. 4, spdy::ERROR_CODE_PROTOCOL_ERROR,
  7042. "Received pushed stream id 2 must be larger than last accepted id 4."));
  7043. MockWrite writes[] = {
  7044. CreateMockWrite(req, 0), CreateMockWrite(priority_a, 2),
  7045. CreateMockWrite(goaway, 4),
  7046. };
  7047. SequencedSocketData data(reads, writes);
  7048. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7049. helper.RunToCompletion(&data);
  7050. TransactionHelperResult out = helper.output();
  7051. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  7052. histogram_tester.ExpectBucketCount(
  7053. "Net.SpdyPushedStreamFate",
  7054. static_cast<int>(SpdyPushedStreamFate::kStreamIdOutOfOrder), 1);
  7055. histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
  7056. }
  7057. // Regression test for https://crbug.com/493348: request header exceeds 16 kB
  7058. // and thus sent in multiple frames when using HTTP/2.
  7059. TEST_F(SpdyNetworkTransactionTest, LargeRequest) {
  7060. const std::string kKey("foo");
  7061. const std::string kValue(1 << 15, 'z');
  7062. request_.extra_headers.SetHeader(kKey, kValue);
  7063. spdy::Http2HeaderBlock headers(
  7064. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  7065. headers[kKey] = kValue;
  7066. spdy::SpdySerializedFrame req(
  7067. spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
  7068. MockWrite writes[] = {
  7069. CreateMockWrite(req, 0),
  7070. };
  7071. spdy::SpdySerializedFrame resp(
  7072. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7073. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7074. MockRead reads[] = {
  7075. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7076. MockRead(ASYNC, 0, 3) // EOF
  7077. };
  7078. SequencedSocketData data(reads, writes);
  7079. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7080. helper.RunToCompletion(&data);
  7081. TransactionHelperResult out = helper.output();
  7082. EXPECT_THAT(out.rv, IsOk());
  7083. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  7084. EXPECT_EQ("hello!", out.response_data);
  7085. }
  7086. // Regression test for https://crbug.com/535629: response header exceeds 16 kB.
  7087. TEST_F(SpdyNetworkTransactionTest, LargeResponseHeader) {
  7088. spdy::Http2HeaderBlock headers(
  7089. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  7090. spdy::SpdySerializedFrame req(
  7091. spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
  7092. MockWrite writes[] = {
  7093. CreateMockWrite(req, 0),
  7094. };
  7095. // HPACK decoder implementation limits string literal length to 16 kB.
  7096. const char* response_headers[2];
  7097. const std::string kKey(16 * 1024, 'a');
  7098. response_headers[0] = kKey.data();
  7099. const std::string kValue(16 * 1024, 'b');
  7100. response_headers[1] = kValue.data();
  7101. spdy::SpdySerializedFrame resp(
  7102. spdy_util_.ConstructSpdyGetReply(response_headers, 1, 1));
  7103. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7104. MockRead reads[] = {
  7105. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7106. MockRead(ASYNC, 0, 3) // EOF
  7107. };
  7108. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7109. SequencedSocketData data(reads, writes);
  7110. helper.RunToCompletion(&data);
  7111. TransactionHelperResult out = helper.output();
  7112. EXPECT_THAT(out.rv, IsOk());
  7113. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  7114. EXPECT_EQ("hello!", out.response_data);
  7115. ASSERT_TRUE(out.response_info.headers->HasHeaderValue(kKey, kValue));
  7116. }
  7117. // End of line delimiter is forbidden according to RFC 7230 Section 3.2.
  7118. TEST_F(SpdyNetworkTransactionTest, CRLFInHeaderValue) {
  7119. spdy::SpdySerializedFrame req(
  7120. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  7121. spdy::SpdySerializedFrame rst(
  7122. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
  7123. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 2)};
  7124. const char* response_headers[] = {"folded", "foo\r\nbar"};
  7125. spdy::SpdySerializedFrame resp(
  7126. spdy_util_.ConstructSpdyGetReply(response_headers, 1, 1));
  7127. MockRead reads[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3)};
  7128. SequencedSocketData data(reads, writes);
  7129. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7130. helper.RunToCompletion(&data);
  7131. TransactionHelperResult out = helper.output();
  7132. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  7133. }
  7134. // Regression test for https://crbug.com/603182.
  7135. // No response headers received before RST_STREAM: error.
  7136. TEST_F(SpdyNetworkTransactionTest, RstStreamNoError) {
  7137. spdy::SpdySerializedFrame req(
  7138. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  7139. MockWrite writes[] = {CreateMockWrite(req, 0, ASYNC)};
  7140. spdy::SpdySerializedFrame rst(
  7141. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
  7142. MockRead reads[] = {CreateMockRead(rst, 1), MockRead(ASYNC, 0, 2)};
  7143. SequencedSocketData data(reads, writes);
  7144. UseChunkedPostRequest();
  7145. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7146. helper.RunToCompletion(&data);
  7147. TransactionHelperResult out = helper.output();
  7148. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  7149. }
  7150. // Regression test for https://crbug.com/603182.
  7151. // Response headers and data, then RST_STREAM received,
  7152. // before request body is sent: success.
  7153. TEST_F(SpdyNetworkTransactionTest, RstStreamNoErrorAfterResponse) {
  7154. spdy::SpdySerializedFrame req(
  7155. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  7156. MockWrite writes[] = {CreateMockWrite(req, 0, ASYNC)};
  7157. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  7158. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7159. spdy::SpdySerializedFrame rst(
  7160. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
  7161. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7162. CreateMockRead(rst, 3), MockRead(ASYNC, 0, 4)};
  7163. SequencedSocketData data(reads, writes);
  7164. UseChunkedPostRequest();
  7165. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7166. helper.RunToCompletion(&data);
  7167. TransactionHelperResult out = helper.output();
  7168. EXPECT_THAT(out.rv, IsOk());
  7169. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  7170. EXPECT_EQ("hello!", out.response_data);
  7171. }
  7172. TEST_F(SpdyNetworkTransactionTest, 100Continue) {
  7173. spdy::SpdySerializedFrame req(
  7174. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  7175. MockWrite writes[] = {CreateMockWrite(req, 0)};
  7176. spdy::Http2HeaderBlock informational_headers;
  7177. informational_headers[spdy::kHttp2StatusHeader] = "100";
  7178. spdy::SpdySerializedFrame informational_response(
  7179. spdy_util_.ConstructSpdyReply(1, std::move(informational_headers)));
  7180. spdy::SpdySerializedFrame resp(
  7181. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7182. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7183. MockRead reads[] = {
  7184. CreateMockRead(informational_response, 1), CreateMockRead(resp, 2),
  7185. CreateMockRead(body, 3), MockRead(ASYNC, 0, 4) // EOF
  7186. };
  7187. SequencedSocketData data(reads, writes);
  7188. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7189. helper.RunToCompletion(&data);
  7190. TransactionHelperResult out = helper.output();
  7191. EXPECT_THAT(out.rv, IsOk());
  7192. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  7193. EXPECT_EQ("hello!", out.response_data);
  7194. }
  7195. // "A server can send a complete response prior to the client sending an entire
  7196. // request if the response does not depend on any portion of the request that
  7197. // has not been sent and received." (RFC7540 Section 8.1)
  7198. // Regression test for https://crbug.com/606990. Server responds before POST
  7199. // data are sent and closes connection: this must result in
  7200. // ERR_CONNECTION_CLOSED (as opposed to ERR_HTTP2_PROTOCOL_ERROR).
  7201. TEST_F(SpdyNetworkTransactionTest, ResponseBeforePostDataSent) {
  7202. spdy::SpdySerializedFrame req(
  7203. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  7204. MockWrite writes[] = {CreateMockWrite(req, 0)};
  7205. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  7206. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7207. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7208. MockRead(ASYNC, 0, 3)};
  7209. SequencedSocketData data(reads, writes);
  7210. UseChunkedPostRequest();
  7211. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7212. helper.RunPreTestSetup();
  7213. helper.AddData(&data);
  7214. helper.StartDefaultTest();
  7215. EXPECT_THAT(helper.output().rv, IsError(ERR_IO_PENDING));
  7216. helper.WaitForCallbackToComplete();
  7217. EXPECT_THAT(helper.output().rv, IsError(ERR_CONNECTION_CLOSED));
  7218. }
  7219. // Regression test for https://crbug.com/606990.
  7220. // Server responds before POST data are sent and resets stream with NO_ERROR.
  7221. TEST_F(SpdyNetworkTransactionTest, ResponseAndRstStreamBeforePostDataSent) {
  7222. spdy::SpdySerializedFrame req(
  7223. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  7224. MockWrite writes[] = {CreateMockWrite(req, 0)};
  7225. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  7226. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7227. spdy::SpdySerializedFrame rst(
  7228. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
  7229. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7230. CreateMockRead(rst, 3), MockRead(ASYNC, 0, 4)};
  7231. SequencedSocketData data(reads, writes);
  7232. UseChunkedPostRequest();
  7233. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7234. helper.RunToCompletion(&data);
  7235. TransactionHelperResult out = helper.output();
  7236. EXPECT_THAT(out.rv, IsOk());
  7237. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  7238. EXPECT_EQ("hello!", out.response_data);
  7239. }
  7240. // Unsupported frames must be ignored. This is especially important for frame
  7241. // type 0xb, which used to be the BLOCKED frame in previous versions of SPDY,
  7242. // but is going to be used for the ORIGIN frame.
  7243. // TODO(bnc): Implement ORIGIN frame support. https://crbug.com/697333
  7244. TEST_F(SpdyNetworkTransactionTest, IgnoreUnsupportedOriginFrame) {
  7245. spdy::SpdySerializedFrame req(
  7246. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  7247. MockWrite writes[] = {CreateMockWrite(req, 0)};
  7248. const char origin_frame_on_stream_zero[] = {
  7249. 0x00, 0x00, 0x05, // Length
  7250. 0x0b, // Type
  7251. 0x00, // Flags
  7252. 0x00, 0x00, 0x00, 0x00, // Stream ID
  7253. 0x00, 0x03, // Origin-Len
  7254. 'f', 'o', 'o' // ASCII-Origin
  7255. };
  7256. const char origin_frame_on_stream_one[] = {
  7257. 0x00, 0x00, 0x05, // Length
  7258. 0x0b, // Type
  7259. 0x00, // Flags
  7260. 0x00, 0x00, 0x00, 0x01, // Stream ID
  7261. 0x00, 0x03, // Origin-Len
  7262. 'b', 'a', 'r' // ASCII-Origin
  7263. };
  7264. spdy::SpdySerializedFrame resp(
  7265. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7266. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7267. MockRead reads[] = {MockRead(ASYNC, origin_frame_on_stream_zero,
  7268. std::size(origin_frame_on_stream_zero), 1),
  7269. CreateMockRead(resp, 2),
  7270. MockRead(ASYNC, origin_frame_on_stream_one,
  7271. std::size(origin_frame_on_stream_one), 3),
  7272. CreateMockRead(body, 4), MockRead(ASYNC, 0, 5)};
  7273. SequencedSocketData data(reads, writes);
  7274. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7275. helper.RunToCompletion(&data);
  7276. TransactionHelperResult out = helper.output();
  7277. EXPECT_THAT(out.rv, IsOk());
  7278. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  7279. EXPECT_EQ("hello!", out.response_data);
  7280. }
  7281. class SpdyNetworkTransactionTLSUsageCheckTest
  7282. : public SpdyNetworkTransactionTest {
  7283. protected:
  7284. void RunTLSUsageCheckTest(
  7285. std::unique_ptr<SSLSocketDataProvider> ssl_provider) {
  7286. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  7287. 0, spdy::ERROR_CODE_INADEQUATE_SECURITY, ""));
  7288. MockWrite writes[] = {CreateMockWrite(goaway)};
  7289. StaticSocketDataProvider data(base::span<MockRead>(), writes);
  7290. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  7291. nullptr);
  7292. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  7293. TransactionHelperResult out = helper.output();
  7294. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY));
  7295. }
  7296. };
  7297. TEST_F(SpdyNetworkTransactionTLSUsageCheckTest, TLSVersionTooOld) {
  7298. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  7299. SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
  7300. &ssl_provider->ssl_info.connection_status);
  7301. RunTLSUsageCheckTest(std::move(ssl_provider));
  7302. }
  7303. TEST_F(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) {
  7304. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  7305. // Set to TLS_RSA_WITH_NULL_MD5
  7306. SSLConnectionStatusSetCipherSuite(0x1,
  7307. &ssl_provider->ssl_info.connection_status);
  7308. RunTLSUsageCheckTest(std::move(ssl_provider));
  7309. }
  7310. // Regression test for https://crbug.com/737143.
  7311. // This test sets up an old TLS version just like in TLSVersionTooOld,
  7312. // and makes sure that it results in an spdy::ERROR_CODE_INADEQUATE_SECURITY
  7313. // even for a non-secure request URL.
  7314. TEST_F(SpdyNetworkTransactionTest, InsecureUrlCreatesSecureSpdySession) {
  7315. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  7316. SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
  7317. &ssl_provider->ssl_info.connection_status);
  7318. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  7319. 0, spdy::ERROR_CODE_INADEQUATE_SECURITY, ""));
  7320. MockWrite writes[] = {CreateMockWrite(goaway)};
  7321. StaticSocketDataProvider data(base::span<MockRead>(), writes);
  7322. request_.url = GURL("http://www.example.org/");
  7323. // Need secure proxy so that insecure URL can use HTTP/2.
  7324. auto session_deps = std::make_unique<SpdySessionDependencies>(
  7325. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  7326. "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  7327. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  7328. std::move(session_deps));
  7329. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  7330. TransactionHelperResult out = helper.output();
  7331. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY));
  7332. }
  7333. TEST_F(SpdyNetworkTransactionTest, RequestHeadersCallback) {
  7334. spdy::SpdySerializedFrame req(
  7335. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
  7336. MockWrite writes[] = {CreateMockWrite(req, 0)};
  7337. spdy::SpdySerializedFrame resp(
  7338. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7339. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7340. MockRead reads[] = {
  7341. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7342. MockRead(ASYNC, 0, 3) // EOF
  7343. };
  7344. HttpRawRequestHeaders raw_headers;
  7345. SequencedSocketData data(reads, writes);
  7346. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7347. helper.RunPreTestSetup();
  7348. helper.AddData(&data);
  7349. helper.trans()->SetRequestHeadersCallback(base::BindRepeating(
  7350. &HttpRawRequestHeaders::Assign, base::Unretained(&raw_headers)));
  7351. helper.StartDefaultTest();
  7352. helper.FinishDefaultTestWithoutVerification();
  7353. EXPECT_FALSE(raw_headers.headers().empty());
  7354. std::string value;
  7355. EXPECT_TRUE(raw_headers.FindHeaderForTest(":path", &value));
  7356. EXPECT_EQ("/", value);
  7357. EXPECT_TRUE(raw_headers.FindHeaderForTest(":method", &value));
  7358. EXPECT_EQ("GET", value);
  7359. EXPECT_TRUE(raw_headers.request_line().empty());
  7360. }
  7361. // A request that has adopted a push promise and later got reset by the server
  7362. // should be retried on a new stream.
  7363. // Regression test for https://crbug.com/798508.
  7364. TEST_F(SpdyNetworkTransactionTest, PushCanceledByServerAfterClaimed) {
  7365. const char pushed_url[] = "https://www.example.org/a.dat";
  7366. // Construct a request to the default URL on stream 1.
  7367. spdy::SpdySerializedFrame req(
  7368. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  7369. spdy::SpdySerializedFrame req2(
  7370. spdy_util_.ConstructSpdyGet(pushed_url, 3, LOWEST));
  7371. // Construct a priority frame for stream 2.
  7372. spdy::SpdySerializedFrame priority(
  7373. spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  7374. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
  7375. CreateMockWrite(req2, 6)};
  7376. // Construct a Push Promise frame, with no response.
  7377. spdy::SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
  7378. 1, 2, spdy_util_.ConstructGetHeaderBlock(pushed_url)));
  7379. // Construct a RST frame, canceling stream 2.
  7380. spdy::SpdySerializedFrame rst_server(
  7381. spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL));
  7382. // Construct response headers and bodies.
  7383. spdy::SpdySerializedFrame resp1(
  7384. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7385. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  7386. spdy::SpdySerializedFrame resp2(
  7387. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  7388. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  7389. MockRead reads[] = {
  7390. CreateMockRead(push_promise, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
  7391. CreateMockRead(rst_server, 4), MockRead(ASYNC, ERR_IO_PENDING, 5),
  7392. CreateMockRead(resp1, 7), CreateMockRead(body1, 8),
  7393. CreateMockRead(resp2, 9), CreateMockRead(body2, 10),
  7394. MockRead(ASYNC, 0, 11)};
  7395. SequencedSocketData data(reads, writes);
  7396. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7397. helper.RunPreTestSetup();
  7398. helper.AddData(&data);
  7399. HttpNetworkTransaction* trans = helper.trans();
  7400. // First request to start the connection.
  7401. TestCompletionCallback callback1;
  7402. int rv = trans->Start(&request_, callback1.callback(), log_);
  7403. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  7404. data.RunUntilPaused();
  7405. // Get a SpdySession.
  7406. SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
  7407. PRIVACY_MODE_DISABLED,
  7408. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  7409. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7410. HttpNetworkSession* session = helper.session();
  7411. base::WeakPtr<SpdySession> spdy_session =
  7412. session->spdy_session_pool()->FindAvailableSession(
  7413. key, /* enable_ip_based_pooling = */ true,
  7414. /* is_websocket = */ false, log_);
  7415. // Verify that there is one unclaimed push stream.
  7416. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
  7417. // Claim the pushed stream.
  7418. HttpNetworkTransaction transaction2(DEFAULT_PRIORITY, session);
  7419. TestCompletionCallback callback2;
  7420. HttpRequestInfo request2;
  7421. request2.method = "GET";
  7422. request2.url = GURL(pushed_url);
  7423. request2.traffic_annotation =
  7424. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  7425. transaction2.Start(&request2, callback2.callback(), log_);
  7426. base::RunLoop().RunUntilIdle();
  7427. EXPECT_EQ(3u, spdy_stream_hi_water_mark(spdy_session));
  7428. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
  7429. // Continue reading and get the RST.
  7430. data.Resume();
  7431. base::RunLoop().RunUntilIdle();
  7432. // Make sure we got the RST and retried the request.
  7433. EXPECT_EQ(2u, num_active_streams(spdy_session));
  7434. EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
  7435. EXPECT_EQ(5u, spdy_stream_hi_water_mark(spdy_session));
  7436. data.Resume();
  7437. // Test that transactions succeeded.
  7438. rv = callback1.WaitForResult();
  7439. ASSERT_THAT(rv, IsOk());
  7440. rv = callback2.WaitForResult();
  7441. ASSERT_THAT(rv, IsOk());
  7442. // Read EOF.
  7443. base::RunLoop().RunUntilIdle();
  7444. // Verify that all data was read and written.
  7445. helper.VerifyDataConsumed();
  7446. }
  7447. #if BUILDFLAG(ENABLE_WEBSOCKETS)
  7448. TEST_F(SpdyNetworkTransactionTest, WebSocketOpensNewConnection) {
  7449. base::HistogramTester histogram_tester;
  7450. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  7451. helper.RunPreTestSetup();
  7452. // First request opens up an HTTP/2 connection.
  7453. spdy::SpdySerializedFrame req(
  7454. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
  7455. MockWrite writes1[] = {CreateMockWrite(req, 0)};
  7456. spdy::SpdySerializedFrame resp(
  7457. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7458. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  7459. MockRead reads1[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
  7460. MockRead(ASYNC, ERR_IO_PENDING, 3),
  7461. MockRead(ASYNC, 0, 4)};
  7462. SequencedSocketData data1(reads1, writes1);
  7463. helper.AddData(&data1);
  7464. // WebSocket request opens a new connection with HTTP/2 disabled.
  7465. MockWrite writes2[] = {
  7466. MockWrite("GET / HTTP/1.1\r\n"
  7467. "Host: www.example.org\r\n"
  7468. "Connection: Upgrade\r\n"
  7469. "Upgrade: websocket\r\n"
  7470. "Origin: http://www.example.org\r\n"
  7471. "Sec-WebSocket-Version: 13\r\n"
  7472. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  7473. "Sec-WebSocket-Extensions: permessage-deflate; "
  7474. "client_max_window_bits\r\n\r\n")};
  7475. MockRead reads2[] = {
  7476. MockRead("HTTP/1.1 101 Switching Protocols\r\n"
  7477. "Upgrade: websocket\r\n"
  7478. "Connection: Upgrade\r\n"
  7479. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
  7480. StaticSocketDataProvider data2(reads2, writes2);
  7481. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  7482. // Test that the request has HTTP/2 disabled.
  7483. ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
  7484. // Force socket to use HTTP/1.1, the default protocol without ALPN.
  7485. ssl_provider2->next_proto = kProtoHTTP11;
  7486. ssl_provider2->ssl_info.cert =
  7487. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  7488. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  7489. TestCompletionCallback callback1;
  7490. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  7491. int rv = trans1.Start(&request_, callback1.callback(), log_);
  7492. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7493. rv = callback1.WaitForResult();
  7494. ASSERT_THAT(rv, IsOk());
  7495. const HttpResponseInfo* response = trans1.GetResponseInfo();
  7496. ASSERT_TRUE(response->headers);
  7497. EXPECT_TRUE(response->was_fetched_via_spdy);
  7498. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  7499. std::string response_data;
  7500. rv = ReadTransaction(&trans1, &response_data);
  7501. EXPECT_THAT(rv, IsOk());
  7502. EXPECT_EQ("hello!", response_data);
  7503. SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
  7504. PRIVACY_MODE_DISABLED,
  7505. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  7506. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7507. base::WeakPtr<SpdySession> spdy_session =
  7508. helper.session()->spdy_session_pool()->FindAvailableSession(
  7509. key, /* enable_ip_based_pooling = */ true,
  7510. /* is_websocket = */ false, log_);
  7511. ASSERT_TRUE(spdy_session);
  7512. EXPECT_FALSE(spdy_session->support_websocket());
  7513. HttpRequestInfo request2;
  7514. request2.method = "GET";
  7515. request2.url = GURL("wss://www.example.org/");
  7516. request2.traffic_annotation =
  7517. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  7518. EXPECT_TRUE(HostPortPair::FromURL(request_.url)
  7519. .Equals(HostPortPair::FromURL(request2.url)));
  7520. request2.extra_headers.SetHeader("Connection", "Upgrade");
  7521. request2.extra_headers.SetHeader("Upgrade", "websocket");
  7522. request2.extra_headers.SetHeader("Origin", "http://www.example.org");
  7523. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  7524. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  7525. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  7526. trans2.SetWebSocketHandshakeStreamCreateHelper(
  7527. &websocket_stream_create_helper);
  7528. TestCompletionCallback callback2;
  7529. rv = trans2.Start(&request2, callback2.callback(), log_);
  7530. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7531. rv = callback2.WaitForResult();
  7532. ASSERT_THAT(rv, IsOk());
  7533. // HTTP/2 connection is still open, but WebSocket request did not pool to it.
  7534. ASSERT_TRUE(spdy_session);
  7535. data1.Resume();
  7536. base::RunLoop().RunUntilIdle();
  7537. helper.VerifyDataConsumed();
  7538. // Server did not advertise WebSocket support.
  7539. histogram_tester.ExpectUniqueSample("Net.SpdySession.ServerSupportsWebSocket",
  7540. /* support_websocket = false */ 0,
  7541. /* expected_count = */ 1);
  7542. }
  7543. // Make sure that a WebSocket job doesn't pick up a newly created SpdySession
  7544. // that doesn't support WebSockets through
  7545. // HttpStreamFactory::Job::OnSpdySessionAvailable().
  7546. TEST_F(SpdyNetworkTransactionTest,
  7547. WebSocketDoesUseNewH2SessionWithoutWebSocketSupport) {
  7548. base::HistogramTester histogram_tester;
  7549. auto session_deps = std::make_unique<SpdySessionDependencies>();
  7550. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
  7551. std::move(session_deps));
  7552. helper.RunPreTestSetup();
  7553. spdy::SpdySerializedFrame req(
  7554. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  7555. MockWrite writes[] = {CreateMockWrite(req, 0)};
  7556. spdy::SpdySerializedFrame resp1(
  7557. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7558. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  7559. MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  7560. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
  7561. SequencedSocketData data(
  7562. // Just as with other operations, this means to pause during connection
  7563. // establishment.
  7564. MockConnect(ASYNC, ERR_IO_PENDING), reads, writes);
  7565. helper.AddData(&data);
  7566. MockWrite writes2[] = {
  7567. MockWrite(SYNCHRONOUS, 0,
  7568. "GET / HTTP/1.1\r\n"
  7569. "Host: www.example.org\r\n"
  7570. "Connection: Upgrade\r\n"
  7571. "Upgrade: websocket\r\n"
  7572. "Origin: http://www.example.org\r\n"
  7573. "Sec-WebSocket-Version: 13\r\n"
  7574. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  7575. "Sec-WebSocket-Extensions: permessage-deflate; "
  7576. "client_max_window_bits\r\n\r\n")};
  7577. MockRead reads2[] = {
  7578. MockRead(SYNCHRONOUS, 1,
  7579. "HTTP/1.1 101 Switching Protocols\r\n"
  7580. "Upgrade: websocket\r\n"
  7581. "Connection: Upgrade\r\n"
  7582. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
  7583. SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2,
  7584. writes2);
  7585. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  7586. // Test that the request has HTTP/2 disabled.
  7587. ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
  7588. // Force socket to use HTTP/1.1, the default protocol without ALPN.
  7589. ssl_provider2->next_proto = kProtoHTTP11;
  7590. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  7591. TestCompletionCallback callback1;
  7592. int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
  7593. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7594. // Create HTTP/2 connection.
  7595. base::RunLoop().RunUntilIdle();
  7596. HttpRequestInfo request2;
  7597. request2.method = "GET";
  7598. request2.url = GURL("wss://www.example.org/");
  7599. request2.traffic_annotation =
  7600. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  7601. EXPECT_TRUE(HostPortPair::FromURL(request_.url)
  7602. .Equals(HostPortPair::FromURL(request2.url)));
  7603. request2.extra_headers.SetHeader("Connection", "Upgrade");
  7604. request2.extra_headers.SetHeader("Upgrade", "websocket");
  7605. request2.extra_headers.SetHeader("Origin", "http://www.example.org");
  7606. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  7607. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  7608. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  7609. trans2.SetWebSocketHandshakeStreamCreateHelper(
  7610. &websocket_stream_create_helper);
  7611. TestCompletionCallback callback2;
  7612. rv = trans2.Start(&request2, callback2.callback(), log_);
  7613. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7614. // Run until waiting on both connections.
  7615. base::RunLoop().RunUntilIdle();
  7616. // The H2 connection completes.
  7617. data.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
  7618. EXPECT_EQ(OK, callback1.WaitForResult());
  7619. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  7620. ASSERT_TRUE(response->headers);
  7621. EXPECT_TRUE(response->was_fetched_via_spdy);
  7622. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  7623. std::string response_data;
  7624. rv = ReadTransaction(helper.trans(), &response_data);
  7625. EXPECT_THAT(rv, IsOk());
  7626. EXPECT_EQ("hello!", response_data);
  7627. SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
  7628. PRIVACY_MODE_DISABLED,
  7629. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  7630. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7631. base::WeakPtr<SpdySession> spdy_session =
  7632. helper.session()->spdy_session_pool()->FindAvailableSession(
  7633. key, /* enable_ip_based_pooling = */ true,
  7634. /* is_websocket = */ false, log_);
  7635. ASSERT_TRUE(spdy_session);
  7636. EXPECT_FALSE(spdy_session->support_websocket());
  7637. EXPECT_FALSE(callback2.have_result());
  7638. // Create WebSocket stream.
  7639. data2.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
  7640. rv = callback2.WaitForResult();
  7641. ASSERT_THAT(rv, IsOk());
  7642. helper.VerifyDataConsumed();
  7643. }
  7644. TEST_F(SpdyNetworkTransactionTest, WebSocketOverHTTP2) {
  7645. base::HistogramTester histogram_tester;
  7646. auto session_deps = std::make_unique<SpdySessionDependencies>();
  7647. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
  7648. std::move(session_deps));
  7649. helper.RunPreTestSetup();
  7650. spdy::SpdySerializedFrame req(
  7651. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  7652. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  7653. spdy::Http2HeaderBlock websocket_request_headers;
  7654. websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
  7655. websocket_request_headers[spdy::kHttp2AuthorityHeader] = "www.example.org";
  7656. websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
  7657. websocket_request_headers[spdy::kHttp2PathHeader] = "/";
  7658. websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
  7659. websocket_request_headers["origin"] = "http://www.example.org";
  7660. websocket_request_headers["sec-websocket-version"] = "13";
  7661. websocket_request_headers["sec-websocket-extensions"] =
  7662. "permessage-deflate; client_max_window_bits";
  7663. spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
  7664. 3, std::move(websocket_request_headers), MEDIUM, false));
  7665. spdy::SpdySerializedFrame priority1(
  7666. spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
  7667. spdy::SpdySerializedFrame priority2(
  7668. spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
  7669. MockWrite writes[] = {
  7670. CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 2),
  7671. CreateMockWrite(websocket_request, 4), CreateMockWrite(priority1, 5),
  7672. CreateMockWrite(priority2, 6)};
  7673. spdy::SettingsMap settings;
  7674. settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
  7675. spdy::SpdySerializedFrame settings_frame(
  7676. spdy_util_.ConstructSpdySettings(settings));
  7677. spdy::SpdySerializedFrame resp1(
  7678. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7679. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  7680. spdy::SpdySerializedFrame websocket_response(
  7681. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  7682. MockRead reads[] = {CreateMockRead(settings_frame, 1),
  7683. CreateMockRead(resp1, 3), CreateMockRead(body1, 7),
  7684. CreateMockRead(websocket_response, 8),
  7685. MockRead(ASYNC, 0, 9)};
  7686. SequencedSocketData data(reads, writes);
  7687. helper.AddData(&data);
  7688. TestCompletionCallback callback1;
  7689. int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
  7690. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7691. // Create HTTP/2 connection.
  7692. base::RunLoop().RunUntilIdle();
  7693. SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
  7694. PRIVACY_MODE_DISABLED,
  7695. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  7696. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7697. base::WeakPtr<SpdySession> spdy_session =
  7698. helper.session()->spdy_session_pool()->FindAvailableSession(
  7699. key, /* enable_ip_based_pooling = */ true,
  7700. /* is_websocket = */ true, log_);
  7701. ASSERT_TRUE(spdy_session);
  7702. EXPECT_TRUE(spdy_session->support_websocket());
  7703. HttpRequestInfo request2;
  7704. request2.method = "GET";
  7705. request2.url = GURL("wss://www.example.org/");
  7706. request2.traffic_annotation =
  7707. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  7708. EXPECT_TRUE(HostPortPair::FromURL(request_.url)
  7709. .Equals(HostPortPair::FromURL(request2.url)));
  7710. request2.extra_headers.SetHeader("Origin", "http://www.example.org");
  7711. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  7712. // The following two headers must be removed by WebSocketHttp2HandshakeStream.
  7713. request2.extra_headers.SetHeader("Connection", "Upgrade");
  7714. request2.extra_headers.SetHeader("Upgrade", "websocket");
  7715. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  7716. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  7717. trans2.SetWebSocketHandshakeStreamCreateHelper(
  7718. &websocket_stream_create_helper);
  7719. TestCompletionCallback callback2;
  7720. rv = trans2.Start(&request2, callback2.callback(), log_);
  7721. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7722. // Create WebSocket stream.
  7723. base::RunLoop().RunUntilIdle();
  7724. ASSERT_TRUE(spdy_session);
  7725. // First request has HIGHEST priority, WebSocket request has MEDIUM priority.
  7726. // Changing the priority of the first request to LOWEST changes their order,
  7727. // and therefore triggers sending PRIORITY frames.
  7728. helper.trans()->SetPriority(LOWEST);
  7729. rv = callback1.WaitForResult();
  7730. ASSERT_THAT(rv, IsOk());
  7731. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  7732. ASSERT_TRUE(response->headers);
  7733. EXPECT_TRUE(response->was_fetched_via_spdy);
  7734. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  7735. std::string response_data;
  7736. rv = ReadTransaction(helper.trans(), &response_data);
  7737. EXPECT_THAT(rv, IsOk());
  7738. EXPECT_EQ("hello!", response_data);
  7739. rv = callback2.WaitForResult();
  7740. ASSERT_THAT(rv, IsOk());
  7741. helper.VerifyDataConsumed();
  7742. // Server advertised WebSocket support.
  7743. histogram_tester.ExpectUniqueSample("Net.SpdySession.ServerSupportsWebSocket",
  7744. /* support_websocket = true */ 1,
  7745. /* expected_count = */ 1);
  7746. }
  7747. // Make sure that a WebSocket job doesn't pick up a newly created SpdySession
  7748. // that supports WebSockets through an HTTPS proxy when an H2 server doesn't
  7749. // support websockets. See https://crbug.com/1010491.
  7750. TEST_F(SpdyNetworkTransactionTest,
  7751. WebSocketDoesNotUseNewH2SessionWithoutWebSocketSupportOverHttpsProxy) {
  7752. auto session_deps = std::make_unique<SpdySessionDependencies>(
  7753. ConfiguredProxyResolutionService::CreateFixedForTest(
  7754. "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  7755. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
  7756. std::move(session_deps));
  7757. helper.RunPreTestSetup();
  7758. spdy::SpdySerializedFrame req(
  7759. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  7760. MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0,
  7761. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  7762. "Host: www.example.org:443\r\n"
  7763. "Proxy-Connection: keep-alive\r\n\r\n"),
  7764. CreateMockWrite(req, 2)};
  7765. spdy::SpdySerializedFrame resp1(
  7766. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7767. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  7768. MockRead reads[] = {MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
  7769. CreateMockRead(resp1, 3), CreateMockRead(body1, 4),
  7770. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
  7771. // SSL data for the proxy.
  7772. SSLSocketDataProvider tunnel_ssl_data(ASYNC, OK);
  7773. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  7774. &tunnel_ssl_data);
  7775. SequencedSocketData data(
  7776. // Just as with other operations, this means to pause during connection
  7777. // establishment.
  7778. MockConnect(ASYNC, ERR_IO_PENDING), reads, writes);
  7779. helper.AddData(&data);
  7780. MockWrite writes2[] = {
  7781. MockWrite(SYNCHRONOUS, 0,
  7782. "CONNECT www.example.org:443 HTTP/1.1\r\n"
  7783. "Host: www.example.org:443\r\n"
  7784. "Proxy-Connection: keep-alive\r\n\r\n"),
  7785. MockWrite(SYNCHRONOUS, 2,
  7786. "GET / HTTP/1.1\r\n"
  7787. "Host: www.example.org\r\n"
  7788. "Connection: Upgrade\r\n"
  7789. "Upgrade: websocket\r\n"
  7790. "Origin: http://www.example.org\r\n"
  7791. "Sec-WebSocket-Version: 13\r\n"
  7792. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  7793. "Sec-WebSocket-Extensions: permessage-deflate; "
  7794. "client_max_window_bits\r\n\r\n")};
  7795. MockRead reads2[] = {
  7796. MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
  7797. MockRead(SYNCHRONOUS, 3,
  7798. "HTTP/1.1 101 Switching Protocols\r\n"
  7799. "Upgrade: websocket\r\n"
  7800. "Connection: Upgrade\r\n"
  7801. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
  7802. SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2,
  7803. writes2);
  7804. // SSL data for the proxy.
  7805. SSLSocketDataProvider tunnel_ssl_data2(ASYNC, OK);
  7806. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  7807. &tunnel_ssl_data2);
  7808. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  7809. // Test that the request has HTTP/2 disabled.
  7810. ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
  7811. // Force socket to use HTTP/1.1, the default protocol without ALPN.
  7812. ssl_provider2->next_proto = kProtoHTTP11;
  7813. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  7814. TestCompletionCallback callback1;
  7815. int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
  7816. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7817. // Create HTTP/2 connection.
  7818. base::RunLoop().RunUntilIdle();
  7819. HttpRequestInfo request2;
  7820. request2.method = "GET";
  7821. request2.url = GURL("wss://www.example.org/");
  7822. request2.traffic_annotation =
  7823. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  7824. EXPECT_TRUE(HostPortPair::FromURL(request_.url)
  7825. .Equals(HostPortPair::FromURL(request2.url)));
  7826. request2.extra_headers.SetHeader("Connection", "Upgrade");
  7827. request2.extra_headers.SetHeader("Upgrade", "websocket");
  7828. request2.extra_headers.SetHeader("Origin", "http://www.example.org");
  7829. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  7830. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  7831. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  7832. trans2.SetWebSocketHandshakeStreamCreateHelper(
  7833. &websocket_stream_create_helper);
  7834. TestCompletionCallback callback2;
  7835. rv = trans2.Start(&request2, callback2.callback(), log_);
  7836. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7837. // Run until waiting on both connections.
  7838. base::RunLoop().RunUntilIdle();
  7839. // The H2 connection completes.
  7840. data.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
  7841. EXPECT_EQ(OK, callback1.WaitForResult());
  7842. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  7843. ASSERT_TRUE(response->headers);
  7844. EXPECT_TRUE(response->was_fetched_via_spdy);
  7845. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  7846. std::string response_data;
  7847. rv = ReadTransaction(helper.trans(), &response_data);
  7848. EXPECT_THAT(rv, IsOk());
  7849. EXPECT_EQ("hello!", response_data);
  7850. SpdySessionKey key(
  7851. HostPortPair::FromURL(request_.url),
  7852. ProxyUriToProxyServer("https://proxy:70", ProxyServer::SCHEME_HTTPS),
  7853. PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse,
  7854. SocketTag(), NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7855. base::WeakPtr<SpdySession> spdy_session =
  7856. helper.session()->spdy_session_pool()->FindAvailableSession(
  7857. key, /* enable_ip_based_pooling = */ true,
  7858. /* is_websocket = */ false, log_);
  7859. ASSERT_TRUE(spdy_session);
  7860. EXPECT_FALSE(spdy_session->support_websocket());
  7861. EXPECT_FALSE(callback2.have_result());
  7862. // Create WebSocket stream.
  7863. data2.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK));
  7864. rv = callback2.WaitForResult();
  7865. ASSERT_THAT(rv, IsOk());
  7866. helper.VerifyDataConsumed();
  7867. }
  7868. // Same as above, but checks that a WebSocket connection avoids creating a new
  7869. // socket if it detects an H2 session when host resolution completes, and
  7870. // requests also use different hostnames.
  7871. TEST_F(SpdyNetworkTransactionTest,
  7872. WebSocketOverHTTP2DetectsNewSessionWithAliasing) {
  7873. base::HistogramTester histogram_tester;
  7874. auto session_deps = std::make_unique<SpdySessionDependencies>();
  7875. session_deps->host_resolver->set_ondemand_mode(true);
  7876. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
  7877. std::move(session_deps));
  7878. helper.RunPreTestSetup();
  7879. spdy::SpdySerializedFrame req(
  7880. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  7881. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  7882. spdy::Http2HeaderBlock websocket_request_headers;
  7883. websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
  7884. websocket_request_headers[spdy::kHttp2AuthorityHeader] = "example.test";
  7885. websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
  7886. websocket_request_headers[spdy::kHttp2PathHeader] = "/";
  7887. websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
  7888. websocket_request_headers["origin"] = "http://example.test";
  7889. websocket_request_headers["sec-websocket-version"] = "13";
  7890. websocket_request_headers["sec-websocket-extensions"] =
  7891. "permessage-deflate; client_max_window_bits";
  7892. spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
  7893. 3, std::move(websocket_request_headers), MEDIUM, false));
  7894. spdy::SpdySerializedFrame priority1(
  7895. spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
  7896. spdy::SpdySerializedFrame priority2(
  7897. spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
  7898. MockWrite writes[] = {
  7899. CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 2),
  7900. CreateMockWrite(websocket_request, 4), CreateMockWrite(priority1, 5),
  7901. CreateMockWrite(priority2, 6)};
  7902. spdy::SettingsMap settings;
  7903. settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
  7904. spdy::SpdySerializedFrame settings_frame(
  7905. spdy_util_.ConstructSpdySettings(settings));
  7906. spdy::SpdySerializedFrame resp1(
  7907. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  7908. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  7909. spdy::SpdySerializedFrame websocket_response(
  7910. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  7911. MockRead reads[] = {CreateMockRead(settings_frame, 1),
  7912. CreateMockRead(resp1, 3), CreateMockRead(body1, 7),
  7913. CreateMockRead(websocket_response, 8),
  7914. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 9)};
  7915. SequencedSocketData data(reads, writes);
  7916. helper.AddData(&data);
  7917. TestCompletionCallback callback1;
  7918. int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
  7919. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7920. HttpRequestInfo request2;
  7921. request2.method = "GET";
  7922. request2.url = GURL("wss://example.test/");
  7923. request2.traffic_annotation =
  7924. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  7925. request2.extra_headers.SetHeader("Origin", "http://example.test");
  7926. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  7927. // The following two headers must be removed by WebSocketHttp2HandshakeStream.
  7928. request2.extra_headers.SetHeader("Connection", "Upgrade");
  7929. request2.extra_headers.SetHeader("Upgrade", "websocket");
  7930. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  7931. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  7932. trans2.SetWebSocketHandshakeStreamCreateHelper(
  7933. &websocket_stream_create_helper);
  7934. TestCompletionCallback callback2;
  7935. rv = trans2.Start(&request2, callback2.callback(), log_);
  7936. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  7937. // Make sure both requests are blocked on host resolution.
  7938. base::RunLoop().RunUntilIdle();
  7939. EXPECT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
  7940. // Complete the first DNS lookup, which should result in the first transaction
  7941. // creating an H2 session (And completing successfully).
  7942. helper.session_deps()->host_resolver->ResolveNow(1);
  7943. base::RunLoop().RunUntilIdle();
  7944. SpdySessionKey key1(HostPortPair::FromURL(request_.url),
  7945. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  7946. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  7947. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7948. EXPECT_TRUE(helper.session()->spdy_session_pool()->HasAvailableSession(
  7949. key1, /* is_websocket = */ false));
  7950. base::WeakPtr<SpdySession> spdy_session1 =
  7951. helper.session()->spdy_session_pool()->FindAvailableSession(
  7952. key1, /* enable_ip_based_pooling = */ true,
  7953. /* is_websocket = */ false, log_);
  7954. ASSERT_TRUE(spdy_session1);
  7955. EXPECT_TRUE(spdy_session1->support_websocket());
  7956. // Second DNS lookup completes, which results in creating a WebSocket stream.
  7957. helper.session_deps()->host_resolver->ResolveNow(2);
  7958. ASSERT_TRUE(spdy_session1);
  7959. SpdySessionKey key2(HostPortPair::FromURL(request2.url),
  7960. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  7961. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  7962. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  7963. EXPECT_TRUE(helper.session()->spdy_session_pool()->HasAvailableSession(
  7964. key2, /* is_websocket = */ true));
  7965. base::WeakPtr<SpdySession> spdy_session2 =
  7966. helper.session()->spdy_session_pool()->FindAvailableSession(
  7967. key1, /* enable_ip_based_pooling = */ true,
  7968. /* is_websocket = */ true, log_);
  7969. ASSERT_TRUE(spdy_session2);
  7970. EXPECT_EQ(spdy_session1.get(), spdy_session2.get());
  7971. base::RunLoop().RunUntilIdle();
  7972. // First request has HIGHEST priority, WebSocket request has MEDIUM priority.
  7973. // Changing the priority of the first request to LOWEST changes their order,
  7974. // and therefore triggers sending PRIORITY frames.
  7975. helper.trans()->SetPriority(LOWEST);
  7976. rv = callback1.WaitForResult();
  7977. ASSERT_THAT(rv, IsOk());
  7978. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  7979. ASSERT_TRUE(response->headers);
  7980. EXPECT_TRUE(response->was_fetched_via_spdy);
  7981. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  7982. std::string response_data;
  7983. rv = ReadTransaction(helper.trans(), &response_data);
  7984. EXPECT_THAT(rv, IsOk());
  7985. EXPECT_EQ("hello!", response_data);
  7986. rv = callback2.WaitForResult();
  7987. ASSERT_THAT(rv, IsOk());
  7988. helper.VerifyDataConsumed();
  7989. }
  7990. // Same as above, but the SpdySession is closed just before use, so the
  7991. // WebSocket is sent over a new HTTP/1.x connection instead.
  7992. TEST_F(SpdyNetworkTransactionTest,
  7993. WebSocketOverDetectsNewSessionWithAliasingButClosedBeforeUse) {
  7994. base::HistogramTester histogram_tester;
  7995. auto session_deps = std::make_unique<SpdySessionDependencies>();
  7996. session_deps->host_resolver->set_ondemand_mode(true);
  7997. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
  7998. std::move(session_deps));
  7999. helper.RunPreTestSetup();
  8000. spdy::SpdySerializedFrame req(
  8001. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  8002. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  8003. MockWrite writes[] = {CreateMockWrite(req, 0),
  8004. CreateMockWrite(settings_ack, 2)};
  8005. spdy::SettingsMap settings;
  8006. settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
  8007. spdy::SpdySerializedFrame settings_frame(
  8008. spdy_util_.ConstructSpdySettings(settings));
  8009. spdy::SpdySerializedFrame resp1(
  8010. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8011. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  8012. MockRead reads[] = {CreateMockRead(settings_frame, 1),
  8013. CreateMockRead(resp1, 3), CreateMockRead(body1, 4),
  8014. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
  8015. SequencedSocketData data(reads, writes);
  8016. helper.AddData(&data);
  8017. MockWrite writes2[] = {
  8018. MockWrite("GET / HTTP/1.1\r\n"
  8019. "Host: example.test\r\n"
  8020. "Connection: Upgrade\r\n"
  8021. "Upgrade: websocket\r\n"
  8022. "Origin: http://example.test\r\n"
  8023. "Sec-WebSocket-Version: 13\r\n"
  8024. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  8025. "Sec-WebSocket-Extensions: permessage-deflate; "
  8026. "client_max_window_bits\r\n\r\n")};
  8027. MockRead reads2[] = {
  8028. MockRead("HTTP/1.1 101 Switching Protocols\r\n"
  8029. "Upgrade: websocket\r\n"
  8030. "Connection: Upgrade\r\n"
  8031. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
  8032. StaticSocketDataProvider data2(reads2, writes2);
  8033. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8034. // Test that the request has HTTP/2 disabled.
  8035. ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
  8036. // Force socket to use HTTP/1.1, the default protocol without ALPN.
  8037. ssl_provider2->next_proto = kProtoHTTP11;
  8038. ssl_provider2->ssl_info.cert =
  8039. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  8040. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  8041. TestCompletionCallback callback1;
  8042. int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
  8043. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  8044. HttpRequestInfo request2;
  8045. request2.method = "GET";
  8046. request2.url = GURL("wss://example.test/");
  8047. request2.traffic_annotation =
  8048. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8049. request2.extra_headers.SetHeader("Connection", "Upgrade");
  8050. request2.extra_headers.SetHeader("Upgrade", "websocket");
  8051. request2.extra_headers.SetHeader("Origin", "http://example.test");
  8052. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  8053. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  8054. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  8055. trans2.SetWebSocketHandshakeStreamCreateHelper(
  8056. &websocket_stream_create_helper);
  8057. TestCompletionCallback callback2;
  8058. rv = trans2.Start(&request2, callback2.callback(), log_);
  8059. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  8060. // Make sure both requests are blocked on host resolution.
  8061. base::RunLoop().RunUntilIdle();
  8062. EXPECT_TRUE(helper.session_deps()->host_resolver->has_pending_requests());
  8063. // Complete the first DNS lookup, which should result in the first transaction
  8064. // creating an H2 session (And completing successfully).
  8065. helper.session_deps()->host_resolver->ResolveNow(1);
  8066. // Complete first request.
  8067. rv = callback1.WaitForResult();
  8068. ASSERT_THAT(rv, IsOk());
  8069. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  8070. ASSERT_TRUE(response->headers);
  8071. EXPECT_TRUE(response->was_fetched_via_spdy);
  8072. EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
  8073. std::string response_data;
  8074. rv = ReadTransaction(helper.trans(), &response_data);
  8075. EXPECT_THAT(rv, IsOk());
  8076. EXPECT_EQ("hello!", response_data);
  8077. SpdySessionKey key1(HostPortPair::FromURL(request_.url),
  8078. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  8079. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  8080. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  8081. base::WeakPtr<SpdySession> spdy_session1 =
  8082. helper.session()->spdy_session_pool()->FindAvailableSession(
  8083. key1, /* enable_ip_based_pooling = */ true,
  8084. /* is_websocket = */ false, log_);
  8085. ASSERT_TRUE(spdy_session1);
  8086. EXPECT_TRUE(spdy_session1->support_websocket());
  8087. // Second DNS lookup completes, which results in creating an alias for the
  8088. // SpdySession immediately, and a task is posted asynchronously to use the
  8089. // alias..
  8090. helper.session_deps()->host_resolver->ResolveNow(2);
  8091. SpdySessionKey key2(HostPortPair::FromURL(request2.url),
  8092. ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
  8093. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  8094. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  8095. base::WeakPtr<SpdySession> spdy_session2 =
  8096. helper.session()->spdy_session_pool()->FindAvailableSession(
  8097. key1, /* enable_ip_based_pooling = */ true,
  8098. /* is_websocket = */ true, log_);
  8099. ASSERT_TRUE(spdy_session2);
  8100. EXPECT_EQ(spdy_session1.get(), spdy_session2.get());
  8101. // But the session is closed before it can be used.
  8102. helper.session()->spdy_session_pool()->CloseAllSessions();
  8103. // The second request establishes another connection (without even doing
  8104. // another DNS lookup) instead, and uses HTTP/1.x.
  8105. rv = callback2.WaitForResult();
  8106. ASSERT_THAT(rv, IsOk());
  8107. helper.VerifyDataConsumed();
  8108. }
  8109. TEST_F(SpdyNetworkTransactionTest, WebSocketNegotiatesHttp2) {
  8110. HttpRequestInfo request;
  8111. request.method = "GET";
  8112. request.url = GURL("wss://www.example.org/");
  8113. request.traffic_annotation =
  8114. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8115. EXPECT_TRUE(HostPortPair::FromURL(request_.url)
  8116. .Equals(HostPortPair::FromURL(request.url)));
  8117. request.extra_headers.SetHeader("Connection", "Upgrade");
  8118. request.extra_headers.SetHeader("Upgrade", "websocket");
  8119. request.extra_headers.SetHeader("Origin", "http://www.example.org");
  8120. request.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  8121. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  8122. helper.RunPreTestSetup();
  8123. StaticSocketDataProvider data;
  8124. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8125. // Test that the request has HTTP/2 disabled.
  8126. ssl_provider->next_protos_expected_in_ssl_config = {kProtoHTTP11};
  8127. // Force socket to use HTTP/2, which should never happen (TLS implementation
  8128. // should fail TLS handshake if server chooses HTTP/2 without client
  8129. // advertising support).
  8130. ssl_provider->next_proto = kProtoHTTP2;
  8131. ssl_provider->ssl_info.cert =
  8132. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  8133. helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
  8134. HttpNetworkTransaction* trans = helper.trans();
  8135. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  8136. trans->SetWebSocketHandshakeStreamCreateHelper(
  8137. &websocket_stream_create_helper);
  8138. TestCompletionCallback callback;
  8139. int rv = trans->Start(&request, callback.callback(), log_);
  8140. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  8141. rv = callback.WaitForResult();
  8142. ASSERT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
  8143. helper.VerifyDataConsumed();
  8144. }
  8145. TEST_F(SpdyNetworkTransactionTest, WebSocketHttp11Required) {
  8146. base::HistogramTester histogram_tester;
  8147. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8148. NormalSpdyTransactionHelper helper(request_, HIGHEST, log_,
  8149. std::move(session_deps));
  8150. helper.RunPreTestSetup();
  8151. spdy::SpdySerializedFrame req(
  8152. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  8153. spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  8154. spdy::Http2HeaderBlock websocket_request_headers;
  8155. websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
  8156. websocket_request_headers[spdy::kHttp2AuthorityHeader] = "www.example.org";
  8157. websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
  8158. websocket_request_headers[spdy::kHttp2PathHeader] = "/";
  8159. websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
  8160. websocket_request_headers["origin"] = "http://www.example.org";
  8161. websocket_request_headers["sec-websocket-version"] = "13";
  8162. websocket_request_headers["sec-websocket-extensions"] =
  8163. "permessage-deflate; client_max_window_bits";
  8164. spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
  8165. 3, std::move(websocket_request_headers), MEDIUM, false));
  8166. spdy::SpdySerializedFrame priority1(
  8167. spdy_util_.ConstructSpdyPriority(3, 0, MEDIUM, true));
  8168. spdy::SpdySerializedFrame priority2(
  8169. spdy_util_.ConstructSpdyPriority(1, 3, LOWEST, true));
  8170. MockWrite writes1[] = {CreateMockWrite(req, 0),
  8171. CreateMockWrite(settings_ack, 2),
  8172. CreateMockWrite(websocket_request, 4)};
  8173. spdy::SettingsMap settings;
  8174. settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
  8175. spdy::SpdySerializedFrame settings_frame(
  8176. spdy_util_.ConstructSpdySettings(settings));
  8177. spdy::SpdySerializedFrame resp1(
  8178. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8179. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  8180. spdy::SpdySerializedFrame websocket_response_http11_required(
  8181. spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
  8182. MockRead reads1[] = {CreateMockRead(settings_frame, 1),
  8183. CreateMockRead(resp1, 3),
  8184. CreateMockRead(websocket_response_http11_required, 5)};
  8185. SequencedSocketData data1(reads1, writes1);
  8186. helper.AddData(&data1);
  8187. MockWrite writes2[] = {
  8188. MockWrite("GET / HTTP/1.1\r\n"
  8189. "Host: www.example.org\r\n"
  8190. "Connection: Upgrade\r\n"
  8191. "Origin: http://www.example.org\r\n"
  8192. "Sec-WebSocket-Version: 13\r\n"
  8193. "Upgrade: websocket\r\n"
  8194. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  8195. "Sec-WebSocket-Extensions: permessage-deflate; "
  8196. "client_max_window_bits\r\n\r\n")};
  8197. MockRead reads2[] = {
  8198. MockRead("HTTP/1.1 101 Switching Protocols\r\n"
  8199. "Upgrade: websocket\r\n"
  8200. "Connection: Upgrade\r\n"
  8201. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
  8202. StaticSocketDataProvider data2(reads2, writes2);
  8203. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8204. // Test that the request has HTTP/2 disabled.
  8205. ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
  8206. // Force socket to use HTTP/1.1, the default protocol without ALPN.
  8207. ssl_provider2->next_proto = kProtoHTTP11;
  8208. ssl_provider2->ssl_info.cert =
  8209. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  8210. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  8211. // Create HTTP/2 connection.
  8212. TestCompletionCallback callback1;
  8213. int rv = helper.trans()->Start(&request_, callback1.callback(), log_);
  8214. ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  8215. // Create HTTP/2 connection.
  8216. base::RunLoop().RunUntilIdle();
  8217. SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
  8218. PRIVACY_MODE_DISABLED,
  8219. SpdySessionKey::IsProxySession::kFalse, SocketTag(),
  8220. NetworkIsolationKey(), SecureDnsPolicy::kAllow);
  8221. base::WeakPtr<SpdySession> spdy_session =
  8222. helper.session()->spdy_session_pool()->FindAvailableSession(
  8223. key, /* enable_ip_based_pooling = */ true,
  8224. /* is_websocket = */ true, log_);
  8225. ASSERT_TRUE(spdy_session);
  8226. EXPECT_TRUE(spdy_session->support_websocket());
  8227. HttpRequestInfo request2;
  8228. request2.method = "GET";
  8229. request2.url = GURL("wss://www.example.org/");
  8230. request2.traffic_annotation =
  8231. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8232. EXPECT_TRUE(HostPortPair::FromURL(request_.url)
  8233. .Equals(HostPortPair::FromURL(request2.url)));
  8234. request2.extra_headers.SetHeader("Origin", "http://www.example.org");
  8235. request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  8236. // The following two headers must be removed by WebSocketHttp2HandshakeStream.
  8237. request2.extra_headers.SetHeader("Connection", "Upgrade");
  8238. request2.extra_headers.SetHeader("Upgrade", "websocket");
  8239. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  8240. HttpNetworkTransaction trans2(MEDIUM, helper.session());
  8241. trans2.SetWebSocketHandshakeStreamCreateHelper(
  8242. &websocket_stream_create_helper);
  8243. TestCompletionCallback callback2;
  8244. rv = trans2.Start(&request2, callback2.callback(), log_);
  8245. EXPECT_THAT(callback2.GetResult(rv), IsOk());
  8246. helper.VerifyDataConsumed();
  8247. // Server advertised WebSocket support.
  8248. histogram_tester.ExpectUniqueSample("Net.SpdySession.ServerSupportsWebSocket",
  8249. /* support_websocket = true */ 1,
  8250. /* expected_count = */ 1);
  8251. }
  8252. // When using an HTTP(S) proxy, plaintext WebSockets use CONNECT tunnels. This
  8253. // should work for HTTP/2 proxies.
  8254. TEST_F(SpdyNetworkTransactionTest, PlaintextWebSocketOverHttp2Proxy) {
  8255. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
  8256. nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
  8257. HostPortPair("www.example.org", 80)));
  8258. const char kWebSocketRequest[] =
  8259. "GET / HTTP/1.1\r\n"
  8260. "Host: www.example.org\r\n"
  8261. "Connection: Upgrade\r\n"
  8262. "Upgrade: websocket\r\n"
  8263. "Origin: http://www.example.org\r\n"
  8264. "Sec-WebSocket-Version: 13\r\n"
  8265. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  8266. "Sec-WebSocket-Extensions: permessage-deflate; "
  8267. "client_max_window_bits\r\n\r\n";
  8268. spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyDataFrame(
  8269. /*stream_id=*/1, kWebSocketRequest, /*fin=*/false));
  8270. MockWrite writes[] = {CreateMockWrite(req, 0),
  8271. CreateMockWrite(websocket_request, 2)};
  8272. spdy::SpdySerializedFrame connect_response(
  8273. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8274. const char kWebSocketResponse[] =
  8275. "HTTP/1.1 101 Switching Protocols\r\n"
  8276. "Upgrade: websocket\r\n"
  8277. "Connection: Upgrade\r\n"
  8278. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
  8279. spdy::SpdySerializedFrame websocket_response(
  8280. spdy_util_.ConstructSpdyDataFrame(/*stream_id=*/1, kWebSocketResponse,
  8281. /*fin=*/false));
  8282. MockRead reads[] = {CreateMockRead(connect_response, 1),
  8283. CreateMockRead(websocket_response, 3),
  8284. MockRead(ASYNC, 0, 4)};
  8285. SequencedSocketData data(reads, writes);
  8286. request_.url = GURL("ws://www.example.org/");
  8287. request_.extra_headers.SetHeader("Connection", "Upgrade");
  8288. request_.extra_headers.SetHeader("Upgrade", "websocket");
  8289. request_.extra_headers.SetHeader("Origin", "http://www.example.org");
  8290. request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  8291. auto session_deps = std::make_unique<SpdySessionDependencies>(
  8292. ConfiguredProxyResolutionService::CreateFixedForTest(
  8293. "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  8294. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8295. std::move(session_deps));
  8296. helper.RunPreTestSetup();
  8297. helper.AddData(&data);
  8298. HttpNetworkTransaction* trans = helper.trans();
  8299. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  8300. trans->SetWebSocketHandshakeStreamCreateHelper(
  8301. &websocket_stream_create_helper);
  8302. EXPECT_TRUE(helper.StartDefaultTest());
  8303. helper.WaitForCallbackToComplete();
  8304. EXPECT_THAT(helper.output().rv, IsOk());
  8305. base::RunLoop().RunUntilIdle();
  8306. helper.VerifyDataConsumed();
  8307. }
  8308. TEST_F(SpdyNetworkTransactionTest, SecureWebSocketOverHttp2Proxy) {
  8309. spdy::SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect(
  8310. nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
  8311. HostPortPair("www.example.org", 443)));
  8312. const char kWebSocketRequest[] =
  8313. "GET / HTTP/1.1\r\n"
  8314. "Host: www.example.org\r\n"
  8315. "Connection: Upgrade\r\n"
  8316. "Upgrade: websocket\r\n"
  8317. "Origin: http://www.example.org\r\n"
  8318. "Sec-WebSocket-Version: 13\r\n"
  8319. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  8320. "Sec-WebSocket-Extensions: permessage-deflate; "
  8321. "client_max_window_bits\r\n\r\n";
  8322. spdy::SpdySerializedFrame websocket_request(
  8323. spdy_util_.ConstructSpdyDataFrame(1, kWebSocketRequest, false));
  8324. MockWrite writes[] = {CreateMockWrite(connect_request, 0),
  8325. CreateMockWrite(websocket_request, 2)};
  8326. spdy::SpdySerializedFrame connect_response(
  8327. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8328. const char kWebSocketResponse[] =
  8329. "HTTP/1.1 101 Switching Protocols\r\n"
  8330. "Upgrade: websocket\r\n"
  8331. "Connection: Upgrade\r\n"
  8332. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
  8333. spdy::SpdySerializedFrame websocket_response(
  8334. spdy_util_.ConstructSpdyDataFrame(1, kWebSocketResponse, false));
  8335. MockRead reads[] = {CreateMockRead(connect_response, 1),
  8336. CreateMockRead(websocket_response, 3),
  8337. MockRead(ASYNC, 0, 4)};
  8338. SequencedSocketData data(reads, writes);
  8339. request_.url = GURL("wss://www.example.org/");
  8340. request_.extra_headers.SetHeader("Connection", "Upgrade");
  8341. request_.extra_headers.SetHeader("Upgrade", "websocket");
  8342. request_.extra_headers.SetHeader("Origin", "http://www.example.org");
  8343. request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  8344. auto session_deps = std::make_unique<SpdySessionDependencies>(
  8345. ConfiguredProxyResolutionService::CreateFixedForTest(
  8346. "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  8347. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8348. std::move(session_deps));
  8349. helper.RunPreTestSetup();
  8350. helper.AddData(&data);
  8351. // Add SSL data for the tunneled connection.
  8352. SSLSocketDataProvider ssl_provider(ASYNC, OK);
  8353. ssl_provider.ssl_info.cert =
  8354. ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
  8355. // A WebSocket request should not advertise HTTP/2 support.
  8356. ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11};
  8357. // This test uses WebSocket over HTTP/1.1.
  8358. ssl_provider.next_proto = kProtoHTTP11;
  8359. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  8360. &ssl_provider);
  8361. HttpNetworkTransaction* trans = helper.trans();
  8362. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  8363. trans->SetWebSocketHandshakeStreamCreateHelper(
  8364. &websocket_stream_create_helper);
  8365. EXPECT_TRUE(helper.StartDefaultTest());
  8366. helper.WaitForCallbackToComplete();
  8367. EXPECT_THAT(helper.output().rv, IsOk());
  8368. const HttpResponseInfo* response = trans->GetResponseInfo();
  8369. ASSERT_TRUE(response);
  8370. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
  8371. response->connection_info);
  8372. EXPECT_TRUE(response->was_alpn_negotiated);
  8373. EXPECT_FALSE(response->was_fetched_via_spdy);
  8374. EXPECT_EQ(70, response->remote_endpoint.port());
  8375. ASSERT_TRUE(response->headers);
  8376. EXPECT_EQ("HTTP/1.1 101 Switching Protocols",
  8377. response->headers->GetStatusLine());
  8378. base::RunLoop().RunUntilIdle();
  8379. helper.VerifyDataConsumed();
  8380. }
  8381. // Regression test for https://crbug.com/828865.
  8382. TEST_F(SpdyNetworkTransactionTest,
  8383. SecureWebSocketOverHttp2ProxyNegotiatesHttp2) {
  8384. spdy::SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect(
  8385. nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
  8386. HostPortPair("www.example.org", 443)));
  8387. MockWrite writes[] = {CreateMockWrite(connect_request, 0)};
  8388. spdy::SpdySerializedFrame connect_response(
  8389. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8390. MockRead reads[] = {CreateMockRead(connect_response, 1),
  8391. MockRead(ASYNC, 0, 2)};
  8392. SequencedSocketData data(reads, writes);
  8393. request_.url = GURL("wss://www.example.org/");
  8394. request_.extra_headers.SetHeader("Connection", "Upgrade");
  8395. request_.extra_headers.SetHeader("Upgrade", "websocket");
  8396. request_.extra_headers.SetHeader("Origin", "http://www.example.org");
  8397. request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
  8398. auto session_deps = std::make_unique<SpdySessionDependencies>(
  8399. ConfiguredProxyResolutionService::CreateFixedForTest(
  8400. "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  8401. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8402. std::move(session_deps));
  8403. helper.RunPreTestSetup();
  8404. helper.AddData(&data);
  8405. // Add SSL data for the tunneled connection.
  8406. SSLSocketDataProvider ssl_provider(ASYNC, OK);
  8407. ssl_provider.ssl_info.cert =
  8408. ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
  8409. // A WebSocket request should not advertise HTTP/2 support.
  8410. ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11};
  8411. // The server should not negotiate HTTP/2 over the tunnelled connection,
  8412. // but it must be handled gracefully if it does.
  8413. ssl_provider.next_proto = kProtoHTTP2;
  8414. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  8415. &ssl_provider);
  8416. HttpNetworkTransaction* trans = helper.trans();
  8417. TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
  8418. trans->SetWebSocketHandshakeStreamCreateHelper(
  8419. &websocket_stream_create_helper);
  8420. EXPECT_TRUE(helper.StartDefaultTest());
  8421. helper.WaitForCallbackToComplete();
  8422. EXPECT_THAT(helper.output().rv, IsError(ERR_NOT_IMPLEMENTED));
  8423. base::RunLoop().RunUntilIdle();
  8424. helper.VerifyDataConsumed();
  8425. }
  8426. #endif // BUILDFLAG(ENABLE_WEBSOCKETS)
  8427. TEST_F(SpdyNetworkTransactionTest, ZeroRTTDoesntConfirm) {
  8428. static const base::TimeDelta kDelay = base::Milliseconds(10);
  8429. spdy::SpdySerializedFrame req(
  8430. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  8431. MockWrite writes[] = {CreateMockWrite(req, 0)};
  8432. spdy::SpdySerializedFrame resp(
  8433. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8434. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8435. MockRead reads[] = {
  8436. CreateMockRead(resp, 1), CreateMockRead(body, 2),
  8437. MockRead(ASYNC, 0, 3) // EOF
  8438. };
  8439. SequencedSocketData data(reads, writes);
  8440. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8441. session_deps->enable_early_data = true;
  8442. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8443. std::move(session_deps));
  8444. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8445. ssl_provider->connect_callback = FastForwardByCallback(kDelay);
  8446. // Configure |ssl_provider| to fail if ConfirmHandshake is called. The request
  8447. // should still succeed.
  8448. ssl_provider->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
  8449. ssl_provider->confirm_callback = FastForwardByCallback(kDelay);
  8450. base::TimeTicks start_time = base::TimeTicks::Now();
  8451. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  8452. TransactionHelperResult out = helper.output();
  8453. EXPECT_THAT(out.rv, IsOk());
  8454. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  8455. EXPECT_EQ("hello!", out.response_data);
  8456. // The handshake time should include the time it took to run Connect(), but
  8457. // not ConfirmHandshake().
  8458. LoadTimingInfo load_timing_info;
  8459. EXPECT_TRUE(helper.trans()->GetLoadTimingInfo(&load_timing_info));
  8460. EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
  8461. EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
  8462. EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
  8463. EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
  8464. }
  8465. // Run multiple concurrent streams that don't require handshake confirmation.
  8466. TEST_F(SpdyNetworkTransactionTest, ZeroRTTNoConfirmMultipleStreams) {
  8467. spdy::SpdySerializedFrame req1(
  8468. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  8469. spdy::SpdySerializedFrame req2(
  8470. spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  8471. MockWrite writes1[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 3)};
  8472. spdy::SpdySerializedFrame resp1(
  8473. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8474. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  8475. spdy::SpdySerializedFrame resp2(
  8476. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  8477. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  8478. MockRead reads1[] = {
  8479. CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  8480. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  8481. MockRead(ASYNC, 0, 6) // EOF
  8482. };
  8483. SequencedSocketData data1(reads1, writes1);
  8484. SequencedSocketData data2({}, {});
  8485. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8486. session_deps->enable_early_data = true;
  8487. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8488. std::move(session_deps));
  8489. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8490. ssl_provider1->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
  8491. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8492. ssl_provider2->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
  8493. helper.RunPreTestSetup();
  8494. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  8495. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  8496. EXPECT_TRUE(helper.StartDefaultTest());
  8497. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  8498. HttpRequestInfo request2;
  8499. request2.method = "GET";
  8500. request2.url = GURL(kDefaultUrl);
  8501. request2.traffic_annotation =
  8502. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8503. TestCompletionCallback callback2;
  8504. int rv = trans2.Start(&request2, callback2.callback(), log_);
  8505. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8506. helper.FinishDefaultTest();
  8507. EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
  8508. helper.VerifyDataConsumed();
  8509. TransactionHelperResult out = helper.output();
  8510. EXPECT_THAT(out.rv, IsOk());
  8511. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  8512. EXPECT_EQ("hello!", out.response_data);
  8513. }
  8514. // Run multiple concurrent streams that require handshake confirmation.
  8515. TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmMultipleStreams) {
  8516. spdy::Http2HeaderBlock req_block1(
  8517. spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
  8518. spdy::SpdySerializedFrame req1(
  8519. spdy_util_.ConstructSpdyHeaders(1, std::move(req_block1), LOWEST, true));
  8520. spdy::Http2HeaderBlock req_block2(
  8521. spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
  8522. spdy::SpdySerializedFrame req2(
  8523. spdy_util_.ConstructSpdyHeaders(3, std::move(req_block2), LOWEST, true));
  8524. MockWrite writes[] = {
  8525. CreateMockWrite(req1, 0),
  8526. CreateMockWrite(req2, 3),
  8527. };
  8528. spdy::SpdySerializedFrame resp1(
  8529. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8530. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  8531. spdy::SpdySerializedFrame resp2(
  8532. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  8533. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  8534. MockRead reads[] = {
  8535. CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  8536. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  8537. MockRead(ASYNC, 0, 6) // EOF
  8538. };
  8539. SequencedSocketData data1(reads, writes);
  8540. SequencedSocketData data2({}, {});
  8541. UsePostRequest();
  8542. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8543. session_deps->enable_early_data = true;
  8544. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8545. std::move(session_deps));
  8546. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8547. ssl_provider1->confirm = MockConfirm(ASYNC, OK);
  8548. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8549. ssl_provider2->confirm = MockConfirm(ASYNC, OK);
  8550. helper.RunPreTestSetup();
  8551. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  8552. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  8553. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  8554. HttpRequestInfo request1;
  8555. request1.method = "POST";
  8556. request1.url = GURL(kDefaultUrl);
  8557. request1.traffic_annotation =
  8558. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8559. TestCompletionCallback callback1;
  8560. int rv = trans1.Start(&request1, callback1.callback(), log_);
  8561. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8562. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  8563. HttpRequestInfo request2;
  8564. request2.method = "POST";
  8565. request2.url = GURL(kDefaultUrl);
  8566. request2.traffic_annotation =
  8567. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8568. TestCompletionCallback callback2;
  8569. rv = trans2.Start(&request2, callback2.callback(), log_);
  8570. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8571. EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
  8572. EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
  8573. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  8574. ASSERT_TRUE(response1);
  8575. ASSERT_TRUE(response1->headers);
  8576. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  8577. response1->connection_info);
  8578. EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
  8579. std::string response_data;
  8580. ReadTransaction(&trans1, &response_data);
  8581. EXPECT_EQ("hello!", response_data);
  8582. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  8583. ASSERT_TRUE(response2);
  8584. ASSERT_TRUE(response2->headers);
  8585. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  8586. response2->connection_info);
  8587. EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
  8588. ReadTransaction(&trans2, &response_data);
  8589. EXPECT_EQ("hello!", response_data);
  8590. helper.VerifyDataConsumed();
  8591. }
  8592. // Run multiple concurrent streams, the first require a confirmation and the
  8593. // second not requiring confirmation.
  8594. TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmNoConfirmStreams) {
  8595. // This test orders the writes such that the GET (no confirmation) is written
  8596. // before the POST (confirmation required).
  8597. spdy::Http2HeaderBlock req_block1(
  8598. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  8599. spdy::SpdySerializedFrame req1(
  8600. spdy_util_.ConstructSpdyHeaders(1, std::move(req_block1), LOWEST, true));
  8601. spdy::Http2HeaderBlock req_block2(
  8602. spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
  8603. spdy::SpdySerializedFrame req2(
  8604. spdy_util_.ConstructSpdyHeaders(3, std::move(req_block2), LOWEST, true));
  8605. MockWrite writes[] = {
  8606. CreateMockWrite(req1, 0),
  8607. CreateMockWrite(req2, 3),
  8608. };
  8609. spdy::SpdySerializedFrame resp1(
  8610. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8611. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  8612. spdy::SpdySerializedFrame resp2(
  8613. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  8614. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  8615. MockRead reads[] = {
  8616. CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  8617. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  8618. MockRead(ASYNC, 0, 6) // EOF
  8619. };
  8620. SequencedSocketData data1(reads, writes);
  8621. SequencedSocketData data2({}, {});
  8622. UsePostRequest();
  8623. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8624. session_deps->enable_early_data = true;
  8625. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8626. std::move(session_deps));
  8627. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8628. ssl_provider1->confirm = MockConfirm(ASYNC, OK);
  8629. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8630. ssl_provider2->confirm = MockConfirm(ASYNC, OK);
  8631. helper.RunPreTestSetup();
  8632. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  8633. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  8634. // TODO(https://crbug.com/949724): Explicitly verify the ordering of
  8635. // ConfirmHandshake and the second stream.
  8636. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  8637. HttpRequestInfo request1;
  8638. request1.method = "POST";
  8639. request1.url = GURL(kDefaultUrl);
  8640. request1.traffic_annotation =
  8641. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8642. TestCompletionCallback callback1;
  8643. int rv = trans1.Start(&request1, callback1.callback(), log_);
  8644. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8645. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  8646. HttpRequestInfo request2;
  8647. request2.method = "GET";
  8648. request2.url = GURL(kDefaultUrl);
  8649. request2.traffic_annotation =
  8650. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8651. TestCompletionCallback callback2;
  8652. rv = trans2.Start(&request2, callback2.callback(), log_);
  8653. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8654. EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
  8655. EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
  8656. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  8657. ASSERT_TRUE(response1);
  8658. ASSERT_TRUE(response1->headers);
  8659. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  8660. response1->connection_info);
  8661. EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
  8662. std::string response_data;
  8663. ReadTransaction(&trans1, &response_data);
  8664. EXPECT_EQ("hello!", response_data);
  8665. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  8666. ASSERT_TRUE(response2);
  8667. ASSERT_TRUE(response2->headers);
  8668. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  8669. response2->connection_info);
  8670. EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
  8671. ReadTransaction(&trans2, &response_data);
  8672. EXPECT_EQ("hello!", response_data);
  8673. helper.VerifyDataConsumed();
  8674. }
  8675. // Run multiple concurrent streams, the first not requiring confirmation and the
  8676. // second requiring confirmation.
  8677. TEST_F(SpdyNetworkTransactionTest, ZeroRTTNoConfirmConfirmStreams) {
  8678. // This test orders the writes such that the GET (no confirmation) is written
  8679. // before the POST (confirmation required).
  8680. spdy::Http2HeaderBlock req_block1(
  8681. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  8682. spdy::SpdySerializedFrame req1(
  8683. spdy_util_.ConstructSpdyHeaders(1, std::move(req_block1), LOWEST, true));
  8684. spdy::Http2HeaderBlock req_block2(
  8685. spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, 0));
  8686. spdy::SpdySerializedFrame req2(
  8687. spdy_util_.ConstructSpdyHeaders(3, std::move(req_block2), LOWEST, true));
  8688. MockWrite writes[] = {
  8689. CreateMockWrite(req1, 0),
  8690. CreateMockWrite(req2, 3),
  8691. };
  8692. spdy::SpdySerializedFrame resp1(
  8693. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  8694. spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  8695. spdy::SpdySerializedFrame resp2(
  8696. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  8697. spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
  8698. MockRead reads[] = {
  8699. CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
  8700. CreateMockRead(resp2, 4), CreateMockRead(body2, 5),
  8701. MockRead(ASYNC, 0, 6) // EOF
  8702. };
  8703. SequencedSocketData data1(reads, writes);
  8704. SequencedSocketData data2({}, {});
  8705. UsePostRequest();
  8706. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8707. session_deps->enable_early_data = true;
  8708. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8709. std::move(session_deps));
  8710. auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8711. ssl_provider1->confirm = MockConfirm(ASYNC, OK);
  8712. auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8713. ssl_provider2->confirm = MockConfirm(ASYNC, OK);
  8714. helper.RunPreTestSetup();
  8715. helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
  8716. helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
  8717. // TODO(https://crbug.com/949724): Explicitly verify the ordering of
  8718. // ConfirmHandshake and the second stream.
  8719. HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
  8720. HttpRequestInfo request1;
  8721. request1.method = "GET";
  8722. request1.url = GURL(kDefaultUrl);
  8723. request1.traffic_annotation =
  8724. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8725. TestCompletionCallback callback1;
  8726. int rv = trans1.Start(&request1, callback1.callback(), log_);
  8727. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8728. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
  8729. HttpRequestInfo request2;
  8730. request2.method = "POST";
  8731. request2.url = GURL(kDefaultUrl);
  8732. request2.traffic_annotation =
  8733. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  8734. TestCompletionCallback callback2;
  8735. rv = trans2.Start(&request2, callback2.callback(), log_);
  8736. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8737. EXPECT_THAT(callback1.GetResult(ERR_IO_PENDING), IsOk());
  8738. EXPECT_THAT(callback2.GetResult(ERR_IO_PENDING), IsOk());
  8739. const HttpResponseInfo* response1 = trans1.GetResponseInfo();
  8740. ASSERT_TRUE(response1);
  8741. ASSERT_TRUE(response1->headers);
  8742. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  8743. response1->connection_info);
  8744. EXPECT_EQ("HTTP/1.1 200", response1->headers->GetStatusLine());
  8745. std::string response_data;
  8746. ReadTransaction(&trans1, &response_data);
  8747. EXPECT_EQ("hello!", response_data);
  8748. const HttpResponseInfo* response2 = trans2.GetResponseInfo();
  8749. ASSERT_TRUE(response2);
  8750. ASSERT_TRUE(response2->headers);
  8751. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
  8752. response2->connection_info);
  8753. EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
  8754. ReadTransaction(&trans2, &response_data);
  8755. EXPECT_EQ("hello!", response_data);
  8756. helper.VerifyDataConsumed();
  8757. }
  8758. TEST_F(SpdyNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
  8759. static const base::TimeDelta kDelay = base::Milliseconds(10);
  8760. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  8761. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  8762. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8763. MockWrite writes[] = {
  8764. CreateMockWrite(req, 0, SYNCHRONOUS),
  8765. CreateMockWrite(body, 1), // POST upload frame
  8766. };
  8767. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  8768. MockRead reads[] = {
  8769. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  8770. MockRead(ASYNC, 0, 4) // EOF
  8771. };
  8772. SequencedSocketData data(reads, writes);
  8773. UsePostRequest();
  8774. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8775. session_deps->enable_early_data = true;
  8776. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8777. std::move(session_deps));
  8778. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8779. ssl_provider->connect_callback = FastForwardByCallback(kDelay);
  8780. ssl_provider->confirm = MockConfirm(SYNCHRONOUS, OK);
  8781. ssl_provider->confirm_callback = FastForwardByCallback(kDelay);
  8782. base::TimeTicks start_time = base::TimeTicks::Now();
  8783. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  8784. TransactionHelperResult out = helper.output();
  8785. EXPECT_THAT(out.rv, IsOk());
  8786. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  8787. EXPECT_EQ("hello!", out.response_data);
  8788. // The handshake time should include the time it took to run Connect(), but
  8789. // not ConfirmHandshake(). If ConfirmHandshake() returns synchronously, we
  8790. // assume the connection did not negotiate 0-RTT or the handshake was already
  8791. // confirmed.
  8792. LoadTimingInfo load_timing_info;
  8793. EXPECT_TRUE(helper.trans()->GetLoadTimingInfo(&load_timing_info));
  8794. EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
  8795. EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
  8796. EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
  8797. EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
  8798. }
  8799. TEST_F(SpdyNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
  8800. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  8801. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  8802. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8803. MockWrite writes[] = {
  8804. CreateMockWrite(req, 0, ASYNC),
  8805. CreateMockWrite(body, 1), // POST upload frame
  8806. };
  8807. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  8808. MockRead reads[] = {
  8809. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  8810. MockRead(ASYNC, 0, 4) // EOF
  8811. };
  8812. SequencedSocketData data(reads, writes);
  8813. UsePostRequest();
  8814. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8815. session_deps->enable_early_data = true;
  8816. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8817. std::move(session_deps));
  8818. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8819. ssl_provider->confirm = MockConfirm(SYNCHRONOUS, OK);
  8820. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  8821. TransactionHelperResult out = helper.output();
  8822. EXPECT_THAT(out.rv, IsOk());
  8823. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  8824. EXPECT_EQ("hello!", out.response_data);
  8825. }
  8826. TEST_F(SpdyNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
  8827. static const base::TimeDelta kDelay = base::Milliseconds(10);
  8828. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  8829. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  8830. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8831. MockWrite writes[] = {
  8832. CreateMockWrite(req, 0, SYNCHRONOUS),
  8833. CreateMockWrite(body, 1), // POST upload frame
  8834. };
  8835. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  8836. MockRead reads[] = {
  8837. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  8838. MockRead(ASYNC, 0, 4) // EOF
  8839. };
  8840. SequencedSocketData data(reads, writes);
  8841. UsePostRequest();
  8842. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8843. session_deps->enable_early_data = true;
  8844. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8845. std::move(session_deps));
  8846. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8847. ssl_provider->connect_callback = FastForwardByCallback(kDelay);
  8848. ssl_provider->confirm = MockConfirm(ASYNC, OK);
  8849. ssl_provider->confirm_callback = FastForwardByCallback(kDelay);
  8850. base::TimeTicks start_time = base::TimeTicks::Now();
  8851. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  8852. TransactionHelperResult out = helper.output();
  8853. EXPECT_THAT(out.rv, IsOk());
  8854. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  8855. EXPECT_EQ("hello!", out.response_data);
  8856. // The handshake time should include the time it took to run Connect() and
  8857. // ConfirmHandshake().
  8858. LoadTimingInfo load_timing_info;
  8859. EXPECT_TRUE(helper.trans()->GetLoadTimingInfo(&load_timing_info));
  8860. EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
  8861. EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
  8862. EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + 2 * kDelay);
  8863. EXPECT_EQ(load_timing_info.connect_timing.connect_end,
  8864. start_time + 2 * kDelay);
  8865. }
  8866. TEST_F(SpdyNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
  8867. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  8868. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  8869. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8870. MockWrite writes[] = {
  8871. CreateMockWrite(req, 0, ASYNC),
  8872. CreateMockWrite(body, 1), // POST upload frame
  8873. };
  8874. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  8875. MockRead reads[] = {
  8876. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  8877. MockRead(ASYNC, 0, 4) // EOF
  8878. };
  8879. SequencedSocketData data(reads, writes);
  8880. UsePostRequest();
  8881. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8882. session_deps->enable_early_data = true;
  8883. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8884. std::move(session_deps));
  8885. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8886. ssl_provider->confirm = MockConfirm(ASYNC, OK);
  8887. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  8888. TransactionHelperResult out = helper.output();
  8889. EXPECT_THAT(out.rv, IsOk());
  8890. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  8891. EXPECT_EQ("hello!", out.response_data);
  8892. }
  8893. TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
  8894. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  8895. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  8896. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8897. MockWrite writes[] = {
  8898. CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
  8899. };
  8900. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  8901. MockRead reads[] = {
  8902. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  8903. MockRead(ASYNC, 0, 4) // EOF
  8904. };
  8905. SequencedSocketData data(reads, writes);
  8906. UsePostRequest();
  8907. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8908. session_deps->enable_early_data = true;
  8909. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8910. std::move(session_deps));
  8911. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8912. ssl_provider->confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
  8913. helper.RunPreTestSetup();
  8914. helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
  8915. helper.RunDefaultTest();
  8916. TransactionHelperResult out = helper.output();
  8917. EXPECT_THAT(out.rv, IsError(ERR_SSL_PROTOCOL_ERROR));
  8918. }
  8919. TEST_F(SpdyNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
  8920. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  8921. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  8922. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  8923. MockWrite writes[] = {
  8924. CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
  8925. };
  8926. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  8927. MockRead reads[] = {
  8928. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  8929. MockRead(ASYNC, 0, 4) // EOF
  8930. };
  8931. SequencedSocketData data(reads, writes);
  8932. UsePostRequest();
  8933. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8934. session_deps->enable_early_data = true;
  8935. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  8936. std::move(session_deps));
  8937. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  8938. ssl_provider->confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  8939. helper.RunPreTestSetup();
  8940. helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
  8941. helper.RunDefaultTest();
  8942. TransactionHelperResult out = helper.output();
  8943. EXPECT_THAT(out.rv, IsError(ERR_SSL_PROTOCOL_ERROR));
  8944. }
  8945. TEST_F(SpdyNetworkTransactionTest, GreaseSettings) {
  8946. RecordingNetLogObserver net_log_observer;
  8947. auto session_deps = std::make_unique<SpdySessionDependencies>();
  8948. session_deps->enable_http2_settings_grease = true;
  8949. NormalSpdyTransactionHelper helper(
  8950. request_, DEFAULT_PRIORITY,
  8951. NetLogWithSource::Make(NetLogSourceType::NONE), std::move(session_deps));
  8952. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
  8953. SpdySessionPoolPeer pool_peer(spdy_session_pool);
  8954. pool_peer.SetEnableSendingInitialData(true);
  8955. // Greased setting parameter is random. Hang writes instead of trying to
  8956. // construct matching mock data. Extra write and read is needed because mock
  8957. // data cannot end on ERR_IO_PENDING. Writes or reads will not actually be
  8958. // resumed.
  8959. MockWrite writes[] = {MockWrite(ASYNC, ERR_IO_PENDING, 0),
  8960. MockWrite(ASYNC, OK, 1)};
  8961. MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 2),
  8962. MockRead(ASYNC, OK, 3)};
  8963. SequencedSocketData data(reads, writes);
  8964. helper.RunPreTestSetup();
  8965. helper.AddData(&data);
  8966. int rv = helper.trans()->Start(&request_, CompletionOnceCallback{}, log_);
  8967. EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  8968. base::RunLoop().RunUntilIdle();
  8969. helper.ResetTrans();
  8970. EXPECT_FALSE(data.AllReadDataConsumed());
  8971. EXPECT_FALSE(data.AllWriteDataConsumed());
  8972. const auto entries = net_log_observer.GetEntries();
  8973. size_t pos = ExpectLogContainsSomewhere(
  8974. entries, 0, NetLogEventType::HTTP2_SESSION_SEND_SETTINGS,
  8975. NetLogEventPhase::NONE);
  8976. ASSERT_LT(pos, entries.size());
  8977. const base::Value& params = entries[pos].params;
  8978. const base::Value::List* const settings =
  8979. params.GetDict().FindList("settings");
  8980. ASSERT_TRUE(settings);
  8981. ASSERT_FALSE(settings->empty());
  8982. // Get last setting parameter.
  8983. const base::Value& greased_setting = (*settings)[settings->size() - 1];
  8984. ASSERT_TRUE(greased_setting.is_string());
  8985. base::StringPiece greased_setting_string(greased_setting.GetString());
  8986. const std::string kExpectedPrefix = "[id:";
  8987. EXPECT_EQ(kExpectedPrefix,
  8988. greased_setting_string.substr(0, kExpectedPrefix.size()));
  8989. int setting_identifier = 0;
  8990. base::StringToInt(greased_setting_string.substr(kExpectedPrefix.size()),
  8991. &setting_identifier);
  8992. // The setting identifier must be of format 0x?a?a.
  8993. EXPECT_EQ(0xa, setting_identifier % 16);
  8994. EXPECT_EQ(0xa, (setting_identifier / 256) % 16);
  8995. }
  8996. // If |http2_end_stream_with_data_frame| is false, then the HEADERS frame of a
  8997. // GET request will close the stream using the END_STREAM flag. Test that
  8998. // |greased_http2_frame| is ignored and no reserved frames are sent on a closed
  8999. // stream.
  9000. TEST_F(SpdyNetworkTransactionTest,
  9001. DoNotGreaseFrameTypeWithGetRequestIfHeadersFrameClosesStream) {
  9002. auto session_deps = std::make_unique<SpdySessionDependencies>();
  9003. const uint8_t type = 0x0b;
  9004. const uint8_t flags = 0xcc;
  9005. const std::string payload("foo");
  9006. session_deps->greased_http2_frame =
  9007. absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
  9008. {type, flags, payload});
  9009. session_deps->http2_end_stream_with_data_frame = false;
  9010. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  9011. std::move(session_deps));
  9012. spdy::SpdySerializedFrame req(
  9013. spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));
  9014. MockWrite writes[] = {CreateMockWrite(req, 0)};
  9015. spdy::SpdySerializedFrame resp(
  9016. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  9017. spdy::SpdySerializedFrame response_body(
  9018. spdy_util_.ConstructSpdyDataFrame(1, true));
  9019. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(response_body, 2),
  9020. MockRead(ASYNC, 0, 3)};
  9021. SequencedSocketData data(reads, writes);
  9022. helper.RunPreTestSetup();
  9023. helper.AddData(&data);
  9024. TestCompletionCallback callback;
  9025. int rv = helper.trans()->Start(&request_, callback.callback(), log_);
  9026. EXPECT_THAT(callback.GetResult(rv), IsOk());
  9027. base::RunLoop().RunUntilIdle();
  9028. helper.VerifyDataConsumed();
  9029. }
  9030. // Test that if |http2_end_stream_with_data_frame| and |greased_http2_frame| are
  9031. // both set, then the HEADERS frame does not have the END_STREAM flag set, it is
  9032. // followed by a greased frame, and then by an empty DATA frame with END_STREAM
  9033. // set.
  9034. TEST_F(SpdyNetworkTransactionTest, GreaseFrameTypeWithGetRequest) {
  9035. auto session_deps = std::make_unique<SpdySessionDependencies>();
  9036. const uint8_t type = 0x0b;
  9037. const uint8_t flags = 0xcc;
  9038. const std::string payload("foo");
  9039. session_deps->greased_http2_frame =
  9040. absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
  9041. {type, flags, payload});
  9042. session_deps->http2_end_stream_with_data_frame = true;
  9043. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  9044. std::move(session_deps));
  9045. spdy::Http2HeaderBlock headers(
  9046. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  9047. spdy::SpdySerializedFrame req(
  9048. spdy_util_.ConstructSpdyHeaders(1, std::move(headers), DEFAULT_PRIORITY,
  9049. /* fin = */ false));
  9050. uint8_t kRawFrameData[] = {
  9051. 0x00, 0x00, 0x03, // length
  9052. 0x0b, // type
  9053. 0xcc, // flags
  9054. 0x00, 0x00, 0x00, 0x01, // stream ID
  9055. 'f', 'o', 'o' // payload
  9056. };
  9057. spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
  9058. std::size(kRawFrameData),
  9059. /* owns_buffer = */ false);
  9060. spdy::SpdySerializedFrame empty_body(
  9061. spdy_util_.ConstructSpdyDataFrame(1, "", true));
  9062. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(grease, 1),
  9063. CreateMockWrite(empty_body, 2)};
  9064. spdy::SpdySerializedFrame resp(
  9065. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  9066. spdy::SpdySerializedFrame response_body(
  9067. spdy_util_.ConstructSpdyDataFrame(1, true));
  9068. MockRead reads[] = {CreateMockRead(resp, 3), CreateMockRead(response_body, 4),
  9069. MockRead(ASYNC, 0, 5)};
  9070. SequencedSocketData data(reads, writes);
  9071. helper.RunPreTestSetup();
  9072. helper.AddData(&data);
  9073. TestCompletionCallback callback;
  9074. int rv = helper.trans()->Start(&request_, callback.callback(), log_);
  9075. EXPECT_THAT(callback.GetResult(rv), IsOk());
  9076. base::RunLoop().RunUntilIdle();
  9077. helper.VerifyDataConsumed();
  9078. }
  9079. // Test sending a greased frame before DATA frame that closes the stream when
  9080. // |http2_end_stream_with_data_frame| is false.
  9081. TEST_F(SpdyNetworkTransactionTest,
  9082. GreaseFrameTypeWithPostRequestWhenHeadersFrameClosesStream) {
  9083. UsePostRequest();
  9084. auto session_deps = std::make_unique<SpdySessionDependencies>();
  9085. const uint8_t type = 0x0b;
  9086. const uint8_t flags = 0xcc;
  9087. const std::string payload("foo");
  9088. session_deps->greased_http2_frame =
  9089. absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
  9090. {type, flags, payload});
  9091. session_deps->http2_end_stream_with_data_frame = true;
  9092. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  9093. std::move(session_deps));
  9094. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  9095. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  9096. uint8_t kRawFrameData[] = {
  9097. 0x00, 0x00, 0x03, // length
  9098. 0x0b, // type
  9099. 0xcc, // flags
  9100. 0x00, 0x00, 0x00, 0x01, // stream ID
  9101. 'f', 'o', 'o' // payload
  9102. };
  9103. spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
  9104. std::size(kRawFrameData),
  9105. /* owns_buffer = */ false);
  9106. spdy::SpdySerializedFrame request_body(
  9107. spdy_util_.ConstructSpdyDataFrame(1, true));
  9108. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(grease, 1),
  9109. CreateMockWrite(request_body, 2)};
  9110. spdy::SpdySerializedFrame resp(
  9111. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  9112. spdy::SpdySerializedFrame response_body(
  9113. spdy_util_.ConstructSpdyDataFrame(1, true));
  9114. MockRead reads[] = {CreateMockRead(resp, 3), CreateMockRead(response_body, 4),
  9115. MockRead(ASYNC, 0, 5)};
  9116. SequencedSocketData data(reads, writes);
  9117. helper.RunPreTestSetup();
  9118. helper.AddData(&data);
  9119. TestCompletionCallback callback;
  9120. int rv = helper.trans()->Start(&request_, callback.callback(), log_);
  9121. EXPECT_THAT(callback.GetResult(rv), IsOk());
  9122. base::RunLoop().RunUntilIdle();
  9123. helper.VerifyDataConsumed();
  9124. }
  9125. // Test sending a greased frame before DATA frame that closes the stream.
  9126. // |http2_end_stream_with_data_frame| is true but should make no difference,
  9127. // because the stream is already closed by a DATA frame.
  9128. TEST_F(SpdyNetworkTransactionTest,
  9129. GreaseFrameTypeWithPostRequestWhenEmptyDataFrameClosesStream) {
  9130. UsePostRequest();
  9131. auto session_deps = std::make_unique<SpdySessionDependencies>();
  9132. const uint8_t type = 0x0b;
  9133. const uint8_t flags = 0xcc;
  9134. const std::string payload("foo");
  9135. session_deps->greased_http2_frame =
  9136. absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
  9137. {type, flags, payload});
  9138. session_deps->http2_end_stream_with_data_frame = true;
  9139. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  9140. std::move(session_deps));
  9141. spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
  9142. kDefaultUrl, 1, kUploadDataSize, LOWEST, nullptr, 0));
  9143. uint8_t kRawFrameData[] = {
  9144. 0x00, 0x00, 0x03, // length
  9145. 0x0b, // type
  9146. 0xcc, // flags
  9147. 0x00, 0x00, 0x00, 0x01, // stream ID
  9148. 'f', 'o', 'o' // payload
  9149. };
  9150. spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
  9151. std::size(kRawFrameData),
  9152. /* owns_buffer = */ false);
  9153. spdy::SpdySerializedFrame request_body(
  9154. spdy_util_.ConstructSpdyDataFrame(1, true));
  9155. MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(grease, 1),
  9156. CreateMockWrite(request_body, 2)};
  9157. spdy::SpdySerializedFrame resp(
  9158. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  9159. spdy::SpdySerializedFrame response_body(
  9160. spdy_util_.ConstructSpdyDataFrame(1, true));
  9161. MockRead reads[] = {CreateMockRead(resp, 3), CreateMockRead(response_body, 4),
  9162. MockRead(ASYNC, 0, 5)};
  9163. SequencedSocketData data(reads, writes);
  9164. helper.RunPreTestSetup();
  9165. helper.AddData(&data);
  9166. TestCompletionCallback callback;
  9167. int rv = helper.trans()->Start(&request_, callback.callback(), log_);
  9168. EXPECT_THAT(callback.GetResult(rv), IsOk());
  9169. base::RunLoop().RunUntilIdle();
  9170. helper.VerifyDataConsumed();
  9171. }
  9172. // According to https://httpwg.org/specs/rfc7540.html#CONNECT, "frame types
  9173. // other than DATA or stream management frames (RST_STREAM, WINDOW_UPDATE, and
  9174. // PRIORITY) MUST NOT be sent on a connected stream".
  9175. // Also test that |http2_end_stream_with_data_frame| has no effect on proxy
  9176. // streams.
  9177. TEST_F(SpdyNetworkTransactionTest, DoNotGreaseFrameTypeWithConnect) {
  9178. auto session_deps = std::make_unique<SpdySessionDependencies>(
  9179. ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
  9180. "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
  9181. const uint8_t type = 0x0b;
  9182. const uint8_t flags = 0xcc;
  9183. const std::string payload("foo");
  9184. session_deps->greased_http2_frame =
  9185. absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
  9186. {type, flags, payload});
  9187. session_deps->http2_end_stream_with_data_frame = true;
  9188. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  9189. std::move(session_deps));
  9190. // CONNECT to proxy.
  9191. spdy::SpdySerializedFrame connect_req(spdy_util_.ConstructSpdyConnect(
  9192. nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
  9193. HostPortPair("www.example.org", 443)));
  9194. spdy::SpdySerializedFrame connect_response(
  9195. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  9196. // Tunneled transaction wrapped in DATA frames.
  9197. const char req[] =
  9198. "GET / HTTP/1.1\r\n"
  9199. "Host: www.example.org\r\n"
  9200. "Connection: keep-alive\r\n\r\n";
  9201. spdy::SpdySerializedFrame tunneled_req(
  9202. spdy_util_.ConstructSpdyDataFrame(1, req, false));
  9203. const char resp[] =
  9204. "HTTP/1.1 200 OK\r\n"
  9205. "Content-Length: 5\r\n\r\n"
  9206. "hello";
  9207. spdy::SpdySerializedFrame tunneled_response(
  9208. spdy_util_.ConstructSpdyDataFrame(1, resp, false));
  9209. MockWrite writes[] = {CreateMockWrite(connect_req, 0),
  9210. CreateMockWrite(tunneled_req, 2)};
  9211. MockRead reads[] = {CreateMockRead(connect_response, 1),
  9212. CreateMockRead(tunneled_response, 3),
  9213. MockRead(ASYNC, 0, 4)};
  9214. SequencedSocketData data0(reads, writes);
  9215. // HTTP/2 connection to proxy.
  9216. auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  9217. ssl_provider0->next_proto = kProtoHTTP2;
  9218. helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
  9219. // HTTP/1.1 to destination.
  9220. SSLSocketDataProvider ssl_provider1(ASYNC, OK);
  9221. ssl_provider1.next_proto = kProtoHTTP11;
  9222. helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
  9223. &ssl_provider1);
  9224. helper.RunPreTestSetup();
  9225. helper.StartDefaultTest();
  9226. helper.FinishDefaultTestWithoutVerification();
  9227. helper.VerifyDataConsumed();
  9228. const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
  9229. ASSERT_TRUE(response);
  9230. ASSERT_TRUE(response->headers);
  9231. EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
  9232. EXPECT_FALSE(response->was_fetched_via_spdy);
  9233. EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
  9234. response->connection_info);
  9235. EXPECT_TRUE(response->was_alpn_negotiated);
  9236. EXPECT_TRUE(request_.url.SchemeIs("https"));
  9237. EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
  9238. EXPECT_EQ(70, response->remote_endpoint.port());
  9239. std::string response_data;
  9240. ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
  9241. EXPECT_EQ("hello", response_data);
  9242. }
  9243. // Regression test for https://crbug.com/1081955.
  9244. // Greasing frame types is enabled, the outgoing HEADERS frame is followed by a
  9245. // frame of reserved type, then an empty DATA frame to close the stream.
  9246. // Response arrives before reserved frame and DATA frame can be sent.
  9247. // SpdyHttpStream::OnDataSent() must not crash.
  9248. TEST_F(SpdyNetworkTransactionTest, OnDataSentDoesNotCrashWithGreasedFrameType) {
  9249. auto session_deps = std::make_unique<SpdySessionDependencies>();
  9250. const uint8_t type = 0x0b;
  9251. const uint8_t flags = 0xcc;
  9252. const std::string payload("foo");
  9253. session_deps->greased_http2_frame =
  9254. absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
  9255. {type, flags, payload});
  9256. session_deps->http2_end_stream_with_data_frame = true;
  9257. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
  9258. std::move(session_deps));
  9259. spdy::Http2HeaderBlock headers(
  9260. spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  9261. spdy::SpdySerializedFrame req(
  9262. spdy_util_.ConstructSpdyHeaders(1, std::move(headers), DEFAULT_PRIORITY,
  9263. /* fin = */ false));
  9264. uint8_t kRawFrameData[] = {
  9265. 0x00, 0x00, 0x03, // length
  9266. 0x0b, // type
  9267. 0xcc, // flags
  9268. 0x00, 0x00, 0x00, 0x01, // stream ID
  9269. 'f', 'o', 'o' // payload
  9270. };
  9271. spdy::SpdySerializedFrame grease(reinterpret_cast<char*>(kRawFrameData),
  9272. std::size(kRawFrameData),
  9273. /* owns_buffer = */ false);
  9274. spdy::SpdySerializedFrame empty_body(
  9275. spdy_util_.ConstructSpdyDataFrame(1, "", true));
  9276. MockWrite writes[] = {
  9277. CreateMockWrite(req, 0), MockWrite(ASYNC, ERR_IO_PENDING, 2),
  9278. CreateMockWrite(grease, 3), CreateMockWrite(empty_body, 4)};
  9279. spdy::SpdySerializedFrame resp(
  9280. spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  9281. spdy::SpdySerializedFrame response_body(
  9282. spdy_util_.ConstructSpdyDataFrame(1, true));
  9283. MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(response_body, 5),
  9284. MockRead(ASYNC, 0, 6)};
  9285. SequencedSocketData data(reads, writes);
  9286. helper.RunPreTestSetup();
  9287. helper.AddData(&data);
  9288. TestCompletionCallback callback;
  9289. int rv = helper.trans()->Start(&request_, callback.callback(), log_);
  9290. base::RunLoop().RunUntilIdle();
  9291. // Response headers received. Resume sending |grease| and |empty_body|.
  9292. data.Resume();
  9293. EXPECT_THAT(callback.GetResult(rv), IsOk());
  9294. base::RunLoop().RunUntilIdle();
  9295. helper.VerifyDataConsumed();
  9296. }
  9297. TEST_F(SpdyNetworkTransactionTest, NotAllowHTTP1NotBlockH2Post) {
  9298. spdy::SpdySerializedFrame req(
  9299. spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
  9300. spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  9301. MockWrite writes[] = {
  9302. CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
  9303. };
  9304. spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
  9305. MockRead reads[] = {
  9306. CreateMockRead(resp, 2), CreateMockRead(body, 3),
  9307. MockRead(ASYNC, 0, 4) // EOF
  9308. };
  9309. SequencedSocketData data(reads, writes);
  9310. request_.method = "POST";
  9311. UploadDataStreamNotAllowHTTP1 upload_data(kUploadData);
  9312. request_.upload_data_stream = &upload_data;
  9313. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  9314. helper.RunToCompletion(&data);
  9315. TransactionHelperResult out = helper.output();
  9316. EXPECT_THAT(out.rv, IsOk());
  9317. EXPECT_EQ("HTTP/1.1 200", out.status_line);
  9318. EXPECT_EQ("hello!", out.response_data);
  9319. }
  9320. TEST_F(SpdyNetworkTransactionTest, AlpsFramingError) {
  9321. base::HistogramTester histogram_tester;
  9322. spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
  9323. 0, spdy::ERROR_CODE_PROTOCOL_ERROR, "Error parsing ALPS: 3"));
  9324. MockWrite writes[] = {CreateMockWrite(goaway, 0)};
  9325. SequencedSocketData data(base::span<MockRead>(), writes);
  9326. auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
  9327. // Not a complete HTTP/2 frame.
  9328. ssl_provider->peer_application_settings = "boo";
  9329. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
  9330. helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
  9331. TransactionHelperResult out = helper.output();
  9332. EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
  9333. histogram_tester.ExpectUniqueSample(
  9334. "Net.SpdySession.AlpsDecoderStatus",
  9335. static_cast<int>(AlpsDecoder::Error::kNotOnFrameBoundary), 1);
  9336. histogram_tester.ExpectTotalCount("Net.SpdySession.AlpsAcceptChEntries", 0);
  9337. histogram_tester.ExpectTotalCount("Net.SpdySession.AlpsSettingParameterCount",
  9338. 0);
  9339. }
  9340. } // namespace net