nghttp3_qpack.c 127 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167
  1. /*
  2. * nghttp3
  3. *
  4. * Copyright (c) 2019 nghttp3 contributors
  5. * Copyright (c) 2013 nghttp2 contributors
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining
  8. * a copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sublicense, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be
  16. * included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. */
  26. #include "nghttp3_qpack.h"
  27. #include <string.h>
  28. #include <assert.h>
  29. #include <stdio.h>
  30. #include "nghttp3_str.h"
  31. #include "nghttp3_macro.h"
  32. #include "nghttp3_debug.h"
  33. #include "nghttp3_unreachable.h"
  34. /* NGHTTP3_QPACK_MAX_QPACK_STREAMS is the maximum number of concurrent
  35. nghttp3_qpack_stream object to handle a client which never cancel
  36. or acknowledge header block. After this limit, encoder stops using
  37. dynamic table. */
  38. #define NGHTTP3_QPACK_MAX_QPACK_STREAMS 2000
  39. /* Make scalar initialization form of nghttp3_qpack_static_entry */
  40. #define MAKE_STATIC_ENT(I, T, H) {I, T, H}
  41. /* Generated by mkstatichdtbl.py */
  42. static nghttp3_qpack_static_entry token_stable[] = {
  43. MAKE_STATIC_ENT(0, NGHTTP3_QPACK_TOKEN__AUTHORITY, 3153725150u),
  44. MAKE_STATIC_ENT(15, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  45. MAKE_STATIC_ENT(16, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  46. MAKE_STATIC_ENT(17, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  47. MAKE_STATIC_ENT(18, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  48. MAKE_STATIC_ENT(19, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  49. MAKE_STATIC_ENT(20, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  50. MAKE_STATIC_ENT(21, NGHTTP3_QPACK_TOKEN__METHOD, 695666056u),
  51. MAKE_STATIC_ENT(1, NGHTTP3_QPACK_TOKEN__PATH, 3292848686u),
  52. MAKE_STATIC_ENT(22, NGHTTP3_QPACK_TOKEN__SCHEME, 2510477674u),
  53. MAKE_STATIC_ENT(23, NGHTTP3_QPACK_TOKEN__SCHEME, 2510477674u),
  54. MAKE_STATIC_ENT(24, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  55. MAKE_STATIC_ENT(25, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  56. MAKE_STATIC_ENT(26, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  57. MAKE_STATIC_ENT(27, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  58. MAKE_STATIC_ENT(28, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  59. MAKE_STATIC_ENT(63, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  60. MAKE_STATIC_ENT(64, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  61. MAKE_STATIC_ENT(65, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  62. MAKE_STATIC_ENT(66, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  63. MAKE_STATIC_ENT(67, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  64. MAKE_STATIC_ENT(68, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  65. MAKE_STATIC_ENT(69, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  66. MAKE_STATIC_ENT(70, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  67. MAKE_STATIC_ENT(71, NGHTTP3_QPACK_TOKEN__STATUS, 4000288983u),
  68. MAKE_STATIC_ENT(29, NGHTTP3_QPACK_TOKEN_ACCEPT, 136609321u),
  69. MAKE_STATIC_ENT(30, NGHTTP3_QPACK_TOKEN_ACCEPT, 136609321u),
  70. MAKE_STATIC_ENT(31, NGHTTP3_QPACK_TOKEN_ACCEPT_ENCODING, 3379649177u),
  71. MAKE_STATIC_ENT(72, NGHTTP3_QPACK_TOKEN_ACCEPT_LANGUAGE, 1979086614u),
  72. MAKE_STATIC_ENT(32, NGHTTP3_QPACK_TOKEN_ACCEPT_RANGES, 1713753958u),
  73. MAKE_STATIC_ENT(73, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_CREDENTIALS,
  74. 901040780u),
  75. MAKE_STATIC_ENT(74, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_CREDENTIALS,
  76. 901040780u),
  77. MAKE_STATIC_ENT(33, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS,
  78. 1524311232u),
  79. MAKE_STATIC_ENT(34, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS,
  80. 1524311232u),
  81. MAKE_STATIC_ENT(75, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS,
  82. 1524311232u),
  83. MAKE_STATIC_ENT(76, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS,
  84. 2175229868u),
  85. MAKE_STATIC_ENT(77, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS,
  86. 2175229868u),
  87. MAKE_STATIC_ENT(78, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS,
  88. 2175229868u),
  89. MAKE_STATIC_ENT(35, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN,
  90. 2710797292u),
  91. MAKE_STATIC_ENT(79, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_EXPOSE_HEADERS,
  92. 2449824425u),
  93. MAKE_STATIC_ENT(80, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_HEADERS,
  94. 3599549072u),
  95. MAKE_STATIC_ENT(81, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_METHOD,
  96. 2417078055u),
  97. MAKE_STATIC_ENT(82, NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_METHOD,
  98. 2417078055u),
  99. MAKE_STATIC_ENT(2, NGHTTP3_QPACK_TOKEN_AGE, 742476188u),
  100. MAKE_STATIC_ENT(83, NGHTTP3_QPACK_TOKEN_ALT_SVC, 2148877059u),
  101. MAKE_STATIC_ENT(84, NGHTTP3_QPACK_TOKEN_AUTHORIZATION, 2436257726u),
  102. MAKE_STATIC_ENT(36, NGHTTP3_QPACK_TOKEN_CACHE_CONTROL, 1355326669u),
  103. MAKE_STATIC_ENT(37, NGHTTP3_QPACK_TOKEN_CACHE_CONTROL, 1355326669u),
  104. MAKE_STATIC_ENT(38, NGHTTP3_QPACK_TOKEN_CACHE_CONTROL, 1355326669u),
  105. MAKE_STATIC_ENT(39, NGHTTP3_QPACK_TOKEN_CACHE_CONTROL, 1355326669u),
  106. MAKE_STATIC_ENT(40, NGHTTP3_QPACK_TOKEN_CACHE_CONTROL, 1355326669u),
  107. MAKE_STATIC_ENT(41, NGHTTP3_QPACK_TOKEN_CACHE_CONTROL, 1355326669u),
  108. MAKE_STATIC_ENT(3, NGHTTP3_QPACK_TOKEN_CONTENT_DISPOSITION, 3889184348u),
  109. MAKE_STATIC_ENT(42, NGHTTP3_QPACK_TOKEN_CONTENT_ENCODING, 65203592u),
  110. MAKE_STATIC_ENT(43, NGHTTP3_QPACK_TOKEN_CONTENT_ENCODING, 65203592u),
  111. MAKE_STATIC_ENT(4, NGHTTP3_QPACK_TOKEN_CONTENT_LENGTH, 1308181789u),
  112. MAKE_STATIC_ENT(85, NGHTTP3_QPACK_TOKEN_CONTENT_SECURITY_POLICY, 1569039836u),
  113. MAKE_STATIC_ENT(44, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  114. MAKE_STATIC_ENT(45, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  115. MAKE_STATIC_ENT(46, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  116. MAKE_STATIC_ENT(47, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  117. MAKE_STATIC_ENT(48, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  118. MAKE_STATIC_ENT(49, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  119. MAKE_STATIC_ENT(50, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  120. MAKE_STATIC_ENT(51, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  121. MAKE_STATIC_ENT(52, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  122. MAKE_STATIC_ENT(53, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  123. MAKE_STATIC_ENT(54, NGHTTP3_QPACK_TOKEN_CONTENT_TYPE, 4244048277u),
  124. MAKE_STATIC_ENT(5, NGHTTP3_QPACK_TOKEN_COOKIE, 2007449791u),
  125. MAKE_STATIC_ENT(6, NGHTTP3_QPACK_TOKEN_DATE, 3564297305u),
  126. MAKE_STATIC_ENT(86, NGHTTP3_QPACK_TOKEN_EARLY_DATA, 4080895051u),
  127. MAKE_STATIC_ENT(7, NGHTTP3_QPACK_TOKEN_ETAG, 113792960u),
  128. MAKE_STATIC_ENT(87, NGHTTP3_QPACK_TOKEN_EXPECT_CT, 1183214960u),
  129. MAKE_STATIC_ENT(88, NGHTTP3_QPACK_TOKEN_FORWARDED, 1485178027u),
  130. MAKE_STATIC_ENT(8, NGHTTP3_QPACK_TOKEN_IF_MODIFIED_SINCE, 2213050793u),
  131. MAKE_STATIC_ENT(9, NGHTTP3_QPACK_TOKEN_IF_NONE_MATCH, 2536202615u),
  132. MAKE_STATIC_ENT(89, NGHTTP3_QPACK_TOKEN_IF_RANGE, 2340978238u),
  133. MAKE_STATIC_ENT(10, NGHTTP3_QPACK_TOKEN_LAST_MODIFIED, 3226950251u),
  134. MAKE_STATIC_ENT(11, NGHTTP3_QPACK_TOKEN_LINK, 232457833u),
  135. MAKE_STATIC_ENT(12, NGHTTP3_QPACK_TOKEN_LOCATION, 200649126u),
  136. MAKE_STATIC_ENT(90, NGHTTP3_QPACK_TOKEN_ORIGIN, 3649018447u),
  137. MAKE_STATIC_ENT(91, NGHTTP3_QPACK_TOKEN_PURPOSE, 4212263681u),
  138. MAKE_STATIC_ENT(55, NGHTTP3_QPACK_TOKEN_RANGE, 4208725202u),
  139. MAKE_STATIC_ENT(13, NGHTTP3_QPACK_TOKEN_REFERER, 3969579366u),
  140. MAKE_STATIC_ENT(92, NGHTTP3_QPACK_TOKEN_SERVER, 1085029842u),
  141. MAKE_STATIC_ENT(14, NGHTTP3_QPACK_TOKEN_SET_COOKIE, 1848371000u),
  142. MAKE_STATIC_ENT(56, NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY,
  143. 4138147361u),
  144. MAKE_STATIC_ENT(57, NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY,
  145. 4138147361u),
  146. MAKE_STATIC_ENT(58, NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY,
  147. 4138147361u),
  148. MAKE_STATIC_ENT(93, NGHTTP3_QPACK_TOKEN_TIMING_ALLOW_ORIGIN, 2432297564u),
  149. MAKE_STATIC_ENT(94, NGHTTP3_QPACK_TOKEN_UPGRADE_INSECURE_REQUESTS,
  150. 2479169413u),
  151. MAKE_STATIC_ENT(95, NGHTTP3_QPACK_TOKEN_USER_AGENT, 606444526u),
  152. MAKE_STATIC_ENT(59, NGHTTP3_QPACK_TOKEN_VARY, 1085005381u),
  153. MAKE_STATIC_ENT(60, NGHTTP3_QPACK_TOKEN_VARY, 1085005381u),
  154. MAKE_STATIC_ENT(61, NGHTTP3_QPACK_TOKEN_X_CONTENT_TYPE_OPTIONS, 3644557769u),
  155. MAKE_STATIC_ENT(96, NGHTTP3_QPACK_TOKEN_X_FORWARDED_FOR, 2914187656u),
  156. MAKE_STATIC_ENT(97, NGHTTP3_QPACK_TOKEN_X_FRAME_OPTIONS, 3993834824u),
  157. MAKE_STATIC_ENT(98, NGHTTP3_QPACK_TOKEN_X_FRAME_OPTIONS, 3993834824u),
  158. MAKE_STATIC_ENT(62, NGHTTP3_QPACK_TOKEN_X_XSS_PROTECTION, 2501058888u),
  159. };
  160. /* Make scalar initialization form of nghttp3_qpack_static_entry */
  161. #define MAKE_STATIC_HD(N, V, T) \
  162. { \
  163. {NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \
  164. {NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \
  165. T, \
  166. }
  167. static nghttp3_qpack_static_header stable[] = {
  168. MAKE_STATIC_HD(":authority", "", NGHTTP3_QPACK_TOKEN__AUTHORITY),
  169. MAKE_STATIC_HD(":path", "/", NGHTTP3_QPACK_TOKEN__PATH),
  170. MAKE_STATIC_HD("age", "0", NGHTTP3_QPACK_TOKEN_AGE),
  171. MAKE_STATIC_HD("content-disposition", "",
  172. NGHTTP3_QPACK_TOKEN_CONTENT_DISPOSITION),
  173. MAKE_STATIC_HD("content-length", "0", NGHTTP3_QPACK_TOKEN_CONTENT_LENGTH),
  174. MAKE_STATIC_HD("cookie", "", NGHTTP3_QPACK_TOKEN_COOKIE),
  175. MAKE_STATIC_HD("date", "", NGHTTP3_QPACK_TOKEN_DATE),
  176. MAKE_STATIC_HD("etag", "", NGHTTP3_QPACK_TOKEN_ETAG),
  177. MAKE_STATIC_HD("if-modified-since", "",
  178. NGHTTP3_QPACK_TOKEN_IF_MODIFIED_SINCE),
  179. MAKE_STATIC_HD("if-none-match", "", NGHTTP3_QPACK_TOKEN_IF_NONE_MATCH),
  180. MAKE_STATIC_HD("last-modified", "", NGHTTP3_QPACK_TOKEN_LAST_MODIFIED),
  181. MAKE_STATIC_HD("link", "", NGHTTP3_QPACK_TOKEN_LINK),
  182. MAKE_STATIC_HD("location", "", NGHTTP3_QPACK_TOKEN_LOCATION),
  183. MAKE_STATIC_HD("referer", "", NGHTTP3_QPACK_TOKEN_REFERER),
  184. MAKE_STATIC_HD("set-cookie", "", NGHTTP3_QPACK_TOKEN_SET_COOKIE),
  185. MAKE_STATIC_HD(":method", "CONNECT", NGHTTP3_QPACK_TOKEN__METHOD),
  186. MAKE_STATIC_HD(":method", "DELETE", NGHTTP3_QPACK_TOKEN__METHOD),
  187. MAKE_STATIC_HD(":method", "GET", NGHTTP3_QPACK_TOKEN__METHOD),
  188. MAKE_STATIC_HD(":method", "HEAD", NGHTTP3_QPACK_TOKEN__METHOD),
  189. MAKE_STATIC_HD(":method", "OPTIONS", NGHTTP3_QPACK_TOKEN__METHOD),
  190. MAKE_STATIC_HD(":method", "POST", NGHTTP3_QPACK_TOKEN__METHOD),
  191. MAKE_STATIC_HD(":method", "PUT", NGHTTP3_QPACK_TOKEN__METHOD),
  192. MAKE_STATIC_HD(":scheme", "http", NGHTTP3_QPACK_TOKEN__SCHEME),
  193. MAKE_STATIC_HD(":scheme", "https", NGHTTP3_QPACK_TOKEN__SCHEME),
  194. MAKE_STATIC_HD(":status", "103", NGHTTP3_QPACK_TOKEN__STATUS),
  195. MAKE_STATIC_HD(":status", "200", NGHTTP3_QPACK_TOKEN__STATUS),
  196. MAKE_STATIC_HD(":status", "304", NGHTTP3_QPACK_TOKEN__STATUS),
  197. MAKE_STATIC_HD(":status", "404", NGHTTP3_QPACK_TOKEN__STATUS),
  198. MAKE_STATIC_HD(":status", "503", NGHTTP3_QPACK_TOKEN__STATUS),
  199. MAKE_STATIC_HD("accept", "*/*", NGHTTP3_QPACK_TOKEN_ACCEPT),
  200. MAKE_STATIC_HD("accept", "application/dns-message",
  201. NGHTTP3_QPACK_TOKEN_ACCEPT),
  202. MAKE_STATIC_HD("accept-encoding", "gzip, deflate, br",
  203. NGHTTP3_QPACK_TOKEN_ACCEPT_ENCODING),
  204. MAKE_STATIC_HD("accept-ranges", "bytes", NGHTTP3_QPACK_TOKEN_ACCEPT_RANGES),
  205. MAKE_STATIC_HD("access-control-allow-headers", "cache-control",
  206. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS),
  207. MAKE_STATIC_HD("access-control-allow-headers", "content-type",
  208. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS),
  209. MAKE_STATIC_HD("access-control-allow-origin", "*",
  210. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN),
  211. MAKE_STATIC_HD("cache-control", "max-age=0",
  212. NGHTTP3_QPACK_TOKEN_CACHE_CONTROL),
  213. MAKE_STATIC_HD("cache-control", "max-age=2592000",
  214. NGHTTP3_QPACK_TOKEN_CACHE_CONTROL),
  215. MAKE_STATIC_HD("cache-control", "max-age=604800",
  216. NGHTTP3_QPACK_TOKEN_CACHE_CONTROL),
  217. MAKE_STATIC_HD("cache-control", "no-cache",
  218. NGHTTP3_QPACK_TOKEN_CACHE_CONTROL),
  219. MAKE_STATIC_HD("cache-control", "no-store",
  220. NGHTTP3_QPACK_TOKEN_CACHE_CONTROL),
  221. MAKE_STATIC_HD("cache-control", "public, max-age=31536000",
  222. NGHTTP3_QPACK_TOKEN_CACHE_CONTROL),
  223. MAKE_STATIC_HD("content-encoding", "br",
  224. NGHTTP3_QPACK_TOKEN_CONTENT_ENCODING),
  225. MAKE_STATIC_HD("content-encoding", "gzip",
  226. NGHTTP3_QPACK_TOKEN_CONTENT_ENCODING),
  227. MAKE_STATIC_HD("content-type", "application/dns-message",
  228. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  229. MAKE_STATIC_HD("content-type", "application/javascript",
  230. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  231. MAKE_STATIC_HD("content-type", "application/json",
  232. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  233. MAKE_STATIC_HD("content-type", "application/x-www-form-urlencoded",
  234. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  235. MAKE_STATIC_HD("content-type", "image/gif", NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  236. MAKE_STATIC_HD("content-type", "image/jpeg",
  237. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  238. MAKE_STATIC_HD("content-type", "image/png", NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  239. MAKE_STATIC_HD("content-type", "text/css", NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  240. MAKE_STATIC_HD("content-type", "text/html; charset=utf-8",
  241. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  242. MAKE_STATIC_HD("content-type", "text/plain",
  243. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  244. MAKE_STATIC_HD("content-type", "text/plain;charset=utf-8",
  245. NGHTTP3_QPACK_TOKEN_CONTENT_TYPE),
  246. MAKE_STATIC_HD("range", "bytes=0-", NGHTTP3_QPACK_TOKEN_RANGE),
  247. MAKE_STATIC_HD("strict-transport-security", "max-age=31536000",
  248. NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY),
  249. MAKE_STATIC_HD("strict-transport-security",
  250. "max-age=31536000; includesubdomains",
  251. NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY),
  252. MAKE_STATIC_HD("strict-transport-security",
  253. "max-age=31536000; includesubdomains; preload",
  254. NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY),
  255. MAKE_STATIC_HD("vary", "accept-encoding", NGHTTP3_QPACK_TOKEN_VARY),
  256. MAKE_STATIC_HD("vary", "origin", NGHTTP3_QPACK_TOKEN_VARY),
  257. MAKE_STATIC_HD("x-content-type-options", "nosniff",
  258. NGHTTP3_QPACK_TOKEN_X_CONTENT_TYPE_OPTIONS),
  259. MAKE_STATIC_HD("x-xss-protection", "1; mode=block",
  260. NGHTTP3_QPACK_TOKEN_X_XSS_PROTECTION),
  261. MAKE_STATIC_HD(":status", "100", NGHTTP3_QPACK_TOKEN__STATUS),
  262. MAKE_STATIC_HD(":status", "204", NGHTTP3_QPACK_TOKEN__STATUS),
  263. MAKE_STATIC_HD(":status", "206", NGHTTP3_QPACK_TOKEN__STATUS),
  264. MAKE_STATIC_HD(":status", "302", NGHTTP3_QPACK_TOKEN__STATUS),
  265. MAKE_STATIC_HD(":status", "400", NGHTTP3_QPACK_TOKEN__STATUS),
  266. MAKE_STATIC_HD(":status", "403", NGHTTP3_QPACK_TOKEN__STATUS),
  267. MAKE_STATIC_HD(":status", "421", NGHTTP3_QPACK_TOKEN__STATUS),
  268. MAKE_STATIC_HD(":status", "425", NGHTTP3_QPACK_TOKEN__STATUS),
  269. MAKE_STATIC_HD(":status", "500", NGHTTP3_QPACK_TOKEN__STATUS),
  270. MAKE_STATIC_HD("accept-language", "", NGHTTP3_QPACK_TOKEN_ACCEPT_LANGUAGE),
  271. MAKE_STATIC_HD("access-control-allow-credentials", "FALSE",
  272. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_CREDENTIALS),
  273. MAKE_STATIC_HD("access-control-allow-credentials", "TRUE",
  274. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_CREDENTIALS),
  275. MAKE_STATIC_HD("access-control-allow-headers", "*",
  276. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS),
  277. MAKE_STATIC_HD("access-control-allow-methods", "get",
  278. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS),
  279. MAKE_STATIC_HD("access-control-allow-methods", "get, post, options",
  280. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS),
  281. MAKE_STATIC_HD("access-control-allow-methods", "options",
  282. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS),
  283. MAKE_STATIC_HD("access-control-expose-headers", "content-length",
  284. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_EXPOSE_HEADERS),
  285. MAKE_STATIC_HD("access-control-request-headers", "content-type",
  286. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_HEADERS),
  287. MAKE_STATIC_HD("access-control-request-method", "get",
  288. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_METHOD),
  289. MAKE_STATIC_HD("access-control-request-method", "post",
  290. NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_METHOD),
  291. MAKE_STATIC_HD("alt-svc", "clear", NGHTTP3_QPACK_TOKEN_ALT_SVC),
  292. MAKE_STATIC_HD("authorization", "", NGHTTP3_QPACK_TOKEN_AUTHORIZATION),
  293. MAKE_STATIC_HD("content-security-policy",
  294. "script-src 'none'; object-src 'none'; base-uri 'none'",
  295. NGHTTP3_QPACK_TOKEN_CONTENT_SECURITY_POLICY),
  296. MAKE_STATIC_HD("early-data", "1", NGHTTP3_QPACK_TOKEN_EARLY_DATA),
  297. MAKE_STATIC_HD("expect-ct", "", NGHTTP3_QPACK_TOKEN_EXPECT_CT),
  298. MAKE_STATIC_HD("forwarded", "", NGHTTP3_QPACK_TOKEN_FORWARDED),
  299. MAKE_STATIC_HD("if-range", "", NGHTTP3_QPACK_TOKEN_IF_RANGE),
  300. MAKE_STATIC_HD("origin", "", NGHTTP3_QPACK_TOKEN_ORIGIN),
  301. MAKE_STATIC_HD("purpose", "prefetch", NGHTTP3_QPACK_TOKEN_PURPOSE),
  302. MAKE_STATIC_HD("server", "", NGHTTP3_QPACK_TOKEN_SERVER),
  303. MAKE_STATIC_HD("timing-allow-origin", "*",
  304. NGHTTP3_QPACK_TOKEN_TIMING_ALLOW_ORIGIN),
  305. MAKE_STATIC_HD("upgrade-insecure-requests", "1",
  306. NGHTTP3_QPACK_TOKEN_UPGRADE_INSECURE_REQUESTS),
  307. MAKE_STATIC_HD("user-agent", "", NGHTTP3_QPACK_TOKEN_USER_AGENT),
  308. MAKE_STATIC_HD("x-forwarded-for", "", NGHTTP3_QPACK_TOKEN_X_FORWARDED_FOR),
  309. MAKE_STATIC_HD("x-frame-options", "deny",
  310. NGHTTP3_QPACK_TOKEN_X_FRAME_OPTIONS),
  311. MAKE_STATIC_HD("x-frame-options", "sameorigin",
  312. NGHTTP3_QPACK_TOKEN_X_FRAME_OPTIONS),
  313. };
  314. static int memeq(const void *s1, const void *s2, size_t n) {
  315. return n == 0 || memcmp(s1, s2, n) == 0;
  316. }
  317. /* Generated by genlibtokenlookup.py */
  318. static int32_t qpack_lookup_token(const uint8_t *name, size_t namelen) {
  319. switch (namelen) {
  320. case 2:
  321. switch (name[1]) {
  322. case 'e':
  323. if (memeq("t", name, 1)) {
  324. return NGHTTP3_QPACK_TOKEN_TE;
  325. }
  326. break;
  327. }
  328. break;
  329. case 3:
  330. switch (name[2]) {
  331. case 'e':
  332. if (memeq("ag", name, 2)) {
  333. return NGHTTP3_QPACK_TOKEN_AGE;
  334. }
  335. break;
  336. }
  337. break;
  338. case 4:
  339. switch (name[3]) {
  340. case 'e':
  341. if (memeq("dat", name, 3)) {
  342. return NGHTTP3_QPACK_TOKEN_DATE;
  343. }
  344. break;
  345. case 'g':
  346. if (memeq("eta", name, 3)) {
  347. return NGHTTP3_QPACK_TOKEN_ETAG;
  348. }
  349. break;
  350. case 'k':
  351. if (memeq("lin", name, 3)) {
  352. return NGHTTP3_QPACK_TOKEN_LINK;
  353. }
  354. break;
  355. case 't':
  356. if (memeq("hos", name, 3)) {
  357. return NGHTTP3_QPACK_TOKEN_HOST;
  358. }
  359. break;
  360. case 'y':
  361. if (memeq("var", name, 3)) {
  362. return NGHTTP3_QPACK_TOKEN_VARY;
  363. }
  364. break;
  365. }
  366. break;
  367. case 5:
  368. switch (name[4]) {
  369. case 'e':
  370. if (memeq("rang", name, 4)) {
  371. return NGHTTP3_QPACK_TOKEN_RANGE;
  372. }
  373. break;
  374. case 'h':
  375. if (memeq(":pat", name, 4)) {
  376. return NGHTTP3_QPACK_TOKEN__PATH;
  377. }
  378. break;
  379. }
  380. break;
  381. case 6:
  382. switch (name[5]) {
  383. case 'e':
  384. if (memeq("cooki", name, 5)) {
  385. return NGHTTP3_QPACK_TOKEN_COOKIE;
  386. }
  387. break;
  388. case 'n':
  389. if (memeq("origi", name, 5)) {
  390. return NGHTTP3_QPACK_TOKEN_ORIGIN;
  391. }
  392. break;
  393. case 'r':
  394. if (memeq("serve", name, 5)) {
  395. return NGHTTP3_QPACK_TOKEN_SERVER;
  396. }
  397. break;
  398. case 't':
  399. if (memeq("accep", name, 5)) {
  400. return NGHTTP3_QPACK_TOKEN_ACCEPT;
  401. }
  402. break;
  403. }
  404. break;
  405. case 7:
  406. switch (name[6]) {
  407. case 'c':
  408. if (memeq("alt-sv", name, 6)) {
  409. return NGHTTP3_QPACK_TOKEN_ALT_SVC;
  410. }
  411. break;
  412. case 'd':
  413. if (memeq(":metho", name, 6)) {
  414. return NGHTTP3_QPACK_TOKEN__METHOD;
  415. }
  416. break;
  417. case 'e':
  418. if (memeq(":schem", name, 6)) {
  419. return NGHTTP3_QPACK_TOKEN__SCHEME;
  420. }
  421. if (memeq("purpos", name, 6)) {
  422. return NGHTTP3_QPACK_TOKEN_PURPOSE;
  423. }
  424. if (memeq("upgrad", name, 6)) {
  425. return NGHTTP3_QPACK_TOKEN_UPGRADE;
  426. }
  427. break;
  428. case 'r':
  429. if (memeq("refere", name, 6)) {
  430. return NGHTTP3_QPACK_TOKEN_REFERER;
  431. }
  432. break;
  433. case 's':
  434. if (memeq(":statu", name, 6)) {
  435. return NGHTTP3_QPACK_TOKEN__STATUS;
  436. }
  437. break;
  438. }
  439. break;
  440. case 8:
  441. switch (name[7]) {
  442. case 'e':
  443. if (memeq("if-rang", name, 7)) {
  444. return NGHTTP3_QPACK_TOKEN_IF_RANGE;
  445. }
  446. break;
  447. case 'n':
  448. if (memeq("locatio", name, 7)) {
  449. return NGHTTP3_QPACK_TOKEN_LOCATION;
  450. }
  451. break;
  452. case 'y':
  453. if (memeq("priorit", name, 7)) {
  454. return NGHTTP3_QPACK_TOKEN_PRIORITY;
  455. }
  456. break;
  457. }
  458. break;
  459. case 9:
  460. switch (name[8]) {
  461. case 'd':
  462. if (memeq("forwarde", name, 8)) {
  463. return NGHTTP3_QPACK_TOKEN_FORWARDED;
  464. }
  465. break;
  466. case 'l':
  467. if (memeq(":protoco", name, 8)) {
  468. return NGHTTP3_QPACK_TOKEN__PROTOCOL;
  469. }
  470. break;
  471. case 't':
  472. if (memeq("expect-c", name, 8)) {
  473. return NGHTTP3_QPACK_TOKEN_EXPECT_CT;
  474. }
  475. break;
  476. }
  477. break;
  478. case 10:
  479. switch (name[9]) {
  480. case 'a':
  481. if (memeq("early-dat", name, 9)) {
  482. return NGHTTP3_QPACK_TOKEN_EARLY_DATA;
  483. }
  484. break;
  485. case 'e':
  486. if (memeq("keep-aliv", name, 9)) {
  487. return NGHTTP3_QPACK_TOKEN_KEEP_ALIVE;
  488. }
  489. if (memeq("set-cooki", name, 9)) {
  490. return NGHTTP3_QPACK_TOKEN_SET_COOKIE;
  491. }
  492. break;
  493. case 'n':
  494. if (memeq("connectio", name, 9)) {
  495. return NGHTTP3_QPACK_TOKEN_CONNECTION;
  496. }
  497. break;
  498. case 't':
  499. if (memeq("user-agen", name, 9)) {
  500. return NGHTTP3_QPACK_TOKEN_USER_AGENT;
  501. }
  502. break;
  503. case 'y':
  504. if (memeq(":authorit", name, 9)) {
  505. return NGHTTP3_QPACK_TOKEN__AUTHORITY;
  506. }
  507. break;
  508. }
  509. break;
  510. case 12:
  511. switch (name[11]) {
  512. case 'e':
  513. if (memeq("content-typ", name, 11)) {
  514. return NGHTTP3_QPACK_TOKEN_CONTENT_TYPE;
  515. }
  516. break;
  517. }
  518. break;
  519. case 13:
  520. switch (name[12]) {
  521. case 'd':
  522. if (memeq("last-modifie", name, 12)) {
  523. return NGHTTP3_QPACK_TOKEN_LAST_MODIFIED;
  524. }
  525. break;
  526. case 'h':
  527. if (memeq("if-none-matc", name, 12)) {
  528. return NGHTTP3_QPACK_TOKEN_IF_NONE_MATCH;
  529. }
  530. break;
  531. case 'l':
  532. if (memeq("cache-contro", name, 12)) {
  533. return NGHTTP3_QPACK_TOKEN_CACHE_CONTROL;
  534. }
  535. break;
  536. case 'n':
  537. if (memeq("authorizatio", name, 12)) {
  538. return NGHTTP3_QPACK_TOKEN_AUTHORIZATION;
  539. }
  540. break;
  541. case 's':
  542. if (memeq("accept-range", name, 12)) {
  543. return NGHTTP3_QPACK_TOKEN_ACCEPT_RANGES;
  544. }
  545. break;
  546. }
  547. break;
  548. case 14:
  549. switch (name[13]) {
  550. case 'h':
  551. if (memeq("content-lengt", name, 13)) {
  552. return NGHTTP3_QPACK_TOKEN_CONTENT_LENGTH;
  553. }
  554. break;
  555. }
  556. break;
  557. case 15:
  558. switch (name[14]) {
  559. case 'e':
  560. if (memeq("accept-languag", name, 14)) {
  561. return NGHTTP3_QPACK_TOKEN_ACCEPT_LANGUAGE;
  562. }
  563. break;
  564. case 'g':
  565. if (memeq("accept-encodin", name, 14)) {
  566. return NGHTTP3_QPACK_TOKEN_ACCEPT_ENCODING;
  567. }
  568. break;
  569. case 'r':
  570. if (memeq("x-forwarded-fo", name, 14)) {
  571. return NGHTTP3_QPACK_TOKEN_X_FORWARDED_FOR;
  572. }
  573. break;
  574. case 's':
  575. if (memeq("x-frame-option", name, 14)) {
  576. return NGHTTP3_QPACK_TOKEN_X_FRAME_OPTIONS;
  577. }
  578. break;
  579. }
  580. break;
  581. case 16:
  582. switch (name[15]) {
  583. case 'g':
  584. if (memeq("content-encodin", name, 15)) {
  585. return NGHTTP3_QPACK_TOKEN_CONTENT_ENCODING;
  586. }
  587. break;
  588. case 'n':
  589. if (memeq("proxy-connectio", name, 15)) {
  590. return NGHTTP3_QPACK_TOKEN_PROXY_CONNECTION;
  591. }
  592. if (memeq("x-xss-protectio", name, 15)) {
  593. return NGHTTP3_QPACK_TOKEN_X_XSS_PROTECTION;
  594. }
  595. break;
  596. }
  597. break;
  598. case 17:
  599. switch (name[16]) {
  600. case 'e':
  601. if (memeq("if-modified-sinc", name, 16)) {
  602. return NGHTTP3_QPACK_TOKEN_IF_MODIFIED_SINCE;
  603. }
  604. break;
  605. case 'g':
  606. if (memeq("transfer-encodin", name, 16)) {
  607. return NGHTTP3_QPACK_TOKEN_TRANSFER_ENCODING;
  608. }
  609. break;
  610. }
  611. break;
  612. case 19:
  613. switch (name[18]) {
  614. case 'n':
  615. if (memeq("content-dispositio", name, 18)) {
  616. return NGHTTP3_QPACK_TOKEN_CONTENT_DISPOSITION;
  617. }
  618. if (memeq("timing-allow-origi", name, 18)) {
  619. return NGHTTP3_QPACK_TOKEN_TIMING_ALLOW_ORIGIN;
  620. }
  621. break;
  622. }
  623. break;
  624. case 22:
  625. switch (name[21]) {
  626. case 's':
  627. if (memeq("x-content-type-option", name, 21)) {
  628. return NGHTTP3_QPACK_TOKEN_X_CONTENT_TYPE_OPTIONS;
  629. }
  630. break;
  631. }
  632. break;
  633. case 23:
  634. switch (name[22]) {
  635. case 'y':
  636. if (memeq("content-security-polic", name, 22)) {
  637. return NGHTTP3_QPACK_TOKEN_CONTENT_SECURITY_POLICY;
  638. }
  639. break;
  640. }
  641. break;
  642. case 25:
  643. switch (name[24]) {
  644. case 's':
  645. if (memeq("upgrade-insecure-request", name, 24)) {
  646. return NGHTTP3_QPACK_TOKEN_UPGRADE_INSECURE_REQUESTS;
  647. }
  648. break;
  649. case 'y':
  650. if (memeq("strict-transport-securit", name, 24)) {
  651. return NGHTTP3_QPACK_TOKEN_STRICT_TRANSPORT_SECURITY;
  652. }
  653. break;
  654. }
  655. break;
  656. case 27:
  657. switch (name[26]) {
  658. case 'n':
  659. if (memeq("access-control-allow-origi", name, 26)) {
  660. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN;
  661. }
  662. break;
  663. }
  664. break;
  665. case 28:
  666. switch (name[27]) {
  667. case 's':
  668. if (memeq("access-control-allow-header", name, 27)) {
  669. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS;
  670. }
  671. if (memeq("access-control-allow-method", name, 27)) {
  672. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_METHODS;
  673. }
  674. break;
  675. }
  676. break;
  677. case 29:
  678. switch (name[28]) {
  679. case 'd':
  680. if (memeq("access-control-request-metho", name, 28)) {
  681. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_METHOD;
  682. }
  683. break;
  684. case 's':
  685. if (memeq("access-control-expose-header", name, 28)) {
  686. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_EXPOSE_HEADERS;
  687. }
  688. break;
  689. }
  690. break;
  691. case 30:
  692. switch (name[29]) {
  693. case 's':
  694. if (memeq("access-control-request-header", name, 29)) {
  695. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_REQUEST_HEADERS;
  696. }
  697. break;
  698. }
  699. break;
  700. case 32:
  701. switch (name[31]) {
  702. case 's':
  703. if (memeq("access-control-allow-credential", name, 31)) {
  704. return NGHTTP3_QPACK_TOKEN_ACCESS_CONTROL_ALLOW_CREDENTIALS;
  705. }
  706. break;
  707. }
  708. break;
  709. }
  710. return -1;
  711. }
  712. static size_t table_space(size_t namelen, size_t valuelen) {
  713. return NGHTTP3_QPACK_ENTRY_OVERHEAD + namelen + valuelen;
  714. }
  715. static int qpack_nv_name_eq(const nghttp3_qpack_nv *a, const nghttp3_nv *b) {
  716. return a->name->len == b->namelen &&
  717. memeq(a->name->base, b->name, b->namelen);
  718. }
  719. static int qpack_nv_value_eq(const nghttp3_qpack_nv *a, const nghttp3_nv *b) {
  720. return a->value->len == b->valuelen &&
  721. memeq(a->value->base, b->value, b->valuelen);
  722. }
  723. static void qpack_map_init(nghttp3_qpack_map *map) {
  724. memset(map, 0, sizeof(nghttp3_qpack_map));
  725. }
  726. static void qpack_map_insert(nghttp3_qpack_map *map, nghttp3_qpack_entry *ent) {
  727. nghttp3_qpack_entry **bucket;
  728. bucket = &map->table[ent->hash & (NGHTTP3_QPACK_MAP_SIZE - 1)];
  729. if (*bucket == NULL) {
  730. *bucket = ent;
  731. return;
  732. }
  733. /* larger absidx is linked near the root */
  734. ent->map_next = *bucket;
  735. *bucket = ent;
  736. }
  737. static void qpack_map_remove(nghttp3_qpack_map *map, nghttp3_qpack_entry *ent) {
  738. nghttp3_qpack_entry **dst;
  739. dst = &map->table[ent->hash & (NGHTTP3_QPACK_MAP_SIZE - 1)];
  740. for (; *dst; dst = &(*dst)->map_next) {
  741. if (*dst != ent) {
  742. continue;
  743. }
  744. *dst = ent->map_next;
  745. ent->map_next = NULL;
  746. return;
  747. }
  748. }
  749. /*
  750. * qpack_context_can_reference returns nonzero if dynamic table entry
  751. * at |absidx| can be referenced. In other words, it is within
  752. * ctx->max_dtable_capacity.
  753. */
  754. static int qpack_context_can_reference(nghttp3_qpack_context *ctx,
  755. uint64_t absidx) {
  756. nghttp3_qpack_entry *ent = nghttp3_qpack_context_dtable_get(ctx, absidx);
  757. return ctx->dtable_sum - ent->sum <= ctx->max_dtable_capacity;
  758. }
  759. /* |*ppb_match| (post-base match), if it is not NULL, is always exact
  760. match. */
  761. static void encoder_qpack_map_find(nghttp3_qpack_encoder *encoder,
  762. int *exact_match,
  763. nghttp3_qpack_entry **pmatch,
  764. nghttp3_qpack_entry **ppb_match,
  765. const nghttp3_nv *nv, int32_t token,
  766. uint32_t hash, uint64_t krcnt,
  767. int allow_blocking, int name_only) {
  768. nghttp3_qpack_entry *p;
  769. *exact_match = 0;
  770. *pmatch = NULL;
  771. *ppb_match = NULL;
  772. for (p = encoder->dtable_map.table[hash & (NGHTTP3_QPACK_MAP_SIZE - 1)]; p;
  773. p = p->map_next) {
  774. if (token != p->nv.token ||
  775. (token == -1 && (hash != p->hash || !qpack_nv_name_eq(&p->nv, nv))) ||
  776. !qpack_context_can_reference(&encoder->ctx, p->absidx)) {
  777. continue;
  778. }
  779. if (allow_blocking || p->absidx + 1 <= krcnt) {
  780. if (!*pmatch) {
  781. *pmatch = p;
  782. if (name_only) {
  783. return;
  784. }
  785. }
  786. if (qpack_nv_value_eq(&p->nv, nv)) {
  787. *pmatch = p;
  788. *exact_match = 1;
  789. return;
  790. }
  791. } else if (!*ppb_match && qpack_nv_value_eq(&p->nv, nv)) {
  792. *ppb_match = p;
  793. }
  794. }
  795. }
  796. /*
  797. * qpack_context_init initializes |ctx|. |hard_max_dtable_capacity|
  798. * is the upper bound of the dynamic table capacity. |mem| is a
  799. * memory allocator.
  800. *
  801. * The maximum dynamic table size is governed by
  802. * ctx->max_dtable_capacity and it is initialized to 0.
  803. * |hard_max_dtable_capacity| is the upper bound of
  804. * ctx->max_dtable_capacity.
  805. *
  806. * This function returns 0 if it succeeds, or one of the following
  807. * negative error codes:
  808. *
  809. * NGHTTP3_ERR_NOMEM
  810. * Out of memory.
  811. */
  812. static int qpack_context_init(nghttp3_qpack_context *ctx,
  813. size_t hard_max_dtable_capacity,
  814. size_t max_blocked_streams,
  815. const nghttp3_mem *mem) {
  816. int rv;
  817. size_t len = 4096 / NGHTTP3_QPACK_ENTRY_OVERHEAD;
  818. size_t len2;
  819. for (len2 = 1; len2 < len; len2 <<= 1)
  820. ;
  821. rv = nghttp3_ringbuf_init(&ctx->dtable, len2, sizeof(nghttp3_qpack_entry *),
  822. mem);
  823. if (rv != 0) {
  824. return rv;
  825. }
  826. ctx->mem = mem;
  827. ctx->dtable_size = 0;
  828. ctx->dtable_sum = 0;
  829. ctx->hard_max_dtable_capacity = hard_max_dtable_capacity;
  830. ctx->max_dtable_capacity = 0;
  831. ctx->max_blocked_streams = max_blocked_streams;
  832. ctx->next_absidx = 0;
  833. ctx->bad = 0;
  834. return 0;
  835. }
  836. static void qpack_context_free(nghttp3_qpack_context *ctx) {
  837. nghttp3_qpack_entry *ent;
  838. size_t i, len = nghttp3_ringbuf_len(&ctx->dtable);
  839. for (i = 0; i < len; ++i) {
  840. ent = *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(&ctx->dtable, i);
  841. nghttp3_qpack_entry_free(ent);
  842. nghttp3_mem_free(ctx->mem, ent);
  843. }
  844. nghttp3_ringbuf_free(&ctx->dtable);
  845. }
  846. static int ref_min_cnt_less(const nghttp3_pq_entry *lhsx,
  847. const nghttp3_pq_entry *rhsx) {
  848. nghttp3_qpack_header_block_ref *lhs =
  849. nghttp3_struct_of(lhsx, nghttp3_qpack_header_block_ref, min_cnts_pe);
  850. nghttp3_qpack_header_block_ref *rhs =
  851. nghttp3_struct_of(rhsx, nghttp3_qpack_header_block_ref, min_cnts_pe);
  852. return lhs->min_cnt < rhs->min_cnt;
  853. }
  854. typedef struct nghttp3_blocked_streams_key {
  855. uint64_t max_cnt;
  856. uint64_t id;
  857. } nghttp3_blocked_streams_key;
  858. static int max_cnt_greater(const nghttp3_ksl_key *lhs,
  859. const nghttp3_ksl_key *rhs) {
  860. const nghttp3_blocked_streams_key *a = lhs;
  861. const nghttp3_blocked_streams_key *b = rhs;
  862. return a->max_cnt > b->max_cnt || (a->max_cnt == b->max_cnt && a->id < b->id);
  863. }
  864. nghttp3_ksl_search_def(max_cnt_greater, max_cnt_greater)
  865. int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
  866. size_t hard_max_dtable_capacity,
  867. const nghttp3_mem *mem) {
  868. int rv;
  869. rv = qpack_context_init(&encoder->ctx, hard_max_dtable_capacity, 0, mem);
  870. if (rv != 0) {
  871. return rv;
  872. }
  873. nghttp3_map_init(&encoder->streams, mem);
  874. nghttp3_ksl_init(&encoder->blocked_streams, max_cnt_greater,
  875. ksl_max_cnt_greater_search,
  876. sizeof(nghttp3_blocked_streams_key), mem);
  877. qpack_map_init(&encoder->dtable_map);
  878. nghttp3_pq_init(&encoder->min_cnts, ref_min_cnt_less, mem);
  879. encoder->krcnt = 0;
  880. encoder->state = NGHTTP3_QPACK_DS_STATE_OPCODE;
  881. encoder->opcode = 0;
  882. encoder->min_dtable_update = SIZE_MAX;
  883. encoder->last_max_dtable_update = 0;
  884. encoder->uninterrupted_decoderlen = 0;
  885. encoder->flags = NGHTTP3_QPACK_ENCODER_FLAG_NONE;
  886. nghttp3_qpack_read_state_reset(&encoder->rstate);
  887. return 0;
  888. }
  889. static int map_stream_free(void *data, void *ptr) {
  890. const nghttp3_mem *mem = ptr;
  891. nghttp3_qpack_stream *stream = data;
  892. nghttp3_qpack_stream_del(stream, mem);
  893. return 0;
  894. }
  895. void nghttp3_qpack_encoder_free(nghttp3_qpack_encoder *encoder) {
  896. nghttp3_pq_free(&encoder->min_cnts);
  897. nghttp3_ksl_free(&encoder->blocked_streams);
  898. nghttp3_map_each(&encoder->streams, map_stream_free,
  899. (void *)encoder->ctx.mem);
  900. nghttp3_map_free(&encoder->streams);
  901. qpack_context_free(&encoder->ctx);
  902. }
  903. void nghttp3_qpack_encoder_set_max_dtable_capacity(
  904. nghttp3_qpack_encoder *encoder, size_t max_dtable_capacity) {
  905. max_dtable_capacity = nghttp3_min_size(max_dtable_capacity,
  906. encoder->ctx.hard_max_dtable_capacity);
  907. if (encoder->ctx.max_dtable_capacity == max_dtable_capacity) {
  908. return;
  909. }
  910. encoder->flags |= NGHTTP3_QPACK_ENCODER_FLAG_PENDING_SET_DTABLE_CAP;
  911. if (encoder->min_dtable_update > max_dtable_capacity) {
  912. encoder->min_dtable_update = max_dtable_capacity;
  913. encoder->ctx.max_dtable_capacity = max_dtable_capacity;
  914. }
  915. encoder->last_max_dtable_update = max_dtable_capacity;
  916. }
  917. void nghttp3_qpack_encoder_set_max_blocked_streams(
  918. nghttp3_qpack_encoder *encoder, size_t max_blocked_streams) {
  919. encoder->ctx.max_blocked_streams = max_blocked_streams;
  920. }
  921. uint64_t nghttp3_qpack_encoder_get_min_cnt(nghttp3_qpack_encoder *encoder) {
  922. assert(!nghttp3_pq_empty(&encoder->min_cnts));
  923. return nghttp3_struct_of(nghttp3_pq_top(&encoder->min_cnts),
  924. nghttp3_qpack_header_block_ref, min_cnts_pe)
  925. ->min_cnt;
  926. }
  927. void nghttp3_qpack_encoder_shrink_dtable(nghttp3_qpack_encoder *encoder) {
  928. nghttp3_ringbuf *dtable = &encoder->ctx.dtable;
  929. const nghttp3_mem *mem = encoder->ctx.mem;
  930. uint64_t min_cnt = UINT64_MAX;
  931. size_t len;
  932. nghttp3_qpack_entry *ent;
  933. if (encoder->ctx.dtable_size <= encoder->ctx.max_dtable_capacity) {
  934. return;
  935. }
  936. if (!nghttp3_pq_empty(&encoder->min_cnts)) {
  937. min_cnt = nghttp3_qpack_encoder_get_min_cnt(encoder);
  938. }
  939. for (; encoder->ctx.dtable_size > encoder->ctx.max_dtable_capacity;) {
  940. len = nghttp3_ringbuf_len(dtable);
  941. ent = *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(dtable, len - 1);
  942. if (ent->absidx + 1 == min_cnt) {
  943. return;
  944. }
  945. encoder->ctx.dtable_size -=
  946. table_space(ent->nv.name->len, ent->nv.value->len);
  947. nghttp3_ringbuf_pop_back(dtable);
  948. qpack_map_remove(&encoder->dtable_map, ent);
  949. nghttp3_qpack_entry_free(ent);
  950. nghttp3_mem_free(mem, ent);
  951. }
  952. }
  953. /*
  954. * qpack_encoder_add_stream_ref adds another dynamic table reference
  955. * to a stream denoted by |stream_id|. |stream| must be NULL if no
  956. * stream object is not found for the given stream ID. |max_cnt| and
  957. * |min_cnt| is the maximum and minimum insert count it references
  958. * respectively.
  959. *
  960. * This function returns 0 if it succeeds, or one of the following
  961. * negative error codes:
  962. *
  963. * NGHTTP3_ERR_NOMEM
  964. * Out of memory.
  965. */
  966. static int qpack_encoder_add_stream_ref(nghttp3_qpack_encoder *encoder,
  967. int64_t stream_id,
  968. nghttp3_qpack_stream *stream,
  969. uint64_t max_cnt, uint64_t min_cnt) {
  970. nghttp3_qpack_header_block_ref *ref;
  971. const nghttp3_mem *mem = encoder->ctx.mem;
  972. uint64_t prev_max_cnt = 0;
  973. int rv;
  974. if (stream == NULL) {
  975. rv = nghttp3_qpack_stream_new(&stream, stream_id, mem);
  976. if (rv != 0) {
  977. assert(rv == NGHTTP3_ERR_NOMEM);
  978. return rv;
  979. }
  980. rv = nghttp3_map_insert(&encoder->streams,
  981. (nghttp3_map_key_type)stream->stream_id, stream);
  982. if (rv != 0) {
  983. assert(rv == NGHTTP3_ERR_NOMEM);
  984. nghttp3_qpack_stream_del(stream, mem);
  985. return rv;
  986. }
  987. } else {
  988. prev_max_cnt = nghttp3_qpack_stream_get_max_cnt(stream);
  989. if (nghttp3_qpack_encoder_stream_is_blocked(encoder, stream) &&
  990. max_cnt > prev_max_cnt) {
  991. nghttp3_qpack_encoder_unblock_stream(encoder, stream);
  992. }
  993. }
  994. rv = nghttp3_qpack_header_block_ref_new(&ref, max_cnt, min_cnt, mem);
  995. if (rv != 0) {
  996. return rv;
  997. }
  998. rv = nghttp3_qpack_stream_add_ref(stream, ref);
  999. if (rv != 0) {
  1000. nghttp3_qpack_header_block_ref_del(ref, mem);
  1001. return rv;
  1002. }
  1003. if (max_cnt > prev_max_cnt &&
  1004. nghttp3_qpack_encoder_stream_is_blocked(encoder, stream)) {
  1005. rv = nghttp3_qpack_encoder_block_stream(encoder, stream);
  1006. if (rv != 0) {
  1007. return rv;
  1008. }
  1009. }
  1010. return nghttp3_pq_push(&encoder->min_cnts, &ref->min_cnts_pe);
  1011. }
  1012. static void qpack_encoder_remove_stream(nghttp3_qpack_encoder *encoder,
  1013. nghttp3_qpack_stream *stream) {
  1014. size_t i, len;
  1015. nghttp3_qpack_header_block_ref *ref;
  1016. nghttp3_map_remove(&encoder->streams,
  1017. (nghttp3_map_key_type)stream->stream_id);
  1018. len = nghttp3_ringbuf_len(&stream->refs);
  1019. for (i = 0; i < len; ++i) {
  1020. ref =
  1021. *(nghttp3_qpack_header_block_ref **)nghttp3_ringbuf_get(&stream->refs, i);
  1022. assert(ref->min_cnts_pe.index != NGHTTP3_PQ_BAD_INDEX);
  1023. nghttp3_pq_remove(&encoder->min_cnts, &ref->min_cnts_pe);
  1024. }
  1025. }
  1026. /*
  1027. * reserve_buf ensures that |buf| contains at least |extra_size| of
  1028. * free space. In other words, if this function succeeds,
  1029. * nghttp3_buf_left(buf) >= extra_size holds.
  1030. *
  1031. * This function returns 0 if it succeeds, or one of the following
  1032. * negative error codes:
  1033. *
  1034. * NGHTTP3_ERR_NOMEM
  1035. * Out of memory.
  1036. */
  1037. static int reserve_buf(nghttp3_buf *buf, size_t extra_size,
  1038. const nghttp3_mem *mem) {
  1039. size_t left = nghttp3_buf_left(buf);
  1040. size_t n = 32;
  1041. if (left >= extra_size) {
  1042. return 0;
  1043. }
  1044. n = nghttp3_max_size(n, nghttp3_buf_cap(buf) + extra_size - left);
  1045. /* Check whether we are requesting too much memory */
  1046. if (n > (1u << 31)) {
  1047. return NGHTTP3_ERR_NOMEM;
  1048. }
  1049. #ifndef WIN32
  1050. n = 1u << (32 - __builtin_clz((uint32_t)n - 1));
  1051. #else /* defined(WIN32) */
  1052. /* Round up to the next highest power of 2 from Bit Twiddling
  1053. Hacks */
  1054. --n;
  1055. n |= n >> 1;
  1056. n |= n >> 2;
  1057. n |= n >> 4;
  1058. n |= n >> 8;
  1059. n |= n >> 16;
  1060. ++n;
  1061. #endif /* defined(WIN32) */
  1062. return nghttp3_buf_reserve(buf, n, mem);
  1063. }
  1064. int nghttp3_qpack_encoder_encode(nghttp3_qpack_encoder *encoder,
  1065. nghttp3_buf *pbuf, nghttp3_buf *rbuf,
  1066. nghttp3_buf *ebuf, int64_t stream_id,
  1067. const nghttp3_nv *nva, size_t nvlen) {
  1068. size_t i;
  1069. uint64_t max_cnt = 0, min_cnt = UINT64_MAX;
  1070. uint64_t base;
  1071. int rv = 0;
  1072. int allow_blocking;
  1073. int blocked_stream;
  1074. nghttp3_qpack_stream *stream;
  1075. if (encoder->ctx.bad) {
  1076. return NGHTTP3_ERR_QPACK_FATAL;
  1077. }
  1078. rv = nghttp3_qpack_encoder_process_dtable_update(encoder, ebuf);
  1079. if (rv != 0) {
  1080. goto fail;
  1081. }
  1082. base = encoder->ctx.next_absidx;
  1083. stream = nghttp3_qpack_encoder_find_stream(encoder, stream_id);
  1084. blocked_stream =
  1085. stream && nghttp3_qpack_encoder_stream_is_blocked(encoder, stream);
  1086. allow_blocking =
  1087. blocked_stream || encoder->ctx.max_blocked_streams >
  1088. nghttp3_ksl_len(&encoder->blocked_streams);
  1089. DEBUGF("qpack::encode: stream %ld blocked=%d allow_blocking=%d\n", stream_id,
  1090. blocked_stream, allow_blocking);
  1091. for (i = 0; i < nvlen; ++i) {
  1092. rv = nghttp3_qpack_encoder_encode_nv(encoder, &max_cnt, &min_cnt, rbuf,
  1093. ebuf, &nva[i], base, allow_blocking);
  1094. if (rv != 0) {
  1095. goto fail;
  1096. }
  1097. }
  1098. nghttp3_qpack_encoder_write_field_section_prefix(encoder, pbuf, max_cnt,
  1099. base);
  1100. encoder->uninterrupted_decoderlen = 0;
  1101. /* TODO If max_cnt == 0, no reference is made to dtable. */
  1102. if (!max_cnt) {
  1103. return 0;
  1104. }
  1105. rv =
  1106. qpack_encoder_add_stream_ref(encoder, stream_id, stream, max_cnt, min_cnt);
  1107. if (rv != 0) {
  1108. goto fail;
  1109. }
  1110. return 0;
  1111. fail:
  1112. encoder->ctx.bad = 1;
  1113. return rv;
  1114. }
  1115. /*
  1116. * qpack_write_number writes variable integer to |rbuf|. |num| is an
  1117. * integer to write. |prefix| is a prefix of variable integer
  1118. * encoding.
  1119. *
  1120. * This function returns 0 if it succeeds, or one of the following
  1121. * negative error codes:
  1122. *
  1123. * NGHTTP3_ERR_NOMEM
  1124. * Out of memory.
  1125. */
  1126. static int qpack_write_number(nghttp3_buf *rbuf, uint8_t fb, uint64_t num,
  1127. size_t prefix, const nghttp3_mem *mem) {
  1128. int rv;
  1129. size_t len = nghttp3_qpack_put_varint_len(num, prefix);
  1130. uint8_t *p;
  1131. rv = reserve_buf(rbuf, len, mem);
  1132. if (rv != 0) {
  1133. return rv;
  1134. }
  1135. p = rbuf->last;
  1136. *p = fb;
  1137. p = nghttp3_qpack_put_varint(p, num, prefix);
  1138. assert((size_t)(p - rbuf->last) == len);
  1139. rbuf->last = p;
  1140. return 0;
  1141. }
  1142. int nghttp3_qpack_encoder_process_dtable_update(nghttp3_qpack_encoder *encoder,
  1143. nghttp3_buf *ebuf) {
  1144. int rv;
  1145. nghttp3_qpack_encoder_shrink_dtable(encoder);
  1146. if (encoder->ctx.max_dtable_capacity < encoder->ctx.dtable_size ||
  1147. !(encoder->flags & NGHTTP3_QPACK_ENCODER_FLAG_PENDING_SET_DTABLE_CAP)) {
  1148. return 0;
  1149. }
  1150. if (encoder->min_dtable_update < encoder->last_max_dtable_update) {
  1151. rv = nghttp3_qpack_encoder_write_set_dtable_cap(encoder, ebuf,
  1152. encoder->min_dtable_update);
  1153. if (rv != 0) {
  1154. return rv;
  1155. }
  1156. }
  1157. rv = nghttp3_qpack_encoder_write_set_dtable_cap(
  1158. encoder, ebuf, encoder->last_max_dtable_update);
  1159. if (rv != 0) {
  1160. return rv;
  1161. }
  1162. encoder->flags &= (uint8_t)~NGHTTP3_QPACK_ENCODER_FLAG_PENDING_SET_DTABLE_CAP;
  1163. encoder->min_dtable_update = SIZE_MAX;
  1164. encoder->ctx.max_dtable_capacity = encoder->last_max_dtable_update;
  1165. return 0;
  1166. }
  1167. int nghttp3_qpack_encoder_write_set_dtable_cap(nghttp3_qpack_encoder *encoder,
  1168. nghttp3_buf *ebuf, size_t cap) {
  1169. DEBUGF("qpack::encode: Set Dynamic Table Capacity capacity=%zu\n", cap);
  1170. return qpack_write_number(ebuf, 0x20, cap, 5, encoder->ctx.mem);
  1171. }
  1172. nghttp3_qpack_stream *
  1173. nghttp3_qpack_encoder_find_stream(nghttp3_qpack_encoder *encoder,
  1174. int64_t stream_id) {
  1175. return nghttp3_map_find(&encoder->streams, (nghttp3_map_key_type)stream_id);
  1176. }
  1177. int nghttp3_qpack_encoder_stream_is_blocked(nghttp3_qpack_encoder *encoder,
  1178. nghttp3_qpack_stream *stream) {
  1179. return stream && encoder->krcnt < nghttp3_qpack_stream_get_max_cnt(stream);
  1180. }
  1181. static uint32_t qpack_hash_name(const nghttp3_nv *nv) {
  1182. /* 32 bit FNV-1a: http://isthe.com/chongo/tech/comp/fnv/ */
  1183. uint32_t h = 2166136261u;
  1184. size_t i;
  1185. for (i = 0; i < nv->namelen; ++i) {
  1186. h ^= nv->name[i];
  1187. h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
  1188. }
  1189. return h;
  1190. }
  1191. /*
  1192. * qpack_encoder_decide_indexing_mode determines and returns indexing
  1193. * mode for header field |nv|. |token| is a token of header field
  1194. * name.
  1195. */
  1196. static nghttp3_qpack_indexing_mode
  1197. qpack_encoder_decide_indexing_mode(nghttp3_qpack_encoder *encoder,
  1198. const nghttp3_nv *nv, int32_t token) {
  1199. if (nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) {
  1200. return NGHTTP3_QPACK_INDEXING_MODE_NEVER;
  1201. }
  1202. switch (token) {
  1203. case NGHTTP3_QPACK_TOKEN_AUTHORIZATION:
  1204. return NGHTTP3_QPACK_INDEXING_MODE_NEVER;
  1205. case NGHTTP3_QPACK_TOKEN_COOKIE:
  1206. if (nv->valuelen < 20) {
  1207. return NGHTTP3_QPACK_INDEXING_MODE_NEVER;
  1208. }
  1209. break;
  1210. case -1:
  1211. case NGHTTP3_QPACK_TOKEN__PATH:
  1212. case NGHTTP3_QPACK_TOKEN_AGE:
  1213. case NGHTTP3_QPACK_TOKEN_CONTENT_LENGTH:
  1214. case NGHTTP3_QPACK_TOKEN_ETAG:
  1215. case NGHTTP3_QPACK_TOKEN_IF_MODIFIED_SINCE:
  1216. case NGHTTP3_QPACK_TOKEN_IF_NONE_MATCH:
  1217. case NGHTTP3_QPACK_TOKEN_LOCATION:
  1218. case NGHTTP3_QPACK_TOKEN_SET_COOKIE:
  1219. if (nv->flags & NGHTTP3_NV_FLAG_TRY_INDEX) {
  1220. break;
  1221. }
  1222. return NGHTTP3_QPACK_INDEXING_MODE_LITERAL;
  1223. case NGHTTP3_QPACK_TOKEN_HOST:
  1224. case NGHTTP3_QPACK_TOKEN_TE:
  1225. case NGHTTP3_QPACK_TOKEN__PROTOCOL:
  1226. case NGHTTP3_QPACK_TOKEN_PRIORITY:
  1227. break;
  1228. default:
  1229. if (nv->flags & NGHTTP3_NV_FLAG_TRY_INDEX) {
  1230. break;
  1231. }
  1232. if (token >= 1000) {
  1233. return NGHTTP3_QPACK_INDEXING_MODE_LITERAL;
  1234. }
  1235. }
  1236. if (table_space(nv->namelen, nv->valuelen) >
  1237. encoder->ctx.max_dtable_capacity * 3 / 4) {
  1238. return NGHTTP3_QPACK_INDEXING_MODE_LITERAL;
  1239. }
  1240. return NGHTTP3_QPACK_INDEXING_MODE_STORE;
  1241. }
  1242. /*
  1243. * qpack_encoder_can_index returns nonzero if an entry which occupies
  1244. * |need| bytes can be inserted into dynamic table. |min_cnt| is the
  1245. * minimum insert count which blocked stream requires.
  1246. */
  1247. static int qpack_encoder_can_index(nghttp3_qpack_encoder *encoder, size_t need,
  1248. uint64_t min_cnt) {
  1249. size_t avail = 0;
  1250. size_t len;
  1251. uint64_t gmin_cnt;
  1252. nghttp3_qpack_entry *min_ent, *last_ent;
  1253. nghttp3_ringbuf *dtable = &encoder->ctx.dtable;
  1254. if (encoder->ctx.max_dtable_capacity > encoder->ctx.dtable_size) {
  1255. avail = encoder->ctx.max_dtable_capacity - encoder->ctx.dtable_size;
  1256. if (need <= avail) {
  1257. return 1;
  1258. }
  1259. }
  1260. if (!nghttp3_pq_empty(&encoder->min_cnts)) {
  1261. gmin_cnt = nghttp3_qpack_encoder_get_min_cnt(encoder);
  1262. min_cnt = nghttp3_min_uint64(min_cnt, gmin_cnt);
  1263. }
  1264. if (min_cnt == UINT64_MAX) {
  1265. return encoder->ctx.max_dtable_capacity >= need;
  1266. }
  1267. min_ent = nghttp3_qpack_context_dtable_get(&encoder->ctx, min_cnt - 1);
  1268. len = nghttp3_ringbuf_len(&encoder->ctx.dtable);
  1269. assert(len);
  1270. last_ent = *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(dtable, len - 1);
  1271. if (min_ent == last_ent) {
  1272. return 0;
  1273. }
  1274. return avail + min_ent->sum - last_ent->sum >= need;
  1275. }
  1276. /*
  1277. * qpack_encoder_can_index_nv returns nonzero if header field |nv| can
  1278. * be inserted into dynamic table. |min_cnt| is the minimum insert
  1279. * count which blocked stream requires.
  1280. */
  1281. static int qpack_encoder_can_index_nv(nghttp3_qpack_encoder *encoder,
  1282. const nghttp3_nv *nv, uint64_t min_cnt) {
  1283. return qpack_encoder_can_index(
  1284. encoder, table_space(nv->namelen, nv->valuelen), min_cnt);
  1285. }
  1286. /*
  1287. * qpack_encoder_can_index_duplicate returns nonzero if an entry at
  1288. * |absidx| in dynamic table can be inserted to dynamic table as
  1289. * duplicate. |min_cnt| is the minimum insert count which blocked
  1290. * stream requires.
  1291. */
  1292. static int qpack_encoder_can_index_duplicate(nghttp3_qpack_encoder *encoder,
  1293. uint64_t absidx,
  1294. uint64_t min_cnt) {
  1295. nghttp3_qpack_entry *ent =
  1296. nghttp3_qpack_context_dtable_get(&encoder->ctx, absidx);
  1297. return qpack_encoder_can_index(
  1298. encoder, table_space(ent->nv.name->len, ent->nv.value->len), min_cnt);
  1299. }
  1300. /*
  1301. * qpack_context_check_draining returns nonzero if an entry at
  1302. * |absidx| in dynamic table is one of draining entries.
  1303. */
  1304. static int qpack_context_check_draining(nghttp3_qpack_context *ctx,
  1305. uint64_t absidx) {
  1306. const size_t safe = ctx->max_dtable_capacity -
  1307. nghttp3_min_size(512, ctx->max_dtable_capacity * 1 / 8);
  1308. nghttp3_qpack_entry *ent = nghttp3_qpack_context_dtable_get(ctx, absidx);
  1309. return ctx->dtable_sum - ent->sum > safe;
  1310. }
  1311. int nghttp3_qpack_encoder_encode_nv(nghttp3_qpack_encoder *encoder,
  1312. uint64_t *pmax_cnt, uint64_t *pmin_cnt,
  1313. nghttp3_buf *rbuf, nghttp3_buf *ebuf,
  1314. const nghttp3_nv *nv, uint64_t base,
  1315. int allow_blocking) {
  1316. uint32_t hash = 0;
  1317. int32_t token;
  1318. nghttp3_qpack_indexing_mode indexing_mode;
  1319. nghttp3_qpack_lookup_result sres = {-1, 0, -1}, dres = {-1, 0, -1};
  1320. nghttp3_qpack_entry *new_ent = NULL;
  1321. int static_entry;
  1322. int just_index = 0;
  1323. int rv;
  1324. token = qpack_lookup_token(nv->name, nv->namelen);
  1325. static_entry = token != -1 && (size_t)token < nghttp3_arraylen(token_stable);
  1326. indexing_mode = qpack_encoder_decide_indexing_mode(encoder, nv, token);
  1327. if (static_entry) {
  1328. sres = nghttp3_qpack_lookup_stable(nv, token, indexing_mode);
  1329. if (sres.index != -1 && sres.name_value_match) {
  1330. return nghttp3_qpack_encoder_write_static_indexed(encoder, rbuf,
  1331. (size_t)sres.index);
  1332. }
  1333. }
  1334. if (static_entry) {
  1335. hash = token_stable[token].hash;
  1336. } else {
  1337. switch (token) {
  1338. case NGHTTP3_QPACK_TOKEN_HOST:
  1339. hash = 2952701295u;
  1340. break;
  1341. case NGHTTP3_QPACK_TOKEN_TE:
  1342. hash = 1011170994u;
  1343. break;
  1344. case NGHTTP3_QPACK_TOKEN__PROTOCOL:
  1345. hash = 1128642621u;
  1346. break;
  1347. case NGHTTP3_QPACK_TOKEN_PRIORITY:
  1348. hash = 2498028297u;
  1349. break;
  1350. default:
  1351. hash = qpack_hash_name(nv);
  1352. }
  1353. }
  1354. if (nghttp3_map_size(&encoder->streams) < NGHTTP3_QPACK_MAX_QPACK_STREAMS) {
  1355. dres = nghttp3_qpack_encoder_lookup_dtable(
  1356. encoder, nv, token, hash, indexing_mode, encoder->krcnt, allow_blocking);
  1357. just_index =
  1358. indexing_mode == NGHTTP3_QPACK_INDEXING_MODE_STORE && dres.pb_index == -1;
  1359. }
  1360. if (dres.index != -1 && dres.name_value_match) {
  1361. if (allow_blocking &&
  1362. qpack_context_check_draining(&encoder->ctx, (size_t)dres.index) &&
  1363. qpack_encoder_can_index_duplicate(encoder, (size_t)dres.index,
  1364. *pmin_cnt)) {
  1365. rv = nghttp3_qpack_encoder_write_duplicate_insert(encoder, ebuf,
  1366. (size_t)dres.index);
  1367. if (rv != 0) {
  1368. return rv;
  1369. }
  1370. rv =
  1371. nghttp3_qpack_encoder_dtable_duplicate_add(encoder, (size_t)dres.index);
  1372. if (rv != 0) {
  1373. return rv;
  1374. }
  1375. new_ent = nghttp3_qpack_context_dtable_top(&encoder->ctx);
  1376. dres.index = (nghttp3_ssize)new_ent->absidx;
  1377. }
  1378. *pmax_cnt = nghttp3_max_uint64(*pmax_cnt, (uint64_t)(dres.index + 1));
  1379. *pmin_cnt = nghttp3_min_uint64(*pmin_cnt, (uint64_t)(dres.index + 1));
  1380. return nghttp3_qpack_encoder_write_dynamic_indexed(
  1381. encoder, rbuf, (size_t)dres.index, base);
  1382. }
  1383. if (sres.index != -1) {
  1384. if (just_index && qpack_encoder_can_index_nv(encoder, nv, *pmin_cnt)) {
  1385. rv = nghttp3_qpack_encoder_write_static_insert(encoder, ebuf,
  1386. (size_t)sres.index, nv);
  1387. if (rv != 0) {
  1388. return rv;
  1389. }
  1390. rv = nghttp3_qpack_encoder_dtable_static_add(encoder, (size_t)sres.index,
  1391. nv, hash);
  1392. if (rv != 0) {
  1393. return rv;
  1394. }
  1395. if (allow_blocking) {
  1396. new_ent = nghttp3_qpack_context_dtable_top(&encoder->ctx);
  1397. *pmax_cnt = nghttp3_max_uint64(*pmax_cnt, new_ent->absidx + 1);
  1398. *pmin_cnt = nghttp3_min_uint64(*pmin_cnt, new_ent->absidx + 1);
  1399. return nghttp3_qpack_encoder_write_dynamic_indexed(
  1400. encoder, rbuf, new_ent->absidx, base);
  1401. }
  1402. }
  1403. return nghttp3_qpack_encoder_write_static_indexed_name(
  1404. encoder, rbuf, (size_t)sres.index, nv);
  1405. }
  1406. if (dres.index != -1) {
  1407. if (just_index &&
  1408. qpack_encoder_can_index_nv(
  1409. encoder, nv,
  1410. allow_blocking
  1411. ? *pmin_cnt
  1412. : nghttp3_min_uint64((uint64_t)dres.index + 1, *pmin_cnt))) {
  1413. rv = nghttp3_qpack_encoder_write_dynamic_insert(encoder, ebuf,
  1414. (size_t)dres.index, nv);
  1415. if (rv != 0) {
  1416. return rv;
  1417. }
  1418. if (!allow_blocking) {
  1419. *pmin_cnt = nghttp3_min_uint64(*pmin_cnt, (uint64_t)dres.index + 1);
  1420. }
  1421. rv = nghttp3_qpack_encoder_dtable_dynamic_add(encoder, (size_t)dres.index,
  1422. nv, hash);
  1423. if (rv != 0) {
  1424. return rv;
  1425. }
  1426. if (allow_blocking) {
  1427. new_ent = nghttp3_qpack_context_dtable_top(&encoder->ctx);
  1428. *pmax_cnt = nghttp3_max_uint64(*pmax_cnt, new_ent->absidx + 1);
  1429. *pmin_cnt = nghttp3_min_uint64(*pmin_cnt, new_ent->absidx + 1);
  1430. return nghttp3_qpack_encoder_write_dynamic_indexed(
  1431. encoder, rbuf, new_ent->absidx, base);
  1432. }
  1433. }
  1434. *pmax_cnt = nghttp3_max_uint64(*pmax_cnt, (uint64_t)(dres.index + 1));
  1435. *pmin_cnt = nghttp3_min_uint64(*pmin_cnt, (uint64_t)(dres.index + 1));
  1436. return nghttp3_qpack_encoder_write_dynamic_indexed_name(
  1437. encoder, rbuf, (size_t)dres.index, base, nv);
  1438. }
  1439. if (just_index && qpack_encoder_can_index_nv(encoder, nv, *pmin_cnt)) {
  1440. rv = nghttp3_qpack_encoder_dtable_literal_add(encoder, nv, token, hash);
  1441. if (rv != 0) {
  1442. return rv;
  1443. }
  1444. rv = nghttp3_qpack_encoder_write_literal_insert(encoder, ebuf, nv);
  1445. if (rv != 0) {
  1446. return rv;
  1447. }
  1448. if (allow_blocking) {
  1449. new_ent = nghttp3_qpack_context_dtable_top(&encoder->ctx);
  1450. *pmax_cnt = nghttp3_max_uint64(*pmax_cnt, new_ent->absidx + 1);
  1451. *pmin_cnt = nghttp3_min_uint64(*pmin_cnt, new_ent->absidx + 1);
  1452. return nghttp3_qpack_encoder_write_dynamic_indexed(encoder, rbuf,
  1453. new_ent->absidx, base);
  1454. }
  1455. }
  1456. return nghttp3_qpack_encoder_write_literal(encoder, rbuf, nv);
  1457. }
  1458. nghttp3_qpack_lookup_result
  1459. nghttp3_qpack_lookup_stable(const nghttp3_nv *nv, int32_t token,
  1460. nghttp3_qpack_indexing_mode indexing_mode) {
  1461. nghttp3_qpack_lookup_result res = {(nghttp3_ssize)token_stable[token].absidx,
  1462. 0, -1};
  1463. nghttp3_qpack_static_entry *ent;
  1464. nghttp3_qpack_static_header *hdr;
  1465. size_t i;
  1466. assert(token >= 0);
  1467. if (indexing_mode == NGHTTP3_QPACK_INDEXING_MODE_NEVER) {
  1468. return res;
  1469. }
  1470. for (i = (size_t)token;
  1471. i < nghttp3_arraylen(token_stable) && token_stable[i].token == token;
  1472. ++i) {
  1473. ent = &token_stable[i];
  1474. hdr = &stable[ent->absidx];
  1475. if (hdr->value.len == nv->valuelen &&
  1476. memeq(hdr->value.base, nv->value, nv->valuelen)) {
  1477. res.index = (nghttp3_ssize)ent->absidx;
  1478. res.name_value_match = 1;
  1479. return res;
  1480. }
  1481. }
  1482. return res;
  1483. }
  1484. nghttp3_qpack_lookup_result nghttp3_qpack_encoder_lookup_dtable(
  1485. nghttp3_qpack_encoder *encoder, const nghttp3_nv *nv, int32_t token,
  1486. uint32_t hash, nghttp3_qpack_indexing_mode indexing_mode, uint64_t krcnt,
  1487. int allow_blocking) {
  1488. nghttp3_qpack_lookup_result res = {-1, 0, -1};
  1489. int exact_match = 0;
  1490. nghttp3_qpack_entry *match, *pb_match;
  1491. encoder_qpack_map_find(encoder, &exact_match, &match, &pb_match, nv, token,
  1492. hash, krcnt, allow_blocking,
  1493. indexing_mode == NGHTTP3_QPACK_INDEXING_MODE_NEVER);
  1494. if (match) {
  1495. res.index = (nghttp3_ssize)match->absidx;
  1496. res.name_value_match = exact_match;
  1497. }
  1498. if (pb_match) {
  1499. res.pb_index = (nghttp3_ssize)pb_match->absidx;
  1500. }
  1501. return res;
  1502. }
  1503. int nghttp3_qpack_header_block_ref_new(nghttp3_qpack_header_block_ref **pref,
  1504. uint64_t max_cnt, uint64_t min_cnt,
  1505. const nghttp3_mem *mem) {
  1506. nghttp3_qpack_header_block_ref *ref =
  1507. nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_header_block_ref));
  1508. if (ref == NULL) {
  1509. return NGHTTP3_ERR_NOMEM;
  1510. }
  1511. ref->max_cnts_pe.index = NGHTTP3_PQ_BAD_INDEX;
  1512. ref->min_cnts_pe.index = NGHTTP3_PQ_BAD_INDEX;
  1513. ref->max_cnt = max_cnt;
  1514. ref->min_cnt = min_cnt;
  1515. *pref = ref;
  1516. return 0;
  1517. }
  1518. void nghttp3_qpack_header_block_ref_del(nghttp3_qpack_header_block_ref *ref,
  1519. const nghttp3_mem *mem) {
  1520. nghttp3_mem_free(mem, ref);
  1521. }
  1522. static int ref_max_cnt_greater(const nghttp3_pq_entry *lhsx,
  1523. const nghttp3_pq_entry *rhsx) {
  1524. const nghttp3_qpack_header_block_ref *lhs =
  1525. nghttp3_struct_of(lhsx, nghttp3_qpack_header_block_ref, max_cnts_pe);
  1526. const nghttp3_qpack_header_block_ref *rhs =
  1527. nghttp3_struct_of(rhsx, nghttp3_qpack_header_block_ref, max_cnts_pe);
  1528. return lhs->max_cnt > rhs->max_cnt;
  1529. }
  1530. int nghttp3_qpack_stream_new(nghttp3_qpack_stream **pstream, int64_t stream_id,
  1531. const nghttp3_mem *mem) {
  1532. int rv;
  1533. nghttp3_qpack_stream *stream;
  1534. stream = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_stream));
  1535. if (stream == NULL) {
  1536. return NGHTTP3_ERR_NOMEM;
  1537. }
  1538. rv = nghttp3_ringbuf_init(&stream->refs, 4,
  1539. sizeof(nghttp3_qpack_header_block_ref *), mem);
  1540. if (rv != 0) {
  1541. nghttp3_mem_free(mem, stream);
  1542. return rv;
  1543. }
  1544. nghttp3_pq_init(&stream->max_cnts, ref_max_cnt_greater, mem);
  1545. stream->stream_id = stream_id;
  1546. *pstream = stream;
  1547. return 0;
  1548. }
  1549. void nghttp3_qpack_stream_del(nghttp3_qpack_stream *stream,
  1550. const nghttp3_mem *mem) {
  1551. nghttp3_qpack_header_block_ref *ref;
  1552. size_t i, len;
  1553. if (stream == NULL) {
  1554. return;
  1555. }
  1556. nghttp3_pq_free(&stream->max_cnts);
  1557. len = nghttp3_ringbuf_len(&stream->refs);
  1558. for (i = 0; i < len; ++i) {
  1559. ref =
  1560. *(nghttp3_qpack_header_block_ref **)nghttp3_ringbuf_get(&stream->refs, i);
  1561. nghttp3_qpack_header_block_ref_del(ref, mem);
  1562. }
  1563. nghttp3_ringbuf_free(&stream->refs);
  1564. nghttp3_mem_free(mem, stream);
  1565. }
  1566. uint64_t nghttp3_qpack_stream_get_max_cnt(const nghttp3_qpack_stream *stream) {
  1567. nghttp3_qpack_header_block_ref *ref;
  1568. if (nghttp3_pq_empty(&stream->max_cnts)) {
  1569. return 0;
  1570. }
  1571. ref = nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
  1572. nghttp3_qpack_header_block_ref, max_cnts_pe);
  1573. return ref->max_cnt;
  1574. }
  1575. int nghttp3_qpack_stream_add_ref(nghttp3_qpack_stream *stream,
  1576. nghttp3_qpack_header_block_ref *ref) {
  1577. nghttp3_qpack_header_block_ref **dest;
  1578. int rv;
  1579. if (nghttp3_ringbuf_full(&stream->refs)) {
  1580. rv = nghttp3_ringbuf_reserve(&stream->refs,
  1581. nghttp3_ringbuf_len(&stream->refs) * 2);
  1582. if (rv != 0) {
  1583. return rv;
  1584. }
  1585. }
  1586. dest = nghttp3_ringbuf_push_back(&stream->refs);
  1587. *dest = ref;
  1588. return nghttp3_pq_push(&stream->max_cnts, &ref->max_cnts_pe);
  1589. }
  1590. void nghttp3_qpack_stream_pop_ref(nghttp3_qpack_stream *stream) {
  1591. nghttp3_qpack_header_block_ref *ref;
  1592. assert(nghttp3_ringbuf_len(&stream->refs));
  1593. ref =
  1594. *(nghttp3_qpack_header_block_ref **)nghttp3_ringbuf_get(&stream->refs, 0);
  1595. assert(ref->max_cnts_pe.index != NGHTTP3_PQ_BAD_INDEX);
  1596. nghttp3_pq_remove(&stream->max_cnts, &ref->max_cnts_pe);
  1597. nghttp3_ringbuf_pop_front(&stream->refs);
  1598. }
  1599. int nghttp3_qpack_encoder_write_static_indexed(nghttp3_qpack_encoder *encoder,
  1600. nghttp3_buf *rbuf,
  1601. uint64_t absidx) {
  1602. DEBUGF("qpack::encode: Indexed Field Line (static) absidx=%" PRIu64 "\n",
  1603. absidx);
  1604. return qpack_write_number(rbuf, 0xc0, absidx, 6, encoder->ctx.mem);
  1605. }
  1606. int nghttp3_qpack_encoder_write_dynamic_indexed(nghttp3_qpack_encoder *encoder,
  1607. nghttp3_buf *rbuf,
  1608. uint64_t absidx,
  1609. uint64_t base) {
  1610. DEBUGF("qpack::encode: Indexed Field Line (dynamic) absidx=%" PRIu64
  1611. " base=%" PRIu64 "\n",
  1612. absidx, base);
  1613. if (absidx < base) {
  1614. return qpack_write_number(rbuf, 0x80, base - absidx - 1, 6,
  1615. encoder->ctx.mem);
  1616. }
  1617. return qpack_write_number(rbuf, 0x10, absidx - base, 4, encoder->ctx.mem);
  1618. }
  1619. /*
  1620. * qpack_encoder_write_indexed_name writes generic indexed name. |fb|
  1621. * is the first byte. |nameidx| is an index of referenced name.
  1622. * |prefix| is a prefix of variable integer encoding. |nv| is a
  1623. * header field to encode.
  1624. *
  1625. * This function returns 0 if it succeeds, or one of the following
  1626. * negative error codes:
  1627. *
  1628. * NGHTTP3_ERR_NOMEM
  1629. * Out of memory.
  1630. */
  1631. static int qpack_encoder_write_indexed_name(nghttp3_qpack_encoder *encoder,
  1632. nghttp3_buf *buf, uint8_t fb,
  1633. uint64_t nameidx, size_t prefix,
  1634. const nghttp3_nv *nv) {
  1635. int rv;
  1636. size_t len = nghttp3_qpack_put_varint_len(nameidx, prefix);
  1637. uint8_t *p;
  1638. size_t hlen;
  1639. int h = 0;
  1640. hlen = nghttp3_qpack_huffman_encode_count(nv->value, nv->valuelen);
  1641. if (hlen < nv->valuelen) {
  1642. h = 1;
  1643. len += nghttp3_qpack_put_varint_len(hlen, 7) + hlen;
  1644. } else {
  1645. len += nghttp3_qpack_put_varint_len(nv->valuelen, 7) + nv->valuelen;
  1646. }
  1647. rv = reserve_buf(buf, len, encoder->ctx.mem);
  1648. if (rv != 0) {
  1649. return rv;
  1650. }
  1651. p = buf->last;
  1652. *p = fb;
  1653. p = nghttp3_qpack_put_varint(p, nameidx, prefix);
  1654. if (h) {
  1655. *p = 0x80;
  1656. p = nghttp3_qpack_put_varint(p, hlen, 7);
  1657. p = nghttp3_qpack_huffman_encode(p, nv->value, nv->valuelen);
  1658. } else {
  1659. *p = 0;
  1660. p = nghttp3_qpack_put_varint(p, nv->valuelen, 7);
  1661. if (nv->valuelen) {
  1662. p = nghttp3_cpymem(p, nv->value, nv->valuelen);
  1663. }
  1664. }
  1665. assert((size_t)(p - buf->last) == len);
  1666. buf->last = p;
  1667. return 0;
  1668. }
  1669. int nghttp3_qpack_encoder_write_static_indexed_name(
  1670. nghttp3_qpack_encoder *encoder, nghttp3_buf *rbuf, uint64_t absidx,
  1671. const nghttp3_nv *nv) {
  1672. uint8_t fb =
  1673. (uint8_t)(0x50 | ((nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) ? 0x20 : 0));
  1674. DEBUGF("qpack::encode: Literal Field Line With Name Reference (static) "
  1675. "absidx=%" PRIu64 " never=%d\n",
  1676. absidx, (nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) != 0);
  1677. return qpack_encoder_write_indexed_name(encoder, rbuf, fb, absidx, 4, nv);
  1678. }
  1679. int nghttp3_qpack_encoder_write_dynamic_indexed_name(
  1680. nghttp3_qpack_encoder *encoder, nghttp3_buf *rbuf, uint64_t absidx,
  1681. uint64_t base, const nghttp3_nv *nv) {
  1682. uint8_t fb;
  1683. DEBUGF("qpack::encode: Literal Field Line With Name Reference (dynamic) "
  1684. "absidx=%" PRIu64 " base=%" PRIu64 " never=%d\n",
  1685. absidx, base, (nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) != 0);
  1686. if (absidx < base) {
  1687. fb =
  1688. (uint8_t)(0x40 | ((nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) ? 0x20 : 0));
  1689. return qpack_encoder_write_indexed_name(encoder, rbuf, fb,
  1690. base - absidx - 1, 4, nv);
  1691. }
  1692. fb = (nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) ? 0x08 : 0;
  1693. return qpack_encoder_write_indexed_name(encoder, rbuf, fb, absidx - base, 3,
  1694. nv);
  1695. }
  1696. /*
  1697. * qpack_encoder_write_literal writes generic literal header field
  1698. * representation. |fb| is a first byte. |prefix| is a prefix of
  1699. * variable integer encoding for name length. |nv| is a header field
  1700. * to encode.
  1701. *
  1702. * This function returns 0 if it succeeds, or one of the following
  1703. * negative error codes:
  1704. *
  1705. * NGHTTP3_ERR_NOMEM
  1706. * Out of memory.
  1707. */
  1708. static int qpack_encoder_write_literal(nghttp3_qpack_encoder *encoder,
  1709. nghttp3_buf *buf, uint8_t fb,
  1710. size_t prefix, const nghttp3_nv *nv) {
  1711. int rv;
  1712. size_t len;
  1713. uint8_t *p;
  1714. size_t nhlen, vhlen;
  1715. int nh = 0, vh = 0;
  1716. nhlen = nghttp3_qpack_huffman_encode_count(nv->name, nv->namelen);
  1717. if (nhlen < nv->namelen) {
  1718. nh = 1;
  1719. len = nghttp3_qpack_put_varint_len(nhlen, prefix) + nhlen;
  1720. } else {
  1721. len = nghttp3_qpack_put_varint_len(nv->namelen, prefix) + nv->namelen;
  1722. }
  1723. vhlen = nghttp3_qpack_huffman_encode_count(nv->value, nv->valuelen);
  1724. if (vhlen < nv->valuelen) {
  1725. vh = 1;
  1726. len += nghttp3_qpack_put_varint_len(vhlen, 7) + vhlen;
  1727. } else {
  1728. len += nghttp3_qpack_put_varint_len(nv->valuelen, 7) + nv->valuelen;
  1729. }
  1730. rv = reserve_buf(buf, len, encoder->ctx.mem);
  1731. if (rv != 0) {
  1732. return rv;
  1733. }
  1734. p = buf->last;
  1735. *p = fb;
  1736. if (nh) {
  1737. *p |= (uint8_t)(1 << prefix);
  1738. p = nghttp3_qpack_put_varint(p, nhlen, prefix);
  1739. p = nghttp3_qpack_huffman_encode(p, nv->name, nv->namelen);
  1740. } else {
  1741. p = nghttp3_qpack_put_varint(p, nv->namelen, prefix);
  1742. if (nv->namelen) {
  1743. p = nghttp3_cpymem(p, nv->name, nv->namelen);
  1744. }
  1745. }
  1746. *p = 0;
  1747. if (vh) {
  1748. *p |= 0x80;
  1749. p = nghttp3_qpack_put_varint(p, vhlen, 7);
  1750. p = nghttp3_qpack_huffman_encode(p, nv->value, nv->valuelen);
  1751. } else {
  1752. p = nghttp3_qpack_put_varint(p, nv->valuelen, 7);
  1753. if (nv->valuelen) {
  1754. p = nghttp3_cpymem(p, nv->value, nv->valuelen);
  1755. }
  1756. }
  1757. assert((size_t)(p - buf->last) == len);
  1758. buf->last = p;
  1759. return 0;
  1760. }
  1761. int nghttp3_qpack_encoder_write_literal(nghttp3_qpack_encoder *encoder,
  1762. nghttp3_buf *rbuf,
  1763. const nghttp3_nv *nv) {
  1764. uint8_t fb =
  1765. (uint8_t)(0x20 | ((nv->flags & NGHTTP3_NV_FLAG_NEVER_INDEX) ? 0x10 : 0));
  1766. DEBUGF("qpack::encode: Literal Field Line With Literal Name\n");
  1767. return qpack_encoder_write_literal(encoder, rbuf, fb, 3, nv);
  1768. }
  1769. int nghttp3_qpack_encoder_write_static_insert(nghttp3_qpack_encoder *encoder,
  1770. nghttp3_buf *ebuf,
  1771. uint64_t absidx,
  1772. const nghttp3_nv *nv) {
  1773. DEBUGF("qpack::encode: Insert With Name Reference (static) absidx=%" PRIu64
  1774. "\n",
  1775. absidx);
  1776. return qpack_encoder_write_indexed_name(encoder, ebuf, 0xc0, absidx, 6, nv);
  1777. }
  1778. int nghttp3_qpack_encoder_write_dynamic_insert(nghttp3_qpack_encoder *encoder,
  1779. nghttp3_buf *ebuf,
  1780. uint64_t absidx,
  1781. const nghttp3_nv *nv) {
  1782. DEBUGF("qpack::encode: Insert With Name Reference (dynamic) absidx=%" PRIu64
  1783. "\n",
  1784. absidx);
  1785. return qpack_encoder_write_indexed_name(
  1786. encoder, ebuf, 0x80, encoder->ctx.next_absidx - absidx - 1, 6, nv);
  1787. }
  1788. int nghttp3_qpack_encoder_write_duplicate_insert(nghttp3_qpack_encoder *encoder,
  1789. nghttp3_buf *ebuf,
  1790. uint64_t absidx) {
  1791. uint64_t idx = encoder->ctx.next_absidx - absidx - 1;
  1792. size_t len = nghttp3_qpack_put_varint_len(idx, 5);
  1793. uint8_t *p;
  1794. int rv;
  1795. DEBUGF("qpack::encode: Insert duplicate absidx=%" PRIu64 "\n", absidx);
  1796. rv = reserve_buf(ebuf, len, encoder->ctx.mem);
  1797. if (rv != 0) {
  1798. return rv;
  1799. }
  1800. p = ebuf->last;
  1801. *p = 0;
  1802. p = nghttp3_qpack_put_varint(p, idx, 5);
  1803. assert((size_t)(p - ebuf->last) == len);
  1804. ebuf->last = p;
  1805. return 0;
  1806. }
  1807. int nghttp3_qpack_encoder_write_literal_insert(nghttp3_qpack_encoder *encoder,
  1808. nghttp3_buf *ebuf,
  1809. const nghttp3_nv *nv) {
  1810. DEBUGF("qpack::encode: Insert With Literal Name\n");
  1811. return qpack_encoder_write_literal(encoder, ebuf, 0x40, 5, nv);
  1812. }
  1813. int nghttp3_qpack_context_dtable_add(nghttp3_qpack_context *ctx,
  1814. nghttp3_qpack_nv *qnv,
  1815. nghttp3_qpack_map *dtable_map,
  1816. uint32_t hash) {
  1817. nghttp3_qpack_entry *new_ent, **p, *ent;
  1818. const nghttp3_mem *mem = ctx->mem;
  1819. size_t space;
  1820. size_t i;
  1821. int rv;
  1822. space = table_space(qnv->name->len, qnv->value->len);
  1823. assert(space <= ctx->max_dtable_capacity);
  1824. while (ctx->dtable_size + space > ctx->max_dtable_capacity) {
  1825. i = nghttp3_ringbuf_len(&ctx->dtable);
  1826. assert(i);
  1827. ent = *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(&ctx->dtable, i - 1);
  1828. ctx->dtable_size -= table_space(ent->nv.name->len, ent->nv.value->len);
  1829. nghttp3_ringbuf_pop_back(&ctx->dtable);
  1830. if (dtable_map) {
  1831. qpack_map_remove(dtable_map, ent);
  1832. }
  1833. nghttp3_qpack_entry_free(ent);
  1834. nghttp3_mem_free(mem, ent);
  1835. }
  1836. new_ent = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_entry));
  1837. if (new_ent == NULL) {
  1838. return NGHTTP3_ERR_NOMEM;
  1839. }
  1840. nghttp3_qpack_entry_init(new_ent, qnv, ctx->dtable_sum, ctx->next_absidx++,
  1841. hash);
  1842. if (nghttp3_ringbuf_full(&ctx->dtable)) {
  1843. rv = nghttp3_ringbuf_reserve(&ctx->dtable,
  1844. nghttp3_ringbuf_len(&ctx->dtable) * 2);
  1845. if (rv != 0) {
  1846. goto fail;
  1847. }
  1848. }
  1849. p = nghttp3_ringbuf_push_front(&ctx->dtable);
  1850. *p = new_ent;
  1851. if (dtable_map) {
  1852. qpack_map_insert(dtable_map, new_ent);
  1853. }
  1854. ctx->dtable_size += space;
  1855. ctx->dtable_sum += space;
  1856. return 0;
  1857. fail:
  1858. nghttp3_qpack_entry_free(new_ent);
  1859. nghttp3_mem_free(mem, new_ent);
  1860. return rv;
  1861. }
  1862. int nghttp3_qpack_encoder_dtable_static_add(nghttp3_qpack_encoder *encoder,
  1863. uint64_t absidx,
  1864. const nghttp3_nv *nv,
  1865. uint32_t hash) {
  1866. const nghttp3_qpack_static_header *shd;
  1867. nghttp3_qpack_nv qnv;
  1868. const nghttp3_mem *mem = encoder->ctx.mem;
  1869. int rv;
  1870. rv = nghttp3_rcbuf_new2(&qnv.value, nv->value, nv->valuelen, mem);
  1871. if (rv != 0) {
  1872. return rv;
  1873. }
  1874. assert(nghttp3_arraylen(stable) > absidx);
  1875. shd = &stable[absidx];
  1876. qnv.name = (nghttp3_rcbuf *)&shd->name;
  1877. qnv.token = shd->token;
  1878. qnv.flags = NGHTTP3_NV_FLAG_NONE;
  1879. rv = nghttp3_qpack_context_dtable_add(&encoder->ctx, &qnv,
  1880. &encoder->dtable_map, hash);
  1881. nghttp3_rcbuf_decref(qnv.value);
  1882. return rv;
  1883. }
  1884. int nghttp3_qpack_encoder_dtable_dynamic_add(nghttp3_qpack_encoder *encoder,
  1885. uint64_t absidx,
  1886. const nghttp3_nv *nv,
  1887. uint32_t hash) {
  1888. nghttp3_qpack_nv qnv;
  1889. nghttp3_qpack_entry *ent;
  1890. const nghttp3_mem *mem = encoder->ctx.mem;
  1891. int rv;
  1892. rv = nghttp3_rcbuf_new2(&qnv.value, nv->value, nv->valuelen, mem);
  1893. if (rv != 0) {
  1894. return rv;
  1895. }
  1896. ent = nghttp3_qpack_context_dtable_get(&encoder->ctx, absidx);
  1897. qnv.name = ent->nv.name;
  1898. qnv.token = ent->nv.token;
  1899. qnv.flags = NGHTTP3_NV_FLAG_NONE;
  1900. nghttp3_rcbuf_incref(qnv.name);
  1901. rv = nghttp3_qpack_context_dtable_add(&encoder->ctx, &qnv,
  1902. &encoder->dtable_map, hash);
  1903. nghttp3_rcbuf_decref(qnv.value);
  1904. nghttp3_rcbuf_decref(qnv.name);
  1905. return rv;
  1906. }
  1907. int nghttp3_qpack_encoder_dtable_duplicate_add(nghttp3_qpack_encoder *encoder,
  1908. uint64_t absidx) {
  1909. nghttp3_qpack_nv qnv;
  1910. nghttp3_qpack_entry *ent;
  1911. int rv;
  1912. ent = nghttp3_qpack_context_dtable_get(&encoder->ctx, absidx);
  1913. qnv = ent->nv;
  1914. nghttp3_rcbuf_incref(qnv.name);
  1915. nghttp3_rcbuf_incref(qnv.value);
  1916. rv = nghttp3_qpack_context_dtable_add(&encoder->ctx, &qnv,
  1917. &encoder->dtable_map, ent->hash);
  1918. nghttp3_rcbuf_decref(qnv.name);
  1919. nghttp3_rcbuf_decref(qnv.value);
  1920. return rv;
  1921. }
  1922. int nghttp3_qpack_encoder_dtable_literal_add(nghttp3_qpack_encoder *encoder,
  1923. const nghttp3_nv *nv,
  1924. int32_t token, uint32_t hash) {
  1925. nghttp3_qpack_nv qnv;
  1926. const nghttp3_mem *mem = encoder->ctx.mem;
  1927. int rv;
  1928. rv = nghttp3_rcbuf_new2(&qnv.name, nv->name, nv->namelen, mem);
  1929. if (rv != 0) {
  1930. return rv;
  1931. }
  1932. rv = nghttp3_rcbuf_new2(&qnv.value, nv->value, nv->valuelen, mem);
  1933. if (rv != 0) {
  1934. nghttp3_rcbuf_decref(qnv.name);
  1935. return rv;
  1936. }
  1937. qnv.token = token;
  1938. qnv.flags = NGHTTP3_NV_FLAG_NONE;
  1939. rv = nghttp3_qpack_context_dtable_add(&encoder->ctx, &qnv,
  1940. &encoder->dtable_map, hash);
  1941. nghttp3_rcbuf_decref(qnv.value);
  1942. nghttp3_rcbuf_decref(qnv.name);
  1943. return rv;
  1944. }
  1945. nghttp3_qpack_entry *
  1946. nghttp3_qpack_context_dtable_get(nghttp3_qpack_context *ctx, uint64_t absidx) {
  1947. size_t relidx;
  1948. assert(ctx->next_absidx > absidx);
  1949. assert(ctx->next_absidx - absidx - 1 < nghttp3_ringbuf_len(&ctx->dtable));
  1950. relidx = (size_t)(ctx->next_absidx - absidx - 1);
  1951. return *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(&ctx->dtable, relidx);
  1952. }
  1953. nghttp3_qpack_entry *
  1954. nghttp3_qpack_context_dtable_top(nghttp3_qpack_context *ctx) {
  1955. assert(nghttp3_ringbuf_len(&ctx->dtable));
  1956. return *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(&ctx->dtable, 0);
  1957. }
  1958. void nghttp3_qpack_entry_init(nghttp3_qpack_entry *ent, nghttp3_qpack_nv *qnv,
  1959. size_t sum, uint64_t absidx, uint32_t hash) {
  1960. ent->nv = *qnv;
  1961. ent->map_next = NULL;
  1962. ent->sum = sum;
  1963. ent->absidx = absidx;
  1964. ent->hash = hash;
  1965. nghttp3_rcbuf_incref(ent->nv.name);
  1966. nghttp3_rcbuf_incref(ent->nv.value);
  1967. }
  1968. void nghttp3_qpack_entry_free(nghttp3_qpack_entry *ent) {
  1969. nghttp3_rcbuf_decref(ent->nv.value);
  1970. nghttp3_rcbuf_decref(ent->nv.name);
  1971. }
  1972. int nghttp3_qpack_encoder_block_stream(nghttp3_qpack_encoder *encoder,
  1973. nghttp3_qpack_stream *stream) {
  1974. nghttp3_blocked_streams_key bsk = {
  1975. nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
  1976. nghttp3_qpack_header_block_ref, max_cnts_pe)
  1977. ->max_cnt,
  1978. (uint64_t)stream->stream_id};
  1979. return nghttp3_ksl_insert(&encoder->blocked_streams, NULL, &bsk, stream);
  1980. }
  1981. void nghttp3_qpack_encoder_unblock_stream(nghttp3_qpack_encoder *encoder,
  1982. nghttp3_qpack_stream *stream) {
  1983. nghttp3_blocked_streams_key bsk = {
  1984. nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
  1985. nghttp3_qpack_header_block_ref, max_cnts_pe)
  1986. ->max_cnt,
  1987. (uint64_t)stream->stream_id};
  1988. nghttp3_ksl_it it;
  1989. /* This is purely debugging purpose only */
  1990. it = nghttp3_ksl_lower_bound(&encoder->blocked_streams, &bsk);
  1991. assert(!nghttp3_ksl_it_end(&it));
  1992. assert(nghttp3_ksl_it_get(&it) == stream);
  1993. nghttp3_ksl_remove_hint(&encoder->blocked_streams, NULL, &it, &bsk);
  1994. }
  1995. void nghttp3_qpack_encoder_unblock(nghttp3_qpack_encoder *encoder,
  1996. uint64_t max_cnt) {
  1997. nghttp3_blocked_streams_key bsk = {max_cnt, 0};
  1998. nghttp3_ksl_it it;
  1999. it = nghttp3_ksl_lower_bound(&encoder->blocked_streams, &bsk);
  2000. for (; !nghttp3_ksl_it_end(&it);) {
  2001. bsk = *(nghttp3_blocked_streams_key *)nghttp3_ksl_it_key(&it);
  2002. nghttp3_ksl_remove_hint(&encoder->blocked_streams, &it, &it, &bsk);
  2003. }
  2004. }
  2005. int nghttp3_qpack_encoder_ack_header(nghttp3_qpack_encoder *encoder,
  2006. int64_t stream_id) {
  2007. nghttp3_qpack_stream *stream =
  2008. nghttp3_qpack_encoder_find_stream(encoder, stream_id);
  2009. const nghttp3_mem *mem = encoder->ctx.mem;
  2010. nghttp3_qpack_header_block_ref *ref;
  2011. if (stream == NULL) {
  2012. return NGHTTP3_ERR_QPACK_DECODER_STREAM_ERROR;
  2013. }
  2014. assert(nghttp3_ringbuf_len(&stream->refs));
  2015. ref =
  2016. *(nghttp3_qpack_header_block_ref **)nghttp3_ringbuf_get(&stream->refs, 0);
  2017. DEBUGF("qpack::encoder: Header acknowledgement stream=%ld ricnt=%" PRIu64
  2018. " krcnt=%" PRIu64 "\n",
  2019. stream_id, ref->max_cnt, encoder->krcnt);
  2020. if (encoder->krcnt < ref->max_cnt) {
  2021. encoder->krcnt = ref->max_cnt;
  2022. nghttp3_qpack_encoder_unblock(encoder, ref->max_cnt);
  2023. }
  2024. nghttp3_qpack_stream_pop_ref(stream);
  2025. assert(ref->min_cnts_pe.index != NGHTTP3_PQ_BAD_INDEX);
  2026. nghttp3_pq_remove(&encoder->min_cnts, &ref->min_cnts_pe);
  2027. nghttp3_qpack_header_block_ref_del(ref, mem);
  2028. if (nghttp3_ringbuf_len(&stream->refs)) {
  2029. return 0;
  2030. }
  2031. qpack_encoder_remove_stream(encoder, stream);
  2032. nghttp3_qpack_stream_del(stream, mem);
  2033. return 0;
  2034. }
  2035. int nghttp3_qpack_encoder_add_icnt(nghttp3_qpack_encoder *encoder, uint64_t n) {
  2036. if (n == 0 || encoder->ctx.next_absidx - encoder->krcnt < n) {
  2037. return NGHTTP3_ERR_QPACK_DECODER_STREAM_ERROR;
  2038. }
  2039. encoder->krcnt += n;
  2040. nghttp3_qpack_encoder_unblock(encoder, encoder->krcnt);
  2041. return 0;
  2042. }
  2043. void nghttp3_qpack_encoder_ack_everything(nghttp3_qpack_encoder *encoder) {
  2044. encoder->krcnt = encoder->ctx.next_absidx;
  2045. nghttp3_ksl_clear(&encoder->blocked_streams);
  2046. nghttp3_pq_clear(&encoder->min_cnts);
  2047. nghttp3_map_each(&encoder->streams, map_stream_free,
  2048. (void *)encoder->ctx.mem);
  2049. nghttp3_map_clear(&encoder->streams);
  2050. }
  2051. void nghttp3_qpack_encoder_cancel_stream(nghttp3_qpack_encoder *encoder,
  2052. int64_t stream_id) {
  2053. nghttp3_qpack_stream *stream =
  2054. nghttp3_qpack_encoder_find_stream(encoder, stream_id);
  2055. const nghttp3_mem *mem = encoder->ctx.mem;
  2056. if (stream == NULL) {
  2057. return;
  2058. }
  2059. if (nghttp3_qpack_encoder_stream_is_blocked(encoder, stream)) {
  2060. nghttp3_qpack_encoder_unblock_stream(encoder, stream);
  2061. }
  2062. qpack_encoder_remove_stream(encoder, stream);
  2063. nghttp3_qpack_stream_del(stream, mem);
  2064. }
  2065. size_t
  2066. nghttp3_qpack_encoder_get_num_blocked_streams(nghttp3_qpack_encoder *encoder) {
  2067. return nghttp3_ksl_len(&encoder->blocked_streams);
  2068. }
  2069. int nghttp3_qpack_encoder_write_field_section_prefix(
  2070. nghttp3_qpack_encoder *encoder, nghttp3_buf *pbuf, uint64_t ricnt,
  2071. uint64_t base) {
  2072. size_t max_ents =
  2073. encoder->ctx.hard_max_dtable_capacity / NGHTTP3_QPACK_ENTRY_OVERHEAD;
  2074. uint64_t encricnt = ricnt == 0 ? 0 : (ricnt % (2 * max_ents)) + 1;
  2075. int sign = base < ricnt;
  2076. uint64_t delta_base = sign ? ricnt - base - 1 : base - ricnt;
  2077. size_t len = nghttp3_qpack_put_varint_len(encricnt, 8) +
  2078. nghttp3_qpack_put_varint_len(delta_base, 7);
  2079. uint8_t *p;
  2080. int rv;
  2081. DEBUGF("qpack::encode: ricnt=%" PRIu64 " base=%" PRIu64 " icnt=%" PRIu64 "\n",
  2082. ricnt, base, encoder->ctx.next_absidx);
  2083. rv = reserve_buf(pbuf, len, encoder->ctx.mem);
  2084. if (rv != 0) {
  2085. return rv;
  2086. }
  2087. p = pbuf->last;
  2088. p = nghttp3_qpack_put_varint(p, encricnt, 8);
  2089. if (sign) {
  2090. *p = 0x80;
  2091. } else {
  2092. *p = 0;
  2093. }
  2094. p = nghttp3_qpack_put_varint(p, delta_base, 7);
  2095. assert((size_t)(p - pbuf->last) == len);
  2096. pbuf->last = p;
  2097. return 0;
  2098. }
  2099. /*
  2100. * qpack_read_varint reads |rstate->prefix| prefixed integer stored
  2101. * from |begin|. The |end| represents the 1 beyond the last of the
  2102. * valid contiguous memory region from |begin|. The decoded integer
  2103. * must be less than or equal to NGHTTP3_QPACK_INT_MAX.
  2104. *
  2105. * If the |rstate->left| is nonzero, it is used as an initial value,
  2106. * and this function assumes the |begin| starts with intermediate
  2107. * data. |rstate->shift| is used as initial integer shift.
  2108. *
  2109. * If an entire integer is decoded successfully, the |*fin| is set to
  2110. * nonzero.
  2111. *
  2112. * This function stores the decoded integer in |rstate->left| if it
  2113. * succeeds, including partial decoding (in this case, number of shift
  2114. * to make in the next call will be stored in |rstate->shift|) and
  2115. * returns number of bytes processed, or returns negative error code
  2116. * NGHTTP3_ERR_QPACK_FATAL, indicating decoding error.
  2117. */
  2118. static nghttp3_ssize qpack_read_varint(int *fin,
  2119. nghttp3_qpack_read_state *rstate,
  2120. const uint8_t *begin,
  2121. const uint8_t *end) {
  2122. uint64_t k = (uint8_t)((1 << rstate->prefix) - 1);
  2123. uint64_t n = rstate->left;
  2124. uint64_t add;
  2125. const uint8_t *p = begin;
  2126. size_t shift = rstate->shift;
  2127. rstate->shift = 0;
  2128. *fin = 0;
  2129. if (n == 0) {
  2130. if (((*p) & k) != k) {
  2131. rstate->left = (*p) & k;
  2132. *fin = 1;
  2133. return 1;
  2134. }
  2135. n = k;
  2136. if (++p == end) {
  2137. rstate->left = n;
  2138. return (nghttp3_ssize)(p - begin);
  2139. }
  2140. }
  2141. for (; p != end; ++p, shift += 7) {
  2142. add = (*p) & 0x7f;
  2143. if (shift > 62) {
  2144. return NGHTTP3_ERR_QPACK_FATAL;
  2145. }
  2146. if ((NGHTTP3_QPACK_INT_MAX >> shift) < add) {
  2147. return NGHTTP3_ERR_QPACK_FATAL;
  2148. }
  2149. add <<= shift;
  2150. if (NGHTTP3_QPACK_INT_MAX - add < n) {
  2151. return NGHTTP3_ERR_QPACK_FATAL;
  2152. }
  2153. n += add;
  2154. if (((*p) & (1 << 7)) == 0) {
  2155. break;
  2156. }
  2157. }
  2158. rstate->shift = shift;
  2159. if (p == end) {
  2160. rstate->left = n;
  2161. return (nghttp3_ssize)(p - begin);
  2162. }
  2163. rstate->left = n;
  2164. *fin = 1;
  2165. return (nghttp3_ssize)(p + 1 - begin);
  2166. }
  2167. nghttp3_ssize nghttp3_qpack_encoder_read_decoder(nghttp3_qpack_encoder *encoder,
  2168. const uint8_t *src,
  2169. size_t srclen) {
  2170. const uint8_t *p = src, *end;
  2171. int rv;
  2172. nghttp3_ssize nread;
  2173. int rfin;
  2174. if (encoder->ctx.bad) {
  2175. return NGHTTP3_ERR_QPACK_FATAL;
  2176. }
  2177. if (srclen == 0) {
  2178. return 0;
  2179. }
  2180. encoder->uninterrupted_decoderlen += srclen;
  2181. if (encoder->uninterrupted_decoderlen > NGHTTP3_QPACK_MAX_DECODERLEN) {
  2182. return NGHTTP3_ERR_QPACK_DECODER_STREAM_ERROR;
  2183. }
  2184. end = src + srclen;
  2185. for (; p != end;) {
  2186. switch (encoder->state) {
  2187. case NGHTTP3_QPACK_DS_STATE_OPCODE:
  2188. switch ((*p) & 0xc0) {
  2189. case 0x80:
  2190. case 0xc0:
  2191. DEBUGF("qpack::encode: OPCODE_SECTION_ACK\n");
  2192. encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_SECTION_ACK;
  2193. encoder->rstate.prefix = 7;
  2194. break;
  2195. case 0x40:
  2196. DEBUGF("qpack::encode: OPCODE_STREAM_CANCEL\n");
  2197. encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_STREAM_CANCEL;
  2198. encoder->rstate.prefix = 6;
  2199. break;
  2200. default:
  2201. DEBUGF("qpack::encode: OPCODE_ICNT_INCREMENT\n");
  2202. encoder->opcode = NGHTTP3_QPACK_DS_OPCODE_ICNT_INCREMENT;
  2203. encoder->rstate.prefix = 6;
  2204. }
  2205. encoder->state = NGHTTP3_QPACK_DS_STATE_READ_NUMBER;
  2206. /* fall through */
  2207. case NGHTTP3_QPACK_DS_STATE_READ_NUMBER:
  2208. nread = qpack_read_varint(&rfin, &encoder->rstate, p, end);
  2209. if (nread < 0) {
  2210. assert(nread == NGHTTP3_ERR_QPACK_FATAL);
  2211. rv = NGHTTP3_ERR_QPACK_DECODER_STREAM_ERROR;
  2212. goto fail;
  2213. }
  2214. p += nread;
  2215. if (!rfin) {
  2216. return p - src;
  2217. }
  2218. switch (encoder->opcode) {
  2219. case NGHTTP3_QPACK_DS_OPCODE_ICNT_INCREMENT:
  2220. rv = nghttp3_qpack_encoder_add_icnt(encoder, encoder->rstate.left);
  2221. if (rv != 0) {
  2222. goto fail;
  2223. }
  2224. break;
  2225. case NGHTTP3_QPACK_DS_OPCODE_SECTION_ACK:
  2226. rv = nghttp3_qpack_encoder_ack_header(encoder,
  2227. (int64_t)encoder->rstate.left);
  2228. if (rv != 0) {
  2229. goto fail;
  2230. }
  2231. break;
  2232. case NGHTTP3_QPACK_DS_OPCODE_STREAM_CANCEL:
  2233. nghttp3_qpack_encoder_cancel_stream(encoder,
  2234. (int64_t)encoder->rstate.left);
  2235. break;
  2236. default:
  2237. nghttp3_unreachable();
  2238. }
  2239. encoder->state = NGHTTP3_QPACK_DS_STATE_OPCODE;
  2240. nghttp3_qpack_read_state_reset(&encoder->rstate);
  2241. break;
  2242. default:
  2243. nghttp3_unreachable();
  2244. }
  2245. }
  2246. return p - src;
  2247. fail:
  2248. encoder->ctx.bad = 1;
  2249. return rv;
  2250. }
  2251. size_t nghttp3_qpack_put_varint_len(uint64_t n, size_t prefix) {
  2252. size_t k = (size_t)((1 << prefix) - 1);
  2253. size_t len = 0;
  2254. if (n < k) {
  2255. return 1;
  2256. }
  2257. n -= k;
  2258. ++len;
  2259. for (; n >= 128; n >>= 7, ++len)
  2260. ;
  2261. return len + 1;
  2262. }
  2263. uint8_t *nghttp3_qpack_put_varint(uint8_t *buf, uint64_t n, size_t prefix) {
  2264. size_t k = (size_t)((1 << prefix) - 1);
  2265. *buf = (uint8_t)(*buf & ~k);
  2266. if (n < k) {
  2267. *buf = (uint8_t)(*buf | n);
  2268. return buf + 1;
  2269. }
  2270. *buf = (uint8_t)(*buf | k);
  2271. ++buf;
  2272. n -= k;
  2273. for (; n >= 128; n >>= 7) {
  2274. *buf++ = (uint8_t)((1 << 7) | (n & 0x7f));
  2275. }
  2276. *buf++ = (uint8_t)n;
  2277. return buf;
  2278. }
  2279. void nghttp3_qpack_read_state_free(nghttp3_qpack_read_state *rstate) {
  2280. nghttp3_rcbuf_decref(rstate->value);
  2281. nghttp3_rcbuf_decref(rstate->name);
  2282. }
  2283. void nghttp3_qpack_read_state_reset(nghttp3_qpack_read_state *rstate) {
  2284. rstate->name = NULL;
  2285. rstate->value = NULL;
  2286. nghttp3_buf_init(&rstate->namebuf);
  2287. nghttp3_buf_init(&rstate->valuebuf);
  2288. rstate->left = 0;
  2289. rstate->prefix = 0;
  2290. rstate->shift = 0;
  2291. rstate->absidx = 0;
  2292. rstate->never = 0;
  2293. rstate->dynamic = 0;
  2294. rstate->huffman_encoded = 0;
  2295. }
  2296. int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder,
  2297. size_t hard_max_dtable_capacity,
  2298. size_t max_blocked_streams,
  2299. const nghttp3_mem *mem) {
  2300. int rv;
  2301. rv = qpack_context_init(&decoder->ctx, hard_max_dtable_capacity,
  2302. max_blocked_streams, mem);
  2303. if (rv != 0) {
  2304. return rv;
  2305. }
  2306. decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE;
  2307. decoder->opcode = 0;
  2308. decoder->written_icnt = 0;
  2309. decoder->max_concurrent_streams = 0;
  2310. decoder->uninterrupted_encoderlen = 0;
  2311. nghttp3_qpack_read_state_reset(&decoder->rstate);
  2312. nghttp3_buf_init(&decoder->dbuf);
  2313. return 0;
  2314. }
  2315. void nghttp3_qpack_decoder_free(nghttp3_qpack_decoder *decoder) {
  2316. nghttp3_buf_free(&decoder->dbuf, decoder->ctx.mem);
  2317. nghttp3_qpack_read_state_free(&decoder->rstate);
  2318. qpack_context_free(&decoder->ctx);
  2319. }
  2320. /*
  2321. * qpack_read_huffman_string decodes huffman string in buffer [begin,
  2322. * end) and writes the decoded string to |dest|. This function
  2323. * assumes the buffer pointed by |dest| has enough space.
  2324. *
  2325. * This function returns 0 if it succeeds, or one of the following
  2326. * negative error codes:
  2327. *
  2328. * NGHTTP3_ERR_QPACK_FATAL
  2329. * Could not decode huffman string.
  2330. */
  2331. static nghttp3_ssize qpack_read_huffman_string(nghttp3_qpack_read_state *rstate,
  2332. nghttp3_buf *dest,
  2333. const uint8_t *begin,
  2334. const uint8_t *end) {
  2335. nghttp3_ssize nwrite;
  2336. size_t len = (size_t)(end - begin);
  2337. int fin = 0;
  2338. if (len >= rstate->left) {
  2339. len = (size_t)rstate->left;
  2340. fin = 1;
  2341. }
  2342. nwrite = nghttp3_qpack_huffman_decode(&rstate->huffman_ctx, dest->last, begin,
  2343. len, fin);
  2344. if (nwrite < 0) {
  2345. return nwrite;
  2346. }
  2347. if (nghttp3_qpack_huffman_decode_failure_state(&rstate->huffman_ctx)) {
  2348. return NGHTTP3_ERR_QPACK_FATAL;
  2349. }
  2350. dest->last += nwrite;
  2351. rstate->left -= len;
  2352. return (nghttp3_ssize)len;
  2353. }
  2354. static nghttp3_ssize qpack_read_string(nghttp3_qpack_read_state *rstate,
  2355. nghttp3_buf *dest, const uint8_t *begin,
  2356. const uint8_t *end) {
  2357. size_t len = (size_t)(end - begin);
  2358. size_t n = (size_t)nghttp3_min_uint64((uint64_t)len, rstate->left);
  2359. dest->last = nghttp3_cpymem(dest->last, begin, n);
  2360. rstate->left -= n;
  2361. return (nghttp3_ssize)n;
  2362. }
  2363. /*
  2364. * qpack_decoder_validate_index checks rstate->absidx is acceptable.
  2365. *
  2366. * It returns 0 if it succeeds, or one of the following negative error
  2367. * codes:
  2368. *
  2369. * NGHTTP3_ERR_QPACK_FATAL
  2370. * rstate->absidx is invalid.
  2371. */
  2372. static int qpack_decoder_validate_index(nghttp3_qpack_decoder *decoder,
  2373. nghttp3_qpack_read_state *rstate) {
  2374. if (rstate->dynamic) {
  2375. return rstate->absidx < decoder->ctx.next_absidx &&
  2376. decoder->ctx.next_absidx - rstate->absidx - 1 <
  2377. nghttp3_ringbuf_len(&decoder->ctx.dtable)
  2378. ? 0
  2379. : NGHTTP3_ERR_QPACK_FATAL;
  2380. }
  2381. return rstate->absidx < nghttp3_arraylen(stable) ? 0
  2382. : NGHTTP3_ERR_QPACK_FATAL;
  2383. }
  2384. static void qpack_read_state_check_huffman(nghttp3_qpack_read_state *rstate,
  2385. const uint8_t b) {
  2386. rstate->huffman_encoded = (b & (1 << rstate->prefix)) != 0;
  2387. }
  2388. static void qpack_read_state_terminate_name(nghttp3_qpack_read_state *rstate) {
  2389. *rstate->namebuf.last = '\0';
  2390. rstate->name->len = nghttp3_buf_len(&rstate->namebuf);
  2391. }
  2392. static void qpack_read_state_terminate_value(nghttp3_qpack_read_state *rstate) {
  2393. *rstate->valuebuf.last = '\0';
  2394. rstate->value->len = nghttp3_buf_len(&rstate->valuebuf);
  2395. }
  2396. nghttp3_ssize nghttp3_qpack_decoder_read_encoder(nghttp3_qpack_decoder *decoder,
  2397. const uint8_t *src,
  2398. size_t srclen) {
  2399. const uint8_t *p = src, *end;
  2400. int rv;
  2401. int busy = 0;
  2402. const nghttp3_mem *mem = decoder->ctx.mem;
  2403. nghttp3_ssize nread;
  2404. int rfin;
  2405. if (decoder->ctx.bad) {
  2406. return NGHTTP3_ERR_QPACK_FATAL;
  2407. }
  2408. if (srclen == 0) {
  2409. return 0;
  2410. }
  2411. decoder->uninterrupted_encoderlen += srclen;
  2412. if (decoder->uninterrupted_encoderlen > NGHTTP3_QPACK_MAX_ENCODERLEN) {
  2413. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2414. }
  2415. end = src + srclen;
  2416. for (; p != end || busy;) {
  2417. busy = 0;
  2418. switch (decoder->state) {
  2419. case NGHTTP3_QPACK_ES_STATE_OPCODE:
  2420. switch ((*p) & 0xe0) {
  2421. case 0x80:
  2422. case 0xa0:
  2423. case 0xc0:
  2424. case 0xe0:
  2425. DEBUGF("qpack::decode: OPCODE_INSERT_INDEXED\n");
  2426. decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_INSERT_INDEXED;
  2427. decoder->rstate.dynamic = !((*p) & 0x40);
  2428. decoder->rstate.prefix = 6;
  2429. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;
  2430. break;
  2431. case 0x40:
  2432. case 0x60:
  2433. DEBUGF("qpack::decode: OPCODE_INSERT\n");
  2434. decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_INSERT;
  2435. decoder->rstate.dynamic = 0;
  2436. decoder->rstate.prefix = 5;
  2437. decoder->state = NGHTTP3_QPACK_ES_STATE_CHECK_NAME_HUFFMAN;
  2438. break;
  2439. case 0x20:
  2440. DEBUGF("qpack::decode: OPCODE_SET_DTABLE_TABLE_CAP\n");
  2441. decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_SET_DTABLE_CAP;
  2442. decoder->rstate.prefix = 5;
  2443. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;
  2444. break;
  2445. default:
  2446. DEBUGF("qpack::decode: OPCODE_DUPLICATE\n");
  2447. decoder->opcode = NGHTTP3_QPACK_ES_OPCODE_DUPLICATE;
  2448. decoder->rstate.dynamic = 1;
  2449. decoder->rstate.prefix = 5;
  2450. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_INDEX;
  2451. }
  2452. break;
  2453. case NGHTTP3_QPACK_ES_STATE_READ_INDEX:
  2454. nread = qpack_read_varint(&rfin, &decoder->rstate, p, end);
  2455. if (nread < 0) {
  2456. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2457. rv = NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2458. goto fail;
  2459. }
  2460. p += nread;
  2461. if (!rfin) {
  2462. return p - src;
  2463. }
  2464. if (decoder->opcode == NGHTTP3_QPACK_ES_OPCODE_SET_DTABLE_CAP) {
  2465. DEBUGF("qpack::decode: Set dtable capacity to %" PRIu64 "\n",
  2466. decoder->rstate.left);
  2467. rv = nghttp3_qpack_decoder_set_max_dtable_capacity(
  2468. decoder, (size_t)decoder->rstate.left);
  2469. if (rv != 0) {
  2470. rv = NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2471. goto fail;
  2472. }
  2473. decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE;
  2474. nghttp3_qpack_read_state_reset(&decoder->rstate);
  2475. break;
  2476. }
  2477. rv = nghttp3_qpack_decoder_rel2abs(decoder, &decoder->rstate);
  2478. if (rv < 0) {
  2479. goto fail;
  2480. }
  2481. switch (decoder->opcode) {
  2482. case NGHTTP3_QPACK_ES_OPCODE_DUPLICATE:
  2483. rv = nghttp3_qpack_decoder_dtable_duplicate_add(decoder);
  2484. if (rv != 0) {
  2485. goto fail;
  2486. }
  2487. decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE;
  2488. nghttp3_qpack_read_state_reset(&decoder->rstate);
  2489. break;
  2490. case NGHTTP3_QPACK_ES_OPCODE_INSERT_INDEXED:
  2491. decoder->rstate.prefix = 7;
  2492. decoder->state = NGHTTP3_QPACK_ES_STATE_CHECK_VALUE_HUFFMAN;
  2493. break;
  2494. default:
  2495. nghttp3_unreachable();
  2496. }
  2497. break;
  2498. case NGHTTP3_QPACK_ES_STATE_CHECK_NAME_HUFFMAN:
  2499. qpack_read_state_check_huffman(&decoder->rstate, *p);
  2500. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_NAMELEN;
  2501. decoder->rstate.left = 0;
  2502. decoder->rstate.shift = 0;
  2503. /* Fall through */
  2504. case NGHTTP3_QPACK_ES_STATE_READ_NAMELEN:
  2505. nread = qpack_read_varint(&rfin, &decoder->rstate, p, end);
  2506. if (nread < 0) {
  2507. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2508. rv = NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2509. goto fail;
  2510. }
  2511. p += nread;
  2512. if (!rfin) {
  2513. return p - src;
  2514. }
  2515. if (decoder->rstate.left > NGHTTP3_QPACK_MAX_NAMELEN) {
  2516. rv = NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE;
  2517. goto fail;
  2518. }
  2519. if (decoder->rstate.huffman_encoded) {
  2520. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_NAME_HUFFMAN;
  2521. nghttp3_qpack_huffman_decode_context_init(&decoder->rstate.huffman_ctx);
  2522. rv = nghttp3_rcbuf_new(&decoder->rstate.name,
  2523. (size_t)decoder->rstate.left * 2 + 1, mem);
  2524. } else {
  2525. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_NAME;
  2526. rv = nghttp3_rcbuf_new(&decoder->rstate.name,
  2527. (size_t)decoder->rstate.left + 1, mem);
  2528. }
  2529. if (rv != 0) {
  2530. goto fail;
  2531. }
  2532. nghttp3_buf_wrap_init(&decoder->rstate.namebuf,
  2533. decoder->rstate.name->base,
  2534. decoder->rstate.name->len);
  2535. break;
  2536. case NGHTTP3_QPACK_ES_STATE_READ_NAME_HUFFMAN:
  2537. nread = qpack_read_huffman_string(&decoder->rstate,
  2538. &decoder->rstate.namebuf, p, end);
  2539. if (nread < 0) {
  2540. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2541. rv = NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2542. goto fail;
  2543. }
  2544. p += nread;
  2545. if (decoder->rstate.left) {
  2546. return p - src;
  2547. }
  2548. qpack_read_state_terminate_name(&decoder->rstate);
  2549. decoder->state = NGHTTP3_QPACK_ES_STATE_CHECK_VALUE_HUFFMAN;
  2550. decoder->rstate.prefix = 7;
  2551. break;
  2552. case NGHTTP3_QPACK_ES_STATE_READ_NAME:
  2553. nread =
  2554. qpack_read_string(&decoder->rstate, &decoder->rstate.namebuf, p, end);
  2555. if (nread < 0) {
  2556. rv = (int)nread;
  2557. goto fail;
  2558. }
  2559. p += nread;
  2560. if (decoder->rstate.left) {
  2561. return p - src;
  2562. }
  2563. qpack_read_state_terminate_name(&decoder->rstate);
  2564. decoder->state = NGHTTP3_QPACK_ES_STATE_CHECK_VALUE_HUFFMAN;
  2565. decoder->rstate.prefix = 7;
  2566. break;
  2567. case NGHTTP3_QPACK_ES_STATE_CHECK_VALUE_HUFFMAN:
  2568. qpack_read_state_check_huffman(&decoder->rstate, *p);
  2569. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_VALUELEN;
  2570. decoder->rstate.left = 0;
  2571. decoder->rstate.shift = 0;
  2572. /* Fall through */
  2573. case NGHTTP3_QPACK_ES_STATE_READ_VALUELEN:
  2574. nread = qpack_read_varint(&rfin, &decoder->rstate, p, end);
  2575. if (nread < 0) {
  2576. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2577. rv = NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2578. goto fail;
  2579. }
  2580. p += nread;
  2581. if (!rfin) {
  2582. return p - src;
  2583. }
  2584. if (decoder->rstate.left > NGHTTP3_QPACK_MAX_VALUELEN) {
  2585. rv = NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE;
  2586. goto fail;
  2587. }
  2588. if (decoder->rstate.huffman_encoded) {
  2589. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_VALUE_HUFFMAN;
  2590. nghttp3_qpack_huffman_decode_context_init(&decoder->rstate.huffman_ctx);
  2591. rv = nghttp3_rcbuf_new(&decoder->rstate.value,
  2592. (size_t)decoder->rstate.left * 2 + 1, mem);
  2593. } else {
  2594. decoder->state = NGHTTP3_QPACK_ES_STATE_READ_VALUE;
  2595. rv = nghttp3_rcbuf_new(&decoder->rstate.value,
  2596. (size_t)decoder->rstate.left + 1, mem);
  2597. }
  2598. if (rv != 0) {
  2599. goto fail;
  2600. }
  2601. nghttp3_buf_wrap_init(&decoder->rstate.valuebuf,
  2602. decoder->rstate.value->base,
  2603. decoder->rstate.value->len);
  2604. /* value might be 0 length */
  2605. busy = 1;
  2606. break;
  2607. case NGHTTP3_QPACK_ES_STATE_READ_VALUE_HUFFMAN:
  2608. nread = qpack_read_huffman_string(&decoder->rstate,
  2609. &decoder->rstate.valuebuf, p, end);
  2610. if (nread < 0) {
  2611. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2612. rv = NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2613. goto fail;
  2614. }
  2615. p += nread;
  2616. if (decoder->rstate.left) {
  2617. return p - src;
  2618. }
  2619. qpack_read_state_terminate_value(&decoder->rstate);
  2620. switch (decoder->opcode) {
  2621. case NGHTTP3_QPACK_ES_OPCODE_INSERT_INDEXED:
  2622. rv = nghttp3_qpack_decoder_dtable_indexed_add(decoder);
  2623. break;
  2624. case NGHTTP3_QPACK_ES_OPCODE_INSERT:
  2625. rv = nghttp3_qpack_decoder_dtable_literal_add(decoder);
  2626. break;
  2627. default:
  2628. nghttp3_unreachable();
  2629. }
  2630. if (rv != 0) {
  2631. goto fail;
  2632. }
  2633. decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE;
  2634. nghttp3_qpack_read_state_reset(&decoder->rstate);
  2635. break;
  2636. case NGHTTP3_QPACK_ES_STATE_READ_VALUE:
  2637. nread =
  2638. qpack_read_string(&decoder->rstate, &decoder->rstate.valuebuf, p, end);
  2639. if (nread < 0) {
  2640. rv = (int)nread;
  2641. goto fail;
  2642. }
  2643. p += nread;
  2644. if (decoder->rstate.left) {
  2645. return p - src;
  2646. }
  2647. qpack_read_state_terminate_value(&decoder->rstate);
  2648. switch (decoder->opcode) {
  2649. case NGHTTP3_QPACK_ES_OPCODE_INSERT_INDEXED:
  2650. rv = nghttp3_qpack_decoder_dtable_indexed_add(decoder);
  2651. break;
  2652. case NGHTTP3_QPACK_ES_OPCODE_INSERT:
  2653. rv = nghttp3_qpack_decoder_dtable_literal_add(decoder);
  2654. break;
  2655. default:
  2656. nghttp3_unreachable();
  2657. }
  2658. if (rv != 0) {
  2659. goto fail;
  2660. }
  2661. decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE;
  2662. nghttp3_qpack_read_state_reset(&decoder->rstate);
  2663. break;
  2664. }
  2665. }
  2666. return p - src;
  2667. fail:
  2668. decoder->ctx.bad = 1;
  2669. return rv;
  2670. }
  2671. int nghttp3_qpack_decoder_set_max_dtable_capacity(
  2672. nghttp3_qpack_decoder *decoder, size_t max_dtable_capacity) {
  2673. nghttp3_qpack_entry *ent;
  2674. size_t i;
  2675. nghttp3_qpack_context *ctx = &decoder->ctx;
  2676. const nghttp3_mem *mem = ctx->mem;
  2677. if (max_dtable_capacity > decoder->ctx.hard_max_dtable_capacity) {
  2678. return NGHTTP3_ERR_INVALID_ARGUMENT;
  2679. }
  2680. ctx->max_dtable_capacity = max_dtable_capacity;
  2681. while (ctx->dtable_size > max_dtable_capacity) {
  2682. i = nghttp3_ringbuf_len(&ctx->dtable);
  2683. assert(i);
  2684. ent = *(nghttp3_qpack_entry **)nghttp3_ringbuf_get(&ctx->dtable, i - 1);
  2685. ctx->dtable_size -= table_space(ent->nv.name->len, ent->nv.value->len);
  2686. nghttp3_ringbuf_pop_back(&ctx->dtable);
  2687. nghttp3_qpack_entry_free(ent);
  2688. nghttp3_mem_free(mem, ent);
  2689. }
  2690. return 0;
  2691. }
  2692. int nghttp3_qpack_decoder_dtable_indexed_add(nghttp3_qpack_decoder *decoder) {
  2693. DEBUGF("qpack::decode: Insert With Name Reference (%s) absidx=%" PRIu64 ": "
  2694. "value=%*s\n",
  2695. decoder->rstate.dynamic ? "dynamic" : "static", decoder->rstate.absidx,
  2696. (int)decoder->rstate.value->len, decoder->rstate.value->base);
  2697. if (decoder->rstate.dynamic) {
  2698. return nghttp3_qpack_decoder_dtable_dynamic_add(decoder);
  2699. }
  2700. return nghttp3_qpack_decoder_dtable_static_add(decoder);
  2701. }
  2702. int nghttp3_qpack_decoder_dtable_static_add(nghttp3_qpack_decoder *decoder) {
  2703. nghttp3_qpack_nv qnv;
  2704. int rv;
  2705. const nghttp3_qpack_static_header *shd;
  2706. shd = &stable[decoder->rstate.absidx];
  2707. if (table_space(shd->name.len, decoder->rstate.value->len) >
  2708. decoder->ctx.max_dtable_capacity) {
  2709. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2710. }
  2711. qnv.name = (nghttp3_rcbuf *)&shd->name;
  2712. qnv.value = decoder->rstate.value;
  2713. qnv.token = shd->token;
  2714. qnv.flags = NGHTTP3_NV_FLAG_NONE;
  2715. rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
  2716. nghttp3_rcbuf_decref(qnv.value);
  2717. return rv;
  2718. }
  2719. int nghttp3_qpack_decoder_dtable_dynamic_add(nghttp3_qpack_decoder *decoder) {
  2720. nghttp3_qpack_nv qnv;
  2721. int rv;
  2722. nghttp3_qpack_entry *ent;
  2723. ent = nghttp3_qpack_context_dtable_get(&decoder->ctx, decoder->rstate.absidx);
  2724. if (table_space(ent->nv.name->len, decoder->rstate.value->len) >
  2725. decoder->ctx.max_dtable_capacity) {
  2726. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2727. }
  2728. qnv.name = ent->nv.name;
  2729. qnv.value = decoder->rstate.value;
  2730. qnv.token = ent->nv.token;
  2731. qnv.flags = NGHTTP3_NV_FLAG_NONE;
  2732. nghttp3_rcbuf_incref(qnv.name);
  2733. rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
  2734. nghttp3_rcbuf_decref(qnv.value);
  2735. nghttp3_rcbuf_decref(qnv.name);
  2736. return rv;
  2737. }
  2738. int nghttp3_qpack_decoder_dtable_duplicate_add(nghttp3_qpack_decoder *decoder) {
  2739. int rv;
  2740. nghttp3_qpack_entry *ent;
  2741. nghttp3_qpack_nv qnv;
  2742. DEBUGF("qpack::decode: Insert duplicate absidx=%" PRIu64 "\n",
  2743. decoder->rstate.absidx);
  2744. ent = nghttp3_qpack_context_dtable_get(&decoder->ctx, decoder->rstate.absidx);
  2745. if (table_space(ent->nv.name->len, ent->nv.value->len) >
  2746. decoder->ctx.max_dtable_capacity) {
  2747. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2748. }
  2749. qnv = ent->nv;
  2750. nghttp3_rcbuf_incref(qnv.name);
  2751. nghttp3_rcbuf_incref(qnv.value);
  2752. rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
  2753. nghttp3_rcbuf_decref(qnv.value);
  2754. nghttp3_rcbuf_decref(qnv.name);
  2755. return rv;
  2756. }
  2757. int nghttp3_qpack_decoder_dtable_literal_add(nghttp3_qpack_decoder *decoder) {
  2758. nghttp3_qpack_nv qnv;
  2759. int rv;
  2760. DEBUGF("qpack::decode: Insert With Literal Name: name=%*s value=%*s\n",
  2761. (int)decoder->rstate.name->len, decoder->rstate.name->base,
  2762. (int)decoder->rstate.value->len, decoder->rstate.value->base);
  2763. if (table_space(decoder->rstate.name->len, decoder->rstate.value->len) >
  2764. decoder->ctx.max_dtable_capacity) {
  2765. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  2766. }
  2767. qnv.name = decoder->rstate.name;
  2768. qnv.value = decoder->rstate.value;
  2769. qnv.token = qpack_lookup_token(qnv.name->base, qnv.name->len);
  2770. qnv.flags = NGHTTP3_NV_FLAG_NONE;
  2771. rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
  2772. nghttp3_rcbuf_decref(qnv.value);
  2773. nghttp3_rcbuf_decref(qnv.name);
  2774. return rv;
  2775. }
  2776. void nghttp3_qpack_decoder_set_max_concurrent_streams(
  2777. nghttp3_qpack_decoder *decoder, size_t max_concurrent_streams) {
  2778. decoder->max_concurrent_streams =
  2779. nghttp3_max_size(decoder->max_concurrent_streams, max_concurrent_streams);
  2780. }
  2781. void nghttp3_qpack_stream_context_init(nghttp3_qpack_stream_context *sctx,
  2782. int64_t stream_id,
  2783. const nghttp3_mem *mem) {
  2784. nghttp3_qpack_read_state_reset(&sctx->rstate);
  2785. sctx->mem = mem;
  2786. sctx->rstate.prefix = 8;
  2787. sctx->state = NGHTTP3_QPACK_RS_STATE_RICNT;
  2788. sctx->opcode = 0;
  2789. sctx->stream_id = stream_id;
  2790. sctx->ricnt = 0;
  2791. sctx->dbase_sign = 0;
  2792. sctx->base = 0;
  2793. }
  2794. void nghttp3_qpack_stream_context_free(nghttp3_qpack_stream_context *sctx) {
  2795. nghttp3_qpack_read_state_free(&sctx->rstate);
  2796. }
  2797. void nghttp3_qpack_stream_context_reset(nghttp3_qpack_stream_context *sctx) {
  2798. nghttp3_qpack_stream_context_init(sctx, sctx->stream_id, sctx->mem);
  2799. }
  2800. uint64_t
  2801. nghttp3_qpack_stream_context_get_ricnt(nghttp3_qpack_stream_context *sctx) {
  2802. return sctx->ricnt;
  2803. }
  2804. nghttp3_ssize
  2805. nghttp3_qpack_decoder_read_request(nghttp3_qpack_decoder *decoder,
  2806. nghttp3_qpack_stream_context *sctx,
  2807. nghttp3_qpack_nv *nv, uint8_t *pflags,
  2808. const uint8_t *src, size_t srclen, int fin) {
  2809. const uint8_t *p = src, *end = src ? src + srclen : src;
  2810. int rv;
  2811. int busy = 0;
  2812. nghttp3_ssize nread;
  2813. int rfin;
  2814. const nghttp3_mem *mem = decoder->ctx.mem;
  2815. if (decoder->ctx.bad) {
  2816. return NGHTTP3_ERR_QPACK_FATAL;
  2817. }
  2818. *pflags = NGHTTP3_QPACK_DECODE_FLAG_NONE;
  2819. for (; p != end || busy;) {
  2820. busy = 0;
  2821. switch (sctx->state) {
  2822. case NGHTTP3_QPACK_RS_STATE_RICNT:
  2823. nread = qpack_read_varint(&rfin, &sctx->rstate, p, end);
  2824. if (nread < 0) {
  2825. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2826. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  2827. goto fail;
  2828. }
  2829. p += nread;
  2830. if (!rfin) {
  2831. goto almost_ok;
  2832. }
  2833. rv = nghttp3_qpack_decoder_reconstruct_ricnt(decoder, &sctx->ricnt,
  2834. sctx->rstate.left);
  2835. if (rv != 0) {
  2836. goto fail;
  2837. }
  2838. sctx->state = NGHTTP3_QPACK_RS_STATE_DBASE_SIGN;
  2839. break;
  2840. case NGHTTP3_QPACK_RS_STATE_DBASE_SIGN:
  2841. if ((*p) & 0x80) {
  2842. sctx->dbase_sign = 1;
  2843. }
  2844. sctx->state = NGHTTP3_QPACK_RS_STATE_DBASE;
  2845. sctx->rstate.left = 0;
  2846. sctx->rstate.prefix = 7;
  2847. sctx->rstate.shift = 0;
  2848. /* Fall through */
  2849. case NGHTTP3_QPACK_RS_STATE_DBASE:
  2850. nread = qpack_read_varint(&rfin, &sctx->rstate, p, end);
  2851. if (nread < 0) {
  2852. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2853. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  2854. goto fail;
  2855. }
  2856. p += nread;
  2857. if (!rfin) {
  2858. goto almost_ok;
  2859. }
  2860. if (sctx->dbase_sign) {
  2861. if (sctx->ricnt <= sctx->rstate.left) {
  2862. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  2863. goto fail;
  2864. }
  2865. sctx->base = sctx->ricnt - sctx->rstate.left - 1;
  2866. } else {
  2867. sctx->base = sctx->ricnt + sctx->rstate.left;
  2868. }
  2869. DEBUGF("qpack::decode: ricnt=%" PRIu64 " base=%" PRIu64 " icnt=%" PRIu64
  2870. "\n",
  2871. sctx->ricnt, sctx->base, decoder->ctx.next_absidx);
  2872. if (sctx->ricnt > decoder->ctx.next_absidx) {
  2873. DEBUGF("qpack::decode: stream blocked\n");
  2874. sctx->state = NGHTTP3_QPACK_RS_STATE_BLOCKED;
  2875. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_BLOCKED;
  2876. return p - src;
  2877. }
  2878. sctx->state = NGHTTP3_QPACK_RS_STATE_OPCODE;
  2879. sctx->rstate.left = 0;
  2880. sctx->rstate.shift = 0;
  2881. break;
  2882. case NGHTTP3_QPACK_RS_STATE_OPCODE:
  2883. assert(sctx->rstate.left == 0);
  2884. assert(sctx->rstate.shift == 0);
  2885. switch ((*p) & 0xf0) {
  2886. case 0x80:
  2887. case 0x90:
  2888. case 0xa0:
  2889. case 0xb0:
  2890. case 0xc0:
  2891. case 0xd0:
  2892. case 0xe0:
  2893. case 0xf0:
  2894. DEBUGF("qpack::decode: OPCODE_INDEXED\n");
  2895. sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED;
  2896. sctx->rstate.dynamic = !((*p) & 0x40);
  2897. sctx->rstate.prefix = 6;
  2898. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;
  2899. break;
  2900. case 0x40:
  2901. case 0x50:
  2902. case 0x60:
  2903. case 0x70:
  2904. DEBUGF("qpack::decode: OPCODE_INDEXED_NAME\n");
  2905. sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME;
  2906. sctx->rstate.never = (*p) & 0x20;
  2907. sctx->rstate.dynamic = !((*p) & 0x10);
  2908. sctx->rstate.prefix = 4;
  2909. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;
  2910. break;
  2911. case 0x20:
  2912. case 0x30:
  2913. DEBUGF("qpack::decode: OPCODE_LITERAL\n");
  2914. sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_LITERAL;
  2915. sctx->rstate.never = (*p) & 0x10;
  2916. sctx->rstate.dynamic = 0;
  2917. sctx->rstate.prefix = 3;
  2918. sctx->state = NGHTTP3_QPACK_RS_STATE_CHECK_NAME_HUFFMAN;
  2919. break;
  2920. case 0x10:
  2921. DEBUGF("qpack::decode: OPCODE_INDEXED_PB\n");
  2922. sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_PB;
  2923. sctx->rstate.dynamic = 1;
  2924. sctx->rstate.prefix = 4;
  2925. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;
  2926. break;
  2927. default:
  2928. DEBUGF("qpack::decode: OPCODE_INDEXED_NAME_PB\n");
  2929. sctx->opcode = NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME_PB;
  2930. sctx->rstate.never = (*p) & 0x08;
  2931. sctx->rstate.dynamic = 1;
  2932. sctx->rstate.prefix = 3;
  2933. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_INDEX;
  2934. }
  2935. break;
  2936. case NGHTTP3_QPACK_RS_STATE_READ_INDEX:
  2937. nread = qpack_read_varint(&rfin, &sctx->rstate, p, end);
  2938. if (nread < 0) {
  2939. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2940. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  2941. goto fail;
  2942. }
  2943. p += nread;
  2944. if (!rfin) {
  2945. goto almost_ok;
  2946. }
  2947. switch (sctx->opcode) {
  2948. case NGHTTP3_QPACK_RS_OPCODE_INDEXED:
  2949. rv = nghttp3_qpack_decoder_brel2abs(decoder, sctx);
  2950. if (rv != 0) {
  2951. goto fail;
  2952. }
  2953. nghttp3_qpack_decoder_emit_indexed(decoder, sctx, nv);
  2954. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_EMIT;
  2955. sctx->state = NGHTTP3_QPACK_RS_STATE_OPCODE;
  2956. nghttp3_qpack_read_state_reset(&sctx->rstate);
  2957. return p - src;
  2958. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_PB:
  2959. rv = nghttp3_qpack_decoder_pbrel2abs(decoder, sctx);
  2960. if (rv != 0) {
  2961. goto fail;
  2962. }
  2963. nghttp3_qpack_decoder_emit_indexed(decoder, sctx, nv);
  2964. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_EMIT;
  2965. sctx->state = NGHTTP3_QPACK_RS_STATE_OPCODE;
  2966. nghttp3_qpack_read_state_reset(&sctx->rstate);
  2967. return p - src;
  2968. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME:
  2969. rv = nghttp3_qpack_decoder_brel2abs(decoder, sctx);
  2970. if (rv != 0) {
  2971. goto fail;
  2972. }
  2973. sctx->rstate.prefix = 7;
  2974. sctx->state = NGHTTP3_QPACK_RS_STATE_CHECK_VALUE_HUFFMAN;
  2975. break;
  2976. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME_PB:
  2977. rv = nghttp3_qpack_decoder_pbrel2abs(decoder, sctx);
  2978. if (rv != 0) {
  2979. goto fail;
  2980. }
  2981. sctx->rstate.prefix = 7;
  2982. sctx->state = NGHTTP3_QPACK_RS_STATE_CHECK_VALUE_HUFFMAN;
  2983. break;
  2984. default:
  2985. nghttp3_unreachable();
  2986. }
  2987. break;
  2988. case NGHTTP3_QPACK_RS_STATE_CHECK_NAME_HUFFMAN:
  2989. qpack_read_state_check_huffman(&sctx->rstate, *p);
  2990. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_NAMELEN;
  2991. sctx->rstate.left = 0;
  2992. sctx->rstate.shift = 0;
  2993. /* Fall through */
  2994. case NGHTTP3_QPACK_RS_STATE_READ_NAMELEN:
  2995. nread = qpack_read_varint(&rfin, &sctx->rstate, p, end);
  2996. if (nread < 0) {
  2997. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  2998. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  2999. goto fail;
  3000. }
  3001. p += nread;
  3002. if (!rfin) {
  3003. goto almost_ok;
  3004. }
  3005. if (sctx->rstate.left > NGHTTP3_QPACK_MAX_NAMELEN) {
  3006. rv = NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE;
  3007. goto fail;
  3008. }
  3009. if (sctx->rstate.huffman_encoded) {
  3010. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_NAME_HUFFMAN;
  3011. nghttp3_qpack_huffman_decode_context_init(&sctx->rstate.huffman_ctx);
  3012. rv = nghttp3_rcbuf_new(&sctx->rstate.name,
  3013. (size_t)sctx->rstate.left * 2 + 1, mem);
  3014. } else {
  3015. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_NAME;
  3016. rv = nghttp3_rcbuf_new(&sctx->rstate.name,
  3017. (size_t)sctx->rstate.left + 1, mem);
  3018. }
  3019. if (rv != 0) {
  3020. goto fail;
  3021. }
  3022. nghttp3_buf_wrap_init(&sctx->rstate.namebuf, sctx->rstate.name->base,
  3023. sctx->rstate.name->len);
  3024. break;
  3025. case NGHTTP3_QPACK_RS_STATE_READ_NAME_HUFFMAN:
  3026. nread =
  3027. qpack_read_huffman_string(&sctx->rstate, &sctx->rstate.namebuf, p, end);
  3028. if (nread < 0) {
  3029. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  3030. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3031. goto fail;
  3032. }
  3033. p += nread;
  3034. if (sctx->rstate.left) {
  3035. goto almost_ok;
  3036. }
  3037. qpack_read_state_terminate_name(&sctx->rstate);
  3038. sctx->state = NGHTTP3_QPACK_RS_STATE_CHECK_VALUE_HUFFMAN;
  3039. sctx->rstate.prefix = 7;
  3040. break;
  3041. case NGHTTP3_QPACK_RS_STATE_READ_NAME:
  3042. nread = qpack_read_string(&sctx->rstate, &sctx->rstate.namebuf, p, end);
  3043. if (nread < 0) {
  3044. rv = (int)nread;
  3045. goto fail;
  3046. }
  3047. p += nread;
  3048. if (sctx->rstate.left) {
  3049. goto almost_ok;
  3050. }
  3051. qpack_read_state_terminate_name(&sctx->rstate);
  3052. sctx->state = NGHTTP3_QPACK_RS_STATE_CHECK_VALUE_HUFFMAN;
  3053. sctx->rstate.prefix = 7;
  3054. break;
  3055. case NGHTTP3_QPACK_RS_STATE_CHECK_VALUE_HUFFMAN:
  3056. qpack_read_state_check_huffman(&sctx->rstate, *p);
  3057. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_VALUELEN;
  3058. sctx->rstate.left = 0;
  3059. sctx->rstate.shift = 0;
  3060. /* Fall through */
  3061. case NGHTTP3_QPACK_RS_STATE_READ_VALUELEN:
  3062. nread = qpack_read_varint(&rfin, &sctx->rstate, p, end);
  3063. if (nread < 0) {
  3064. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  3065. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3066. goto fail;
  3067. }
  3068. p += nread;
  3069. if (!rfin) {
  3070. goto almost_ok;
  3071. }
  3072. if (sctx->rstate.left > NGHTTP3_QPACK_MAX_VALUELEN) {
  3073. rv = NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE;
  3074. goto fail;
  3075. }
  3076. if (sctx->rstate.huffman_encoded) {
  3077. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_VALUE_HUFFMAN;
  3078. nghttp3_qpack_huffman_decode_context_init(&sctx->rstate.huffman_ctx);
  3079. rv = nghttp3_rcbuf_new(&sctx->rstate.value,
  3080. (size_t)sctx->rstate.left * 2 + 1, mem);
  3081. } else {
  3082. sctx->state = NGHTTP3_QPACK_RS_STATE_READ_VALUE;
  3083. rv = nghttp3_rcbuf_new(&sctx->rstate.value,
  3084. (size_t)sctx->rstate.left + 1, mem);
  3085. }
  3086. if (rv != 0) {
  3087. goto fail;
  3088. }
  3089. nghttp3_buf_wrap_init(&sctx->rstate.valuebuf, sctx->rstate.value->base,
  3090. sctx->rstate.value->len);
  3091. /* value might be 0 length */
  3092. busy = 1;
  3093. break;
  3094. case NGHTTP3_QPACK_RS_STATE_READ_VALUE_HUFFMAN:
  3095. nread = qpack_read_huffman_string(&sctx->rstate, &sctx->rstate.valuebuf,
  3096. p, end);
  3097. if (nread < 0) {
  3098. assert(NGHTTP3_ERR_QPACK_FATAL == nread);
  3099. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3100. goto fail;
  3101. }
  3102. p += nread;
  3103. if (sctx->rstate.left) {
  3104. goto almost_ok;
  3105. }
  3106. qpack_read_state_terminate_value(&sctx->rstate);
  3107. switch (sctx->opcode) {
  3108. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME:
  3109. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME_PB:
  3110. rv = nghttp3_qpack_decoder_emit_indexed_name(decoder, sctx, nv);
  3111. if (rv != 0) {
  3112. goto fail;
  3113. }
  3114. break;
  3115. case NGHTTP3_QPACK_RS_OPCODE_LITERAL:
  3116. nghttp3_qpack_decoder_emit_literal(decoder, sctx, nv);
  3117. break;
  3118. default:
  3119. nghttp3_unreachable();
  3120. }
  3121. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_EMIT;
  3122. sctx->state = NGHTTP3_QPACK_RS_STATE_OPCODE;
  3123. nghttp3_qpack_read_state_reset(&sctx->rstate);
  3124. return p - src;
  3125. case NGHTTP3_QPACK_RS_STATE_READ_VALUE:
  3126. nread = qpack_read_string(&sctx->rstate, &sctx->rstate.valuebuf, p, end);
  3127. if (nread < 0) {
  3128. rv = (int)nread;
  3129. goto fail;
  3130. }
  3131. p += nread;
  3132. if (sctx->rstate.left) {
  3133. goto almost_ok;
  3134. }
  3135. qpack_read_state_terminate_value(&sctx->rstate);
  3136. switch (sctx->opcode) {
  3137. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME:
  3138. case NGHTTP3_QPACK_RS_OPCODE_INDEXED_NAME_PB:
  3139. rv = nghttp3_qpack_decoder_emit_indexed_name(decoder, sctx, nv);
  3140. if (rv != 0) {
  3141. goto fail;
  3142. }
  3143. break;
  3144. case NGHTTP3_QPACK_RS_OPCODE_LITERAL:
  3145. nghttp3_qpack_decoder_emit_literal(decoder, sctx, nv);
  3146. break;
  3147. default:
  3148. nghttp3_unreachable();
  3149. }
  3150. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_EMIT;
  3151. sctx->state = NGHTTP3_QPACK_RS_STATE_OPCODE;
  3152. nghttp3_qpack_read_state_reset(&sctx->rstate);
  3153. return p - src;
  3154. case NGHTTP3_QPACK_RS_STATE_BLOCKED:
  3155. if (sctx->ricnt > decoder->ctx.next_absidx) {
  3156. DEBUGF("qpack::decode: stream still blocked\n");
  3157. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_BLOCKED;
  3158. return p - src;
  3159. }
  3160. sctx->state = NGHTTP3_QPACK_RS_STATE_OPCODE;
  3161. nghttp3_qpack_read_state_reset(&sctx->rstate);
  3162. break;
  3163. }
  3164. }
  3165. almost_ok:
  3166. if (fin) {
  3167. if (sctx->state != NGHTTP3_QPACK_RS_STATE_OPCODE) {
  3168. rv = NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3169. goto fail;
  3170. }
  3171. *pflags |= NGHTTP3_QPACK_DECODE_FLAG_FINAL;
  3172. if (sctx->ricnt) {
  3173. rv = nghttp3_qpack_decoder_write_section_ack(decoder, sctx);
  3174. if (rv != 0) {
  3175. goto fail;
  3176. }
  3177. }
  3178. decoder->uninterrupted_encoderlen = 0;
  3179. }
  3180. return p - src;
  3181. fail:
  3182. decoder->ctx.bad = 1;
  3183. return rv;
  3184. }
  3185. static int qpack_decoder_dbuf_overflow(nghttp3_qpack_decoder *decoder) {
  3186. size_t limit = nghttp3_max_size(decoder->max_concurrent_streams, 100);
  3187. /* 10 = nghttp3_qpack_put_varint_len((1ULL << 62) - 1, 2)) */
  3188. return nghttp3_buf_len(&decoder->dbuf) > limit * 2 * 10;
  3189. }
  3190. int nghttp3_qpack_decoder_write_section_ack(
  3191. nghttp3_qpack_decoder *decoder, const nghttp3_qpack_stream_context *sctx) {
  3192. nghttp3_buf *dbuf = &decoder->dbuf;
  3193. uint8_t *p;
  3194. int rv;
  3195. if (qpack_decoder_dbuf_overflow(decoder)) {
  3196. return NGHTTP3_ERR_QPACK_FATAL;
  3197. }
  3198. rv = reserve_buf(dbuf,
  3199. nghttp3_qpack_put_varint_len((uint64_t)sctx->stream_id, 7),
  3200. decoder->ctx.mem);
  3201. if (rv != 0) {
  3202. return rv;
  3203. }
  3204. p = dbuf->last;
  3205. *p = 0x80;
  3206. dbuf->last = nghttp3_qpack_put_varint(p, (uint64_t)sctx->stream_id, 7);
  3207. if (decoder->written_icnt < sctx->ricnt) {
  3208. decoder->written_icnt = sctx->ricnt;
  3209. }
  3210. return 0;
  3211. }
  3212. size_t
  3213. nghttp3_qpack_decoder_get_decoder_streamlen(nghttp3_qpack_decoder *decoder) {
  3214. uint64_t n;
  3215. size_t len = 0;
  3216. if (decoder->written_icnt < decoder->ctx.next_absidx) {
  3217. n = decoder->ctx.next_absidx - decoder->written_icnt;
  3218. len = nghttp3_qpack_put_varint_len(n, 6);
  3219. }
  3220. return nghttp3_buf_len(&decoder->dbuf) + len;
  3221. }
  3222. void nghttp3_qpack_decoder_write_decoder(nghttp3_qpack_decoder *decoder,
  3223. nghttp3_buf *dbuf) {
  3224. uint8_t *p;
  3225. uint64_t n = 0;
  3226. size_t len = 0;
  3227. (void)len;
  3228. if (decoder->written_icnt < decoder->ctx.next_absidx) {
  3229. n = decoder->ctx.next_absidx - decoder->written_icnt;
  3230. len = nghttp3_qpack_put_varint_len(n, 6);
  3231. }
  3232. assert(nghttp3_buf_left(dbuf) >= nghttp3_buf_len(&decoder->dbuf) + len);
  3233. if (nghttp3_buf_len(&decoder->dbuf)) {
  3234. dbuf->last = nghttp3_cpymem(dbuf->last, decoder->dbuf.pos,
  3235. nghttp3_buf_len(&decoder->dbuf));
  3236. }
  3237. if (n) {
  3238. p = dbuf->last;
  3239. *p = 0;
  3240. dbuf->last = nghttp3_qpack_put_varint(p, n, 6);
  3241. decoder->written_icnt = decoder->ctx.next_absidx;
  3242. }
  3243. nghttp3_buf_reset(&decoder->dbuf);
  3244. }
  3245. int nghttp3_qpack_decoder_cancel_stream(nghttp3_qpack_decoder *decoder,
  3246. int64_t stream_id) {
  3247. uint8_t *p;
  3248. int rv;
  3249. if (qpack_decoder_dbuf_overflow(decoder)) {
  3250. return NGHTTP3_ERR_QPACK_FATAL;
  3251. }
  3252. rv = reserve_buf(&decoder->dbuf,
  3253. nghttp3_qpack_put_varint_len((uint64_t)stream_id, 6),
  3254. decoder->ctx.mem);
  3255. if (rv != 0) {
  3256. return rv;
  3257. }
  3258. p = decoder->dbuf.last;
  3259. *p = 0x40;
  3260. decoder->dbuf.last = nghttp3_qpack_put_varint(p, (uint64_t)stream_id, 6);
  3261. return 0;
  3262. }
  3263. int nghttp3_qpack_decoder_reconstruct_ricnt(nghttp3_qpack_decoder *decoder,
  3264. uint64_t *dest, uint64_t encricnt) {
  3265. uint64_t max_ents, full, max, max_wrapped, ricnt;
  3266. if (encricnt == 0) {
  3267. *dest = 0;
  3268. return 0;
  3269. }
  3270. max_ents =
  3271. decoder->ctx.hard_max_dtable_capacity / NGHTTP3_QPACK_ENTRY_OVERHEAD;
  3272. full = 2 * max_ents;
  3273. if (encricnt > full) {
  3274. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3275. }
  3276. max = decoder->ctx.next_absidx + max_ents;
  3277. max_wrapped = max / full * full;
  3278. ricnt = max_wrapped + encricnt - 1;
  3279. if (ricnt > max) {
  3280. if (ricnt <= full) {
  3281. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3282. }
  3283. ricnt -= full;
  3284. }
  3285. if (ricnt == 0) {
  3286. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3287. }
  3288. *dest = ricnt;
  3289. return 0;
  3290. }
  3291. int nghttp3_qpack_decoder_rel2abs(nghttp3_qpack_decoder *decoder,
  3292. nghttp3_qpack_read_state *rstate) {
  3293. DEBUGF("qpack::decode: dynamic=%d relidx=%" PRIu64 " icnt=%" PRIu64 "\n",
  3294. rstate->dynamic, rstate->left, decoder->ctx.next_absidx);
  3295. if (rstate->dynamic) {
  3296. if (decoder->ctx.next_absidx < rstate->left + 1) {
  3297. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  3298. }
  3299. rstate->absidx = decoder->ctx.next_absidx - rstate->left - 1;
  3300. } else {
  3301. rstate->absidx = rstate->left;
  3302. }
  3303. if (qpack_decoder_validate_index(decoder, rstate) != 0) {
  3304. return NGHTTP3_ERR_QPACK_ENCODER_STREAM_ERROR;
  3305. }
  3306. return 0;
  3307. }
  3308. int nghttp3_qpack_decoder_brel2abs(nghttp3_qpack_decoder *decoder,
  3309. nghttp3_qpack_stream_context *sctx) {
  3310. nghttp3_qpack_read_state *rstate = &sctx->rstate;
  3311. DEBUGF("qpack::decode: dynamic=%d relidx=%" PRIu64 " base=%" PRIu64
  3312. " icnt=%" PRIu64 "\n",
  3313. rstate->dynamic, rstate->left, sctx->base, decoder->ctx.next_absidx);
  3314. if (rstate->dynamic) {
  3315. if (sctx->base < rstate->left + 1) {
  3316. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3317. }
  3318. rstate->absidx = sctx->base - rstate->left - 1;
  3319. if (rstate->absidx >= sctx->ricnt) {
  3320. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3321. }
  3322. } else {
  3323. rstate->absidx = rstate->left;
  3324. }
  3325. if (qpack_decoder_validate_index(decoder, rstate) != 0) {
  3326. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3327. }
  3328. return 0;
  3329. }
  3330. int nghttp3_qpack_decoder_pbrel2abs(nghttp3_qpack_decoder *decoder,
  3331. nghttp3_qpack_stream_context *sctx) {
  3332. nghttp3_qpack_read_state *rstate = &sctx->rstate;
  3333. DEBUGF("qpack::decode: pbidx=%" PRIu64 " base=%" PRIu64 " icnt=%" PRIu64 "\n",
  3334. rstate->left, sctx->base, decoder->ctx.next_absidx);
  3335. assert(rstate->dynamic);
  3336. rstate->absidx = rstate->left + sctx->base;
  3337. if (rstate->absidx >= sctx->ricnt) {
  3338. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3339. }
  3340. if (qpack_decoder_validate_index(decoder, rstate) != 0) {
  3341. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3342. }
  3343. return 0;
  3344. }
  3345. static void
  3346. qpack_decoder_emit_static_indexed(nghttp3_qpack_decoder *decoder,
  3347. nghttp3_qpack_stream_context *sctx,
  3348. nghttp3_qpack_nv *nv) {
  3349. const nghttp3_qpack_static_header *shd = &stable[sctx->rstate.absidx];
  3350. (void)decoder;
  3351. nv->name = (nghttp3_rcbuf *)&shd->name;
  3352. nv->value = (nghttp3_rcbuf *)&shd->value;
  3353. nv->token = shd->token;
  3354. nv->flags = NGHTTP3_NV_FLAG_NONE;
  3355. }
  3356. static void
  3357. qpack_decoder_emit_dynamic_indexed(nghttp3_qpack_decoder *decoder,
  3358. nghttp3_qpack_stream_context *sctx,
  3359. nghttp3_qpack_nv *nv) {
  3360. nghttp3_qpack_entry *ent =
  3361. nghttp3_qpack_context_dtable_get(&decoder->ctx, sctx->rstate.absidx);
  3362. *nv = ent->nv;
  3363. nghttp3_rcbuf_incref(nv->name);
  3364. nghttp3_rcbuf_incref(nv->value);
  3365. }
  3366. void nghttp3_qpack_decoder_emit_indexed(nghttp3_qpack_decoder *decoder,
  3367. nghttp3_qpack_stream_context *sctx,
  3368. nghttp3_qpack_nv *nv) {
  3369. DEBUGF("qpack::decode: Indexed (%s) absidx=%" PRIu64 "\n",
  3370. sctx->rstate.dynamic ? "dynamic" : "static", sctx->rstate.absidx);
  3371. if (sctx->rstate.dynamic) {
  3372. qpack_decoder_emit_dynamic_indexed(decoder, sctx, nv);
  3373. } else {
  3374. qpack_decoder_emit_static_indexed(decoder, sctx, nv);
  3375. }
  3376. }
  3377. static void
  3378. qpack_decoder_emit_static_indexed_name(nghttp3_qpack_decoder *decoder,
  3379. nghttp3_qpack_stream_context *sctx,
  3380. nghttp3_qpack_nv *nv) {
  3381. const nghttp3_qpack_static_header *shd = &stable[sctx->rstate.absidx];
  3382. (void)decoder;
  3383. nv->name = (nghttp3_rcbuf *)&shd->name;
  3384. nv->value = sctx->rstate.value;
  3385. nv->token = shd->token;
  3386. nv->flags =
  3387. sctx->rstate.never ? NGHTTP3_NV_FLAG_NEVER_INDEX : NGHTTP3_NV_FLAG_NONE;
  3388. sctx->rstate.value = NULL;
  3389. }
  3390. static int
  3391. qpack_decoder_emit_dynamic_indexed_name(nghttp3_qpack_decoder *decoder,
  3392. nghttp3_qpack_stream_context *sctx,
  3393. nghttp3_qpack_nv *nv) {
  3394. nghttp3_qpack_entry *ent;
  3395. /* A broken encoder might change dtable capacity while processing
  3396. request stream instruction. Check the absidx again. */
  3397. if (qpack_decoder_validate_index(decoder, &sctx->rstate) != 0) {
  3398. return NGHTTP3_ERR_QPACK_DECOMPRESSION_FAILED;
  3399. }
  3400. ent = nghttp3_qpack_context_dtable_get(&decoder->ctx, sctx->rstate.absidx);
  3401. nv->name = ent->nv.name;
  3402. nv->value = sctx->rstate.value;
  3403. nv->token = ent->nv.token;
  3404. nv->flags =
  3405. sctx->rstate.never ? NGHTTP3_NV_FLAG_NEVER_INDEX : NGHTTP3_NV_FLAG_NONE;
  3406. nghttp3_rcbuf_incref(nv->name);
  3407. sctx->rstate.value = NULL;
  3408. return 0;
  3409. }
  3410. int nghttp3_qpack_decoder_emit_indexed_name(nghttp3_qpack_decoder *decoder,
  3411. nghttp3_qpack_stream_context *sctx,
  3412. nghttp3_qpack_nv *nv) {
  3413. (void)decoder;
  3414. DEBUGF("qpack::decode: Indexed name (%s) absidx=%" PRIu64 " value=%*s\n",
  3415. sctx->rstate.dynamic ? "dynamic" : "static", sctx->rstate.absidx,
  3416. (int)sctx->rstate.value->len, sctx->rstate.value->base);
  3417. if (sctx->rstate.dynamic) {
  3418. return qpack_decoder_emit_dynamic_indexed_name(decoder, sctx, nv);
  3419. }
  3420. qpack_decoder_emit_static_indexed_name(decoder, sctx, nv);
  3421. return 0;
  3422. }
  3423. void nghttp3_qpack_decoder_emit_literal(nghttp3_qpack_decoder *decoder,
  3424. nghttp3_qpack_stream_context *sctx,
  3425. nghttp3_qpack_nv *nv) {
  3426. (void)decoder;
  3427. DEBUGF("qpack::decode: Emit literal name=%*s value=%*s\n",
  3428. (int)sctx->rstate.name->len, sctx->rstate.name->base,
  3429. (int)sctx->rstate.value->len, sctx->rstate.value->base);
  3430. nv->name = sctx->rstate.name;
  3431. nv->value = sctx->rstate.value;
  3432. nv->token = qpack_lookup_token(nv->name->base, nv->name->len);
  3433. nv->flags =
  3434. sctx->rstate.never ? NGHTTP3_NV_FLAG_NEVER_INDEX : NGHTTP3_NV_FLAG_NONE;
  3435. sctx->rstate.name = NULL;
  3436. sctx->rstate.value = NULL;
  3437. }
  3438. int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder,
  3439. size_t hard_max_dtable_capacity,
  3440. const nghttp3_mem *mem) {
  3441. int rv;
  3442. nghttp3_qpack_encoder *p;
  3443. p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_encoder));
  3444. if (p == NULL) {
  3445. return NGHTTP3_ERR_NOMEM;
  3446. }
  3447. rv = nghttp3_qpack_encoder_init(p, hard_max_dtable_capacity, mem);
  3448. if (rv != 0) {
  3449. return rv;
  3450. }
  3451. *pencoder = p;
  3452. return 0;
  3453. }
  3454. void nghttp3_qpack_encoder_del(nghttp3_qpack_encoder *encoder) {
  3455. const nghttp3_mem *mem;
  3456. if (encoder == NULL) {
  3457. return;
  3458. }
  3459. mem = encoder->ctx.mem;
  3460. nghttp3_qpack_encoder_free(encoder);
  3461. nghttp3_mem_free(mem, encoder);
  3462. }
  3463. int nghttp3_qpack_stream_context_new(nghttp3_qpack_stream_context **psctx,
  3464. int64_t stream_id,
  3465. const nghttp3_mem *mem) {
  3466. nghttp3_qpack_stream_context *p;
  3467. p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_stream_context));
  3468. if (p == NULL) {
  3469. return NGHTTP3_ERR_NOMEM;
  3470. }
  3471. nghttp3_qpack_stream_context_init(p, stream_id, mem);
  3472. *psctx = p;
  3473. return 0;
  3474. }
  3475. void nghttp3_qpack_stream_context_del(nghttp3_qpack_stream_context *sctx) {
  3476. const nghttp3_mem *mem;
  3477. if (sctx == NULL) {
  3478. return;
  3479. }
  3480. mem = sctx->mem;
  3481. nghttp3_qpack_stream_context_free(sctx);
  3482. nghttp3_mem_free(mem, sctx);
  3483. }
  3484. int nghttp3_qpack_decoder_new(nghttp3_qpack_decoder **pdecoder,
  3485. size_t hard_max_dtable_capacity,
  3486. size_t max_blocked_streams,
  3487. const nghttp3_mem *mem) {
  3488. int rv;
  3489. nghttp3_qpack_decoder *p;
  3490. p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_decoder));
  3491. if (p == NULL) {
  3492. return NGHTTP3_ERR_NOMEM;
  3493. }
  3494. rv = nghttp3_qpack_decoder_init(p, hard_max_dtable_capacity,
  3495. max_blocked_streams, mem);
  3496. if (rv != 0) {
  3497. return rv;
  3498. }
  3499. *pdecoder = p;
  3500. return 0;
  3501. }
  3502. void nghttp3_qpack_decoder_del(nghttp3_qpack_decoder *decoder) {
  3503. const nghttp3_mem *mem;
  3504. if (decoder == NULL) {
  3505. return;
  3506. }
  3507. mem = decoder->ctx.mem;
  3508. nghttp3_qpack_decoder_free(decoder);
  3509. nghttp3_mem_free(mem, decoder);
  3510. }
  3511. uint64_t nghttp3_qpack_decoder_get_icnt(const nghttp3_qpack_decoder *decoder) {
  3512. return decoder->ctx.next_absidx;
  3513. }