test.c 120 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599
  1. /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to
  5. * deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7. * sell copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  19. * IN THE SOFTWARE.
  20. */
  21. #include "http_parser.h"
  22. #include <stdlib.h>
  23. #include <assert.h>
  24. #include <stdio.h>
  25. #include <stdlib.h> /* rand */
  26. #include <string.h>
  27. #include <stdarg.h>
  28. #if defined(__APPLE__)
  29. # undef strlncpy
  30. #endif /* defined(__APPLE__) */
  31. #undef TRUE
  32. #define TRUE 1
  33. #undef FALSE
  34. #define FALSE 0
  35. #define MAX_HEADERS 13
  36. #define MAX_ELEMENT_SIZE 2048
  37. #define MAX_CHUNKS 16
  38. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  39. #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
  40. static http_parser parser;
  41. struct message {
  42. const char *name; // for debugging purposes
  43. const char *raw;
  44. enum http_parser_type type;
  45. enum http_method method;
  46. int status_code;
  47. char response_status[MAX_ELEMENT_SIZE];
  48. char request_path[MAX_ELEMENT_SIZE];
  49. char request_url[MAX_ELEMENT_SIZE];
  50. char fragment[MAX_ELEMENT_SIZE];
  51. char query_string[MAX_ELEMENT_SIZE];
  52. char body[MAX_ELEMENT_SIZE];
  53. size_t body_size;
  54. const char *host;
  55. const char *userinfo;
  56. uint16_t port;
  57. int num_headers;
  58. enum { NONE=0, FIELD, VALUE } last_header_element;
  59. char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE];
  60. int should_keep_alive;
  61. int num_chunks;
  62. int num_chunks_complete;
  63. int chunk_lengths[MAX_CHUNKS];
  64. const char *upgrade; // upgraded body
  65. unsigned short http_major;
  66. unsigned short http_minor;
  67. int message_begin_cb_called;
  68. int headers_complete_cb_called;
  69. int message_complete_cb_called;
  70. int status_cb_called;
  71. int message_complete_on_eof;
  72. int body_is_final;
  73. };
  74. static int currently_parsing_eof;
  75. static struct message messages[5];
  76. static int num_messages;
  77. static http_parser_settings *current_pause_parser;
  78. /* * R E Q U E S T S * */
  79. const struct message requests[] =
  80. #define CURL_GET 0
  81. { {.name= "curl get"
  82. ,.type= HTTP_REQUEST
  83. ,.raw= "GET /test HTTP/1.1\r\n"
  84. "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n"
  85. "Host: 0.0.0.0=5000\r\n"
  86. "Accept: */*\r\n"
  87. "\r\n"
  88. ,.should_keep_alive= TRUE
  89. ,.message_complete_on_eof= FALSE
  90. ,.http_major= 1
  91. ,.http_minor= 1
  92. ,.method= HTTP_GET
  93. ,.query_string= ""
  94. ,.fragment= ""
  95. ,.request_path= "/test"
  96. ,.request_url= "/test"
  97. ,.num_headers= 3
  98. ,.headers=
  99. { { "User-Agent", "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" }
  100. , { "Host", "0.0.0.0=5000" }
  101. , { "Accept", "*/*" }
  102. }
  103. ,.body= ""
  104. }
  105. #define FIREFOX_GET 1
  106. , {.name= "firefox get"
  107. ,.type= HTTP_REQUEST
  108. ,.raw= "GET /favicon.ico HTTP/1.1\r\n"
  109. "Host: 0.0.0.0=5000\r\n"
  110. "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\n"
  111. "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
  112. "Accept-Language: en-us,en;q=0.5\r\n"
  113. "Accept-Encoding: gzip,deflate\r\n"
  114. "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
  115. "Keep-Alive: 300\r\n"
  116. "Connection: keep-alive\r\n"
  117. "\r\n"
  118. ,.should_keep_alive= TRUE
  119. ,.message_complete_on_eof= FALSE
  120. ,.http_major= 1
  121. ,.http_minor= 1
  122. ,.method= HTTP_GET
  123. ,.query_string= ""
  124. ,.fragment= ""
  125. ,.request_path= "/favicon.ico"
  126. ,.request_url= "/favicon.ico"
  127. ,.num_headers= 8
  128. ,.headers=
  129. { { "Host", "0.0.0.0=5000" }
  130. , { "User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0" }
  131. , { "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" }
  132. , { "Accept-Language", "en-us,en;q=0.5" }
  133. , { "Accept-Encoding", "gzip,deflate" }
  134. , { "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7" }
  135. , { "Keep-Alive", "300" }
  136. , { "Connection", "keep-alive" }
  137. }
  138. ,.body= ""
  139. }
  140. #define DUMBLUCK 2
  141. , {.name= "dumbluck"
  142. ,.type= HTTP_REQUEST
  143. ,.raw= "GET /dumbluck HTTP/1.1\r\n"
  144. "aaaaaaaaaaaaa:++++++++++\r\n"
  145. "\r\n"
  146. ,.should_keep_alive= TRUE
  147. ,.message_complete_on_eof= FALSE
  148. ,.http_major= 1
  149. ,.http_minor= 1
  150. ,.method= HTTP_GET
  151. ,.query_string= ""
  152. ,.fragment= ""
  153. ,.request_path= "/dumbluck"
  154. ,.request_url= "/dumbluck"
  155. ,.num_headers= 1
  156. ,.headers=
  157. { { "aaaaaaaaaaaaa", "++++++++++" }
  158. }
  159. ,.body= ""
  160. }
  161. #define FRAGMENT_IN_URI 3
  162. , {.name= "fragment in url"
  163. ,.type= HTTP_REQUEST
  164. ,.raw= "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n"
  165. "\r\n"
  166. ,.should_keep_alive= TRUE
  167. ,.message_complete_on_eof= FALSE
  168. ,.http_major= 1
  169. ,.http_minor= 1
  170. ,.method= HTTP_GET
  171. ,.query_string= "page=1"
  172. ,.fragment= "posts-17408"
  173. ,.request_path= "/forums/1/topics/2375"
  174. /* XXX request url does include fragment? */
  175. ,.request_url= "/forums/1/topics/2375?page=1#posts-17408"
  176. ,.num_headers= 0
  177. ,.body= ""
  178. }
  179. #define GET_NO_HEADERS_NO_BODY 4
  180. , {.name= "get no headers no body"
  181. ,.type= HTTP_REQUEST
  182. ,.raw= "GET /get_no_headers_no_body/world HTTP/1.1\r\n"
  183. "\r\n"
  184. ,.should_keep_alive= TRUE
  185. ,.message_complete_on_eof= FALSE /* would need Connection: close */
  186. ,.http_major= 1
  187. ,.http_minor= 1
  188. ,.method= HTTP_GET
  189. ,.query_string= ""
  190. ,.fragment= ""
  191. ,.request_path= "/get_no_headers_no_body/world"
  192. ,.request_url= "/get_no_headers_no_body/world"
  193. ,.num_headers= 0
  194. ,.body= ""
  195. }
  196. #define GET_ONE_HEADER_NO_BODY 5
  197. , {.name= "get one header no body"
  198. ,.type= HTTP_REQUEST
  199. ,.raw= "GET /get_one_header_no_body HTTP/1.1\r\n"
  200. "Accept: */*\r\n"
  201. "\r\n"
  202. ,.should_keep_alive= TRUE
  203. ,.message_complete_on_eof= FALSE /* would need Connection: close */
  204. ,.http_major= 1
  205. ,.http_minor= 1
  206. ,.method= HTTP_GET
  207. ,.query_string= ""
  208. ,.fragment= ""
  209. ,.request_path= "/get_one_header_no_body"
  210. ,.request_url= "/get_one_header_no_body"
  211. ,.num_headers= 1
  212. ,.headers=
  213. { { "Accept" , "*/*" }
  214. }
  215. ,.body= ""
  216. }
  217. #define GET_FUNKY_CONTENT_LENGTH 6
  218. , {.name= "get funky content length body hello"
  219. ,.type= HTTP_REQUEST
  220. ,.raw= "GET /get_funky_content_length_body_hello HTTP/1.0\r\n"
  221. "conTENT-Length: 5\r\n"
  222. "\r\n"
  223. "HELLO"
  224. ,.should_keep_alive= FALSE
  225. ,.message_complete_on_eof= FALSE
  226. ,.http_major= 1
  227. ,.http_minor= 0
  228. ,.method= HTTP_GET
  229. ,.query_string= ""
  230. ,.fragment= ""
  231. ,.request_path= "/get_funky_content_length_body_hello"
  232. ,.request_url= "/get_funky_content_length_body_hello"
  233. ,.num_headers= 1
  234. ,.headers=
  235. { { "conTENT-Length" , "5" }
  236. }
  237. ,.body= "HELLO"
  238. }
  239. #define POST_IDENTITY_BODY_WORLD 7
  240. , {.name= "post identity body world"
  241. ,.type= HTTP_REQUEST
  242. ,.raw= "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n"
  243. "Accept: */*\r\n"
  244. "Content-Length: 5\r\n"
  245. "\r\n"
  246. "World"
  247. ,.should_keep_alive= TRUE
  248. ,.message_complete_on_eof= FALSE
  249. ,.http_major= 1
  250. ,.http_minor= 1
  251. ,.method= HTTP_POST
  252. ,.query_string= "q=search"
  253. ,.fragment= "hey"
  254. ,.request_path= "/post_identity_body_world"
  255. ,.request_url= "/post_identity_body_world?q=search#hey"
  256. ,.num_headers= 2
  257. ,.headers=
  258. { { "Accept", "*/*" }
  259. , { "Content-Length", "5" }
  260. }
  261. ,.body= "World"
  262. }
  263. #define POST_CHUNKED_ALL_YOUR_BASE 8
  264. , {.name= "post - chunked body: all your base are belong to us"
  265. ,.type= HTTP_REQUEST
  266. ,.raw= "POST /post_chunked_all_your_base HTTP/1.1\r\n"
  267. "Transfer-Encoding: chunked\r\n"
  268. "\r\n"
  269. "1e\r\nall your base are belong to us\r\n"
  270. "0\r\n"
  271. "\r\n"
  272. ,.should_keep_alive= TRUE
  273. ,.message_complete_on_eof= FALSE
  274. ,.http_major= 1
  275. ,.http_minor= 1
  276. ,.method= HTTP_POST
  277. ,.query_string= ""
  278. ,.fragment= ""
  279. ,.request_path= "/post_chunked_all_your_base"
  280. ,.request_url= "/post_chunked_all_your_base"
  281. ,.num_headers= 1
  282. ,.headers=
  283. { { "Transfer-Encoding" , "chunked" }
  284. }
  285. ,.body= "all your base are belong to us"
  286. ,.num_chunks_complete= 2
  287. ,.chunk_lengths= { 0x1e }
  288. }
  289. #define TWO_CHUNKS_MULT_ZERO_END 9
  290. , {.name= "two chunks ; triple zero ending"
  291. ,.type= HTTP_REQUEST
  292. ,.raw= "POST /two_chunks_mult_zero_end HTTP/1.1\r\n"
  293. "Transfer-Encoding: chunked\r\n"
  294. "\r\n"
  295. "5\r\nhello\r\n"
  296. "6\r\n world\r\n"
  297. "000\r\n"
  298. "\r\n"
  299. ,.should_keep_alive= TRUE
  300. ,.message_complete_on_eof= FALSE
  301. ,.http_major= 1
  302. ,.http_minor= 1
  303. ,.method= HTTP_POST
  304. ,.query_string= ""
  305. ,.fragment= ""
  306. ,.request_path= "/two_chunks_mult_zero_end"
  307. ,.request_url= "/two_chunks_mult_zero_end"
  308. ,.num_headers= 1
  309. ,.headers=
  310. { { "Transfer-Encoding", "chunked" }
  311. }
  312. ,.body= "hello world"
  313. ,.num_chunks_complete= 3
  314. ,.chunk_lengths= { 5, 6 }
  315. }
  316. #define CHUNKED_W_TRAILING_HEADERS 10
  317. , {.name= "chunked with trailing headers. blech."
  318. ,.type= HTTP_REQUEST
  319. ,.raw= "POST /chunked_w_trailing_headers HTTP/1.1\r\n"
  320. "Transfer-Encoding: chunked\r\n"
  321. "\r\n"
  322. "5\r\nhello\r\n"
  323. "6\r\n world\r\n"
  324. "0\r\n"
  325. "Vary: *\r\n"
  326. "Content-Type: text/plain\r\n"
  327. "\r\n"
  328. ,.should_keep_alive= TRUE
  329. ,.message_complete_on_eof= FALSE
  330. ,.http_major= 1
  331. ,.http_minor= 1
  332. ,.method= HTTP_POST
  333. ,.query_string= ""
  334. ,.fragment= ""
  335. ,.request_path= "/chunked_w_trailing_headers"
  336. ,.request_url= "/chunked_w_trailing_headers"
  337. ,.num_headers= 3
  338. ,.headers=
  339. { { "Transfer-Encoding", "chunked" }
  340. , { "Vary", "*" }
  341. , { "Content-Type", "text/plain" }
  342. }
  343. ,.body= "hello world"
  344. ,.num_chunks_complete= 3
  345. ,.chunk_lengths= { 5, 6 }
  346. }
  347. #define CHUNKED_W_NONSENSE_AFTER_LENGTH 11
  348. , {.name= "with nonsense after the length"
  349. ,.type= HTTP_REQUEST
  350. ,.raw= "POST /chunked_w_nonsense_after_length HTTP/1.1\r\n"
  351. "Transfer-Encoding: chunked\r\n"
  352. "\r\n"
  353. "5; ilovew3;whattheluck=aretheseparametersfor\r\nhello\r\n"
  354. "6; blahblah; blah\r\n world\r\n"
  355. "0\r\n"
  356. "\r\n"
  357. ,.should_keep_alive= TRUE
  358. ,.message_complete_on_eof= FALSE
  359. ,.http_major= 1
  360. ,.http_minor= 1
  361. ,.method= HTTP_POST
  362. ,.query_string= ""
  363. ,.fragment= ""
  364. ,.request_path= "/chunked_w_nonsense_after_length"
  365. ,.request_url= "/chunked_w_nonsense_after_length"
  366. ,.num_headers= 1
  367. ,.headers=
  368. { { "Transfer-Encoding", "chunked" }
  369. }
  370. ,.body= "hello world"
  371. ,.num_chunks_complete= 3
  372. ,.chunk_lengths= { 5, 6 }
  373. }
  374. #define WITH_QUOTES 12
  375. , {.name= "with quotes"
  376. ,.type= HTTP_REQUEST
  377. ,.raw= "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n"
  378. ,.should_keep_alive= TRUE
  379. ,.message_complete_on_eof= FALSE
  380. ,.http_major= 1
  381. ,.http_minor= 1
  382. ,.method= HTTP_GET
  383. ,.query_string= "foo=\"bar\""
  384. ,.fragment= ""
  385. ,.request_path= "/with_\"stupid\"_quotes"
  386. ,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\""
  387. ,.num_headers= 0
  388. ,.headers= { }
  389. ,.body= ""
  390. }
  391. #define APACHEBENCH_GET 13
  392. /* The server receiving this request SHOULD NOT wait for EOF
  393. * to know that content-length == 0.
  394. * How to represent this in a unit test? message_complete_on_eof
  395. * Compare with NO_CONTENT_LENGTH_RESPONSE.
  396. */
  397. , {.name = "apachebench get"
  398. ,.type= HTTP_REQUEST
  399. ,.raw= "GET /test HTTP/1.0\r\n"
  400. "Host: 0.0.0.0:5000\r\n"
  401. "User-Agent: ApacheBench/2.3\r\n"
  402. "Accept: */*\r\n\r\n"
  403. ,.should_keep_alive= FALSE
  404. ,.message_complete_on_eof= FALSE
  405. ,.http_major= 1
  406. ,.http_minor= 0
  407. ,.method= HTTP_GET
  408. ,.query_string= ""
  409. ,.fragment= ""
  410. ,.request_path= "/test"
  411. ,.request_url= "/test"
  412. ,.num_headers= 3
  413. ,.headers= { { "Host", "0.0.0.0:5000" }
  414. , { "User-Agent", "ApacheBench/2.3" }
  415. , { "Accept", "*/*" }
  416. }
  417. ,.body= ""
  418. }
  419. #define QUERY_URL_WITH_QUESTION_MARK_GET 14
  420. /* Some clients include '?' characters in query strings.
  421. */
  422. , {.name = "query url with question mark"
  423. ,.type= HTTP_REQUEST
  424. ,.raw= "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n"
  425. ,.should_keep_alive= TRUE
  426. ,.message_complete_on_eof= FALSE
  427. ,.http_major= 1
  428. ,.http_minor= 1
  429. ,.method= HTTP_GET
  430. ,.query_string= "foo=bar?baz"
  431. ,.fragment= ""
  432. ,.request_path= "/test.cgi"
  433. ,.request_url= "/test.cgi?foo=bar?baz"
  434. ,.num_headers= 0
  435. ,.headers= {}
  436. ,.body= ""
  437. }
  438. #define PREFIX_NEWLINE_GET 15
  439. /* Some clients, especially after a POST in a keep-alive connection,
  440. * will send an extra CRLF before the next request
  441. */
  442. , {.name = "newline prefix get"
  443. ,.type= HTTP_REQUEST
  444. ,.raw= "\r\nGET /test HTTP/1.1\r\n\r\n"
  445. ,.should_keep_alive= TRUE
  446. ,.message_complete_on_eof= FALSE
  447. ,.http_major= 1
  448. ,.http_minor= 1
  449. ,.method= HTTP_GET
  450. ,.query_string= ""
  451. ,.fragment= ""
  452. ,.request_path= "/test"
  453. ,.request_url= "/test"
  454. ,.num_headers= 0
  455. ,.headers= { }
  456. ,.body= ""
  457. }
  458. #define UPGRADE_REQUEST 16
  459. , {.name = "upgrade request"
  460. ,.type= HTTP_REQUEST
  461. ,.raw= "GET /demo HTTP/1.1\r\n"
  462. "Host: example.com\r\n"
  463. "Connection: Upgrade\r\n"
  464. "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n"
  465. "Sec-WebSocket-Protocol: sample\r\n"
  466. "Upgrade: WebSocket\r\n"
  467. "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n"
  468. "Origin: http://example.com\r\n"
  469. "\r\n"
  470. "Hot diggity dogg"
  471. ,.should_keep_alive= TRUE
  472. ,.message_complete_on_eof= FALSE
  473. ,.http_major= 1
  474. ,.http_minor= 1
  475. ,.method= HTTP_GET
  476. ,.query_string= ""
  477. ,.fragment= ""
  478. ,.request_path= "/demo"
  479. ,.request_url= "/demo"
  480. ,.num_headers= 7
  481. ,.upgrade="Hot diggity dogg"
  482. ,.headers= { { "Host", "example.com" }
  483. , { "Connection", "Upgrade" }
  484. , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" }
  485. , { "Sec-WebSocket-Protocol", "sample" }
  486. , { "Upgrade", "WebSocket" }
  487. , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" }
  488. , { "Origin", "http://example.com" }
  489. }
  490. ,.body= ""
  491. }
  492. #define CONNECT_REQUEST 17
  493. , {.name = "connect request"
  494. ,.type= HTTP_REQUEST
  495. ,.raw= "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n"
  496. "User-agent: Mozilla/1.1N\r\n"
  497. "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
  498. "\r\n"
  499. "some data\r\n"
  500. "and yet even more data"
  501. ,.should_keep_alive= FALSE
  502. ,.message_complete_on_eof= FALSE
  503. ,.http_major= 1
  504. ,.http_minor= 0
  505. ,.method= HTTP_CONNECT
  506. ,.query_string= ""
  507. ,.fragment= ""
  508. ,.request_path= ""
  509. ,.request_url= "0-home0.netscape.com:443"
  510. ,.num_headers= 2
  511. ,.upgrade="some data\r\nand yet even more data"
  512. ,.headers= { { "User-agent", "Mozilla/1.1N" }
  513. , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
  514. }
  515. ,.body= ""
  516. }
  517. #define REPORT_REQ 18
  518. , {.name= "report request"
  519. ,.type= HTTP_REQUEST
  520. ,.raw= "REPORT /test HTTP/1.1\r\n"
  521. "\r\n"
  522. ,.should_keep_alive= TRUE
  523. ,.message_complete_on_eof= FALSE
  524. ,.http_major= 1
  525. ,.http_minor= 1
  526. ,.method= HTTP_REPORT
  527. ,.query_string= ""
  528. ,.fragment= ""
  529. ,.request_path= "/test"
  530. ,.request_url= "/test"
  531. ,.num_headers= 0
  532. ,.headers= {}
  533. ,.body= ""
  534. }
  535. #define NO_HTTP_VERSION 19
  536. , {.name= "request with no http version"
  537. ,.type= HTTP_REQUEST
  538. ,.raw= "GET /\r\n"
  539. "\r\n"
  540. ,.should_keep_alive= FALSE
  541. ,.message_complete_on_eof= FALSE
  542. ,.http_major= 0
  543. ,.http_minor= 9
  544. ,.method= HTTP_GET
  545. ,.query_string= ""
  546. ,.fragment= ""
  547. ,.request_path= "/"
  548. ,.request_url= "/"
  549. ,.num_headers= 0
  550. ,.headers= {}
  551. ,.body= ""
  552. }
  553. #define MSEARCH_REQ 20
  554. , {.name= "m-search request"
  555. ,.type= HTTP_REQUEST
  556. ,.raw= "M-SEARCH * HTTP/1.1\r\n"
  557. "HOST: 239.255.255.250:1900\r\n"
  558. "MAN: \"ssdp:discover\"\r\n"
  559. "ST: \"ssdp:all\"\r\n"
  560. "\r\n"
  561. ,.should_keep_alive= TRUE
  562. ,.message_complete_on_eof= FALSE
  563. ,.http_major= 1
  564. ,.http_minor= 1
  565. ,.method= HTTP_MSEARCH
  566. ,.query_string= ""
  567. ,.fragment= ""
  568. ,.request_path= "*"
  569. ,.request_url= "*"
  570. ,.num_headers= 3
  571. ,.headers= { { "HOST", "239.255.255.250:1900" }
  572. , { "MAN", "\"ssdp:discover\"" }
  573. , { "ST", "\"ssdp:all\"" }
  574. }
  575. ,.body= ""
  576. }
  577. #define LINE_FOLDING_IN_HEADER 21
  578. , {.name= "line folding in header value"
  579. ,.type= HTTP_REQUEST
  580. ,.raw= "GET / HTTP/1.1\r\n"
  581. "Line1: abc\r\n"
  582. "\tdef\r\n"
  583. " ghi\r\n"
  584. "\t\tjkl\r\n"
  585. " mno \r\n"
  586. "\t \tqrs\r\n"
  587. "Line2: \t line2\t\r\n"
  588. "Line3:\r\n"
  589. " line3\r\n"
  590. "Line4: \r\n"
  591. " \r\n"
  592. "Connection:\r\n"
  593. " close\r\n"
  594. "\r\n"
  595. ,.should_keep_alive= FALSE
  596. ,.message_complete_on_eof= FALSE
  597. ,.http_major= 1
  598. ,.http_minor= 1
  599. ,.method= HTTP_GET
  600. ,.query_string= ""
  601. ,.fragment= ""
  602. ,.request_path= "/"
  603. ,.request_url= "/"
  604. ,.num_headers= 5
  605. ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" }
  606. , { "Line2", "line2\t" }
  607. , { "Line3", "line3" }
  608. , { "Line4", "" }
  609. , { "Connection", "close" },
  610. }
  611. ,.body= ""
  612. }
  613. #define QUERY_TERMINATED_HOST 22
  614. , {.name= "host terminated by a query string"
  615. ,.type= HTTP_REQUEST
  616. ,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n"
  617. "\r\n"
  618. ,.should_keep_alive= TRUE
  619. ,.message_complete_on_eof= FALSE
  620. ,.http_major= 1
  621. ,.http_minor= 1
  622. ,.method= HTTP_GET
  623. ,.query_string= "hail=all"
  624. ,.fragment= ""
  625. ,.request_path= ""
  626. ,.request_url= "http://hypnotoad.org?hail=all"
  627. ,.host= "hypnotoad.org"
  628. ,.num_headers= 0
  629. ,.headers= { }
  630. ,.body= ""
  631. }
  632. #define QUERY_TERMINATED_HOSTPORT 23
  633. , {.name= "host:port terminated by a query string"
  634. ,.type= HTTP_REQUEST
  635. ,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n"
  636. "\r\n"
  637. ,.should_keep_alive= TRUE
  638. ,.message_complete_on_eof= FALSE
  639. ,.http_major= 1
  640. ,.http_minor= 1
  641. ,.method= HTTP_GET
  642. ,.query_string= "hail=all"
  643. ,.fragment= ""
  644. ,.request_path= ""
  645. ,.request_url= "http://hypnotoad.org:1234?hail=all"
  646. ,.host= "hypnotoad.org"
  647. ,.port= 1234
  648. ,.num_headers= 0
  649. ,.headers= { }
  650. ,.body= ""
  651. }
  652. #define SPACE_TERMINATED_HOSTPORT 24
  653. , {.name= "host:port terminated by a space"
  654. ,.type= HTTP_REQUEST
  655. ,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n"
  656. "\r\n"
  657. ,.should_keep_alive= TRUE
  658. ,.message_complete_on_eof= FALSE
  659. ,.http_major= 1
  660. ,.http_minor= 1
  661. ,.method= HTTP_GET
  662. ,.query_string= ""
  663. ,.fragment= ""
  664. ,.request_path= ""
  665. ,.request_url= "http://hypnotoad.org:1234"
  666. ,.host= "hypnotoad.org"
  667. ,.port= 1234
  668. ,.num_headers= 0
  669. ,.headers= { }
  670. ,.body= ""
  671. }
  672. #define PATCH_REQ 25
  673. , {.name = "PATCH request"
  674. ,.type= HTTP_REQUEST
  675. ,.raw= "PATCH /file.txt HTTP/1.1\r\n"
  676. "Host: www.example.com\r\n"
  677. "Content-Type: application/example\r\n"
  678. "If-Match: \"e0023aa4e\"\r\n"
  679. "Content-Length: 10\r\n"
  680. "\r\n"
  681. "cccccccccc"
  682. ,.should_keep_alive= TRUE
  683. ,.message_complete_on_eof= FALSE
  684. ,.http_major= 1
  685. ,.http_minor= 1
  686. ,.method= HTTP_PATCH
  687. ,.query_string= ""
  688. ,.fragment= ""
  689. ,.request_path= "/file.txt"
  690. ,.request_url= "/file.txt"
  691. ,.num_headers= 4
  692. ,.headers= { { "Host", "www.example.com" }
  693. , { "Content-Type", "application/example" }
  694. , { "If-Match", "\"e0023aa4e\"" }
  695. , { "Content-Length", "10" }
  696. }
  697. ,.body= "cccccccccc"
  698. }
  699. #define CONNECT_CAPS_REQUEST 26
  700. , {.name = "connect caps request"
  701. ,.type= HTTP_REQUEST
  702. ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n"
  703. "User-agent: Mozilla/1.1N\r\n"
  704. "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
  705. "\r\n"
  706. ,.should_keep_alive= FALSE
  707. ,.message_complete_on_eof= FALSE
  708. ,.http_major= 1
  709. ,.http_minor= 0
  710. ,.method= HTTP_CONNECT
  711. ,.query_string= ""
  712. ,.fragment= ""
  713. ,.request_path= ""
  714. ,.request_url= "HOME0.NETSCAPE.COM:443"
  715. ,.num_headers= 2
  716. ,.upgrade=""
  717. ,.headers= { { "User-agent", "Mozilla/1.1N" }
  718. , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
  719. }
  720. ,.body= ""
  721. }
  722. #if !HTTP_PARSER_STRICT
  723. #define UTF8_PATH_REQ 27
  724. , {.name= "utf-8 path request"
  725. ,.type= HTTP_REQUEST
  726. ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n"
  727. "Host: github.com\r\n"
  728. "\r\n"
  729. ,.should_keep_alive= TRUE
  730. ,.message_complete_on_eof= FALSE
  731. ,.http_major= 1
  732. ,.http_minor= 1
  733. ,.method= HTTP_GET
  734. ,.query_string= "q=1"
  735. ,.fragment= "narf"
  736. ,.request_path= "/δ¶/δt/pope"
  737. ,.request_url= "/δ¶/δt/pope?q=1#narf"
  738. ,.num_headers= 1
  739. ,.headers= { {"Host", "github.com" }
  740. }
  741. ,.body= ""
  742. }
  743. #define HOSTNAME_UNDERSCORE 28
  744. , {.name = "hostname underscore"
  745. ,.type= HTTP_REQUEST
  746. ,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n"
  747. "User-agent: Mozilla/1.1N\r\n"
  748. "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
  749. "\r\n"
  750. ,.should_keep_alive= FALSE
  751. ,.message_complete_on_eof= FALSE
  752. ,.http_major= 1
  753. ,.http_minor= 0
  754. ,.method= HTTP_CONNECT
  755. ,.query_string= ""
  756. ,.fragment= ""
  757. ,.request_path= ""
  758. ,.request_url= "home_0.netscape.com:443"
  759. ,.num_headers= 2
  760. ,.upgrade=""
  761. ,.headers= { { "User-agent", "Mozilla/1.1N" }
  762. , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
  763. }
  764. ,.body= ""
  765. }
  766. #endif /* !HTTP_PARSER_STRICT */
  767. /* see https://github.com/ry/http-parser/issues/47 */
  768. #define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29
  769. , {.name = "eat CRLF between requests, no \"Connection: close\" header"
  770. ,.raw= "POST / HTTP/1.1\r\n"
  771. "Host: www.example.com\r\n"
  772. "Content-Type: application/x-www-form-urlencoded\r\n"
  773. "Content-Length: 4\r\n"
  774. "\r\n"
  775. "q=42\r\n" /* note the trailing CRLF */
  776. ,.should_keep_alive= TRUE
  777. ,.message_complete_on_eof= FALSE
  778. ,.http_major= 1
  779. ,.http_minor= 1
  780. ,.method= HTTP_POST
  781. ,.query_string= ""
  782. ,.fragment= ""
  783. ,.request_path= "/"
  784. ,.request_url= "/"
  785. ,.num_headers= 3
  786. ,.upgrade= 0
  787. ,.headers= { { "Host", "www.example.com" }
  788. , { "Content-Type", "application/x-www-form-urlencoded" }
  789. , { "Content-Length", "4" }
  790. }
  791. ,.body= "q=42"
  792. }
  793. /* see https://github.com/ry/http-parser/issues/47 */
  794. #define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30
  795. , {.name = "eat CRLF between requests even if \"Connection: close\" is set"
  796. ,.raw= "POST / HTTP/1.1\r\n"
  797. "Host: www.example.com\r\n"
  798. "Content-Type: application/x-www-form-urlencoded\r\n"
  799. "Content-Length: 4\r\n"
  800. "Connection: close\r\n"
  801. "\r\n"
  802. "q=42\r\n" /* note the trailing CRLF */
  803. ,.should_keep_alive= FALSE
  804. ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */
  805. ,.http_major= 1
  806. ,.http_minor= 1
  807. ,.method= HTTP_POST
  808. ,.query_string= ""
  809. ,.fragment= ""
  810. ,.request_path= "/"
  811. ,.request_url= "/"
  812. ,.num_headers= 4
  813. ,.upgrade= 0
  814. ,.headers= { { "Host", "www.example.com" }
  815. , { "Content-Type", "application/x-www-form-urlencoded" }
  816. , { "Content-Length", "4" }
  817. , { "Connection", "close" }
  818. }
  819. ,.body= "q=42"
  820. }
  821. #define PURGE_REQ 31
  822. , {.name = "PURGE request"
  823. ,.type= HTTP_REQUEST
  824. ,.raw= "PURGE /file.txt HTTP/1.1\r\n"
  825. "Host: www.example.com\r\n"
  826. "\r\n"
  827. ,.should_keep_alive= TRUE
  828. ,.message_complete_on_eof= FALSE
  829. ,.http_major= 1
  830. ,.http_minor= 1
  831. ,.method= HTTP_PURGE
  832. ,.query_string= ""
  833. ,.fragment= ""
  834. ,.request_path= "/file.txt"
  835. ,.request_url= "/file.txt"
  836. ,.num_headers= 1
  837. ,.headers= { { "Host", "www.example.com" } }
  838. ,.body= ""
  839. }
  840. #define SEARCH_REQ 32
  841. , {.name = "SEARCH request"
  842. ,.type= HTTP_REQUEST
  843. ,.raw= "SEARCH / HTTP/1.1\r\n"
  844. "Host: www.example.com\r\n"
  845. "\r\n"
  846. ,.should_keep_alive= TRUE
  847. ,.message_complete_on_eof= FALSE
  848. ,.http_major= 1
  849. ,.http_minor= 1
  850. ,.method= HTTP_SEARCH
  851. ,.query_string= ""
  852. ,.fragment= ""
  853. ,.request_path= "/"
  854. ,.request_url= "/"
  855. ,.num_headers= 1
  856. ,.headers= { { "Host", "www.example.com" } }
  857. ,.body= ""
  858. }
  859. #define PROXY_WITH_BASIC_AUTH 33
  860. , {.name= "host:port and basic_auth"
  861. ,.type= HTTP_REQUEST
  862. ,.raw= "GET http://a%12:b!&*$@hypnotoad.org:1234/toto HTTP/1.1\r\n"
  863. "\r\n"
  864. ,.should_keep_alive= TRUE
  865. ,.message_complete_on_eof= FALSE
  866. ,.http_major= 1
  867. ,.http_minor= 1
  868. ,.method= HTTP_GET
  869. ,.fragment= ""
  870. ,.request_path= "/toto"
  871. ,.request_url= "http://a%12:b!&*$@hypnotoad.org:1234/toto"
  872. ,.host= "hypnotoad.org"
  873. ,.userinfo= "a%12:b!&*$"
  874. ,.port= 1234
  875. ,.num_headers= 0
  876. ,.headers= { }
  877. ,.body= ""
  878. }
  879. #define LINE_FOLDING_IN_HEADER_WITH_LF 34
  880. , {.name= "line folding in header value"
  881. ,.type= HTTP_REQUEST
  882. ,.raw= "GET / HTTP/1.1\n"
  883. "Line1: abc\n"
  884. "\tdef\n"
  885. " ghi\n"
  886. "\t\tjkl\n"
  887. " mno \n"
  888. "\t \tqrs\n"
  889. "Line2: \t line2\t\n"
  890. "Line3:\n"
  891. " line3\n"
  892. "Line4: \n"
  893. " \n"
  894. "Connection:\n"
  895. " close\n"
  896. "\n"
  897. ,.should_keep_alive= FALSE
  898. ,.message_complete_on_eof= FALSE
  899. ,.http_major= 1
  900. ,.http_minor= 1
  901. ,.method= HTTP_GET
  902. ,.query_string= ""
  903. ,.fragment= ""
  904. ,.request_path= "/"
  905. ,.request_url= "/"
  906. ,.num_headers= 5
  907. ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" }
  908. , { "Line2", "line2\t" }
  909. , { "Line3", "line3" }
  910. , { "Line4", "" }
  911. , { "Connection", "close" },
  912. }
  913. ,.body= ""
  914. }
  915. #define CONNECTION_MULTI 35
  916. , {.name = "multiple connection header values with folding"
  917. ,.type= HTTP_REQUEST
  918. ,.raw= "GET /demo HTTP/1.1\r\n"
  919. "Host: example.com\r\n"
  920. "Connection: Something,\r\n"
  921. " Upgrade, ,Keep-Alive\r\n"
  922. "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n"
  923. "Sec-WebSocket-Protocol: sample\r\n"
  924. "Upgrade: WebSocket\r\n"
  925. "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n"
  926. "Origin: http://example.com\r\n"
  927. "\r\n"
  928. "Hot diggity dogg"
  929. ,.should_keep_alive= TRUE
  930. ,.message_complete_on_eof= FALSE
  931. ,.http_major= 1
  932. ,.http_minor= 1
  933. ,.method= HTTP_GET
  934. ,.query_string= ""
  935. ,.fragment= ""
  936. ,.request_path= "/demo"
  937. ,.request_url= "/demo"
  938. ,.num_headers= 7
  939. ,.upgrade="Hot diggity dogg"
  940. ,.headers= { { "Host", "example.com" }
  941. , { "Connection", "Something, Upgrade, ,Keep-Alive" }
  942. , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" }
  943. , { "Sec-WebSocket-Protocol", "sample" }
  944. , { "Upgrade", "WebSocket" }
  945. , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" }
  946. , { "Origin", "http://example.com" }
  947. }
  948. ,.body= ""
  949. }
  950. #define CONNECTION_MULTI_LWS 36
  951. , {.name = "multiple connection header values with folding and lws"
  952. ,.type= HTTP_REQUEST
  953. ,.raw= "GET /demo HTTP/1.1\r\n"
  954. "Connection: keep-alive, upgrade\r\n"
  955. "Upgrade: WebSocket\r\n"
  956. "\r\n"
  957. "Hot diggity dogg"
  958. ,.should_keep_alive= TRUE
  959. ,.message_complete_on_eof= FALSE
  960. ,.http_major= 1
  961. ,.http_minor= 1
  962. ,.method= HTTP_GET
  963. ,.query_string= ""
  964. ,.fragment= ""
  965. ,.request_path= "/demo"
  966. ,.request_url= "/demo"
  967. ,.num_headers= 2
  968. ,.upgrade="Hot diggity dogg"
  969. ,.headers= { { "Connection", "keep-alive, upgrade" }
  970. , { "Upgrade", "WebSocket" }
  971. }
  972. ,.body= ""
  973. }
  974. #define CONNECTION_MULTI_LWS_CRLF 37
  975. , {.name = "multiple connection header values with folding and lws"
  976. ,.type= HTTP_REQUEST
  977. ,.raw= "GET /demo HTTP/1.1\r\n"
  978. "Connection: keep-alive, \r\n upgrade\r\n"
  979. "Upgrade: WebSocket\r\n"
  980. "\r\n"
  981. "Hot diggity dogg"
  982. ,.should_keep_alive= TRUE
  983. ,.message_complete_on_eof= FALSE
  984. ,.http_major= 1
  985. ,.http_minor= 1
  986. ,.method= HTTP_GET
  987. ,.query_string= ""
  988. ,.fragment= ""
  989. ,.request_path= "/demo"
  990. ,.request_url= "/demo"
  991. ,.num_headers= 2
  992. ,.upgrade="Hot diggity dogg"
  993. ,.headers= { { "Connection", "keep-alive, upgrade" }
  994. , { "Upgrade", "WebSocket" }
  995. }
  996. ,.body= ""
  997. }
  998. #define UPGRADE_POST_REQUEST 38
  999. , {.name = "upgrade post request"
  1000. ,.type= HTTP_REQUEST
  1001. ,.raw= "POST /demo HTTP/1.1\r\n"
  1002. "Host: example.com\r\n"
  1003. "Connection: Upgrade\r\n"
  1004. "Upgrade: HTTP/2.0\r\n"
  1005. "Content-Length: 15\r\n"
  1006. "\r\n"
  1007. "sweet post body"
  1008. "Hot diggity dogg"
  1009. ,.should_keep_alive= TRUE
  1010. ,.message_complete_on_eof= FALSE
  1011. ,.http_major= 1
  1012. ,.http_minor= 1
  1013. ,.method= HTTP_POST
  1014. ,.request_path= "/demo"
  1015. ,.request_url= "/demo"
  1016. ,.num_headers= 4
  1017. ,.upgrade="Hot diggity dogg"
  1018. ,.headers= { { "Host", "example.com" }
  1019. , { "Connection", "Upgrade" }
  1020. , { "Upgrade", "HTTP/2.0" }
  1021. , { "Content-Length", "15" }
  1022. }
  1023. ,.body= "sweet post body"
  1024. }
  1025. #define CONNECT_WITH_BODY_REQUEST 39
  1026. , {.name = "connect with body request"
  1027. ,.type= HTTP_REQUEST
  1028. ,.raw= "CONNECT foo.bar.com:443 HTTP/1.0\r\n"
  1029. "User-agent: Mozilla/1.1N\r\n"
  1030. "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
  1031. "Content-Length: 10\r\n"
  1032. "\r\n"
  1033. "blarfcicle"
  1034. ,.should_keep_alive= FALSE
  1035. ,.message_complete_on_eof= FALSE
  1036. ,.http_major= 1
  1037. ,.http_minor= 0
  1038. ,.method= HTTP_CONNECT
  1039. ,.request_url= "foo.bar.com:443"
  1040. ,.num_headers= 3
  1041. ,.upgrade="blarfcicle"
  1042. ,.headers= { { "User-agent", "Mozilla/1.1N" }
  1043. , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
  1044. , { "Content-Length", "10" }
  1045. }
  1046. ,.body= ""
  1047. }
  1048. /* Examples from the Internet draft for LINK/UNLINK methods:
  1049. * https://tools.ietf.org/id/draft-snell-link-method-01.html#rfc.section.5
  1050. */
  1051. #define LINK_REQUEST 40
  1052. , {.name = "link request"
  1053. ,.type= HTTP_REQUEST
  1054. ,.raw= "LINK /images/my_dog.jpg HTTP/1.1\r\n"
  1055. "Host: example.com\r\n"
  1056. "Link: <http://example.com/profiles/joe>; rel=\"tag\"\r\n"
  1057. "Link: <http://example.com/profiles/sally>; rel=\"tag\"\r\n"
  1058. "\r\n"
  1059. ,.should_keep_alive= TRUE
  1060. ,.message_complete_on_eof= FALSE
  1061. ,.http_major= 1
  1062. ,.http_minor= 1
  1063. ,.method= HTTP_LINK
  1064. ,.request_path= "/images/my_dog.jpg"
  1065. ,.request_url= "/images/my_dog.jpg"
  1066. ,.query_string= ""
  1067. ,.fragment= ""
  1068. ,.num_headers= 3
  1069. ,.headers= { { "Host", "example.com" }
  1070. , { "Link", "<http://example.com/profiles/joe>; rel=\"tag\"" }
  1071. , { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
  1072. }
  1073. ,.body= ""
  1074. }
  1075. #define UNLINK_REQUEST 41
  1076. , {.name = "unlink request"
  1077. ,.type= HTTP_REQUEST
  1078. ,.raw= "UNLINK /images/my_dog.jpg HTTP/1.1\r\n"
  1079. "Host: example.com\r\n"
  1080. "Link: <http://example.com/profiles/sally>; rel=\"tag\"\r\n"
  1081. "\r\n"
  1082. ,.should_keep_alive= TRUE
  1083. ,.message_complete_on_eof= FALSE
  1084. ,.http_major= 1
  1085. ,.http_minor= 1
  1086. ,.method= HTTP_UNLINK
  1087. ,.request_path= "/images/my_dog.jpg"
  1088. ,.request_url= "/images/my_dog.jpg"
  1089. ,.query_string= ""
  1090. ,.fragment= ""
  1091. ,.num_headers= 2
  1092. ,.headers= { { "Host", "example.com" }
  1093. , { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
  1094. }
  1095. ,.body= ""
  1096. }
  1097. #define SOURCE_REQUEST 42
  1098. , {.name = "source request"
  1099. ,.type= HTTP_REQUEST
  1100. ,.raw= "SOURCE /music/sweet/music HTTP/1.1\r\n"
  1101. "Host: example.com\r\n"
  1102. "\r\n"
  1103. ,.should_keep_alive= TRUE
  1104. ,.message_complete_on_eof= FALSE
  1105. ,.http_major= 1
  1106. ,.http_minor= 1
  1107. ,.method= HTTP_SOURCE
  1108. ,.request_path= "/music/sweet/music"
  1109. ,.request_url= "/music/sweet/music"
  1110. ,.query_string= ""
  1111. ,.fragment= ""
  1112. ,.num_headers= 1
  1113. ,.headers= { { "Host", "example.com" } }
  1114. ,.body= ""
  1115. }
  1116. #define SOURCE_ICE_REQUEST 42
  1117. , {.name = "source request"
  1118. ,.type= HTTP_REQUEST
  1119. ,.raw= "SOURCE /music/sweet/music ICE/1.0\r\n"
  1120. "Host: example.com\r\n"
  1121. "\r\n"
  1122. ,.should_keep_alive= FALSE
  1123. ,.message_complete_on_eof= FALSE
  1124. ,.http_major= 1
  1125. ,.http_minor= 0
  1126. ,.method= HTTP_SOURCE
  1127. ,.request_path= "/music/sweet/music"
  1128. ,.request_url= "/music/sweet/music"
  1129. ,.query_string= ""
  1130. ,.fragment= ""
  1131. ,.num_headers= 1
  1132. ,.headers= { { "Host", "example.com" } }
  1133. ,.body= ""
  1134. }
  1135. #define POST_MULTI_TE_LAST_CHUNKED 43
  1136. , {.name= "post - multi coding transfer-encoding chunked body"
  1137. ,.type= HTTP_REQUEST
  1138. ,.raw= "POST / HTTP/1.1\r\n"
  1139. "Transfer-Encoding: deflate, chunked\r\n"
  1140. "\r\n"
  1141. "1e\r\nall your base are belong to us\r\n"
  1142. "0\r\n"
  1143. "\r\n"
  1144. ,.should_keep_alive= TRUE
  1145. ,.message_complete_on_eof= FALSE
  1146. ,.http_major= 1
  1147. ,.http_minor= 1
  1148. ,.method= HTTP_POST
  1149. ,.query_string= ""
  1150. ,.fragment= ""
  1151. ,.request_path= "/"
  1152. ,.request_url= "/"
  1153. ,.num_headers= 1
  1154. ,.headers=
  1155. { { "Transfer-Encoding" , "deflate, chunked" }
  1156. }
  1157. ,.body= "all your base are belong to us"
  1158. ,.num_chunks_complete= 2
  1159. ,.chunk_lengths= { 0x1e }
  1160. }
  1161. #define POST_MULTI_LINE_TE_LAST_CHUNKED 43
  1162. , {.name= "post - multi coding transfer-encoding chunked body"
  1163. ,.type= HTTP_REQUEST
  1164. ,.raw= "POST / HTTP/1.1\r\n"
  1165. "Transfer-Encoding: deflate,\r\n"
  1166. " chunked\r\n"
  1167. "\r\n"
  1168. "1e\r\nall your base are belong to us\r\n"
  1169. "0\r\n"
  1170. "\r\n"
  1171. ,.should_keep_alive= TRUE
  1172. ,.message_complete_on_eof= FALSE
  1173. ,.http_major= 1
  1174. ,.http_minor= 1
  1175. ,.method= HTTP_POST
  1176. ,.query_string= ""
  1177. ,.fragment= ""
  1178. ,.request_path= "/"
  1179. ,.request_url= "/"
  1180. ,.num_headers= 1
  1181. ,.headers=
  1182. { { "Transfer-Encoding" , "deflate, chunked" }
  1183. }
  1184. ,.body= "all your base are belong to us"
  1185. ,.num_chunks_complete= 2
  1186. ,.chunk_lengths= { 0x1e }
  1187. }
  1188. };
  1189. /* * R E S P O N S E S * */
  1190. const struct message responses[] =
  1191. #define GOOGLE_301 0
  1192. { {.name= "google 301"
  1193. ,.type= HTTP_RESPONSE
  1194. ,.raw= "HTTP/1.1 301 Moved Permanently\r\n"
  1195. "Location: http://www.google.com/\r\n"
  1196. "Content-Type: text/html; charset=UTF-8\r\n"
  1197. "Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n"
  1198. "Expires: Tue, 26 May 2009 11:11:49 GMT\r\n"
  1199. "X-$PrototypeBI-Version: 1.6.0.3\r\n" /* $ char in header field */
  1200. "Cache-Control: public, max-age=2592000\r\n"
  1201. "Server: gws\r\n"
  1202. "Content-Length: 219 \r\n"
  1203. "\r\n"
  1204. "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n"
  1205. "<TITLE>301 Moved</TITLE></HEAD><BODY>\n"
  1206. "<H1>301 Moved</H1>\n"
  1207. "The document has moved\n"
  1208. "<A HREF=\"http://www.google.com/\">here</A>.\r\n"
  1209. "</BODY></HTML>\r\n"
  1210. ,.should_keep_alive= TRUE
  1211. ,.message_complete_on_eof= FALSE
  1212. ,.http_major= 1
  1213. ,.http_minor= 1
  1214. ,.status_code= 301
  1215. ,.response_status= "Moved Permanently"
  1216. ,.num_headers= 8
  1217. ,.headers=
  1218. { { "Location", "http://www.google.com/" }
  1219. , { "Content-Type", "text/html; charset=UTF-8" }
  1220. , { "Date", "Sun, 26 Apr 2009 11:11:49 GMT" }
  1221. , { "Expires", "Tue, 26 May 2009 11:11:49 GMT" }
  1222. , { "X-$PrototypeBI-Version", "1.6.0.3" }
  1223. , { "Cache-Control", "public, max-age=2592000" }
  1224. , { "Server", "gws" }
  1225. , { "Content-Length", "219 " }
  1226. }
  1227. ,.body= "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n"
  1228. "<TITLE>301 Moved</TITLE></HEAD><BODY>\n"
  1229. "<H1>301 Moved</H1>\n"
  1230. "The document has moved\n"
  1231. "<A HREF=\"http://www.google.com/\">here</A>.\r\n"
  1232. "</BODY></HTML>\r\n"
  1233. }
  1234. #define NO_CONTENT_LENGTH_RESPONSE 1
  1235. /* The client should wait for the server's EOF. That is, when content-length
  1236. * is not specified, and "Connection: close", the end of body is specified
  1237. * by the EOF.
  1238. * Compare with APACHEBENCH_GET
  1239. */
  1240. , {.name= "no content-length response"
  1241. ,.type= HTTP_RESPONSE
  1242. ,.raw= "HTTP/1.1 200 OK\r\n"
  1243. "Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n"
  1244. "Server: Apache\r\n"
  1245. "X-Powered-By: Servlet/2.5 JSP/2.1\r\n"
  1246. "Content-Type: text/xml; charset=utf-8\r\n"
  1247. "Connection: close\r\n"
  1248. "\r\n"
  1249. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  1250. "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
  1251. " <SOAP-ENV:Body>\n"
  1252. " <SOAP-ENV:Fault>\n"
  1253. " <faultcode>SOAP-ENV:Client</faultcode>\n"
  1254. " <faultstring>Client Error</faultstring>\n"
  1255. " </SOAP-ENV:Fault>\n"
  1256. " </SOAP-ENV:Body>\n"
  1257. "</SOAP-ENV:Envelope>"
  1258. ,.should_keep_alive= FALSE
  1259. ,.message_complete_on_eof= TRUE
  1260. ,.http_major= 1
  1261. ,.http_minor= 1
  1262. ,.status_code= 200
  1263. ,.response_status= "OK"
  1264. ,.num_headers= 5
  1265. ,.headers=
  1266. { { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" }
  1267. , { "Server", "Apache" }
  1268. , { "X-Powered-By", "Servlet/2.5 JSP/2.1" }
  1269. , { "Content-Type", "text/xml; charset=utf-8" }
  1270. , { "Connection", "close" }
  1271. }
  1272. ,.body= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  1273. "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
  1274. " <SOAP-ENV:Body>\n"
  1275. " <SOAP-ENV:Fault>\n"
  1276. " <faultcode>SOAP-ENV:Client</faultcode>\n"
  1277. " <faultstring>Client Error</faultstring>\n"
  1278. " </SOAP-ENV:Fault>\n"
  1279. " </SOAP-ENV:Body>\n"
  1280. "</SOAP-ENV:Envelope>"
  1281. }
  1282. #define NO_HEADERS_NO_BODY_404 2
  1283. , {.name= "404 no headers no body"
  1284. ,.type= HTTP_RESPONSE
  1285. ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n"
  1286. ,.should_keep_alive= FALSE
  1287. ,.message_complete_on_eof= TRUE
  1288. ,.http_major= 1
  1289. ,.http_minor= 1
  1290. ,.status_code= 404
  1291. ,.response_status= "Not Found"
  1292. ,.num_headers= 0
  1293. ,.headers= {}
  1294. ,.body_size= 0
  1295. ,.body= ""
  1296. }
  1297. #define NO_REASON_PHRASE 3
  1298. , {.name= "301 no response phrase"
  1299. ,.type= HTTP_RESPONSE
  1300. ,.raw= "HTTP/1.1 301\r\n\r\n"
  1301. ,.should_keep_alive = FALSE
  1302. ,.message_complete_on_eof= TRUE
  1303. ,.http_major= 1
  1304. ,.http_minor= 1
  1305. ,.status_code= 301
  1306. ,.response_status= ""
  1307. ,.num_headers= 0
  1308. ,.headers= {}
  1309. ,.body= ""
  1310. }
  1311. #define TRAILING_SPACE_ON_CHUNKED_BODY 4
  1312. , {.name="200 trailing space on chunked body"
  1313. ,.type= HTTP_RESPONSE
  1314. ,.raw= "HTTP/1.1 200 OK\r\n"
  1315. "Content-Type: text/plain\r\n"
  1316. "Transfer-Encoding: chunked\r\n"
  1317. "\r\n"
  1318. "25 \r\n"
  1319. "This is the data in the first chunk\r\n"
  1320. "\r\n"
  1321. "1C\r\n"
  1322. "and this is the second one\r\n"
  1323. "\r\n"
  1324. "0 \r\n"
  1325. "\r\n"
  1326. ,.should_keep_alive= TRUE
  1327. ,.message_complete_on_eof= FALSE
  1328. ,.http_major= 1
  1329. ,.http_minor= 1
  1330. ,.status_code= 200
  1331. ,.response_status= "OK"
  1332. ,.num_headers= 2
  1333. ,.headers=
  1334. { {"Content-Type", "text/plain" }
  1335. , {"Transfer-Encoding", "chunked" }
  1336. }
  1337. ,.body_size = 37+28
  1338. ,.body =
  1339. "This is the data in the first chunk\r\n"
  1340. "and this is the second one\r\n"
  1341. ,.num_chunks_complete= 3
  1342. ,.chunk_lengths= { 0x25, 0x1c }
  1343. }
  1344. #define NO_CARRIAGE_RET 5
  1345. , {.name="no carriage ret"
  1346. ,.type= HTTP_RESPONSE
  1347. ,.raw= "HTTP/1.1 200 OK\n"
  1348. "Content-Type: text/html; charset=utf-8\n"
  1349. "Connection: close\n"
  1350. "\n"
  1351. "these headers are from http://news.ycombinator.com/"
  1352. ,.should_keep_alive= FALSE
  1353. ,.message_complete_on_eof= TRUE
  1354. ,.http_major= 1
  1355. ,.http_minor= 1
  1356. ,.status_code= 200
  1357. ,.response_status= "OK"
  1358. ,.num_headers= 2
  1359. ,.headers=
  1360. { {"Content-Type", "text/html; charset=utf-8" }
  1361. , {"Connection", "close" }
  1362. }
  1363. ,.body= "these headers are from http://news.ycombinator.com/"
  1364. }
  1365. #define PROXY_CONNECTION 6
  1366. , {.name="proxy connection"
  1367. ,.type= HTTP_RESPONSE
  1368. ,.raw= "HTTP/1.1 200 OK\r\n"
  1369. "Content-Type: text/html; charset=UTF-8\r\n"
  1370. "Content-Length: 11\r\n"
  1371. "Proxy-Connection: close\r\n"
  1372. "Date: Thu, 31 Dec 2009 20:55:48 +0000\r\n"
  1373. "\r\n"
  1374. "hello world"
  1375. ,.should_keep_alive= FALSE
  1376. ,.message_complete_on_eof= FALSE
  1377. ,.http_major= 1
  1378. ,.http_minor= 1
  1379. ,.status_code= 200
  1380. ,.response_status= "OK"
  1381. ,.num_headers= 4
  1382. ,.headers=
  1383. { {"Content-Type", "text/html; charset=UTF-8" }
  1384. , {"Content-Length", "11" }
  1385. , {"Proxy-Connection", "close" }
  1386. , {"Date", "Thu, 31 Dec 2009 20:55:48 +0000"}
  1387. }
  1388. ,.body= "hello world"
  1389. }
  1390. #define UNDERSTORE_HEADER_KEY 7
  1391. // shown by
  1392. // curl -o /dev/null -v "http://ad.doubleclick.net/pfadx/DARTSHELLCONFIGXML;dcmt=text/xml;"
  1393. , {.name="underscore header key"
  1394. ,.type= HTTP_RESPONSE
  1395. ,.raw= "HTTP/1.1 200 OK\r\n"
  1396. "Server: DCLK-AdSvr\r\n"
  1397. "Content-Type: text/xml\r\n"
  1398. "Content-Length: 0\r\n"
  1399. "DCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n"
  1400. ,.should_keep_alive= TRUE
  1401. ,.message_complete_on_eof= FALSE
  1402. ,.http_major= 1
  1403. ,.http_minor= 1
  1404. ,.status_code= 200
  1405. ,.response_status= "OK"
  1406. ,.num_headers= 4
  1407. ,.headers=
  1408. { {"Server", "DCLK-AdSvr" }
  1409. , {"Content-Type", "text/xml" }
  1410. , {"Content-Length", "0" }
  1411. , {"DCLK_imp", "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o" }
  1412. }
  1413. ,.body= ""
  1414. }
  1415. #define BONJOUR_MADAME_FR 8
  1416. /* The client should not merge two headers fields when the first one doesn't
  1417. * have a value.
  1418. */
  1419. , {.name= "bonjourmadame.fr"
  1420. ,.type= HTTP_RESPONSE
  1421. ,.raw= "HTTP/1.0 301 Moved Permanently\r\n"
  1422. "Date: Thu, 03 Jun 2010 09:56:32 GMT\r\n"
  1423. "Server: Apache/2.2.3 (Red Hat)\r\n"
  1424. "Cache-Control: public\r\n"
  1425. "Pragma: \r\n"
  1426. "Location: http://www.bonjourmadame.fr/\r\n"
  1427. "Vary: Accept-Encoding\r\n"
  1428. "Content-Length: 0\r\n"
  1429. "Content-Type: text/html; charset=UTF-8\r\n"
  1430. "Connection: keep-alive\r\n"
  1431. "\r\n"
  1432. ,.should_keep_alive= TRUE
  1433. ,.message_complete_on_eof= FALSE
  1434. ,.http_major= 1
  1435. ,.http_minor= 0
  1436. ,.status_code= 301
  1437. ,.response_status= "Moved Permanently"
  1438. ,.num_headers= 9
  1439. ,.headers=
  1440. { { "Date", "Thu, 03 Jun 2010 09:56:32 GMT" }
  1441. , { "Server", "Apache/2.2.3 (Red Hat)" }
  1442. , { "Cache-Control", "public" }
  1443. , { "Pragma", "" }
  1444. , { "Location", "http://www.bonjourmadame.fr/" }
  1445. , { "Vary", "Accept-Encoding" }
  1446. , { "Content-Length", "0" }
  1447. , { "Content-Type", "text/html; charset=UTF-8" }
  1448. , { "Connection", "keep-alive" }
  1449. }
  1450. ,.body= ""
  1451. }
  1452. #define RES_FIELD_UNDERSCORE 9
  1453. /* Should handle spaces in header fields */
  1454. , {.name= "field underscore"
  1455. ,.type= HTTP_RESPONSE
  1456. ,.raw= "HTTP/1.1 200 OK\r\n"
  1457. "Date: Tue, 28 Sep 2010 01:14:13 GMT\r\n"
  1458. "Server: Apache\r\n"
  1459. "Cache-Control: no-cache, must-revalidate\r\n"
  1460. "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n"
  1461. ".et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\n"
  1462. "Vary: Accept-Encoding\r\n"
  1463. "_eep-Alive: timeout=45\r\n" /* semantic value ignored */
  1464. "_onnection: Keep-Alive\r\n" /* semantic value ignored */
  1465. "Transfer-Encoding: chunked\r\n"
  1466. "Content-Type: text/html\r\n"
  1467. "Connection: close\r\n"
  1468. "\r\n"
  1469. "0\r\n\r\n"
  1470. ,.should_keep_alive= FALSE
  1471. ,.message_complete_on_eof= FALSE
  1472. ,.http_major= 1
  1473. ,.http_minor= 1
  1474. ,.status_code= 200
  1475. ,.response_status= "OK"
  1476. ,.num_headers= 11
  1477. ,.headers=
  1478. { { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" }
  1479. , { "Server", "Apache" }
  1480. , { "Cache-Control", "no-cache, must-revalidate" }
  1481. , { "Expires", "Mon, 26 Jul 1997 05:00:00 GMT" }
  1482. , { ".et-Cookie", "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com" }
  1483. , { "Vary", "Accept-Encoding" }
  1484. , { "_eep-Alive", "timeout=45" }
  1485. , { "_onnection", "Keep-Alive" }
  1486. , { "Transfer-Encoding", "chunked" }
  1487. , { "Content-Type", "text/html" }
  1488. , { "Connection", "close" }
  1489. }
  1490. ,.body= ""
  1491. ,.num_chunks_complete= 1
  1492. ,.chunk_lengths= {}
  1493. }
  1494. #define NON_ASCII_IN_STATUS_LINE 10
  1495. /* Should handle non-ASCII in status line */
  1496. , {.name= "non-ASCII in status line"
  1497. ,.type= HTTP_RESPONSE
  1498. ,.raw= "HTTP/1.1 500 Oriëntatieprobleem\r\n"
  1499. "Date: Fri, 5 Nov 2010 23:07:12 GMT+2\r\n"
  1500. "Content-Length: 0\r\n"
  1501. "Connection: close\r\n"
  1502. "\r\n"
  1503. ,.should_keep_alive= FALSE
  1504. ,.message_complete_on_eof= FALSE
  1505. ,.http_major= 1
  1506. ,.http_minor= 1
  1507. ,.status_code= 500
  1508. ,.response_status= "Oriëntatieprobleem"
  1509. ,.num_headers= 3
  1510. ,.headers=
  1511. { { "Date", "Fri, 5 Nov 2010 23:07:12 GMT+2" }
  1512. , { "Content-Length", "0" }
  1513. , { "Connection", "close" }
  1514. }
  1515. ,.body= ""
  1516. }
  1517. #define HTTP_VERSION_0_9 11
  1518. /* Should handle HTTP/0.9 */
  1519. , {.name= "http version 0.9"
  1520. ,.type= HTTP_RESPONSE
  1521. ,.raw= "HTTP/0.9 200 OK\r\n"
  1522. "\r\n"
  1523. ,.should_keep_alive= FALSE
  1524. ,.message_complete_on_eof= TRUE
  1525. ,.http_major= 0
  1526. ,.http_minor= 9
  1527. ,.status_code= 200
  1528. ,.response_status= "OK"
  1529. ,.num_headers= 0
  1530. ,.headers=
  1531. {}
  1532. ,.body= ""
  1533. }
  1534. #define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12
  1535. /* The client should wait for the server's EOF. That is, when neither
  1536. * content-length nor transfer-encoding is specified, the end of body
  1537. * is specified by the EOF.
  1538. */
  1539. , {.name= "neither content-length nor transfer-encoding response"
  1540. ,.type= HTTP_RESPONSE
  1541. ,.raw= "HTTP/1.1 200 OK\r\n"
  1542. "Content-Type: text/plain\r\n"
  1543. "\r\n"
  1544. "hello world"
  1545. ,.should_keep_alive= FALSE
  1546. ,.message_complete_on_eof= TRUE
  1547. ,.http_major= 1
  1548. ,.http_minor= 1
  1549. ,.status_code= 200
  1550. ,.response_status= "OK"
  1551. ,.num_headers= 1
  1552. ,.headers=
  1553. { { "Content-Type", "text/plain" }
  1554. }
  1555. ,.body= "hello world"
  1556. }
  1557. #define NO_BODY_HTTP10_KA_200 13
  1558. , {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status"
  1559. ,.type= HTTP_RESPONSE
  1560. ,.raw= "HTTP/1.0 200 OK\r\n"
  1561. "Connection: keep-alive\r\n"
  1562. "\r\n"
  1563. ,.should_keep_alive= FALSE
  1564. ,.message_complete_on_eof= TRUE
  1565. ,.http_major= 1
  1566. ,.http_minor= 0
  1567. ,.status_code= 200
  1568. ,.response_status= "OK"
  1569. ,.num_headers= 1
  1570. ,.headers=
  1571. { { "Connection", "keep-alive" }
  1572. }
  1573. ,.body_size= 0
  1574. ,.body= ""
  1575. }
  1576. #define NO_BODY_HTTP10_KA_204 14
  1577. , {.name= "HTTP/1.0 with keep-alive and a 204 status"
  1578. ,.type= HTTP_RESPONSE
  1579. ,.raw= "HTTP/1.0 204 No content\r\n"
  1580. "Connection: keep-alive\r\n"
  1581. "\r\n"
  1582. ,.should_keep_alive= TRUE
  1583. ,.message_complete_on_eof= FALSE
  1584. ,.http_major= 1
  1585. ,.http_minor= 0
  1586. ,.status_code= 204
  1587. ,.response_status= "No content"
  1588. ,.num_headers= 1
  1589. ,.headers=
  1590. { { "Connection", "keep-alive" }
  1591. }
  1592. ,.body_size= 0
  1593. ,.body= ""
  1594. }
  1595. #define NO_BODY_HTTP11_KA_200 15
  1596. , {.name= "HTTP/1.1 with an EOF-terminated 200 status"
  1597. ,.type= HTTP_RESPONSE
  1598. ,.raw= "HTTP/1.1 200 OK\r\n"
  1599. "\r\n"
  1600. ,.should_keep_alive= FALSE
  1601. ,.message_complete_on_eof= TRUE
  1602. ,.http_major= 1
  1603. ,.http_minor= 1
  1604. ,.status_code= 200
  1605. ,.response_status= "OK"
  1606. ,.num_headers= 0
  1607. ,.headers={}
  1608. ,.body_size= 0
  1609. ,.body= ""
  1610. }
  1611. #define NO_BODY_HTTP11_KA_204 16
  1612. , {.name= "HTTP/1.1 with a 204 status"
  1613. ,.type= HTTP_RESPONSE
  1614. ,.raw= "HTTP/1.1 204 No content\r\n"
  1615. "\r\n"
  1616. ,.should_keep_alive= TRUE
  1617. ,.message_complete_on_eof= FALSE
  1618. ,.http_major= 1
  1619. ,.http_minor= 1
  1620. ,.status_code= 204
  1621. ,.response_status= "No content"
  1622. ,.num_headers= 0
  1623. ,.headers={}
  1624. ,.body_size= 0
  1625. ,.body= ""
  1626. }
  1627. #define NO_BODY_HTTP11_NOKA_204 17
  1628. , {.name= "HTTP/1.1 with a 204 status and keep-alive disabled"
  1629. ,.type= HTTP_RESPONSE
  1630. ,.raw= "HTTP/1.1 204 No content\r\n"
  1631. "Connection: close\r\n"
  1632. "\r\n"
  1633. ,.should_keep_alive= FALSE
  1634. ,.message_complete_on_eof= FALSE
  1635. ,.http_major= 1
  1636. ,.http_minor= 1
  1637. ,.status_code= 204
  1638. ,.response_status= "No content"
  1639. ,.num_headers= 1
  1640. ,.headers=
  1641. { { "Connection", "close" }
  1642. }
  1643. ,.body_size= 0
  1644. ,.body= ""
  1645. }
  1646. #define NO_BODY_HTTP11_KA_CHUNKED_200 18
  1647. , {.name= "HTTP/1.1 with chunked endocing and a 200 response"
  1648. ,.type= HTTP_RESPONSE
  1649. ,.raw= "HTTP/1.1 200 OK\r\n"
  1650. "Transfer-Encoding: chunked\r\n"
  1651. "\r\n"
  1652. "0\r\n"
  1653. "\r\n"
  1654. ,.should_keep_alive= TRUE
  1655. ,.message_complete_on_eof= FALSE
  1656. ,.http_major= 1
  1657. ,.http_minor= 1
  1658. ,.status_code= 200
  1659. ,.response_status= "OK"
  1660. ,.num_headers= 1
  1661. ,.headers=
  1662. { { "Transfer-Encoding", "chunked" }
  1663. }
  1664. ,.body_size= 0
  1665. ,.body= ""
  1666. ,.num_chunks_complete= 1
  1667. }
  1668. #if !HTTP_PARSER_STRICT
  1669. #define SPACE_IN_FIELD_RES 19
  1670. /* Should handle spaces in header fields */
  1671. , {.name= "field space"
  1672. ,.type= HTTP_RESPONSE
  1673. ,.raw= "HTTP/1.1 200 OK\r\n"
  1674. "Server: Microsoft-IIS/6.0\r\n"
  1675. "X-Powered-By: ASP.NET\r\n"
  1676. "en-US Content-Type: text/xml\r\n" /* this is the problem */
  1677. "Content-Type: text/xml\r\n"
  1678. "Content-Length: 16\r\n"
  1679. "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
  1680. "Connection: keep-alive\r\n"
  1681. "\r\n"
  1682. "<xml>hello</xml>" /* fake body */
  1683. ,.should_keep_alive= TRUE
  1684. ,.message_complete_on_eof= FALSE
  1685. ,.http_major= 1
  1686. ,.http_minor= 1
  1687. ,.status_code= 200
  1688. ,.response_status= "OK"
  1689. ,.num_headers= 7
  1690. ,.headers=
  1691. { { "Server", "Microsoft-IIS/6.0" }
  1692. , { "X-Powered-By", "ASP.NET" }
  1693. , { "en-US Content-Type", "text/xml" }
  1694. , { "Content-Type", "text/xml" }
  1695. , { "Content-Length", "16" }
  1696. , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
  1697. , { "Connection", "keep-alive" }
  1698. }
  1699. ,.body= "<xml>hello</xml>"
  1700. }
  1701. #endif /* !HTTP_PARSER_STRICT */
  1702. #define AMAZON_COM 20
  1703. , {.name= "amazon.com"
  1704. ,.type= HTTP_RESPONSE
  1705. ,.raw= "HTTP/1.1 301 MovedPermanently\r\n"
  1706. "Date: Wed, 15 May 2013 17:06:33 GMT\r\n"
  1707. "Server: Server\r\n"
  1708. "x-amz-id-1: 0GPHKXSJQ826RK7GZEB2\r\n"
  1709. "p3p: policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"\r\n"
  1710. "x-amz-id-2: STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD\r\n"
  1711. "Location: http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846\r\n"
  1712. "Vary: Accept-Encoding,User-Agent\r\n"
  1713. "Content-Type: text/html; charset=ISO-8859-1\r\n"
  1714. "Transfer-Encoding: chunked\r\n"
  1715. "\r\n"
  1716. "1\r\n"
  1717. "\n\r\n"
  1718. "0\r\n"
  1719. "\r\n"
  1720. ,.should_keep_alive= TRUE
  1721. ,.message_complete_on_eof= FALSE
  1722. ,.http_major= 1
  1723. ,.http_minor= 1
  1724. ,.status_code= 301
  1725. ,.response_status= "MovedPermanently"
  1726. ,.num_headers= 9
  1727. ,.headers= { { "Date", "Wed, 15 May 2013 17:06:33 GMT" }
  1728. , { "Server", "Server" }
  1729. , { "x-amz-id-1", "0GPHKXSJQ826RK7GZEB2" }
  1730. , { "p3p", "policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"" }
  1731. , { "x-amz-id-2", "STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD" }
  1732. , { "Location", "http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846" }
  1733. , { "Vary", "Accept-Encoding,User-Agent" }
  1734. , { "Content-Type", "text/html; charset=ISO-8859-1" }
  1735. , { "Transfer-Encoding", "chunked" }
  1736. }
  1737. ,.body= "\n"
  1738. ,.num_chunks_complete= 2
  1739. ,.chunk_lengths= { 1 }
  1740. }
  1741. #define EMPTY_REASON_PHRASE_AFTER_SPACE 20
  1742. , {.name= "empty reason phrase after space"
  1743. ,.type= HTTP_RESPONSE
  1744. ,.raw= "HTTP/1.1 200 \r\n"
  1745. "\r\n"
  1746. ,.should_keep_alive= FALSE
  1747. ,.message_complete_on_eof= TRUE
  1748. ,.http_major= 1
  1749. ,.http_minor= 1
  1750. ,.status_code= 200
  1751. ,.response_status= ""
  1752. ,.num_headers= 0
  1753. ,.headers= {}
  1754. ,.body= ""
  1755. }
  1756. #define CONTENT_LENGTH_X 21
  1757. , {.name= "Content-Length-X"
  1758. ,.type= HTTP_RESPONSE
  1759. ,.raw= "HTTP/1.1 200 OK\r\n"
  1760. "Content-Length-X: 0\r\n"
  1761. "Transfer-Encoding: chunked\r\n"
  1762. "\r\n"
  1763. "2\r\n"
  1764. "OK\r\n"
  1765. "0\r\n"
  1766. "\r\n"
  1767. ,.should_keep_alive= TRUE
  1768. ,.message_complete_on_eof= FALSE
  1769. ,.http_major= 1
  1770. ,.http_minor= 1
  1771. ,.status_code= 200
  1772. ,.response_status= "OK"
  1773. ,.num_headers= 2
  1774. ,.headers= { { "Content-Length-X", "0" }
  1775. , { "Transfer-Encoding", "chunked" }
  1776. }
  1777. ,.body= "OK"
  1778. ,.num_chunks_complete= 2
  1779. ,.chunk_lengths= { 2 }
  1780. }
  1781. #define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER 22
  1782. , {.name= "HTTP 101 response with Upgrade header"
  1783. ,.type= HTTP_RESPONSE
  1784. ,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
  1785. "Connection: upgrade\r\n"
  1786. "Upgrade: h2c\r\n"
  1787. "\r\n"
  1788. "proto"
  1789. ,.should_keep_alive= TRUE
  1790. ,.message_complete_on_eof= FALSE
  1791. ,.http_major= 1
  1792. ,.http_minor= 1
  1793. ,.status_code= 101
  1794. ,.response_status= "Switching Protocols"
  1795. ,.upgrade= "proto"
  1796. ,.num_headers= 2
  1797. ,.headers=
  1798. { { "Connection", "upgrade" }
  1799. , { "Upgrade", "h2c" }
  1800. }
  1801. }
  1802. #define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 23
  1803. , {.name= "HTTP 101 response with Upgrade and Content-Length header"
  1804. ,.type= HTTP_RESPONSE
  1805. ,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
  1806. "Connection: upgrade\r\n"
  1807. "Upgrade: h2c\r\n"
  1808. "Content-Length: 4\r\n"
  1809. "\r\n"
  1810. "body"
  1811. "proto"
  1812. ,.should_keep_alive= TRUE
  1813. ,.message_complete_on_eof= FALSE
  1814. ,.http_major= 1
  1815. ,.http_minor= 1
  1816. ,.status_code= 101
  1817. ,.response_status= "Switching Protocols"
  1818. ,.body= "body"
  1819. ,.upgrade= "proto"
  1820. ,.num_headers= 3
  1821. ,.headers=
  1822. { { "Connection", "upgrade" }
  1823. , { "Upgrade", "h2c" }
  1824. , { "Content-Length", "4" }
  1825. }
  1826. }
  1827. #define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 24
  1828. , {.name= "HTTP 101 response with Upgrade and Transfer-Encoding header"
  1829. ,.type= HTTP_RESPONSE
  1830. ,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
  1831. "Connection: upgrade\r\n"
  1832. "Upgrade: h2c\r\n"
  1833. "Transfer-Encoding: chunked\r\n"
  1834. "\r\n"
  1835. "2\r\n"
  1836. "bo\r\n"
  1837. "2\r\n"
  1838. "dy\r\n"
  1839. "0\r\n"
  1840. "\r\n"
  1841. "proto"
  1842. ,.should_keep_alive= TRUE
  1843. ,.message_complete_on_eof= FALSE
  1844. ,.http_major= 1
  1845. ,.http_minor= 1
  1846. ,.status_code= 101
  1847. ,.response_status= "Switching Protocols"
  1848. ,.body= "body"
  1849. ,.upgrade= "proto"
  1850. ,.num_headers= 3
  1851. ,.headers=
  1852. { { "Connection", "upgrade" }
  1853. , { "Upgrade", "h2c" }
  1854. , { "Transfer-Encoding", "chunked" }
  1855. }
  1856. ,.num_chunks_complete= 3
  1857. ,.chunk_lengths= { 2, 2 }
  1858. }
  1859. #define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 25
  1860. , {.name= "HTTP 200 response with Upgrade header"
  1861. ,.type= HTTP_RESPONSE
  1862. ,.raw= "HTTP/1.1 200 OK\r\n"
  1863. "Connection: upgrade\r\n"
  1864. "Upgrade: h2c\r\n"
  1865. "\r\n"
  1866. "body"
  1867. ,.should_keep_alive= FALSE
  1868. ,.message_complete_on_eof= TRUE
  1869. ,.http_major= 1
  1870. ,.http_minor= 1
  1871. ,.status_code= 200
  1872. ,.response_status= "OK"
  1873. ,.body= "body"
  1874. ,.upgrade= NULL
  1875. ,.num_headers= 2
  1876. ,.headers=
  1877. { { "Connection", "upgrade" }
  1878. , { "Upgrade", "h2c" }
  1879. }
  1880. }
  1881. #define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 26
  1882. , {.name= "HTTP 200 response with Upgrade and Content-Length header"
  1883. ,.type= HTTP_RESPONSE
  1884. ,.raw= "HTTP/1.1 200 OK\r\n"
  1885. "Connection: upgrade\r\n"
  1886. "Upgrade: h2c\r\n"
  1887. "Content-Length: 4\r\n"
  1888. "\r\n"
  1889. "body"
  1890. ,.should_keep_alive= TRUE
  1891. ,.message_complete_on_eof= FALSE
  1892. ,.http_major= 1
  1893. ,.http_minor= 1
  1894. ,.status_code= 200
  1895. ,.response_status= "OK"
  1896. ,.num_headers= 3
  1897. ,.body= "body"
  1898. ,.upgrade= NULL
  1899. ,.headers=
  1900. { { "Connection", "upgrade" }
  1901. , { "Upgrade", "h2c" }
  1902. , { "Content-Length", "4" }
  1903. }
  1904. }
  1905. #define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 27
  1906. , {.name= "HTTP 200 response with Upgrade and Transfer-Encoding header"
  1907. ,.type= HTTP_RESPONSE
  1908. ,.raw= "HTTP/1.1 200 OK\r\n"
  1909. "Connection: upgrade\r\n"
  1910. "Upgrade: h2c\r\n"
  1911. "Transfer-Encoding: chunked\r\n"
  1912. "\r\n"
  1913. "2\r\n"
  1914. "bo\r\n"
  1915. "2\r\n"
  1916. "dy\r\n"
  1917. "0\r\n"
  1918. "\r\n"
  1919. ,.should_keep_alive= TRUE
  1920. ,.message_complete_on_eof= FALSE
  1921. ,.http_major= 1
  1922. ,.http_minor= 1
  1923. ,.status_code= 200
  1924. ,.response_status= "OK"
  1925. ,.num_headers= 3
  1926. ,.body= "body"
  1927. ,.upgrade= NULL
  1928. ,.headers=
  1929. { { "Connection", "upgrade" }
  1930. , { "Upgrade", "h2c" }
  1931. , { "Transfer-Encoding", "chunked" }
  1932. }
  1933. ,.num_chunks_complete= 3
  1934. ,.chunk_lengths= { 2, 2 }
  1935. }
  1936. #define HTTP_200_MULTI_TE_NOT_LAST_CHUNKED 28
  1937. , {.name= "HTTP 200 response with `chunked` being *not last* Transfer-Encoding"
  1938. ,.type= HTTP_RESPONSE
  1939. ,.raw= "HTTP/1.1 200 OK\r\n"
  1940. "Transfer-Encoding: chunked, identity\r\n"
  1941. "\r\n"
  1942. "2\r\n"
  1943. "OK\r\n"
  1944. "0\r\n"
  1945. "\r\n"
  1946. ,.should_keep_alive= FALSE
  1947. ,.message_complete_on_eof= TRUE
  1948. ,.http_major= 1
  1949. ,.http_minor= 1
  1950. ,.status_code= 200
  1951. ,.response_status= "OK"
  1952. ,.num_headers= 1
  1953. ,.headers= { { "Transfer-Encoding", "chunked, identity" }
  1954. }
  1955. ,.body= "2\r\nOK\r\n0\r\n\r\n"
  1956. ,.num_chunks_complete= 0
  1957. }
  1958. };
  1959. /* strnlen() is a POSIX.2008 addition. Can't rely on it being available so
  1960. * define it ourselves.
  1961. */
  1962. size_t
  1963. strnlen(const char *s, size_t maxlen)
  1964. {
  1965. const char *p;
  1966. p = memchr(s, '\0', maxlen);
  1967. if (p == NULL)
  1968. return maxlen;
  1969. return p - s;
  1970. }
  1971. size_t
  1972. strlncat(char *dst, size_t len, const char *src, size_t n)
  1973. {
  1974. size_t slen;
  1975. size_t dlen;
  1976. size_t rlen;
  1977. size_t ncpy;
  1978. slen = strnlen(src, n);
  1979. dlen = strnlen(dst, len);
  1980. if (dlen < len) {
  1981. rlen = len - dlen;
  1982. ncpy = slen < rlen ? slen : (rlen - 1);
  1983. memcpy(dst + dlen, src, ncpy);
  1984. dst[dlen + ncpy] = '\0';
  1985. }
  1986. assert(len > slen + dlen);
  1987. return slen + dlen;
  1988. }
  1989. size_t
  1990. strlncpy(char *dst, size_t len, const char *src, size_t n)
  1991. {
  1992. size_t slen;
  1993. size_t ncpy;
  1994. slen = strnlen(src, n);
  1995. if (len > 0) {
  1996. ncpy = slen < len ? slen : (len - 1);
  1997. memcpy(dst, src, ncpy);
  1998. dst[ncpy] = '\0';
  1999. }
  2000. assert(len > slen);
  2001. return slen;
  2002. }
  2003. int
  2004. request_url_cb (http_parser *p, const char *buf, size_t len)
  2005. {
  2006. assert(p == &parser);
  2007. strlncat(messages[num_messages].request_url,
  2008. sizeof(messages[num_messages].request_url),
  2009. buf,
  2010. len);
  2011. return 0;
  2012. }
  2013. int
  2014. header_field_cb (http_parser *p, const char *buf, size_t len)
  2015. {
  2016. assert(p == &parser);
  2017. struct message *m = &messages[num_messages];
  2018. if (m->last_header_element != FIELD)
  2019. m->num_headers++;
  2020. strlncat(m->headers[m->num_headers-1][0],
  2021. sizeof(m->headers[m->num_headers-1][0]),
  2022. buf,
  2023. len);
  2024. m->last_header_element = FIELD;
  2025. return 0;
  2026. }
  2027. int
  2028. header_value_cb (http_parser *p, const char *buf, size_t len)
  2029. {
  2030. assert(p == &parser);
  2031. struct message *m = &messages[num_messages];
  2032. strlncat(m->headers[m->num_headers-1][1],
  2033. sizeof(m->headers[m->num_headers-1][1]),
  2034. buf,
  2035. len);
  2036. m->last_header_element = VALUE;
  2037. return 0;
  2038. }
  2039. void
  2040. check_body_is_final (const http_parser *p)
  2041. {
  2042. if (messages[num_messages].body_is_final) {
  2043. fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 "
  2044. "on last on_body callback call "
  2045. "but it doesn't! ***\n\n");
  2046. assert(0);
  2047. abort();
  2048. }
  2049. messages[num_messages].body_is_final = http_body_is_final(p);
  2050. }
  2051. int
  2052. body_cb (http_parser *p, const char *buf, size_t len)
  2053. {
  2054. assert(p == &parser);
  2055. strlncat(messages[num_messages].body,
  2056. sizeof(messages[num_messages].body),
  2057. buf,
  2058. len);
  2059. messages[num_messages].body_size += len;
  2060. check_body_is_final(p);
  2061. // printf("body_cb: '%s'\n", requests[num_messages].body);
  2062. return 0;
  2063. }
  2064. int
  2065. count_body_cb (http_parser *p, const char *buf, size_t len)
  2066. {
  2067. assert(p == &parser);
  2068. assert(buf);
  2069. messages[num_messages].body_size += len;
  2070. check_body_is_final(p);
  2071. return 0;
  2072. }
  2073. int
  2074. message_begin_cb (http_parser *p)
  2075. {
  2076. assert(p == &parser);
  2077. assert(!messages[num_messages].message_begin_cb_called);
  2078. messages[num_messages].message_begin_cb_called = TRUE;
  2079. return 0;
  2080. }
  2081. int
  2082. headers_complete_cb (http_parser *p)
  2083. {
  2084. assert(p == &parser);
  2085. messages[num_messages].method = parser.method;
  2086. messages[num_messages].status_code = parser.status_code;
  2087. messages[num_messages].http_major = parser.http_major;
  2088. messages[num_messages].http_minor = parser.http_minor;
  2089. messages[num_messages].headers_complete_cb_called = TRUE;
  2090. messages[num_messages].should_keep_alive = http_should_keep_alive(&parser);
  2091. return 0;
  2092. }
  2093. int
  2094. message_complete_cb (http_parser *p)
  2095. {
  2096. assert(p == &parser);
  2097. if (messages[num_messages].should_keep_alive !=
  2098. http_should_keep_alive(&parser))
  2099. {
  2100. fprintf(stderr, "\n\n *** Error http_should_keep_alive() should have same "
  2101. "value in both on_message_complete and on_headers_complete "
  2102. "but it doesn't! ***\n\n");
  2103. assert(0);
  2104. abort();
  2105. }
  2106. if (messages[num_messages].body_size &&
  2107. http_body_is_final(p) &&
  2108. !messages[num_messages].body_is_final)
  2109. {
  2110. fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 "
  2111. "on last on_body callback call "
  2112. "but it doesn't! ***\n\n");
  2113. assert(0);
  2114. abort();
  2115. }
  2116. messages[num_messages].message_complete_cb_called = TRUE;
  2117. messages[num_messages].message_complete_on_eof = currently_parsing_eof;
  2118. num_messages++;
  2119. return 0;
  2120. }
  2121. int
  2122. response_status_cb (http_parser *p, const char *buf, size_t len)
  2123. {
  2124. assert(p == &parser);
  2125. messages[num_messages].status_cb_called = TRUE;
  2126. strlncat(messages[num_messages].response_status,
  2127. sizeof(messages[num_messages].response_status),
  2128. buf,
  2129. len);
  2130. return 0;
  2131. }
  2132. int
  2133. chunk_header_cb (http_parser *p)
  2134. {
  2135. assert(p == &parser);
  2136. int chunk_idx = messages[num_messages].num_chunks;
  2137. messages[num_messages].num_chunks++;
  2138. if (chunk_idx < MAX_CHUNKS) {
  2139. messages[num_messages].chunk_lengths[chunk_idx] = p->content_length;
  2140. }
  2141. return 0;
  2142. }
  2143. int
  2144. chunk_complete_cb (http_parser *p)
  2145. {
  2146. assert(p == &parser);
  2147. /* Here we want to verify that each chunk_header_cb is matched by a
  2148. * chunk_complete_cb, so not only should the total number of calls to
  2149. * both callbacks be the same, but they also should be interleaved
  2150. * properly */
  2151. assert(messages[num_messages].num_chunks ==
  2152. messages[num_messages].num_chunks_complete + 1);
  2153. messages[num_messages].num_chunks_complete++;
  2154. return 0;
  2155. }
  2156. /* These dontcall_* callbacks exist so that we can verify that when we're
  2157. * paused, no additional callbacks are invoked */
  2158. int
  2159. dontcall_message_begin_cb (http_parser *p)
  2160. {
  2161. if (p) { } // gcc
  2162. fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n");
  2163. abort();
  2164. }
  2165. int
  2166. dontcall_header_field_cb (http_parser *p, const char *buf, size_t len)
  2167. {
  2168. if (p || buf || len) { } // gcc
  2169. fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n");
  2170. abort();
  2171. }
  2172. int
  2173. dontcall_header_value_cb (http_parser *p, const char *buf, size_t len)
  2174. {
  2175. if (p || buf || len) { } // gcc
  2176. fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n");
  2177. abort();
  2178. }
  2179. int
  2180. dontcall_request_url_cb (http_parser *p, const char *buf, size_t len)
  2181. {
  2182. if (p || buf || len) { } // gcc
  2183. fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n");
  2184. abort();
  2185. }
  2186. int
  2187. dontcall_body_cb (http_parser *p, const char *buf, size_t len)
  2188. {
  2189. if (p || buf || len) { } // gcc
  2190. fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n");
  2191. abort();
  2192. }
  2193. int
  2194. dontcall_headers_complete_cb (http_parser *p)
  2195. {
  2196. if (p) { } // gcc
  2197. fprintf(stderr, "\n\n*** on_headers_complete() called on paused "
  2198. "parser ***\n\n");
  2199. abort();
  2200. }
  2201. int
  2202. dontcall_message_complete_cb (http_parser *p)
  2203. {
  2204. if (p) { } // gcc
  2205. fprintf(stderr, "\n\n*** on_message_complete() called on paused "
  2206. "parser ***\n\n");
  2207. abort();
  2208. }
  2209. int
  2210. dontcall_response_status_cb (http_parser *p, const char *buf, size_t len)
  2211. {
  2212. if (p || buf || len) { } // gcc
  2213. fprintf(stderr, "\n\n*** on_status() called on paused parser ***\n\n");
  2214. abort();
  2215. }
  2216. int
  2217. dontcall_chunk_header_cb (http_parser *p)
  2218. {
  2219. if (p) { } // gcc
  2220. fprintf(stderr, "\n\n*** on_chunk_header() called on paused parser ***\n\n");
  2221. exit(1);
  2222. }
  2223. int
  2224. dontcall_chunk_complete_cb (http_parser *p)
  2225. {
  2226. if (p) { } // gcc
  2227. fprintf(stderr, "\n\n*** on_chunk_complete() "
  2228. "called on paused parser ***\n\n");
  2229. exit(1);
  2230. }
  2231. static http_parser_settings settings_dontcall =
  2232. {.on_message_begin = dontcall_message_begin_cb
  2233. ,.on_header_field = dontcall_header_field_cb
  2234. ,.on_header_value = dontcall_header_value_cb
  2235. ,.on_url = dontcall_request_url_cb
  2236. ,.on_status = dontcall_response_status_cb
  2237. ,.on_body = dontcall_body_cb
  2238. ,.on_headers_complete = dontcall_headers_complete_cb
  2239. ,.on_message_complete = dontcall_message_complete_cb
  2240. ,.on_chunk_header = dontcall_chunk_header_cb
  2241. ,.on_chunk_complete = dontcall_chunk_complete_cb
  2242. };
  2243. /* These pause_* callbacks always pause the parser and just invoke the regular
  2244. * callback that tracks content. Before returning, we overwrite the parser
  2245. * settings to point to the _dontcall variety so that we can verify that
  2246. * the pause actually did, you know, pause. */
  2247. int
  2248. pause_message_begin_cb (http_parser *p)
  2249. {
  2250. http_parser_pause(p, 1);
  2251. *current_pause_parser = settings_dontcall;
  2252. return message_begin_cb(p);
  2253. }
  2254. int
  2255. pause_header_field_cb (http_parser *p, const char *buf, size_t len)
  2256. {
  2257. http_parser_pause(p, 1);
  2258. *current_pause_parser = settings_dontcall;
  2259. return header_field_cb(p, buf, len);
  2260. }
  2261. int
  2262. pause_header_value_cb (http_parser *p, const char *buf, size_t len)
  2263. {
  2264. http_parser_pause(p, 1);
  2265. *current_pause_parser = settings_dontcall;
  2266. return header_value_cb(p, buf, len);
  2267. }
  2268. int
  2269. pause_request_url_cb (http_parser *p, const char *buf, size_t len)
  2270. {
  2271. http_parser_pause(p, 1);
  2272. *current_pause_parser = settings_dontcall;
  2273. return request_url_cb(p, buf, len);
  2274. }
  2275. int
  2276. pause_body_cb (http_parser *p, const char *buf, size_t len)
  2277. {
  2278. http_parser_pause(p, 1);
  2279. *current_pause_parser = settings_dontcall;
  2280. return body_cb(p, buf, len);
  2281. }
  2282. int
  2283. pause_headers_complete_cb (http_parser *p)
  2284. {
  2285. http_parser_pause(p, 1);
  2286. *current_pause_parser = settings_dontcall;
  2287. return headers_complete_cb(p);
  2288. }
  2289. int
  2290. pause_message_complete_cb (http_parser *p)
  2291. {
  2292. http_parser_pause(p, 1);
  2293. *current_pause_parser = settings_dontcall;
  2294. return message_complete_cb(p);
  2295. }
  2296. int
  2297. pause_response_status_cb (http_parser *p, const char *buf, size_t len)
  2298. {
  2299. http_parser_pause(p, 1);
  2300. *current_pause_parser = settings_dontcall;
  2301. return response_status_cb(p, buf, len);
  2302. }
  2303. int
  2304. pause_chunk_header_cb (http_parser *p)
  2305. {
  2306. http_parser_pause(p, 1);
  2307. *current_pause_parser = settings_dontcall;
  2308. return chunk_header_cb(p);
  2309. }
  2310. int
  2311. pause_chunk_complete_cb (http_parser *p)
  2312. {
  2313. http_parser_pause(p, 1);
  2314. *current_pause_parser = settings_dontcall;
  2315. return chunk_complete_cb(p);
  2316. }
  2317. int
  2318. connect_headers_complete_cb (http_parser *p)
  2319. {
  2320. headers_complete_cb(p);
  2321. return 1;
  2322. }
  2323. int
  2324. connect_message_complete_cb (http_parser *p)
  2325. {
  2326. messages[num_messages].should_keep_alive = http_should_keep_alive(&parser);
  2327. return message_complete_cb(p);
  2328. }
  2329. static http_parser_settings settings_pause =
  2330. {.on_message_begin = pause_message_begin_cb
  2331. ,.on_header_field = pause_header_field_cb
  2332. ,.on_header_value = pause_header_value_cb
  2333. ,.on_url = pause_request_url_cb
  2334. ,.on_status = pause_response_status_cb
  2335. ,.on_body = pause_body_cb
  2336. ,.on_headers_complete = pause_headers_complete_cb
  2337. ,.on_message_complete = pause_message_complete_cb
  2338. ,.on_chunk_header = pause_chunk_header_cb
  2339. ,.on_chunk_complete = pause_chunk_complete_cb
  2340. };
  2341. static http_parser_settings settings =
  2342. {.on_message_begin = message_begin_cb
  2343. ,.on_header_field = header_field_cb
  2344. ,.on_header_value = header_value_cb
  2345. ,.on_url = request_url_cb
  2346. ,.on_status = response_status_cb
  2347. ,.on_body = body_cb
  2348. ,.on_headers_complete = headers_complete_cb
  2349. ,.on_message_complete = message_complete_cb
  2350. ,.on_chunk_header = chunk_header_cb
  2351. ,.on_chunk_complete = chunk_complete_cb
  2352. };
  2353. static http_parser_settings settings_count_body =
  2354. {.on_message_begin = message_begin_cb
  2355. ,.on_header_field = header_field_cb
  2356. ,.on_header_value = header_value_cb
  2357. ,.on_url = request_url_cb
  2358. ,.on_status = response_status_cb
  2359. ,.on_body = count_body_cb
  2360. ,.on_headers_complete = headers_complete_cb
  2361. ,.on_message_complete = message_complete_cb
  2362. ,.on_chunk_header = chunk_header_cb
  2363. ,.on_chunk_complete = chunk_complete_cb
  2364. };
  2365. static http_parser_settings settings_connect =
  2366. {.on_message_begin = message_begin_cb
  2367. ,.on_header_field = header_field_cb
  2368. ,.on_header_value = header_value_cb
  2369. ,.on_url = request_url_cb
  2370. ,.on_status = response_status_cb
  2371. ,.on_body = dontcall_body_cb
  2372. ,.on_headers_complete = connect_headers_complete_cb
  2373. ,.on_message_complete = connect_message_complete_cb
  2374. ,.on_chunk_header = chunk_header_cb
  2375. ,.on_chunk_complete = chunk_complete_cb
  2376. };
  2377. static http_parser_settings settings_null =
  2378. {.on_message_begin = 0
  2379. ,.on_header_field = 0
  2380. ,.on_header_value = 0
  2381. ,.on_url = 0
  2382. ,.on_status = 0
  2383. ,.on_body = 0
  2384. ,.on_headers_complete = 0
  2385. ,.on_message_complete = 0
  2386. ,.on_chunk_header = 0
  2387. ,.on_chunk_complete = 0
  2388. };
  2389. void
  2390. parser_init (enum http_parser_type type)
  2391. {
  2392. num_messages = 0;
  2393. http_parser_init(&parser, type);
  2394. memset(&messages, 0, sizeof messages);
  2395. }
  2396. size_t parse (const char *buf, size_t len)
  2397. {
  2398. size_t nparsed;
  2399. currently_parsing_eof = (len == 0);
  2400. nparsed = http_parser_execute(&parser, &settings, buf, len);
  2401. return nparsed;
  2402. }
  2403. size_t parse_count_body (const char *buf, size_t len)
  2404. {
  2405. size_t nparsed;
  2406. currently_parsing_eof = (len == 0);
  2407. nparsed = http_parser_execute(&parser, &settings_count_body, buf, len);
  2408. return nparsed;
  2409. }
  2410. size_t parse_pause (const char *buf, size_t len)
  2411. {
  2412. size_t nparsed;
  2413. http_parser_settings s = settings_pause;
  2414. currently_parsing_eof = (len == 0);
  2415. current_pause_parser = &s;
  2416. nparsed = http_parser_execute(&parser, current_pause_parser, buf, len);
  2417. return nparsed;
  2418. }
  2419. size_t parse_connect (const char *buf, size_t len)
  2420. {
  2421. size_t nparsed;
  2422. currently_parsing_eof = (len == 0);
  2423. nparsed = http_parser_execute(&parser, &settings_connect, buf, len);
  2424. return nparsed;
  2425. }
  2426. static inline int
  2427. check_str_eq (const struct message *m,
  2428. const char *prop,
  2429. const char *expected,
  2430. const char *found) {
  2431. if ((expected == NULL) != (found == NULL)) {
  2432. printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name);
  2433. printf("expected %s\n", (expected == NULL) ? "NULL" : expected);
  2434. printf(" found %s\n", (found == NULL) ? "NULL" : found);
  2435. return 0;
  2436. }
  2437. if (expected != NULL && 0 != strcmp(expected, found)) {
  2438. printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name);
  2439. printf("expected '%s'\n", expected);
  2440. printf(" found '%s'\n", found);
  2441. return 0;
  2442. }
  2443. return 1;
  2444. }
  2445. static inline int
  2446. check_num_eq (const struct message *m,
  2447. const char *prop,
  2448. int expected,
  2449. int found) {
  2450. if (expected != found) {
  2451. printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name);
  2452. printf("expected %d\n", expected);
  2453. printf(" found %d\n", found);
  2454. return 0;
  2455. }
  2456. return 1;
  2457. }
  2458. #define MESSAGE_CHECK_STR_EQ(expected, found, prop) \
  2459. if (!check_str_eq(expected, #prop, expected->prop, found->prop)) return 0
  2460. #define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \
  2461. if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0
  2462. #define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \
  2463. do { \
  2464. char ubuf[256]; \
  2465. \
  2466. if ((u)->field_set & (1 << (fn))) { \
  2467. memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \
  2468. (u)->field_data[(fn)].len); \
  2469. ubuf[(u)->field_data[(fn)].len] = '\0'; \
  2470. } else { \
  2471. ubuf[0] = '\0'; \
  2472. } \
  2473. \
  2474. check_str_eq(expected, #prop, expected->prop, ubuf); \
  2475. } while(0)
  2476. int
  2477. message_eq (int index, int connect, const struct message *expected)
  2478. {
  2479. int i;
  2480. struct message *m = &messages[index];
  2481. MESSAGE_CHECK_NUM_EQ(expected, m, http_major);
  2482. MESSAGE_CHECK_NUM_EQ(expected, m, http_minor);
  2483. if (expected->type == HTTP_REQUEST) {
  2484. MESSAGE_CHECK_NUM_EQ(expected, m, method);
  2485. } else {
  2486. MESSAGE_CHECK_NUM_EQ(expected, m, status_code);
  2487. MESSAGE_CHECK_STR_EQ(expected, m, response_status);
  2488. assert(m->status_cb_called);
  2489. }
  2490. if (!connect) {
  2491. MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive);
  2492. MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof);
  2493. }
  2494. assert(m->message_begin_cb_called);
  2495. assert(m->headers_complete_cb_called);
  2496. assert(m->message_complete_cb_called);
  2497. MESSAGE_CHECK_STR_EQ(expected, m, request_url);
  2498. /* Check URL components; we can't do this w/ CONNECT since it doesn't
  2499. * send us a well-formed URL.
  2500. */
  2501. if (*m->request_url && m->method != HTTP_CONNECT) {
  2502. struct http_parser_url u;
  2503. if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) {
  2504. fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n",
  2505. m->request_url);
  2506. abort();
  2507. }
  2508. if (expected->host) {
  2509. MESSAGE_CHECK_URL_EQ(&u, expected, m, host, UF_HOST);
  2510. }
  2511. if (expected->userinfo) {
  2512. MESSAGE_CHECK_URL_EQ(&u, expected, m, userinfo, UF_USERINFO);
  2513. }
  2514. m->port = (u.field_set & (1 << UF_PORT)) ?
  2515. u.port : 0;
  2516. MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY);
  2517. MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT);
  2518. MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH);
  2519. MESSAGE_CHECK_NUM_EQ(expected, m, port);
  2520. }
  2521. if (connect) {
  2522. check_num_eq(m, "body_size", 0, m->body_size);
  2523. } else if (expected->body_size) {
  2524. MESSAGE_CHECK_NUM_EQ(expected, m, body_size);
  2525. } else {
  2526. MESSAGE_CHECK_STR_EQ(expected, m, body);
  2527. }
  2528. if (connect) {
  2529. check_num_eq(m, "num_chunks_complete", 0, m->num_chunks_complete);
  2530. } else {
  2531. assert(m->num_chunks == m->num_chunks_complete);
  2532. MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks_complete);
  2533. for (i = 0; i < m->num_chunks && i < MAX_CHUNKS; i++) {
  2534. MESSAGE_CHECK_NUM_EQ(expected, m, chunk_lengths[i]);
  2535. }
  2536. }
  2537. MESSAGE_CHECK_NUM_EQ(expected, m, num_headers);
  2538. int r;
  2539. for (i = 0; i < m->num_headers; i++) {
  2540. r = check_str_eq(expected, "header field", expected->headers[i][0], m->headers[i][0]);
  2541. if (!r) return 0;
  2542. r = check_str_eq(expected, "header value", expected->headers[i][1], m->headers[i][1]);
  2543. if (!r) return 0;
  2544. }
  2545. if (!connect) {
  2546. MESSAGE_CHECK_STR_EQ(expected, m, upgrade);
  2547. }
  2548. return 1;
  2549. }
  2550. /* Given a sequence of varargs messages, return the number of them that the
  2551. * parser should successfully parse, taking into account that upgraded
  2552. * messages prevent all subsequent messages from being parsed.
  2553. */
  2554. size_t
  2555. count_parsed_messages(const size_t nmsgs, ...) {
  2556. size_t i;
  2557. va_list ap;
  2558. va_start(ap, nmsgs);
  2559. for (i = 0; i < nmsgs; i++) {
  2560. struct message *m = va_arg(ap, struct message *);
  2561. if (m->upgrade) {
  2562. va_end(ap);
  2563. return i + 1;
  2564. }
  2565. }
  2566. va_end(ap);
  2567. return nmsgs;
  2568. }
  2569. /* Given a sequence of bytes and the number of these that we were able to
  2570. * parse, verify that upgrade bodies are correct.
  2571. */
  2572. void
  2573. upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
  2574. va_list ap;
  2575. size_t i;
  2576. size_t off = 0;
  2577. va_start(ap, nmsgs);
  2578. for (i = 0; i < nmsgs; i++) {
  2579. struct message *m = va_arg(ap, struct message *);
  2580. off += strlen(m->raw);
  2581. if (m->upgrade) {
  2582. off -= strlen(m->upgrade);
  2583. /* Check the portion of the response after its specified upgrade */
  2584. if (!check_str_eq(m, "upgrade", body + off, body + nread)) {
  2585. abort();
  2586. }
  2587. /* Fix up the response so that message_eq() will verify the beginning
  2588. * of the upgrade */
  2589. *(body + nread + strlen(m->upgrade)) = '\0';
  2590. messages[num_messages -1 ].upgrade = body + nread;
  2591. va_end(ap);
  2592. return;
  2593. }
  2594. }
  2595. va_end(ap);
  2596. printf("\n\n*** Error: expected a message with upgrade ***\n");
  2597. abort();
  2598. }
  2599. static void
  2600. print_error (const char *raw, size_t error_location)
  2601. {
  2602. fprintf(stderr, "\n*** %s ***\n\n",
  2603. http_errno_description(HTTP_PARSER_ERRNO(&parser)));
  2604. int this_line = 0, char_len = 0;
  2605. size_t i, j, len = strlen(raw), error_location_line = 0;
  2606. for (i = 0; i < len; i++) {
  2607. if (i == error_location) this_line = 1;
  2608. switch (raw[i]) {
  2609. case '\r':
  2610. char_len = 2;
  2611. fprintf(stderr, "\\r");
  2612. break;
  2613. case '\n':
  2614. fprintf(stderr, "\\n\n");
  2615. if (this_line) goto print;
  2616. error_location_line = 0;
  2617. continue;
  2618. default:
  2619. char_len = 1;
  2620. fputc(raw[i], stderr);
  2621. break;
  2622. }
  2623. if (!this_line) error_location_line += char_len;
  2624. }
  2625. fprintf(stderr, "[eof]\n");
  2626. print:
  2627. for (j = 0; j < error_location_line; j++) {
  2628. fputc(' ', stderr);
  2629. }
  2630. fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location);
  2631. }
  2632. void
  2633. test_preserve_data (void)
  2634. {
  2635. char my_data[] = "application-specific data";
  2636. http_parser parser;
  2637. parser.data = my_data;
  2638. http_parser_init(&parser, HTTP_REQUEST);
  2639. if (parser.data != my_data) {
  2640. printf("\n*** parser.data not preserved accross http_parser_init ***\n\n");
  2641. abort();
  2642. }
  2643. }
  2644. struct url_test {
  2645. const char *name;
  2646. const char *url;
  2647. int is_connect;
  2648. struct http_parser_url u;
  2649. int rv;
  2650. };
  2651. const struct url_test url_tests[] =
  2652. { {.name="proxy request"
  2653. ,.url="http://hostname/"
  2654. ,.is_connect=0
  2655. ,.u=
  2656. {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
  2657. ,.port=0
  2658. ,.field_data=
  2659. {{ 0, 4 } /* UF_SCHEMA */
  2660. ,{ 7, 8 } /* UF_HOST */
  2661. ,{ 0, 0 } /* UF_PORT */
  2662. ,{ 15, 1 } /* UF_PATH */
  2663. ,{ 0, 0 } /* UF_QUERY */
  2664. ,{ 0, 0 } /* UF_FRAGMENT */
  2665. ,{ 0, 0 } /* UF_USERINFO */
  2666. }
  2667. }
  2668. ,.rv=0
  2669. }
  2670. , {.name="proxy request with port"
  2671. ,.url="http://hostname:444/"
  2672. ,.is_connect=0
  2673. ,.u=
  2674. {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH)
  2675. ,.port=444
  2676. ,.field_data=
  2677. {{ 0, 4 } /* UF_SCHEMA */
  2678. ,{ 7, 8 } /* UF_HOST */
  2679. ,{ 16, 3 } /* UF_PORT */
  2680. ,{ 19, 1 } /* UF_PATH */
  2681. ,{ 0, 0 } /* UF_QUERY */
  2682. ,{ 0, 0 } /* UF_FRAGMENT */
  2683. ,{ 0, 0 } /* UF_USERINFO */
  2684. }
  2685. }
  2686. ,.rv=0
  2687. }
  2688. , {.name="CONNECT request"
  2689. ,.url="hostname:443"
  2690. ,.is_connect=1
  2691. ,.u=
  2692. {.field_set=(1 << UF_HOST) | (1 << UF_PORT)
  2693. ,.port=443
  2694. ,.field_data=
  2695. {{ 0, 0 } /* UF_SCHEMA */
  2696. ,{ 0, 8 } /* UF_HOST */
  2697. ,{ 9, 3 } /* UF_PORT */
  2698. ,{ 0, 0 } /* UF_PATH */
  2699. ,{ 0, 0 } /* UF_QUERY */
  2700. ,{ 0, 0 } /* UF_FRAGMENT */
  2701. ,{ 0, 0 } /* UF_USERINFO */
  2702. }
  2703. }
  2704. ,.rv=0
  2705. }
  2706. , {.name="CONNECT request but not connect"
  2707. ,.url="hostname:443"
  2708. ,.is_connect=0
  2709. ,.rv=1
  2710. }
  2711. , {.name="proxy ipv6 request"
  2712. ,.url="http://[1:2::3:4]/"
  2713. ,.is_connect=0
  2714. ,.u=
  2715. {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
  2716. ,.port=0
  2717. ,.field_data=
  2718. {{ 0, 4 } /* UF_SCHEMA */
  2719. ,{ 8, 8 } /* UF_HOST */
  2720. ,{ 0, 0 } /* UF_PORT */
  2721. ,{ 17, 1 } /* UF_PATH */
  2722. ,{ 0, 0 } /* UF_QUERY */
  2723. ,{ 0, 0 } /* UF_FRAGMENT */
  2724. ,{ 0, 0 } /* UF_USERINFO */
  2725. }
  2726. }
  2727. ,.rv=0
  2728. }
  2729. , {.name="proxy ipv6 request with port"
  2730. ,.url="http://[1:2::3:4]:67/"
  2731. ,.is_connect=0
  2732. ,.u=
  2733. {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH)
  2734. ,.port=67
  2735. ,.field_data=
  2736. {{ 0, 4 } /* UF_SCHEMA */
  2737. ,{ 8, 8 } /* UF_HOST */
  2738. ,{ 18, 2 } /* UF_PORT */
  2739. ,{ 20, 1 } /* UF_PATH */
  2740. ,{ 0, 0 } /* UF_QUERY */
  2741. ,{ 0, 0 } /* UF_FRAGMENT */
  2742. ,{ 0, 0 } /* UF_USERINFO */
  2743. }
  2744. }
  2745. ,.rv=0
  2746. }
  2747. , {.name="CONNECT ipv6 address"
  2748. ,.url="[1:2::3:4]:443"
  2749. ,.is_connect=1
  2750. ,.u=
  2751. {.field_set=(1 << UF_HOST) | (1 << UF_PORT)
  2752. ,.port=443
  2753. ,.field_data=
  2754. {{ 0, 0 } /* UF_SCHEMA */
  2755. ,{ 1, 8 } /* UF_HOST */
  2756. ,{ 11, 3 } /* UF_PORT */
  2757. ,{ 0, 0 } /* UF_PATH */
  2758. ,{ 0, 0 } /* UF_QUERY */
  2759. ,{ 0, 0 } /* UF_FRAGMENT */
  2760. ,{ 0, 0 } /* UF_USERINFO */
  2761. }
  2762. }
  2763. ,.rv=0
  2764. }
  2765. , {.name="ipv4 in ipv6 address"
  2766. ,.url="http://[2001:0000:0000:0000:0000:0000:1.9.1.1]/"
  2767. ,.is_connect=0
  2768. ,.u=
  2769. {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
  2770. ,.port=0
  2771. ,.field_data=
  2772. {{ 0, 4 } /* UF_SCHEMA */
  2773. ,{ 8, 37 } /* UF_HOST */
  2774. ,{ 0, 0 } /* UF_PORT */
  2775. ,{ 46, 1 } /* UF_PATH */
  2776. ,{ 0, 0 } /* UF_QUERY */
  2777. ,{ 0, 0 } /* UF_FRAGMENT */
  2778. ,{ 0, 0 } /* UF_USERINFO */
  2779. }
  2780. }
  2781. ,.rv=0
  2782. }
  2783. , {.name="extra ? in query string"
  2784. ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css,"
  2785. "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css,"
  2786. "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css"
  2787. ,.is_connect=0
  2788. ,.u=
  2789. {.field_set=(1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_QUERY)
  2790. ,.port=0
  2791. ,.field_data=
  2792. {{ 0, 4 } /* UF_SCHEMA */
  2793. ,{ 7, 10 } /* UF_HOST */
  2794. ,{ 0, 0 } /* UF_PORT */
  2795. ,{ 17, 12 } /* UF_PATH */
  2796. ,{ 30,187 } /* UF_QUERY */
  2797. ,{ 0, 0 } /* UF_FRAGMENT */
  2798. ,{ 0, 0 } /* UF_USERINFO */
  2799. }
  2800. }
  2801. ,.rv=0
  2802. }
  2803. , {.name="space URL encoded"
  2804. ,.url="/toto.html?toto=a%20b"
  2805. ,.is_connect=0
  2806. ,.u=
  2807. {.field_set= (1<<UF_PATH) | (1<<UF_QUERY)
  2808. ,.port=0
  2809. ,.field_data=
  2810. {{ 0, 0 } /* UF_SCHEMA */
  2811. ,{ 0, 0 } /* UF_HOST */
  2812. ,{ 0, 0 } /* UF_PORT */
  2813. ,{ 0, 10 } /* UF_PATH */
  2814. ,{ 11, 10 } /* UF_QUERY */
  2815. ,{ 0, 0 } /* UF_FRAGMENT */
  2816. ,{ 0, 0 } /* UF_USERINFO */
  2817. }
  2818. }
  2819. ,.rv=0
  2820. }
  2821. , {.name="URL fragment"
  2822. ,.url="/toto.html#titi"
  2823. ,.is_connect=0
  2824. ,.u=
  2825. {.field_set= (1<<UF_PATH) | (1<<UF_FRAGMENT)
  2826. ,.port=0
  2827. ,.field_data=
  2828. {{ 0, 0 } /* UF_SCHEMA */
  2829. ,{ 0, 0 } /* UF_HOST */
  2830. ,{ 0, 0 } /* UF_PORT */
  2831. ,{ 0, 10 } /* UF_PATH */
  2832. ,{ 0, 0 } /* UF_QUERY */
  2833. ,{ 11, 4 } /* UF_FRAGMENT */
  2834. ,{ 0, 0 } /* UF_USERINFO */
  2835. }
  2836. }
  2837. ,.rv=0
  2838. }
  2839. , {.name="complex URL fragment"
  2840. ,.url="http://www.webmasterworld.com/r.cgi?f=21&d=8405&url="
  2841. "http://www.example.com/index.html?foo=bar&hello=world#midpage"
  2842. ,.is_connect=0
  2843. ,.u=
  2844. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_QUERY) |\
  2845. (1<<UF_FRAGMENT)
  2846. ,.port=0
  2847. ,.field_data=
  2848. {{ 0, 4 } /* UF_SCHEMA */
  2849. ,{ 7, 22 } /* UF_HOST */
  2850. ,{ 0, 0 } /* UF_PORT */
  2851. ,{ 29, 6 } /* UF_PATH */
  2852. ,{ 36, 69 } /* UF_QUERY */
  2853. ,{106, 7 } /* UF_FRAGMENT */
  2854. ,{ 0, 0 } /* UF_USERINFO */
  2855. }
  2856. }
  2857. ,.rv=0
  2858. }
  2859. , {.name="complex URL from node js url parser doc"
  2860. ,.url="http://host.com:8080/p/a/t/h?query=string#hash"
  2861. ,.is_connect=0
  2862. ,.u=
  2863. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PORT) | (1<<UF_PATH) |\
  2864. (1<<UF_QUERY) | (1<<UF_FRAGMENT)
  2865. ,.port=8080
  2866. ,.field_data=
  2867. {{ 0, 4 } /* UF_SCHEMA */
  2868. ,{ 7, 8 } /* UF_HOST */
  2869. ,{ 16, 4 } /* UF_PORT */
  2870. ,{ 20, 8 } /* UF_PATH */
  2871. ,{ 29, 12 } /* UF_QUERY */
  2872. ,{ 42, 4 } /* UF_FRAGMENT */
  2873. ,{ 0, 0 } /* UF_USERINFO */
  2874. }
  2875. }
  2876. ,.rv=0
  2877. }
  2878. , {.name="complex URL with basic auth from node js url parser doc"
  2879. ,.url="http://a:b@host.com:8080/p/a/t/h?query=string#hash"
  2880. ,.is_connect=0
  2881. ,.u=
  2882. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PORT) | (1<<UF_PATH) |\
  2883. (1<<UF_QUERY) | (1<<UF_FRAGMENT) | (1<<UF_USERINFO)
  2884. ,.port=8080
  2885. ,.field_data=
  2886. {{ 0, 4 } /* UF_SCHEMA */
  2887. ,{ 11, 8 } /* UF_HOST */
  2888. ,{ 20, 4 } /* UF_PORT */
  2889. ,{ 24, 8 } /* UF_PATH */
  2890. ,{ 33, 12 } /* UF_QUERY */
  2891. ,{ 46, 4 } /* UF_FRAGMENT */
  2892. ,{ 7, 3 } /* UF_USERINFO */
  2893. }
  2894. }
  2895. ,.rv=0
  2896. }
  2897. , {.name="double @"
  2898. ,.url="http://a:b@@hostname:443/"
  2899. ,.is_connect=0
  2900. ,.rv=1
  2901. }
  2902. , {.name="proxy empty host"
  2903. ,.url="http://:443/"
  2904. ,.is_connect=0
  2905. ,.rv=1
  2906. }
  2907. , {.name="proxy empty port"
  2908. ,.url="http://hostname:/"
  2909. ,.is_connect=0
  2910. ,.rv=1
  2911. }
  2912. , {.name="CONNECT with basic auth"
  2913. ,.url="a:b@hostname:443"
  2914. ,.is_connect=1
  2915. ,.rv=1
  2916. }
  2917. , {.name="CONNECT empty host"
  2918. ,.url=":443"
  2919. ,.is_connect=1
  2920. ,.rv=1
  2921. }
  2922. , {.name="CONNECT empty port"
  2923. ,.url="hostname:"
  2924. ,.is_connect=1
  2925. ,.rv=1
  2926. }
  2927. , {.name="CONNECT with extra bits"
  2928. ,.url="hostname:443/"
  2929. ,.is_connect=1
  2930. ,.rv=1
  2931. }
  2932. , {.name="space in URL"
  2933. ,.url="/foo bar/"
  2934. ,.rv=1 /* s_dead */
  2935. }
  2936. , {.name="proxy basic auth with space url encoded"
  2937. ,.url="http://a%20:b@host.com/"
  2938. ,.is_connect=0
  2939. ,.u=
  2940. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_USERINFO)
  2941. ,.port=0
  2942. ,.field_data=
  2943. {{ 0, 4 } /* UF_SCHEMA */
  2944. ,{ 14, 8 } /* UF_HOST */
  2945. ,{ 0, 0 } /* UF_PORT */
  2946. ,{ 22, 1 } /* UF_PATH */
  2947. ,{ 0, 0 } /* UF_QUERY */
  2948. ,{ 0, 0 } /* UF_FRAGMENT */
  2949. ,{ 7, 6 } /* UF_USERINFO */
  2950. }
  2951. }
  2952. ,.rv=0
  2953. }
  2954. , {.name="carriage return in URL"
  2955. ,.url="/foo\rbar/"
  2956. ,.rv=1 /* s_dead */
  2957. }
  2958. , {.name="proxy double : in URL"
  2959. ,.url="http://hostname::443/"
  2960. ,.rv=1 /* s_dead */
  2961. }
  2962. , {.name="proxy basic auth with double :"
  2963. ,.url="http://a::b@host.com/"
  2964. ,.is_connect=0
  2965. ,.u=
  2966. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_USERINFO)
  2967. ,.port=0
  2968. ,.field_data=
  2969. {{ 0, 4 } /* UF_SCHEMA */
  2970. ,{ 12, 8 } /* UF_HOST */
  2971. ,{ 0, 0 } /* UF_PORT */
  2972. ,{ 20, 1 } /* UF_PATH */
  2973. ,{ 0, 0 } /* UF_QUERY */
  2974. ,{ 0, 0 } /* UF_FRAGMENT */
  2975. ,{ 7, 4 } /* UF_USERINFO */
  2976. }
  2977. }
  2978. ,.rv=0
  2979. }
  2980. , {.name="line feed in URL"
  2981. ,.url="/foo\nbar/"
  2982. ,.rv=1 /* s_dead */
  2983. }
  2984. , {.name="proxy empty basic auth"
  2985. ,.url="http://@hostname/fo"
  2986. ,.u=
  2987. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH)
  2988. ,.port=0
  2989. ,.field_data=
  2990. {{ 0, 4 } /* UF_SCHEMA */
  2991. ,{ 8, 8 } /* UF_HOST */
  2992. ,{ 0, 0 } /* UF_PORT */
  2993. ,{ 16, 3 } /* UF_PATH */
  2994. ,{ 0, 0 } /* UF_QUERY */
  2995. ,{ 0, 0 } /* UF_FRAGMENT */
  2996. ,{ 0, 0 } /* UF_USERINFO */
  2997. }
  2998. }
  2999. ,.rv=0
  3000. }
  3001. , {.name="proxy line feed in hostname"
  3002. ,.url="http://host\name/fo"
  3003. ,.rv=1 /* s_dead */
  3004. }
  3005. , {.name="proxy % in hostname"
  3006. ,.url="http://host%name/fo"
  3007. ,.rv=1 /* s_dead */
  3008. }
  3009. , {.name="proxy ; in hostname"
  3010. ,.url="http://host;ame/fo"
  3011. ,.rv=1 /* s_dead */
  3012. }
  3013. , {.name="proxy basic auth with unreservedchars"
  3014. ,.url="http://a!;-_!=+$@host.com/"
  3015. ,.is_connect=0
  3016. ,.u=
  3017. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH) | (1<<UF_USERINFO)
  3018. ,.port=0
  3019. ,.field_data=
  3020. {{ 0, 4 } /* UF_SCHEMA */
  3021. ,{ 17, 8 } /* UF_HOST */
  3022. ,{ 0, 0 } /* UF_PORT */
  3023. ,{ 25, 1 } /* UF_PATH */
  3024. ,{ 0, 0 } /* UF_QUERY */
  3025. ,{ 0, 0 } /* UF_FRAGMENT */
  3026. ,{ 7, 9 } /* UF_USERINFO */
  3027. }
  3028. }
  3029. ,.rv=0
  3030. }
  3031. , {.name="proxy only empty basic auth"
  3032. ,.url="http://@/fo"
  3033. ,.rv=1 /* s_dead */
  3034. }
  3035. , {.name="proxy only basic auth"
  3036. ,.url="http://toto@/fo"
  3037. ,.rv=1 /* s_dead */
  3038. }
  3039. , {.name="proxy emtpy hostname"
  3040. ,.url="http:///fo"
  3041. ,.rv=1 /* s_dead */
  3042. }
  3043. , {.name="proxy = in URL"
  3044. ,.url="http://host=ame/fo"
  3045. ,.rv=1 /* s_dead */
  3046. }
  3047. , {.name="ipv6 address with Zone ID"
  3048. ,.url="http://[fe80::a%25eth0]/"
  3049. ,.is_connect=0
  3050. ,.u=
  3051. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH)
  3052. ,.port=0
  3053. ,.field_data=
  3054. {{ 0, 4 } /* UF_SCHEMA */
  3055. ,{ 8, 14 } /* UF_HOST */
  3056. ,{ 0, 0 } /* UF_PORT */
  3057. ,{ 23, 1 } /* UF_PATH */
  3058. ,{ 0, 0 } /* UF_QUERY */
  3059. ,{ 0, 0 } /* UF_FRAGMENT */
  3060. ,{ 0, 0 } /* UF_USERINFO */
  3061. }
  3062. }
  3063. ,.rv=0
  3064. }
  3065. , {.name="ipv6 address with Zone ID, but '%' is not percent-encoded"
  3066. ,.url="http://[fe80::a%eth0]/"
  3067. ,.is_connect=0
  3068. ,.u=
  3069. {.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH)
  3070. ,.port=0
  3071. ,.field_data=
  3072. {{ 0, 4 } /* UF_SCHEMA */
  3073. ,{ 8, 12 } /* UF_HOST */
  3074. ,{ 0, 0 } /* UF_PORT */
  3075. ,{ 21, 1 } /* UF_PATH */
  3076. ,{ 0, 0 } /* UF_QUERY */
  3077. ,{ 0, 0 } /* UF_FRAGMENT */
  3078. ,{ 0, 0 } /* UF_USERINFO */
  3079. }
  3080. }
  3081. ,.rv=0
  3082. }
  3083. , {.name="ipv6 address ending with '%'"
  3084. ,.url="http://[fe80::a%]/"
  3085. ,.rv=1 /* s_dead */
  3086. }
  3087. , {.name="ipv6 address with Zone ID including bad character"
  3088. ,.url="http://[fe80::a%$HOME]/"
  3089. ,.rv=1 /* s_dead */
  3090. }
  3091. , {.name="just ipv6 Zone ID"
  3092. ,.url="http://[%eth0]/"
  3093. ,.rv=1 /* s_dead */
  3094. }
  3095. , {.name="empty url"
  3096. ,.url=""
  3097. ,.is_connect=0
  3098. ,.rv=1
  3099. }
  3100. , {.name="NULL url"
  3101. ,.url=NULL
  3102. ,.is_connect=0
  3103. ,.rv=1
  3104. }
  3105. , {.name="full of spaces url"
  3106. ,.url=" "
  3107. ,.is_connect=0
  3108. ,.rv=1
  3109. }
  3110. #if HTTP_PARSER_STRICT
  3111. , {.name="tab in URL"
  3112. ,.url="/foo\tbar/"
  3113. ,.rv=1 /* s_dead */
  3114. }
  3115. , {.name="form feed in URL"
  3116. ,.url="/foo\fbar/"
  3117. ,.rv=1 /* s_dead */
  3118. }
  3119. #else /* !HTTP_PARSER_STRICT */
  3120. , {.name="tab in URL"
  3121. ,.url="/foo\tbar/"
  3122. ,.u=
  3123. {.field_set=(1 << UF_PATH)
  3124. ,.field_data=
  3125. {{ 0, 0 } /* UF_SCHEMA */
  3126. ,{ 0, 0 } /* UF_HOST */
  3127. ,{ 0, 0 } /* UF_PORT */
  3128. ,{ 0, 9 } /* UF_PATH */
  3129. ,{ 0, 0 } /* UF_QUERY */
  3130. ,{ 0, 0 } /* UF_FRAGMENT */
  3131. ,{ 0, 0 } /* UF_USERINFO */
  3132. }
  3133. }
  3134. ,.rv=0
  3135. }
  3136. , {.name="form feed in URL"
  3137. ,.url="/foo\fbar/"
  3138. ,.u=
  3139. {.field_set=(1 << UF_PATH)
  3140. ,.field_data=
  3141. {{ 0, 0 } /* UF_SCHEMA */
  3142. ,{ 0, 0 } /* UF_HOST */
  3143. ,{ 0, 0 } /* UF_PORT */
  3144. ,{ 0, 9 } /* UF_PATH */
  3145. ,{ 0, 0 } /* UF_QUERY */
  3146. ,{ 0, 0 } /* UF_FRAGMENT */
  3147. ,{ 0, 0 } /* UF_USERINFO */
  3148. }
  3149. }
  3150. ,.rv=0
  3151. }
  3152. #endif
  3153. };
  3154. void
  3155. dump_url (const char *url, const struct http_parser_url *u)
  3156. {
  3157. unsigned int i;
  3158. printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port);
  3159. for (i = 0; i < UF_MAX; i++) {
  3160. if ((u->field_set & (1 << i)) == 0) {
  3161. printf("\tfield_data[%u]: unset\n", i);
  3162. continue;
  3163. }
  3164. printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"",
  3165. i,
  3166. u->field_data[i].off,
  3167. u->field_data[i].len,
  3168. u->field_data[i].len,
  3169. url + u->field_data[i].off);
  3170. }
  3171. }
  3172. void
  3173. test_parse_url (void)
  3174. {
  3175. struct http_parser_url u;
  3176. const struct url_test *test;
  3177. unsigned int i;
  3178. int rv;
  3179. for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) {
  3180. test = &url_tests[i];
  3181. memset(&u, 0, sizeof(u));
  3182. rv = http_parser_parse_url(test->url,
  3183. test->url ? strlen(test->url) : 0,
  3184. test->is_connect,
  3185. &u);
  3186. if (test->rv == 0) {
  3187. if (rv != 0) {
  3188. printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, "
  3189. "unexpected rv %d ***\n\n", test->url, test->name, rv);
  3190. abort();
  3191. }
  3192. if (memcmp(&u, &test->u, sizeof(u)) != 0) {
  3193. printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n",
  3194. test->url, test->name);
  3195. printf("target http_parser_url:\n");
  3196. dump_url(test->url, &test->u);
  3197. printf("result http_parser_url:\n");
  3198. dump_url(test->url, &u);
  3199. abort();
  3200. }
  3201. } else {
  3202. /* test->rv != 0 */
  3203. if (rv == 0) {
  3204. printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, "
  3205. "unexpected rv %d ***\n\n", test->url, test->name, rv);
  3206. abort();
  3207. }
  3208. }
  3209. }
  3210. }
  3211. void
  3212. test_method_str (void)
  3213. {
  3214. assert(0 == strcmp("GET", http_method_str(HTTP_GET)));
  3215. assert(0 == strcmp("<unknown>", http_method_str(1337)));
  3216. }
  3217. void
  3218. test_status_str (void)
  3219. {
  3220. assert(0 == strcmp("OK", http_status_str(HTTP_STATUS_OK)));
  3221. assert(0 == strcmp("Not Found", http_status_str(HTTP_STATUS_NOT_FOUND)));
  3222. assert(0 == strcmp("<unknown>", http_status_str(1337)));
  3223. }
  3224. void
  3225. test_message (const struct message *message)
  3226. {
  3227. size_t raw_len = strlen(message->raw);
  3228. size_t msg1len;
  3229. for (msg1len = 0; msg1len < raw_len; msg1len++) {
  3230. parser_init(message->type);
  3231. size_t read;
  3232. const char *msg1 = message->raw;
  3233. const char *msg2 = msg1 + msg1len;
  3234. size_t msg2len = raw_len - msg1len;
  3235. if (msg1len) {
  3236. assert(num_messages == 0);
  3237. messages[0].headers_complete_cb_called = FALSE;
  3238. read = parse(msg1, msg1len);
  3239. if (!messages[0].headers_complete_cb_called && parser.nread != read) {
  3240. assert(parser.nread == read);
  3241. print_error(msg1, read);
  3242. abort();
  3243. }
  3244. if (message->upgrade && parser.upgrade && num_messages > 0) {
  3245. messages[num_messages - 1].upgrade = msg1 + read;
  3246. goto test;
  3247. }
  3248. if (read != msg1len) {
  3249. print_error(msg1, read);
  3250. abort();
  3251. }
  3252. }
  3253. read = parse(msg2, msg2len);
  3254. if (message->upgrade && parser.upgrade) {
  3255. messages[num_messages - 1].upgrade = msg2 + read;
  3256. goto test;
  3257. }
  3258. if (read != msg2len) {
  3259. print_error(msg2, read);
  3260. abort();
  3261. }
  3262. read = parse(NULL, 0);
  3263. if (read != 0) {
  3264. print_error(message->raw, read);
  3265. abort();
  3266. }
  3267. test:
  3268. if (num_messages != 1) {
  3269. printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
  3270. abort();
  3271. }
  3272. if(!message_eq(0, 0, message)) abort();
  3273. }
  3274. }
  3275. void
  3276. test_message_count_body (const struct message *message)
  3277. {
  3278. parser_init(message->type);
  3279. size_t read;
  3280. size_t l = strlen(message->raw);
  3281. size_t i, toread;
  3282. size_t chunk = 4024;
  3283. for (i = 0; i < l; i+= chunk) {
  3284. toread = MIN(l-i, chunk);
  3285. read = parse_count_body(message->raw + i, toread);
  3286. if (read != toread) {
  3287. print_error(message->raw, read);
  3288. abort();
  3289. }
  3290. }
  3291. read = parse_count_body(NULL, 0);
  3292. if (read != 0) {
  3293. print_error(message->raw, read);
  3294. abort();
  3295. }
  3296. if (num_messages != 1) {
  3297. printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name);
  3298. abort();
  3299. }
  3300. if(!message_eq(0, 0, message)) abort();
  3301. }
  3302. void
  3303. test_simple_type (const char *buf,
  3304. enum http_errno err_expected,
  3305. enum http_parser_type type)
  3306. {
  3307. parser_init(type);
  3308. enum http_errno err;
  3309. parse(buf, strlen(buf));
  3310. err = HTTP_PARSER_ERRNO(&parser);
  3311. parse(NULL, 0);
  3312. /* In strict mode, allow us to pass with an unexpected HPE_STRICT as
  3313. * long as the caller isn't expecting success.
  3314. */
  3315. #if HTTP_PARSER_STRICT
  3316. if (err_expected != err && err_expected != HPE_OK && err != HPE_STRICT) {
  3317. #else
  3318. if (err_expected != err) {
  3319. #endif
  3320. fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n",
  3321. http_errno_name(err_expected), http_errno_name(err), buf);
  3322. abort();
  3323. }
  3324. }
  3325. void
  3326. test_simple (const char *buf, enum http_errno err_expected)
  3327. {
  3328. test_simple_type(buf, err_expected, HTTP_REQUEST);
  3329. }
  3330. void
  3331. test_invalid_header_content (int req, const char* str)
  3332. {
  3333. http_parser parser;
  3334. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3335. size_t parsed;
  3336. const char *buf;
  3337. buf = req ?
  3338. "GET / HTTP/1.1\r\n" :
  3339. "HTTP/1.1 200 OK\r\n";
  3340. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3341. assert(parsed == strlen(buf));
  3342. buf = str;
  3343. size_t buflen = strlen(buf);
  3344. parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
  3345. if (parsed != buflen) {
  3346. assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_HEADER_TOKEN);
  3347. return;
  3348. }
  3349. fprintf(stderr,
  3350. "\n*** Error expected but none in invalid header content test ***\n");
  3351. abort();
  3352. }
  3353. void
  3354. test_invalid_header_field_content_error (int req)
  3355. {
  3356. test_invalid_header_content(req, "Foo: F\01ailure");
  3357. test_invalid_header_content(req, "Foo: B\02ar");
  3358. }
  3359. void
  3360. test_invalid_header_field (int req, const char* str)
  3361. {
  3362. http_parser parser;
  3363. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3364. size_t parsed;
  3365. const char *buf;
  3366. buf = req ?
  3367. "GET / HTTP/1.1\r\n" :
  3368. "HTTP/1.1 200 OK\r\n";
  3369. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3370. assert(parsed == strlen(buf));
  3371. buf = str;
  3372. size_t buflen = strlen(buf);
  3373. parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
  3374. if (parsed != buflen) {
  3375. assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_HEADER_TOKEN);
  3376. return;
  3377. }
  3378. fprintf(stderr,
  3379. "\n*** Error expected but none in invalid header token test ***\n");
  3380. abort();
  3381. }
  3382. void
  3383. test_invalid_header_field_token_error (int req)
  3384. {
  3385. test_invalid_header_field(req, "Fo@: Failure");
  3386. test_invalid_header_field(req, "Foo\01\test: Bar");
  3387. }
  3388. void
  3389. test_double_content_length_error (int req)
  3390. {
  3391. http_parser parser;
  3392. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3393. size_t parsed;
  3394. const char *buf;
  3395. buf = req ?
  3396. "GET / HTTP/1.1\r\n" :
  3397. "HTTP/1.1 200 OK\r\n";
  3398. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3399. assert(parsed == strlen(buf));
  3400. buf = "Content-Length: 0\r\nContent-Length: 1\r\n\r\n";
  3401. size_t buflen = strlen(buf);
  3402. parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
  3403. if (parsed != buflen) {
  3404. assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH);
  3405. return;
  3406. }
  3407. fprintf(stderr,
  3408. "\n*** Error expected but none in double content-length test ***\n");
  3409. abort();
  3410. }
  3411. void
  3412. test_chunked_content_length_error (int req)
  3413. {
  3414. http_parser parser;
  3415. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3416. size_t parsed;
  3417. const char *buf;
  3418. buf = req ?
  3419. "GET / HTTP/1.1\r\n" :
  3420. "HTTP/1.1 200 OK\r\n";
  3421. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3422. assert(parsed == strlen(buf));
  3423. buf = "Transfer-Encoding: anything\r\nContent-Length: 1\r\n\r\n";
  3424. size_t buflen = strlen(buf);
  3425. parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
  3426. if (parsed != buflen) {
  3427. assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH);
  3428. return;
  3429. }
  3430. fprintf(stderr,
  3431. "\n*** Error expected but none in chunked content-length test ***\n");
  3432. abort();
  3433. }
  3434. void
  3435. test_header_cr_no_lf_error (int req)
  3436. {
  3437. http_parser parser;
  3438. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3439. size_t parsed;
  3440. const char *buf;
  3441. buf = req ?
  3442. "GET / HTTP/1.1\r\n" :
  3443. "HTTP/1.1 200 OK\r\n";
  3444. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3445. assert(parsed == strlen(buf));
  3446. buf = "Foo: 1\rBar: 1\r\n\r\n";
  3447. size_t buflen = strlen(buf);
  3448. parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
  3449. if (parsed != buflen) {
  3450. assert(HTTP_PARSER_ERRNO(&parser) == HPE_LF_EXPECTED);
  3451. return;
  3452. }
  3453. fprintf(stderr,
  3454. "\n*** Error expected but none in header whitespace test ***\n");
  3455. abort();
  3456. }
  3457. void
  3458. test_no_overflow_parse_url (void)
  3459. {
  3460. int rv;
  3461. struct http_parser_url u;
  3462. http_parser_url_init(&u);
  3463. rv = http_parser_parse_url("http://example.com:8001", 22, 0, &u);
  3464. if (rv != 0) {
  3465. fprintf(stderr,
  3466. "\n*** test_no_overflow_parse_url invalid return value=%d\n",
  3467. rv);
  3468. abort();
  3469. }
  3470. if (u.port != 800) {
  3471. fprintf(stderr,
  3472. "\n*** test_no_overflow_parse_url invalid port number=%d\n",
  3473. u.port);
  3474. abort();
  3475. }
  3476. }
  3477. void
  3478. test_header_overflow_error (int req)
  3479. {
  3480. http_parser parser;
  3481. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3482. size_t parsed;
  3483. const char *buf;
  3484. buf = req ? "GET / HTTP/1.1\r\n" : "HTTP/1.0 200 OK\r\n";
  3485. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3486. assert(parsed == strlen(buf));
  3487. buf = "header-key: header-value\r\n";
  3488. size_t buflen = strlen(buf);
  3489. int i;
  3490. for (i = 0; i < 10000; i++) {
  3491. parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
  3492. if (parsed != buflen) {
  3493. //fprintf(stderr, "error found on iter %d\n", i);
  3494. assert(HTTP_PARSER_ERRNO(&parser) == HPE_HEADER_OVERFLOW);
  3495. return;
  3496. }
  3497. }
  3498. fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n");
  3499. abort();
  3500. }
  3501. void
  3502. test_header_nread_value ()
  3503. {
  3504. http_parser parser;
  3505. http_parser_init(&parser, HTTP_REQUEST);
  3506. size_t parsed;
  3507. const char *buf;
  3508. buf = "GET / HTTP/1.1\r\nheader: value\nhdr: value\r\n";
  3509. parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
  3510. assert(parsed == strlen(buf));
  3511. assert(parser.nread == strlen(buf));
  3512. }
  3513. static void
  3514. test_content_length_overflow (const char *buf, size_t buflen, int expect_ok)
  3515. {
  3516. http_parser parser;
  3517. http_parser_init(&parser, HTTP_RESPONSE);
  3518. http_parser_execute(&parser, &settings_null, buf, buflen);
  3519. if (expect_ok)
  3520. assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK);
  3521. else
  3522. assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH);
  3523. }
  3524. void
  3525. test_header_content_length_overflow_error (void)
  3526. {
  3527. #define X(size) \
  3528. "HTTP/1.1 200 OK\r\n" \
  3529. "Content-Length: " #size "\r\n" \
  3530. "\r\n"
  3531. const char a[] = X(1844674407370955160); /* 2^64 / 10 - 1 */
  3532. const char b[] = X(18446744073709551615); /* 2^64-1 */
  3533. const char c[] = X(18446744073709551616); /* 2^64 */
  3534. #undef X
  3535. test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */
  3536. test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */
  3537. test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */
  3538. }
  3539. void
  3540. test_chunk_content_length_overflow_error (void)
  3541. {
  3542. #define X(size) \
  3543. "HTTP/1.1 200 OK\r\n" \
  3544. "Transfer-Encoding: chunked\r\n" \
  3545. "\r\n" \
  3546. #size "\r\n" \
  3547. "..."
  3548. const char a[] = X(FFFFFFFFFFFFFFE); /* 2^64 / 16 - 1 */
  3549. const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */
  3550. const char c[] = X(10000000000000000); /* 2^64 */
  3551. #undef X
  3552. test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */
  3553. test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */
  3554. test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */
  3555. }
  3556. void
  3557. test_no_overflow_long_body (int req, size_t length)
  3558. {
  3559. http_parser parser;
  3560. http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE);
  3561. size_t parsed;
  3562. size_t i;
  3563. char buf1[3000];
  3564. size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %lu\r\n\r\n",
  3565. req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", (unsigned long)length);
  3566. parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len);
  3567. if (parsed != buf1len)
  3568. goto err;
  3569. for (i = 0; i < length; i++) {
  3570. char foo = 'a';
  3571. parsed = http_parser_execute(&parser, &settings_null, &foo, 1);
  3572. if (parsed != 1)
  3573. goto err;
  3574. }
  3575. parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len);
  3576. if (parsed != buf1len) goto err;
  3577. return;
  3578. err:
  3579. fprintf(stderr,
  3580. "\n*** error in test_no_overflow_long_body %s of length %lu ***\n",
  3581. req ? "REQUEST" : "RESPONSE",
  3582. (unsigned long)length);
  3583. abort();
  3584. }
  3585. void
  3586. test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3)
  3587. {
  3588. int message_count = count_parsed_messages(3, r1, r2, r3);
  3589. char total[ strlen(r1->raw)
  3590. + strlen(r2->raw)
  3591. + strlen(r3->raw)
  3592. + 1
  3593. ];
  3594. total[0] = '\0';
  3595. strcat(total, r1->raw);
  3596. strcat(total, r2->raw);
  3597. strcat(total, r3->raw);
  3598. parser_init(r1->type);
  3599. size_t read;
  3600. read = parse(total, strlen(total));
  3601. if (parser.upgrade) {
  3602. upgrade_message_fix(total, read, 3, r1, r2, r3);
  3603. goto test;
  3604. }
  3605. if (read != strlen(total)) {
  3606. print_error(total, read);
  3607. abort();
  3608. }
  3609. read = parse(NULL, 0);
  3610. if (read != 0) {
  3611. print_error(total, read);
  3612. abort();
  3613. }
  3614. test:
  3615. if (message_count != num_messages) {
  3616. fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages);
  3617. abort();
  3618. }
  3619. if (!message_eq(0, 0, r1)) abort();
  3620. if (message_count > 1 && !message_eq(1, 0, r2)) abort();
  3621. if (message_count > 2 && !message_eq(2, 0, r3)) abort();
  3622. }
  3623. /* SCAN through every possible breaking to make sure the
  3624. * parser can handle getting the content in any chunks that
  3625. * might come from the socket
  3626. */
  3627. void
  3628. test_scan (const struct message *r1, const struct message *r2, const struct message *r3)
  3629. {
  3630. char total[80*1024] = "\0";
  3631. char buf1[80*1024] = "\0";
  3632. char buf2[80*1024] = "\0";
  3633. char buf3[80*1024] = "\0";
  3634. strcat(total, r1->raw);
  3635. strcat(total, r2->raw);
  3636. strcat(total, r3->raw);
  3637. size_t read;
  3638. int total_len = strlen(total);
  3639. int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2;
  3640. int ops = 0 ;
  3641. size_t buf1_len, buf2_len, buf3_len;
  3642. int message_count = count_parsed_messages(3, r1, r2, r3);
  3643. int i,j,type_both;
  3644. for (type_both = 0; type_both < 2; type_both ++ ) {
  3645. for (j = 2; j < total_len; j ++ ) {
  3646. for (i = 1; i < j; i ++ ) {
  3647. if (ops % 1000 == 0) {
  3648. printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops);
  3649. fflush(stdout);
  3650. }
  3651. ops += 1;
  3652. parser_init(type_both ? HTTP_BOTH : r1->type);
  3653. buf1_len = i;
  3654. strlncpy(buf1, sizeof(buf1), total, buf1_len);
  3655. buf1[buf1_len] = 0;
  3656. buf2_len = j - i;
  3657. strlncpy(buf2, sizeof(buf1), total+i, buf2_len);
  3658. buf2[buf2_len] = 0;
  3659. buf3_len = total_len - j;
  3660. strlncpy(buf3, sizeof(buf1), total+j, buf3_len);
  3661. buf3[buf3_len] = 0;
  3662. assert(num_messages == 0);
  3663. messages[0].headers_complete_cb_called = FALSE;
  3664. read = parse(buf1, buf1_len);
  3665. if (!messages[0].headers_complete_cb_called && parser.nread != read) {
  3666. print_error(buf1, read);
  3667. goto error;
  3668. }
  3669. if (parser.upgrade) goto test;
  3670. if (read != buf1_len) {
  3671. print_error(buf1, read);
  3672. goto error;
  3673. }
  3674. read += parse(buf2, buf2_len);
  3675. if (parser.upgrade) goto test;
  3676. if (read != buf1_len + buf2_len) {
  3677. print_error(buf2, read);
  3678. goto error;
  3679. }
  3680. read += parse(buf3, buf3_len);
  3681. if (parser.upgrade) goto test;
  3682. if (read != buf1_len + buf2_len + buf3_len) {
  3683. print_error(buf3, read);
  3684. goto error;
  3685. }
  3686. parse(NULL, 0);
  3687. test:
  3688. if (parser.upgrade) {
  3689. upgrade_message_fix(total, read, 3, r1, r2, r3);
  3690. }
  3691. if (message_count != num_messages) {
  3692. fprintf(stderr, "\n\nParser didn't see %d messages only %d\n",
  3693. message_count, num_messages);
  3694. goto error;
  3695. }
  3696. if (!message_eq(0, 0, r1)) {
  3697. fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n");
  3698. goto error;
  3699. }
  3700. if (message_count > 1 && !message_eq(1, 0, r2)) {
  3701. fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n");
  3702. goto error;
  3703. }
  3704. if (message_count > 2 && !message_eq(2, 0, r3)) {
  3705. fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n");
  3706. goto error;
  3707. }
  3708. }
  3709. }
  3710. }
  3711. puts("\b\b\b\b100%");
  3712. return;
  3713. error:
  3714. fprintf(stderr, "i=%d j=%d\n", i, j);
  3715. fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1);
  3716. fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2);
  3717. fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3);
  3718. abort();
  3719. }
  3720. // user required to free the result
  3721. // string terminated by \0
  3722. char *
  3723. create_large_chunked_message (int body_size_in_kb, const char* headers)
  3724. {
  3725. int i;
  3726. size_t wrote = 0;
  3727. size_t headers_len = strlen(headers);
  3728. size_t bufsize = headers_len + (5+1024+2)*body_size_in_kb + 6;
  3729. char * buf = malloc(bufsize);
  3730. memcpy(buf, headers, headers_len);
  3731. wrote += headers_len;
  3732. for (i = 0; i < body_size_in_kb; i++) {
  3733. // write 1kb chunk into the body.
  3734. memcpy(buf + wrote, "400\r\n", 5);
  3735. wrote += 5;
  3736. memset(buf + wrote, 'C', 1024);
  3737. wrote += 1024;
  3738. strcpy(buf + wrote, "\r\n");
  3739. wrote += 2;
  3740. }
  3741. memcpy(buf + wrote, "0\r\n\r\n", 6);
  3742. wrote += 6;
  3743. assert(wrote == bufsize);
  3744. return buf;
  3745. }
  3746. /* Verify that we can pause parsing at any of the bytes in the
  3747. * message and still get the result that we're expecting. */
  3748. void
  3749. test_message_pause (const struct message *msg)
  3750. {
  3751. char *buf = (char*) msg->raw;
  3752. size_t buflen = strlen(msg->raw);
  3753. size_t nread;
  3754. parser_init(msg->type);
  3755. do {
  3756. nread = parse_pause(buf, buflen);
  3757. // We can only set the upgrade buffer once we've gotten our message
  3758. // completion callback.
  3759. if (messages[0].message_complete_cb_called &&
  3760. msg->upgrade &&
  3761. parser.upgrade) {
  3762. messages[0].upgrade = buf + nread;
  3763. goto test;
  3764. }
  3765. if (nread < buflen) {
  3766. // Not much do to if we failed a strict-mode check
  3767. if (HTTP_PARSER_ERRNO(&parser) == HPE_STRICT) {
  3768. return;
  3769. }
  3770. assert (HTTP_PARSER_ERRNO(&parser) == HPE_PAUSED);
  3771. }
  3772. buf += nread;
  3773. buflen -= nread;
  3774. http_parser_pause(&parser, 0);
  3775. } while (buflen > 0);
  3776. nread = parse_pause(NULL, 0);
  3777. assert (nread == 0);
  3778. test:
  3779. if (num_messages != 1) {
  3780. printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name);
  3781. abort();
  3782. }
  3783. if(!message_eq(0, 0, msg)) abort();
  3784. }
  3785. /* Verify that body and next message won't be parsed in responses to CONNECT */
  3786. void
  3787. test_message_connect (const struct message *msg)
  3788. {
  3789. char *buf = (char*) msg->raw;
  3790. size_t buflen = strlen(msg->raw);
  3791. parser_init(msg->type);
  3792. parse_connect(buf, buflen);
  3793. if (num_messages != 1) {
  3794. printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name);
  3795. abort();
  3796. }
  3797. if(!message_eq(0, 1, msg)) abort();
  3798. }
  3799. int
  3800. main (void)
  3801. {
  3802. unsigned i, j, k;
  3803. unsigned long version;
  3804. unsigned major;
  3805. unsigned minor;
  3806. unsigned patch;
  3807. version = http_parser_version();
  3808. major = (version >> 16) & 255;
  3809. minor = (version >> 8) & 255;
  3810. patch = version & 255;
  3811. printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version);
  3812. printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser));
  3813. //// API
  3814. test_preserve_data();
  3815. test_parse_url();
  3816. test_method_str();
  3817. test_status_str();
  3818. //// NREAD
  3819. test_header_nread_value();
  3820. //// OVERFLOW CONDITIONS
  3821. test_no_overflow_parse_url();
  3822. test_header_overflow_error(HTTP_REQUEST);
  3823. test_no_overflow_long_body(HTTP_REQUEST, 1000);
  3824. test_no_overflow_long_body(HTTP_REQUEST, 100000);
  3825. test_header_overflow_error(HTTP_RESPONSE);
  3826. test_no_overflow_long_body(HTTP_RESPONSE, 1000);
  3827. test_no_overflow_long_body(HTTP_RESPONSE, 100000);
  3828. test_header_content_length_overflow_error();
  3829. test_chunk_content_length_overflow_error();
  3830. //// HEADER FIELD CONDITIONS
  3831. test_double_content_length_error(HTTP_REQUEST);
  3832. test_chunked_content_length_error(HTTP_REQUEST);
  3833. test_header_cr_no_lf_error(HTTP_REQUEST);
  3834. test_invalid_header_field_token_error(HTTP_REQUEST);
  3835. test_invalid_header_field_content_error(HTTP_REQUEST);
  3836. test_double_content_length_error(HTTP_RESPONSE);
  3837. test_chunked_content_length_error(HTTP_RESPONSE);
  3838. test_header_cr_no_lf_error(HTTP_RESPONSE);
  3839. test_invalid_header_field_token_error(HTTP_RESPONSE);
  3840. test_invalid_header_field_content_error(HTTP_RESPONSE);
  3841. test_simple_type(
  3842. "POST / HTTP/1.1\r\n"
  3843. "Content-Length:\r\n" // empty
  3844. "\r\n",
  3845. HPE_INVALID_CONTENT_LENGTH,
  3846. HTTP_REQUEST);
  3847. test_simple_type(
  3848. "POST / HTTP/1.1\r\n"
  3849. "Content-Length: 42 \r\n" // Note the surrounding whitespace.
  3850. "\r\n",
  3851. HPE_OK,
  3852. HTTP_REQUEST);
  3853. test_simple_type(
  3854. "POST / HTTP/1.1\r\n"
  3855. "Content-Length: 4 2\r\n"
  3856. "\r\n",
  3857. HPE_INVALID_CONTENT_LENGTH,
  3858. HTTP_REQUEST);
  3859. test_simple_type(
  3860. "POST / HTTP/1.1\r\n"
  3861. "Content-Length: 13 37\r\n"
  3862. "\r\n",
  3863. HPE_INVALID_CONTENT_LENGTH,
  3864. HTTP_REQUEST);
  3865. test_simple_type(
  3866. "POST / HTTP/1.1\r\n"
  3867. "Content-Length: 42\r\n"
  3868. " Hello world!\r\n",
  3869. HPE_INVALID_CONTENT_LENGTH,
  3870. HTTP_REQUEST);
  3871. test_simple_type(
  3872. "POST / HTTP/1.1\r\n"
  3873. "Content-Length: 42\r\n"
  3874. " \r\n",
  3875. HPE_OK,
  3876. HTTP_REQUEST);
  3877. //// RESPONSES
  3878. test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
  3879. test_simple_type("HTTP/01.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
  3880. test_simple_type("HTTP/11.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
  3881. test_simple_type("HTTP/1.01 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
  3882. test_simple_type("HTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
  3883. test_simple_type("\rHTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
  3884. for (i = 0; i < ARRAY_SIZE(responses); i++) {
  3885. test_message(&responses[i]);
  3886. }
  3887. for (i = 0; i < ARRAY_SIZE(responses); i++) {
  3888. test_message_pause(&responses[i]);
  3889. }
  3890. for (i = 0; i < ARRAY_SIZE(responses); i++) {
  3891. test_message_connect(&responses[i]);
  3892. }
  3893. for (i = 0; i < ARRAY_SIZE(responses); i++) {
  3894. if (!responses[i].should_keep_alive) continue;
  3895. for (j = 0; j < ARRAY_SIZE(responses); j++) {
  3896. if (!responses[j].should_keep_alive) continue;
  3897. for (k = 0; k < ARRAY_SIZE(responses); k++) {
  3898. test_multiple3(&responses[i], &responses[j], &responses[k]);
  3899. }
  3900. }
  3901. }
  3902. test_message_count_body(&responses[NO_HEADERS_NO_BODY_404]);
  3903. test_message_count_body(&responses[TRAILING_SPACE_ON_CHUNKED_BODY]);
  3904. // test very large chunked response
  3905. {
  3906. char * msg = create_large_chunked_message(31337,
  3907. "HTTP/1.0 200 OK\r\n"
  3908. "Transfer-Encoding: chunked\r\n"
  3909. "Content-Type: text/plain\r\n"
  3910. "\r\n");
  3911. struct message large_chunked =
  3912. {.name= "large chunked"
  3913. ,.type= HTTP_RESPONSE
  3914. ,.raw= msg
  3915. ,.should_keep_alive= FALSE
  3916. ,.message_complete_on_eof= FALSE
  3917. ,.http_major= 1
  3918. ,.http_minor= 0
  3919. ,.status_code= 200
  3920. ,.response_status= "OK"
  3921. ,.num_headers= 2
  3922. ,.headers=
  3923. { { "Transfer-Encoding", "chunked" }
  3924. , { "Content-Type", "text/plain" }
  3925. }
  3926. ,.body_size= 31337*1024
  3927. ,.num_chunks_complete= 31338
  3928. };
  3929. for (i = 0; i < MAX_CHUNKS; i++) {
  3930. large_chunked.chunk_lengths[i] = 1024;
  3931. }
  3932. test_message_count_body(&large_chunked);
  3933. free(msg);
  3934. }
  3935. printf("response scan 1/2 ");
  3936. test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY]
  3937. , &responses[NO_BODY_HTTP10_KA_204]
  3938. , &responses[NO_REASON_PHRASE]
  3939. );
  3940. printf("response scan 2/2 ");
  3941. test_scan( &responses[BONJOUR_MADAME_FR]
  3942. , &responses[UNDERSTORE_HEADER_KEY]
  3943. , &responses[NO_CARRIAGE_RET]
  3944. );
  3945. puts("responses okay");
  3946. /// REQUESTS
  3947. test_simple("GET / IHTTP/1.0\r\n\r\n", HPE_INVALID_CONSTANT);
  3948. test_simple("GET / ICE/1.0\r\n\r\n", HPE_INVALID_CONSTANT);
  3949. test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION);
  3950. test_simple("GET / HTTP/01.1\r\n\r\n", HPE_INVALID_VERSION);
  3951. test_simple("GET / HTTP/11.1\r\n\r\n", HPE_INVALID_VERSION);
  3952. test_simple("GET / HTTP/1.01\r\n\r\n", HPE_INVALID_VERSION);
  3953. test_simple("GET / HTTP/1.0\r\nHello: w\1rld\r\n\r\n", HPE_INVALID_HEADER_TOKEN);
  3954. test_simple("GET / HTTP/1.0\r\nHello: woooo\2rld\r\n\r\n", HPE_INVALID_HEADER_TOKEN);
  3955. // Extended characters - see nodejs/test/parallel/test-http-headers-obstext.js
  3956. test_simple("GET / HTTP/1.1\r\n"
  3957. "Test: Düsseldorf\r\n",
  3958. HPE_OK);
  3959. // Well-formed but incomplete
  3960. test_simple("GET / HTTP/1.1\r\n"
  3961. "Content-Type: text/plain\r\n"
  3962. "Content-Length: 6\r\n"
  3963. "\r\n"
  3964. "fooba",
  3965. HPE_OK);
  3966. // Unknown Transfer-Encoding in request
  3967. test_simple("GET / HTTP/1.1\r\n"
  3968. "Transfer-Encoding: unknown\r\n"
  3969. "\r\n",
  3970. HPE_INVALID_TRANSFER_ENCODING);
  3971. static const char *all_methods[] = {
  3972. "DELETE",
  3973. "GET",
  3974. "HEAD",
  3975. "POST",
  3976. "PUT",
  3977. //"CONNECT", //CONNECT can't be tested like other methods, it's a tunnel
  3978. "OPTIONS",
  3979. "TRACE",
  3980. "COPY",
  3981. "LOCK",
  3982. "MKCOL",
  3983. "MOVE",
  3984. "PROPFIND",
  3985. "PROPPATCH",
  3986. "SEARCH",
  3987. "UNLOCK",
  3988. "BIND",
  3989. "REBIND",
  3990. "UNBIND",
  3991. "ACL",
  3992. "REPORT",
  3993. "MKACTIVITY",
  3994. "CHECKOUT",
  3995. "MERGE",
  3996. "M-SEARCH",
  3997. "NOTIFY",
  3998. "SUBSCRIBE",
  3999. "UNSUBSCRIBE",
  4000. "PATCH",
  4001. "PURGE",
  4002. "MKCALENDAR",
  4003. "LINK",
  4004. "UNLINK",
  4005. 0 };
  4006. const char **this_method;
  4007. for (this_method = all_methods; *this_method; this_method++) {
  4008. char buf[200];
  4009. sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method);
  4010. test_simple(buf, HPE_OK);
  4011. }
  4012. static const char *bad_methods[] = {
  4013. "ASDF",
  4014. "C******",
  4015. "COLA",
  4016. "GEM",
  4017. "GETA",
  4018. "M****",
  4019. "MKCOLA",
  4020. "PROPPATCHA",
  4021. "PUN",
  4022. "PX",
  4023. "SA",
  4024. "hello world",
  4025. 0 };
  4026. for (this_method = bad_methods; *this_method; this_method++) {
  4027. char buf[200];
  4028. sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method);
  4029. test_simple(buf, HPE_INVALID_METHOD);
  4030. }
  4031. // illegal header field name line folding
  4032. test_simple("GET / HTTP/1.1\r\n"
  4033. "name\r\n"
  4034. " : value\r\n"
  4035. "\r\n",
  4036. HPE_INVALID_HEADER_TOKEN);
  4037. const char *dumbluck2 =
  4038. "GET / HTTP/1.1\r\n"
  4039. "X-SSL-Nonsense: -----BEGIN CERTIFICATE-----\r\n"
  4040. "\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n"
  4041. "\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n"
  4042. "\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n"
  4043. "\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n"
  4044. "\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n"
  4045. "\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n"
  4046. "\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n"
  4047. "\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n"
  4048. "\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n"
  4049. "\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n"
  4050. "\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n"
  4051. "\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n"
  4052. "\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgHTTPAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n"
  4053. "\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n"
  4054. "\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n"
  4055. "\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n"
  4056. "\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n"
  4057. "\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n"
  4058. "\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n"
  4059. "\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n"
  4060. "\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n"
  4061. "\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n"
  4062. "\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n"
  4063. "\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n"
  4064. "\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n"
  4065. "\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n"
  4066. "\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n"
  4067. "\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n"
  4068. "\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n"
  4069. "\tRA==\r\n"
  4070. "\t-----END CERTIFICATE-----\r\n"
  4071. "\r\n";
  4072. test_simple(dumbluck2, HPE_OK);
  4073. const char *corrupted_connection =
  4074. "GET / HTTP/1.1\r\n"
  4075. "Host: www.example.com\r\n"
  4076. "Connection\r\033\065\325eep-Alive\r\n"
  4077. "Accept-Encoding: gzip\r\n"
  4078. "\r\n";
  4079. test_simple(corrupted_connection, HPE_INVALID_HEADER_TOKEN);
  4080. const char *corrupted_header_name =
  4081. "GET / HTTP/1.1\r\n"
  4082. "Host: www.example.com\r\n"
  4083. "X-Some-Header\r\033\065\325eep-Alive\r\n"
  4084. "Accept-Encoding: gzip\r\n"
  4085. "\r\n";
  4086. test_simple(corrupted_header_name, HPE_INVALID_HEADER_TOKEN);
  4087. #if 0
  4088. // NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body
  4089. // until EOF.
  4090. //
  4091. // no content-length
  4092. // error if there is a body without content length
  4093. const char *bad_get_no_headers_no_body = "GET /bad_get_no_headers_no_body/world HTTP/1.1\r\n"
  4094. "Accept: */*\r\n"
  4095. "\r\n"
  4096. "HELLO";
  4097. test_simple(bad_get_no_headers_no_body, 0);
  4098. #endif
  4099. /* TODO sending junk and large headers gets rejected */
  4100. /* check to make sure our predefined requests are okay */
  4101. for (i = 0; i < ARRAY_SIZE(requests); i++) {
  4102. test_message(&requests[i]);
  4103. }
  4104. for (i = 0; i < ARRAY_SIZE(requests); i++) {
  4105. test_message_pause(&requests[i]);
  4106. }
  4107. for (i = 0; i < ARRAY_SIZE(requests); i++) {
  4108. if (!requests[i].should_keep_alive) continue;
  4109. for (j = 0; j < ARRAY_SIZE(requests); j++) {
  4110. if (!requests[j].should_keep_alive) continue;
  4111. for (k = 0; k < ARRAY_SIZE(requests); k++) {
  4112. test_multiple3(&requests[i], &requests[j], &requests[k]);
  4113. }
  4114. }
  4115. }
  4116. printf("request scan 1/4 ");
  4117. test_scan( &requests[GET_NO_HEADERS_NO_BODY]
  4118. , &requests[GET_ONE_HEADER_NO_BODY]
  4119. , &requests[GET_NO_HEADERS_NO_BODY]
  4120. );
  4121. printf("request scan 2/4 ");
  4122. test_scan( &requests[POST_CHUNKED_ALL_YOUR_BASE]
  4123. , &requests[POST_IDENTITY_BODY_WORLD]
  4124. , &requests[GET_FUNKY_CONTENT_LENGTH]
  4125. );
  4126. printf("request scan 3/4 ");
  4127. test_scan( &requests[TWO_CHUNKS_MULT_ZERO_END]
  4128. , &requests[CHUNKED_W_TRAILING_HEADERS]
  4129. , &requests[CHUNKED_W_NONSENSE_AFTER_LENGTH]
  4130. );
  4131. printf("request scan 4/4 ");
  4132. test_scan( &requests[QUERY_URL_WITH_QUESTION_MARK_GET]
  4133. , &requests[PREFIX_NEWLINE_GET ]
  4134. , &requests[CONNECT_REQUEST]
  4135. );
  4136. puts("requests okay");
  4137. return 0;
  4138. }