test.c 115 KB

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