crow_all.h 434 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796
  1. // SPDX-License-Identifier: BSD-3-Clause AND ISC AND MIT
  2. /*BSD 3-Clause License
  3. Copyright (c) 2014-2017, ipkn
  4. 2020-2026, CrowCpp
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without
  7. modification, are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice, this
  9. list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice,
  11. this list of conditions and the following disclaimer in the documentation
  12. and/or other materials provided with the distribution.
  13. * Neither the name of the author nor the names of its
  14. contributors may be used to endorse or promote products derived from
  15. this software without specific prior written permission.
  16. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  20. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  24. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. The Crow logo and other graphic material (excluding third party logos) used are
  27. under exclusive Copyright (c) 2021-2022, Farook Al-Sammarraie (The-EDev), All
  28. rights reserved.
  29. */
  30. #pragma once
  31. #ifdef CROW_ENABLE_COMPRESSION
  32. #include <string>
  33. #include <zlib.h>
  34. // http://zlib.net/manual.html
  35. namespace crow // NOTE: Already documented in "crow/app.h"
  36. {
  37. namespace compression {
  38. // Values used in the 'windowBits' parameter for deflateInit2.
  39. enum algorithm {
  40. // 15 is the default value for deflate
  41. DEFLATE = 15,
  42. // windowBits can also be greater than 15 for optional gzip encoding.
  43. // Add 16 to windowBits to write a simple gzip header and trailer around the
  44. // compressed data instead of a zlib wrapper.
  45. GZIP = 15 | 16,
  46. };
  47. inline std::string compress_string(std::string const &str, algorithm algo) {
  48. std::string compressed_str;
  49. z_stream stream{};
  50. // Initialize with the default values
  51. if (::deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, algo, 8,
  52. Z_DEFAULT_STRATEGY) == Z_OK) {
  53. char buffer[8192];
  54. stream.avail_in = str.size();
  55. // zlib does not take a const pointer. The data is not altered.
  56. stream.next_in =
  57. const_cast<Bytef *>(reinterpret_cast<const Bytef *>(str.c_str()));
  58. int code = Z_OK;
  59. do {
  60. stream.avail_out = sizeof(buffer);
  61. stream.next_out = reinterpret_cast<Bytef *>(&buffer[0]);
  62. code = ::deflate(&stream, Z_FINISH);
  63. // Successful and non-fatal error code returned by deflate when used with
  64. // Z_FINISH flush
  65. if (code == Z_OK || code == Z_STREAM_END) {
  66. std::copy(&buffer[0], &buffer[sizeof(buffer) - stream.avail_out],
  67. std::back_inserter(compressed_str));
  68. }
  69. } while (code == Z_OK);
  70. if (code != Z_STREAM_END) compressed_str.clear();
  71. ::deflateEnd(&stream);
  72. }
  73. return compressed_str;
  74. }
  75. inline std::string decompress_string(std::string const &deflated_string) {
  76. std::string inflated_string;
  77. Bytef tmp[8192];
  78. z_stream zstream{};
  79. zstream.avail_in = deflated_string.size();
  80. // Nasty const_cast but zlib won't alter its contents
  81. zstream.next_in = const_cast<Bytef *>(
  82. reinterpret_cast<Bytef const *>(deflated_string.c_str()));
  83. // Initialize with automatic header detection, for gzip support
  84. if (::inflateInit2(&zstream, MAX_WBITS | 32) == Z_OK) {
  85. do {
  86. zstream.avail_out = sizeof(tmp);
  87. zstream.next_out = &tmp[0];
  88. auto ret = ::inflate(&zstream, Z_NO_FLUSH);
  89. if (ret == Z_OK || ret == Z_STREAM_END) {
  90. std::copy(&tmp[0], &tmp[sizeof(tmp) - zstream.avail_out],
  91. std::back_inserter(inflated_string));
  92. } else {
  93. // Something went wrong with inflate; make sure we return an empty
  94. // string
  95. inflated_string.clear();
  96. break;
  97. }
  98. } while (zstream.avail_out == 0);
  99. // Free zlib's internal memory
  100. ::inflateEnd(&zstream);
  101. }
  102. return inflated_string;
  103. }
  104. } // namespace compression
  105. } // namespace crow
  106. #endif
  107. namespace crow {
  108. constexpr const char VERSION[] = "master";
  109. }
  110. /*
  111. * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1
  112. *
  113. * Copyright (c) 2012-22 SAURAV MOHAPATRA <mohaps@gmail.com>
  114. *
  115. * Permission to use, copy, modify, and distribute this software for any
  116. * purpose with or without fee is hereby granted, provided that the above
  117. * copyright notice and this permission notice appear in all copies.
  118. *
  119. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  120. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  121. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  122. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  123. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  124. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  125. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  126. */
  127. /**
  128. * \file TinySHA1.hpp
  129. * \author SAURAV MOHAPATRA <mohaps@gmail.com>
  130. * \date 2012-22
  131. * \brief TinySHA1 - a header only implementation of the SHA1 algorithm in C++.
  132. * Based on the implementation in boost::uuid::details.
  133. *
  134. * In this file are defined:
  135. * - sha1::SHA1
  136. */
  137. #ifndef _TINY_SHA1_HPP_
  138. #define _TINY_SHA1_HPP_
  139. #include <cstdio>
  140. #include <cstdlib>
  141. #include <cstring>
  142. #include <stdint.h>
  143. /**
  144. * \namespace sha1
  145. * \brief Here is defined the SHA1 class
  146. */
  147. namespace sha1 {
  148. /**
  149. * \class SHA1
  150. * \brief A tiny SHA1 algorithm implementation used internally in the
  151. * Crow server (specifically in crow/websocket.h).
  152. */
  153. class SHA1 {
  154. public:
  155. typedef uint32_t digest32_t[5];
  156. typedef uint8_t digest8_t[20];
  157. inline static uint32_t LeftRotate(uint32_t value, size_t count) {
  158. return (value << count) ^ (value >> (32 - count));
  159. }
  160. SHA1() { reset(); }
  161. virtual ~SHA1() {}
  162. SHA1(const SHA1 &s) { *this = s; }
  163. const SHA1 &operator=(const SHA1 &s) {
  164. memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
  165. memcpy(m_block, s.m_block, 64);
  166. m_blockByteIndex = s.m_blockByteIndex;
  167. m_byteCount = s.m_byteCount;
  168. return *this;
  169. }
  170. SHA1 &reset() {
  171. m_digest[0] = 0x67452301;
  172. m_digest[1] = 0xEFCDAB89;
  173. m_digest[2] = 0x98BADCFE;
  174. m_digest[3] = 0x10325476;
  175. m_digest[4] = 0xC3D2E1F0;
  176. m_blockByteIndex = 0;
  177. m_byteCount = 0;
  178. return *this;
  179. }
  180. SHA1 &processByte(uint8_t octet) {
  181. this->m_block[this->m_blockByteIndex++] = octet;
  182. ++this->m_byteCount;
  183. if (m_blockByteIndex == 64) {
  184. this->m_blockByteIndex = 0;
  185. processBlock();
  186. }
  187. return *this;
  188. }
  189. SHA1 &processBlock(const void *const start, const void *const end) {
  190. const uint8_t *begin = static_cast<const uint8_t *>(start);
  191. const uint8_t *finish = static_cast<const uint8_t *>(end);
  192. while (begin != finish) {
  193. processByte(*begin);
  194. begin++;
  195. }
  196. return *this;
  197. }
  198. SHA1 &processBytes(const void *const data, size_t len) {
  199. const uint8_t *block = static_cast<const uint8_t *>(data);
  200. processBlock(block, block + len);
  201. return *this;
  202. }
  203. const uint32_t *getDigest(digest32_t digest) {
  204. size_t bitCount = this->m_byteCount * 8;
  205. processByte(0x80);
  206. if (this->m_blockByteIndex > 56) {
  207. while (m_blockByteIndex != 0) {
  208. processByte(0);
  209. }
  210. while (m_blockByteIndex < 56) {
  211. processByte(0);
  212. }
  213. } else {
  214. while (m_blockByteIndex < 56) {
  215. processByte(0);
  216. }
  217. }
  218. processByte(0);
  219. processByte(0);
  220. processByte(0);
  221. processByte(0);
  222. processByte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
  223. processByte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
  224. processByte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
  225. processByte(static_cast<unsigned char>((bitCount) & 0xFF));
  226. memcpy(digest, m_digest, 5 * sizeof(uint32_t));
  227. return digest;
  228. }
  229. const uint8_t *getDigestBytes(digest8_t digest) {
  230. digest32_t d32;
  231. getDigest(d32);
  232. size_t di = 0;
  233. digest[di++] = ((d32[0] >> 24) & 0xFF);
  234. digest[di++] = ((d32[0] >> 16) & 0xFF);
  235. digest[di++] = ((d32[0] >> 8) & 0xFF);
  236. digest[di++] = ((d32[0]) & 0xFF);
  237. digest[di++] = ((d32[1] >> 24) & 0xFF);
  238. digest[di++] = ((d32[1] >> 16) & 0xFF);
  239. digest[di++] = ((d32[1] >> 8) & 0xFF);
  240. digest[di++] = ((d32[1]) & 0xFF);
  241. digest[di++] = ((d32[2] >> 24) & 0xFF);
  242. digest[di++] = ((d32[2] >> 16) & 0xFF);
  243. digest[di++] = ((d32[2] >> 8) & 0xFF);
  244. digest[di++] = ((d32[2]) & 0xFF);
  245. digest[di++] = ((d32[3] >> 24) & 0xFF);
  246. digest[di++] = ((d32[3] >> 16) & 0xFF);
  247. digest[di++] = ((d32[3] >> 8) & 0xFF);
  248. digest[di++] = ((d32[3]) & 0xFF);
  249. digest[di++] = ((d32[4] >> 24) & 0xFF);
  250. digest[di++] = ((d32[4] >> 16) & 0xFF);
  251. digest[di++] = ((d32[4] >> 8) & 0xFF);
  252. digest[di++] = ((d32[4]) & 0xFF);
  253. return digest;
  254. }
  255. protected:
  256. void processBlock() {
  257. uint32_t w[80];
  258. for (size_t i = 0; i < 16; i++) {
  259. w[i] = (m_block[i * 4 + 0] << 24);
  260. w[i] |= (m_block[i * 4 + 1] << 16);
  261. w[i] |= (m_block[i * 4 + 2] << 8);
  262. w[i] |= (m_block[i * 4 + 3]);
  263. }
  264. for (size_t i = 16; i < 80; i++) {
  265. w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
  266. }
  267. uint32_t a = m_digest[0];
  268. uint32_t b = m_digest[1];
  269. uint32_t c = m_digest[2];
  270. uint32_t d = m_digest[3];
  271. uint32_t e = m_digest[4];
  272. for (std::size_t i = 0; i < 80; ++i) {
  273. uint32_t f = 0;
  274. uint32_t k = 0;
  275. if (i < 20) {
  276. f = (b & c) | (~b & d);
  277. k = 0x5A827999;
  278. } else if (i < 40) {
  279. f = b ^ c ^ d;
  280. k = 0x6ED9EBA1;
  281. } else if (i < 60) {
  282. f = (b & c) | (b & d) | (c & d);
  283. k = 0x8F1BBCDC;
  284. } else {
  285. f = b ^ c ^ d;
  286. k = 0xCA62C1D6;
  287. }
  288. uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
  289. e = d;
  290. d = c;
  291. c = LeftRotate(b, 30);
  292. b = a;
  293. a = temp;
  294. }
  295. m_digest[0] += a;
  296. m_digest[1] += b;
  297. m_digest[2] += c;
  298. m_digest[3] += d;
  299. m_digest[4] += e;
  300. }
  301. private:
  302. digest32_t m_digest;
  303. uint8_t m_block[64];
  304. size_t m_blockByteIndex;
  305. size_t m_byteCount;
  306. };
  307. } // namespace sha1
  308. #endif
  309. #include <iostream>
  310. #include <memory>
  311. #include <stdio.h>
  312. #include <string.h>
  313. #include <string>
  314. #include <unordered_map>
  315. #include <vector>
  316. namespace crow {
  317. // ----------------------------------------------------------------------------
  318. // qs_parse (modified)
  319. // https://github.com/bartgrantham/qs_parse
  320. // ----------------------------------------------------------------------------
  321. /* Similar to strncmp, but handles URL-encoding for either string */
  322. int qs_strncmp(const char *s, const char *qs, size_t n);
  323. /* Finds the beginning of each key/value pair and stores a pointer in qs_kv.
  324. * Also decodes the value portion of the k/v pair *in-place*. In a future
  325. * enhancement it will also have a compile-time option of sorting qs_kv
  326. * alphabetically by key. */
  327. size_t qs_parse(char *qs, char *qs_kv[], size_t qs_kv_size, bool parse_url);
  328. /* Used by qs_parse to decode the value portion of a k/v pair */
  329. int qs_decode(char *qs);
  330. /* Looks up the value according to the key on a pre-processed query string
  331. * A future enhancement will be a compile-time option to look up the key
  332. * in a pre-sorted qs_kv array via a binary search. */
  333. // char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size);
  334. char *qs_k2v(const char *key, char *const *qs_kv, size_t qs_kv_size, int nth);
  335. /* Non-destructive lookup of value, based on key. User provides the
  336. * destinaton string and length. */
  337. char *qs_scanvalue(const char *key, const char *qs, char *val, size_t val_len);
  338. // TODO: implement sorting of the qs_kv array; for now ensure it's not compiled
  339. #undef _qsSORTING
  340. // isxdigit _is_ available in <ctype.h>, but let's avoid another header instead
  341. #define CROW_QS_ISHEX(x) \
  342. ((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') || \
  343. ((x) >= 'a' && (x) <= 'f')) \
  344. ? 1 \
  345. : 0)
  346. #define CROW_QS_HEX2DEC(x) \
  347. (((x) >= '0' && (x) <= '9') ? (x) - 48 \
  348. : ((x) >= 'A' && (x) <= 'F') ? (x) - 55 \
  349. : ((x) >= 'a' && (x) <= 'f') ? (x) - 87 \
  350. : 0)
  351. #define CROW_QS_ISQSCHR(x) \
  352. ((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1)
  353. inline int qs_strncmp(const char *s, const char *qs, size_t n) {
  354. unsigned char u1, u2, unyb, lnyb;
  355. while (n-- > 0) {
  356. u1 = static_cast<unsigned char>(*s++);
  357. u2 = static_cast<unsigned char>(*qs++);
  358. if (!CROW_QS_ISQSCHR(u1)) { u1 = '\0'; }
  359. if (!CROW_QS_ISQSCHR(u2)) { u2 = '\0'; }
  360. if (u1 == '+') { u1 = ' '; }
  361. if (u1 == '%') // easier/safer than scanf
  362. {
  363. unyb = static_cast<unsigned char>(*s++);
  364. lnyb = static_cast<unsigned char>(*s++);
  365. if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb))
  366. u1 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb);
  367. else
  368. u1 = '\0';
  369. }
  370. if (u2 == '+') { u2 = ' '; }
  371. if (u2 == '%') // easier/safer than scanf
  372. {
  373. unyb = static_cast<unsigned char>(*qs++);
  374. lnyb = static_cast<unsigned char>(*qs++);
  375. if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb))
  376. u2 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb);
  377. else
  378. u2 = '\0';
  379. }
  380. if (u1 != u2) return u1 - u2;
  381. if (u1 == '\0') return 0;
  382. }
  383. if (CROW_QS_ISQSCHR(*qs))
  384. return -1;
  385. else
  386. return 0;
  387. }
  388. inline size_t qs_parse(char *qs, char *qs_kv[], size_t qs_kv_size,
  389. bool parse_url = true) {
  390. size_t i, j;
  391. char *substr_ptr;
  392. for (i = 0; i < qs_kv_size; i++)
  393. qs_kv[i] = NULL;
  394. // find the beginning of the k/v substrings or the fragment
  395. substr_ptr = parse_url ? qs + strcspn(qs, "?#") : qs;
  396. if (parse_url) {
  397. if (substr_ptr[0] != '\0')
  398. substr_ptr++;
  399. else
  400. return 0; // no query or fragment
  401. }
  402. i = 0;
  403. while (i < qs_kv_size) {
  404. qs_kv[i] = substr_ptr;
  405. j = strcspn(substr_ptr, "&");
  406. if (substr_ptr[j] == '\0') {
  407. i++;
  408. break;
  409. } // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
  410. substr_ptr += j + 1;
  411. i++;
  412. }
  413. // we only decode the values in place, the keys could have '='s in them
  414. // which will hose our ability to distinguish keys from values later
  415. for (j = 0; j < i; j++) {
  416. substr_ptr = qs_kv[j] + strcspn(qs_kv[j], "=&#");
  417. if (substr_ptr[0] == '&' ||
  418. substr_ptr[0] == '\0') // blank value: skip decoding
  419. substr_ptr[0] = '\0';
  420. else
  421. qs_decode(++substr_ptr);
  422. }
  423. #ifdef _qsSORTING
  424. // TODO: qsort qs_kv, using qs_strncmp() for the comparison
  425. #endif
  426. return i;
  427. }
  428. inline int qs_decode(char *qs) {
  429. int i = 0, j = 0;
  430. while (CROW_QS_ISQSCHR(qs[j])) {
  431. if (qs[j] == '+') {
  432. qs[i] = ' ';
  433. } else if (qs[j] == '%') // easier/safer than scanf
  434. {
  435. if (!CROW_QS_ISHEX(qs[j + 1]) || !CROW_QS_ISHEX(qs[j + 2])) {
  436. qs[i] = '\0';
  437. return i;
  438. }
  439. qs[i] = (CROW_QS_HEX2DEC(qs[j + 1]) * 16) + CROW_QS_HEX2DEC(qs[j + 2]);
  440. j += 2;
  441. } else {
  442. qs[i] = qs[j];
  443. }
  444. i++;
  445. j++;
  446. }
  447. qs[i] = '\0';
  448. return i;
  449. }
  450. inline char *qs_k2v(const char *key, char *const *qs_kv, size_t qs_kv_size,
  451. int nth = 0) {
  452. size_t i;
  453. size_t key_len, skip;
  454. key_len = strlen(key);
  455. #ifdef _qsSORTING
  456. // TODO: binary search for key in the sorted qs_kv
  457. #else // _qsSORTING
  458. for (i = 0; i < qs_kv_size; i++) {
  459. // we rely on the unambiguous '=' to find the value in our k/v pair
  460. if (qs_strncmp(key, qs_kv[i], key_len) == 0) {
  461. skip = strcspn(qs_kv[i], "=");
  462. if (qs_kv[i][skip] == '=') skip++;
  463. // return (zero-char value) ? ptr to trailing '\0' : ptr to value
  464. if (nth == 0)
  465. return qs_kv[i] + skip;
  466. else
  467. --nth;
  468. }
  469. }
  470. #endif // _qsSORTING
  471. return nullptr;
  472. }
  473. inline std::unique_ptr<std::pair<std::string, std::string>>
  474. qs_dict_name2kv(const char *dict_name, char *const *qs_kv, size_t qs_kv_size,
  475. int nth = 0) {
  476. size_t i;
  477. size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close;
  478. name_len = strlen(dict_name);
  479. #ifdef _qsSORTING
  480. // TODO: binary search for key in the sorted qs_kv
  481. #else // _qsSORTING
  482. for (i = 0; i < qs_kv_size; i++) {
  483. if (strncmp(dict_name, qs_kv[i], name_len) == 0) {
  484. skip_to_eq = strcspn(qs_kv[i], "=");
  485. if (qs_kv[i][skip_to_eq] == '=') skip_to_eq++;
  486. skip_to_brace_open = strcspn(qs_kv[i], "[");
  487. if (qs_kv[i][skip_to_brace_open] == '[') skip_to_brace_open++;
  488. skip_to_brace_close = strcspn(qs_kv[i], "]");
  489. if (skip_to_brace_open <= skip_to_brace_close && skip_to_brace_open > 0 &&
  490. skip_to_brace_close > 0 && nth == 0) {
  491. auto key = std::string(qs_kv[i] + skip_to_brace_open,
  492. skip_to_brace_close - skip_to_brace_open);
  493. auto value = std::string(qs_kv[i] + skip_to_eq);
  494. return std::unique_ptr<std::pair<std::string, std::string>>(
  495. new std::pair<std::string, std::string>(key, value));
  496. } else {
  497. --nth;
  498. }
  499. }
  500. }
  501. #endif // _qsSORTING
  502. return nullptr;
  503. }
  504. inline char *qs_scanvalue(const char *key, const char *qs, char *val,
  505. size_t val_len) {
  506. const char *tmp = strchr(qs, '?');
  507. // find the beginning of the k/v substrings
  508. if (tmp != nullptr) qs = tmp + 1;
  509. const size_t key_len = strlen(key);
  510. while (*qs != '#' && *qs != '\0') {
  511. if (qs_strncmp(key, qs, key_len) == 0) break;
  512. qs += strcspn(qs, "&");
  513. if (*qs == '&') qs++;
  514. }
  515. if (qs[0] == '\0') return nullptr;
  516. qs += strcspn(qs, "=&#");
  517. if (qs[0] == '=') {
  518. qs++;
  519. size_t i = strcspn(qs, "&=#");
  520. #ifdef _MSC_VER
  521. strncpy_s(val, val_len, qs,
  522. (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
  523. #else
  524. strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
  525. #endif
  526. qs_decode(val);
  527. } else {
  528. if (val_len > 0) val[0] = '\0';
  529. }
  530. return val;
  531. }
  532. } // namespace crow
  533. // ----------------------------------------------------------------------------
  534. namespace crow {
  535. struct request;
  536. /// A class to represent any data coming after the `?` in the request URL into
  537. /// key-value pairs.
  538. class query_string {
  539. public:
  540. static const int MAX_KEY_VALUE_PAIRS_COUNT = 256;
  541. query_string() = default;
  542. query_string(const query_string &qs) : url_(qs.url_) {
  543. for (auto p : qs.key_value_pairs_) {
  544. key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str()));
  545. }
  546. }
  547. query_string &operator=(const query_string &qs) {
  548. url_ = qs.url_;
  549. key_value_pairs_.clear();
  550. for (auto p : qs.key_value_pairs_) {
  551. key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str()));
  552. }
  553. return *this;
  554. }
  555. query_string &operator=(query_string &&qs) noexcept {
  556. key_value_pairs_ = std::move(qs.key_value_pairs_);
  557. char *old_data = (char *)qs.url_.c_str();
  558. url_ = std::move(qs.url_);
  559. for (auto &p : key_value_pairs_) {
  560. p += (char *)url_.c_str() - old_data;
  561. }
  562. return *this;
  563. }
  564. query_string(std::string params, bool url = true) : url_(std::move(params)) {
  565. if (url_.empty()) return;
  566. key_value_pairs_.resize(MAX_KEY_VALUE_PAIRS_COUNT);
  567. size_t count = qs_parse(&url_[0], &key_value_pairs_[0],
  568. MAX_KEY_VALUE_PAIRS_COUNT, url);
  569. key_value_pairs_.resize(count);
  570. key_value_pairs_.shrink_to_fit();
  571. }
  572. void clear() {
  573. key_value_pairs_.clear();
  574. url_.clear();
  575. }
  576. friend std::ostream &operator<<(std::ostream &os, const query_string &qs) {
  577. os << "[ ";
  578. for (size_t i = 0; i < qs.key_value_pairs_.size(); ++i) {
  579. if (i) os << ", ";
  580. os << qs.key_value_pairs_[i];
  581. }
  582. os << " ]";
  583. return os;
  584. }
  585. /// Get a value from a name, used for `?name=value`.
  586. ///
  587. /// Note: this method returns the value of the first occurrence of the key
  588. /// only, to return all occurrences, see \ref get_list().
  589. char *get(const std::string &name) const {
  590. char *ret =
  591. qs_k2v(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size());
  592. return ret;
  593. }
  594. /// Works similar to \ref get() except it removes the item from the query
  595. /// string.
  596. char *pop(const std::string &name) {
  597. char *ret = get(name);
  598. if (ret != nullptr) {
  599. const std::string key_name = name + '=';
  600. for (unsigned int i = 0; i < key_value_pairs_.size(); i++) {
  601. std::string str_item(key_value_pairs_[i]);
  602. if (str_item.find(key_name) == 0) {
  603. key_value_pairs_.erase(key_value_pairs_.begin() + i);
  604. break;
  605. }
  606. }
  607. }
  608. return ret;
  609. }
  610. /// Returns a list of values, passed as
  611. /// `?name[]=value1&name[]=value2&...name[]=valuen` with n being the size of
  612. /// the list.
  613. ///
  614. /// Note: Square brackets in the above example are controlled by
  615. /// `use_brackets` boolean (true by default). If set to false, the example
  616. /// becomes `?name=value1,name=value2...name=valuen`
  617. std::vector<char *> get_list(const std::string &name,
  618. bool use_brackets = true) const {
  619. std::vector<char *> ret;
  620. std::string plus = name + (use_brackets ? "[]" : "");
  621. char *element = nullptr;
  622. int count = 0;
  623. while (1) {
  624. element = qs_k2v(plus.c_str(), key_value_pairs_.data(),
  625. key_value_pairs_.size(), count++);
  626. if (!element) break;
  627. ret.push_back(element);
  628. }
  629. return ret;
  630. }
  631. /// Similar to \ref get_list() but it removes the
  632. std::vector<char *> pop_list(const std::string &name,
  633. bool use_brackets = true) {
  634. std::vector<char *> ret = get_list(name, use_brackets);
  635. const size_t name_len = name.length();
  636. if (!ret.empty()) {
  637. for (unsigned int i = 0; i < key_value_pairs_.size(); i++) {
  638. std::string str_item(key_value_pairs_[i]);
  639. if (str_item.find(name) == 0) {
  640. if (use_brackets && str_item.find("[]=", name_len) == name_len) {
  641. key_value_pairs_.erase(key_value_pairs_.begin() + i--);
  642. } else if (!use_brackets &&
  643. str_item.find('=', name_len) == name_len) {
  644. key_value_pairs_.erase(key_value_pairs_.begin() + i--);
  645. }
  646. }
  647. }
  648. }
  649. return ret;
  650. }
  651. /// Works similar to \ref get_list() except the brackets are mandatory must
  652. /// not be empty.
  653. ///
  654. /// For example calling `get_dict(yourname)` on
  655. /// `?yourname[sub1]=42&yourname[sub2]=84` would give a map containing `{sub1
  656. /// : 42, sub2 : 84}`.
  657. ///
  658. /// if your query string has both empty brackets and ones with a key inside,
  659. /// use pop_list() to get all the values without a key before running this
  660. /// method.
  661. std::unordered_map<std::string, std::string>
  662. get_dict(const std::string &name) const {
  663. std::unordered_map<std::string, std::string> ret;
  664. int count = 0;
  665. while (1) {
  666. if (auto element = qs_dict_name2kv(name.c_str(), key_value_pairs_.data(),
  667. key_value_pairs_.size(), count++))
  668. ret.insert(*element);
  669. else
  670. break;
  671. }
  672. return ret;
  673. }
  674. /// Works the same as \ref get_dict() but removes the values from the query
  675. /// string.
  676. std::unordered_map<std::string, std::string>
  677. pop_dict(const std::string &name) {
  678. const std::string name_value = name + '[';
  679. std::unordered_map<std::string, std::string> ret = get_dict(name);
  680. if (!ret.empty()) {
  681. for (unsigned int i = 0; i < key_value_pairs_.size(); i++) {
  682. std::string str_item(key_value_pairs_[i]);
  683. if (str_item.find(name_value) == 0) {
  684. key_value_pairs_.erase(key_value_pairs_.begin() + i--);
  685. }
  686. }
  687. }
  688. return ret;
  689. }
  690. std::vector<std::string> keys() const {
  691. std::vector<std::string> keys;
  692. keys.reserve(key_value_pairs_.size());
  693. for (const char *const element : key_value_pairs_) {
  694. const char *delimiter = strchr(element, '=');
  695. if (delimiter)
  696. keys.emplace_back(element, delimiter);
  697. else
  698. keys.emplace_back(element);
  699. }
  700. return keys;
  701. }
  702. private:
  703. std::string url_;
  704. std::vector<char *> key_value_pairs_;
  705. };
  706. } // namespace crow
  707. // This file is generated from nginx/conf/mime.types using nginx_mime2cpp.py on
  708. // 2021-12-03.
  709. #include <string>
  710. #include <unordered_map>
  711. namespace crow {
  712. const std::unordered_map<std::string, std::string> mime_types{
  713. {"gz", "application/gzip"},
  714. {"shtml", "text/html"},
  715. {"htm", "text/html"},
  716. {"html", "text/html"},
  717. {"css", "text/css"},
  718. {"xml", "text/xml"},
  719. {"gif", "image/gif"},
  720. {"jpg", "image/jpeg"},
  721. {"jpeg", "image/jpeg"},
  722. {"js", "application/javascript"},
  723. {"atom", "application/atom+xml"},
  724. {"rss", "application/rss+xml"},
  725. {"mml", "text/mathml"},
  726. {"txt", "text/plain"},
  727. {"jad", "text/vnd.sun.j2me.app-descriptor"},
  728. {"wml", "text/vnd.wap.wml"},
  729. {"htc", "text/x-component"},
  730. {"avif", "image/avif"},
  731. {"png", "image/png"},
  732. {"svgz", "image/svg+xml"},
  733. {"svg", "image/svg+xml"},
  734. {"tiff", "image/tiff"},
  735. {"tif", "image/tiff"},
  736. {"wbmp", "image/vnd.wap.wbmp"},
  737. {"webp", "image/webp"},
  738. {"ico", "image/x-icon"},
  739. {"jng", "image/x-jng"},
  740. {"bmp", "image/x-ms-bmp"},
  741. {"woff", "font/woff"},
  742. {"woff2", "font/woff2"},
  743. {"ear", "application/java-archive"},
  744. {"war", "application/java-archive"},
  745. {"jar", "application/java-archive"},
  746. {"json", "application/json"},
  747. {"hqx", "application/mac-binhex40"},
  748. {"doc", "application/msword"},
  749. {"pdf", "application/pdf"},
  750. {"ai", "application/postscript"},
  751. {"eps", "application/postscript"},
  752. {"ps", "application/postscript"},
  753. {"rtf", "application/rtf"},
  754. {"m3u8", "application/vnd.apple.mpegurl"},
  755. {"kml", "application/vnd.google-earth.kml+xml"},
  756. {"kmz", "application/vnd.google-earth.kmz"},
  757. {"xls", "application/vnd.ms-excel"},
  758. {"eot", "application/vnd.ms-fontobject"},
  759. {"ppt", "application/vnd.ms-powerpoint"},
  760. {"odg", "application/vnd.oasis.opendocument.graphics"},
  761. {"odp", "application/vnd.oasis.opendocument.presentation"},
  762. {"ods", "application/vnd.oasis.opendocument.spreadsheet"},
  763. {"odt", "application/vnd.oasis.opendocument.text"},
  764. {"pptx", "application/"
  765. "vnd.openxmlformats-officedocument.presentationml.presentation"},
  766. {"xlsx",
  767. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
  768. {"docx",
  769. "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
  770. {"wmlc", "application/vnd.wap.wmlc"},
  771. {"wasm", "application/wasm"},
  772. {"7z", "application/x-7z-compressed"},
  773. {"cco", "application/x-cocoa"},
  774. {"jardiff", "application/x-java-archive-diff"},
  775. {"jnlp", "application/x-java-jnlp-file"},
  776. {"run", "application/x-makeself"},
  777. {"pm", "application/x-perl"},
  778. {"pl", "application/x-perl"},
  779. {"pdb", "application/x-pilot"},
  780. {"prc", "application/x-pilot"},
  781. {"rar", "application/x-rar-compressed"},
  782. {"rpm", "application/x-redhat-package-manager"},
  783. {"sea", "application/x-sea"},
  784. {"swf", "application/x-shockwave-flash"},
  785. {"sit", "application/x-stuffit"},
  786. {"tk", "application/x-tcl"},
  787. {"tcl", "application/x-tcl"},
  788. {"crt", "application/x-x509-ca-cert"},
  789. {"pem", "application/x-x509-ca-cert"},
  790. {"der", "application/x-x509-ca-cert"},
  791. {"xpi", "application/x-xpinstall"},
  792. {"xhtml", "application/xhtml+xml"},
  793. {"xspf", "application/xspf+xml"},
  794. {"zip", "application/zip"},
  795. {"dll", "application/octet-stream"},
  796. {"exe", "application/octet-stream"},
  797. {"bin", "application/octet-stream"},
  798. {"deb", "application/octet-stream"},
  799. {"dmg", "application/octet-stream"},
  800. {"img", "application/octet-stream"},
  801. {"iso", "application/octet-stream"},
  802. {"msm", "application/octet-stream"},
  803. {"msp", "application/octet-stream"},
  804. {"msi", "application/octet-stream"},
  805. {"kar", "audio/midi"},
  806. {"midi", "audio/midi"},
  807. {"mid", "audio/midi"},
  808. {"mp3", "audio/mpeg"},
  809. {"ogg", "audio/ogg"},
  810. {"m4a", "audio/x-m4a"},
  811. {"ra", "audio/x-realaudio"},
  812. {"3gp", "video/3gpp"},
  813. {"3gpp", "video/3gpp"},
  814. {"ts", "video/mp2t"},
  815. {"mp4", "video/mp4"},
  816. {"mpg", "video/mpeg"},
  817. {"mpeg", "video/mpeg"},
  818. {"mov", "video/quicktime"},
  819. {"webm", "video/webm"},
  820. {"flv", "video/x-flv"},
  821. {"m4v", "video/x-m4v"},
  822. {"mng", "video/x-mng"},
  823. {"asf", "video/x-ms-asf"},
  824. {"asx", "video/x-ms-asf"},
  825. {"wmv", "video/x-ms-wmv"},
  826. {"avi", "video/x-msvideo"}};
  827. }
  828. // settings for crow
  829. // TODO(ipkn) replace with runtime config. libucl?
  830. /* #ifdef - enables debug mode */
  831. // #define CROW_ENABLE_DEBUG
  832. /* #ifdef - enables logging */
  833. #define CROW_ENABLE_LOGGING
  834. /* #ifdef - enforces section 5.2 and 6.1 of RFC6455 (only accepting masked
  835. * messages from clients) */
  836. // #define CROW_ENFORCE_WS_SPEC
  837. /* #define - specifies log level */
  838. /*
  839. Debug = 0
  840. Info = 1
  841. Warning = 2
  842. Error = 3
  843. Critical = 4
  844. default to INFO
  845. */
  846. #ifndef CROW_LOG_LEVEL
  847. #define CROW_LOG_LEVEL 1
  848. #endif
  849. #ifndef CROW_STATIC_DIRECTORY
  850. #define CROW_STATIC_DIRECTORY "static/"
  851. #endif
  852. #ifndef CROW_STATIC_ENDPOINT
  853. #define CROW_STATIC_ENDPOINT "/static/<path>"
  854. #endif
  855. // compiler flags
  856. #if defined(_MSC_VER)
  857. #if _MSC_VER < 1900
  858. #define CROW_MSVC_WORKAROUND
  859. #define constexpr const
  860. #define noexcept throw()
  861. #endif
  862. #endif
  863. #ifdef CROW_USE_BOOST
  864. #include <boost/asio.hpp>
  865. #include <boost/asio/version.hpp>
  866. #ifdef CROW_ENABLE_SSL
  867. #include <boost/asio/ssl.hpp>
  868. #endif
  869. #else
  870. #ifndef ASIO_STANDALONE
  871. #define ASIO_STANDALONE
  872. #endif
  873. #include <asio.hpp>
  874. #include <asio/version.hpp>
  875. #ifdef CROW_ENABLE_SSL
  876. #include <asio/ssl.hpp>
  877. #endif
  878. #endif
  879. #if (defined(CROW_USE_BOOST) && BOOST_VERSION >= 107000) || \
  880. (ASIO_VERSION >= 101008)
  881. #define GET_IO_CONTEXT(s) ((asio::io_context &)(s).get_executor().context())
  882. #else
  883. #define GET_IO_CONTEXT(s) ((s).get_io_service())
  884. #endif
  885. namespace crow {
  886. #ifdef CROW_USE_BOOST
  887. namespace asio = boost::asio;
  888. using error_code = boost::system::error_code;
  889. #else
  890. using error_code = asio::error_code;
  891. #endif
  892. using tcp = asio::ip::tcp;
  893. using stream_protocol = asio::local::stream_protocol;
  894. /// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
  895. struct SocketAdaptor {
  896. using context = void;
  897. SocketAdaptor(asio::io_context &io_context, context *)
  898. : socket_(io_context) {}
  899. asio::io_context &get_io_context() { return GET_IO_CONTEXT(socket_); }
  900. /// Get the TCP socket handling data transfers, regardless of what layer is
  901. /// handling transfers on top of the socket.
  902. tcp::socket &raw_socket() { return socket_; }
  903. /// Get the object handling data transfers, this can be either a TCP socket or
  904. /// an SSL stream (if SSL is enabled).
  905. tcp::socket &socket() { return socket_; }
  906. tcp::endpoint remote_endpoint() const { return socket_.remote_endpoint(); }
  907. std::string address() const {
  908. return socket_.remote_endpoint().address().to_string();
  909. }
  910. bool is_open() const { return socket_.is_open(); }
  911. void close() {
  912. error_code ec;
  913. socket_.close(ec);
  914. }
  915. void shutdown_readwrite() {
  916. error_code ec;
  917. socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
  918. }
  919. void shutdown_write() {
  920. error_code ec;
  921. socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
  922. }
  923. void shutdown_read() {
  924. error_code ec;
  925. socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
  926. }
  927. template <typename F> void start(F f) { f(error_code()); }
  928. tcp::socket socket_;
  929. };
  930. struct UnixSocketAdaptor {
  931. using context = void;
  932. UnixSocketAdaptor(asio::io_context &io_context, context *)
  933. : socket_(io_context) {}
  934. asio::io_context &get_io_context() { return GET_IO_CONTEXT(socket_); }
  935. stream_protocol::socket &raw_socket() { return socket_; }
  936. stream_protocol::socket &socket() { return socket_; }
  937. stream_protocol::endpoint remote_endpoint() {
  938. return socket_.local_endpoint();
  939. }
  940. std::string address() const { return ""; }
  941. bool is_open() { return socket_.is_open(); }
  942. void close() {
  943. error_code ec;
  944. socket_.close(ec);
  945. }
  946. void shutdown_readwrite() {
  947. error_code ec;
  948. socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
  949. }
  950. void shutdown_write() {
  951. error_code ec;
  952. socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
  953. }
  954. void shutdown_read() {
  955. error_code ec;
  956. socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
  957. }
  958. template <typename F> void start(F f) { f(error_code()); }
  959. stream_protocol::socket socket_;
  960. };
  961. #ifdef CROW_ENABLE_SSL
  962. struct SSLAdaptor {
  963. using context = asio::ssl::context;
  964. using ssl_socket_t = asio::ssl::stream<tcp::socket>;
  965. SSLAdaptor(asio::io_context &io_context, context *ctx)
  966. : ssl_socket_(new ssl_socket_t(io_context, *ctx)) {}
  967. asio::ssl::stream<tcp::socket> &socket() { return *ssl_socket_; }
  968. tcp::socket::lowest_layer_type &raw_socket() {
  969. return ssl_socket_->lowest_layer();
  970. }
  971. tcp::endpoint remote_endpoint() { return raw_socket().remote_endpoint(); }
  972. std::string address() const {
  973. return ssl_socket_->lowest_layer().remote_endpoint().address().to_string();
  974. }
  975. bool is_open() { return ssl_socket_ ? raw_socket().is_open() : false; }
  976. void close() {
  977. if (is_open()) {
  978. error_code ec;
  979. raw_socket().close(ec);
  980. }
  981. }
  982. void shutdown_readwrite() {
  983. if (is_open()) {
  984. error_code ec;
  985. raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_both,
  986. ec);
  987. }
  988. }
  989. void shutdown_write() {
  990. if (is_open()) {
  991. error_code ec;
  992. raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_send,
  993. ec);
  994. }
  995. }
  996. void shutdown_read() {
  997. if (is_open()) {
  998. error_code ec;
  999. raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_receive,
  1000. ec);
  1001. }
  1002. }
  1003. asio::io_context &get_io_context() { return GET_IO_CONTEXT(raw_socket()); }
  1004. template <typename F> void start(F f) {
  1005. ssl_socket_->async_handshake(asio::ssl::stream_base::server,
  1006. [f](const error_code &ec) { f(ec); });
  1007. }
  1008. std::unique_ptr<asio::ssl::stream<tcp::socket>> ssl_socket_;
  1009. };
  1010. #endif
  1011. } // namespace crow
  1012. #include <cstdio>
  1013. #include <cstdlib>
  1014. #include <ctime>
  1015. #include <iostream>
  1016. #include <sstream>
  1017. #include <string>
  1018. namespace crow {
  1019. enum class LogLevel {
  1020. #ifndef ERROR
  1021. #ifndef DEBUG
  1022. DEBUG = 0,
  1023. INFO,
  1024. WARNING,
  1025. ERROR,
  1026. CRITICAL,
  1027. #endif
  1028. #endif
  1029. Debug = 0,
  1030. Info,
  1031. Warning,
  1032. Error,
  1033. Critical,
  1034. };
  1035. class ILogHandler {
  1036. public:
  1037. virtual ~ILogHandler() = default;
  1038. virtual void log(const std::string &message, LogLevel level) = 0;
  1039. };
  1040. class CerrLogHandler : public ILogHandler {
  1041. public:
  1042. void log(const std::string &message, LogLevel level) override {
  1043. std::string log_msg;
  1044. log_msg.reserve(message.length() + 1 + 32 + 3 + 8 + 2);
  1045. log_msg.append("(").append(timestamp()).append(") [");
  1046. switch (level) {
  1047. case LogLevel::Debug: log_msg.append("DEBUG "); break;
  1048. case LogLevel::Info: log_msg.append("INFO "); break;
  1049. case LogLevel::Warning: log_msg.append("WARNING "); break;
  1050. case LogLevel::Error: log_msg.append("ERROR "); break;
  1051. case LogLevel::Critical: log_msg.append("CRITICAL"); break;
  1052. }
  1053. log_msg.append("] ").append(message);
  1054. std::cerr << log_msg << std::endl;
  1055. }
  1056. private:
  1057. static std::string timestamp() {
  1058. char date[32];
  1059. time_t t = time(0);
  1060. tm my_tm;
  1061. #if defined(_MSC_VER) || defined(__MINGW32__)
  1062. #ifdef CROW_USE_LOCALTIMEZONE
  1063. localtime_s(&my_tm, &t);
  1064. #else
  1065. gmtime_s(&my_tm, &t);
  1066. #endif
  1067. #else
  1068. #ifdef CROW_USE_LOCALTIMEZONE
  1069. localtime_r(&t, &my_tm);
  1070. #else
  1071. gmtime_r(&t, &my_tm);
  1072. #endif
  1073. #endif
  1074. size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm);
  1075. return std::string(date, date + sz);
  1076. }
  1077. };
  1078. class logger {
  1079. public:
  1080. logger(LogLevel level) : level_(level) {}
  1081. ~logger() {
  1082. #ifdef CROW_ENABLE_LOGGING
  1083. if (level_ >= get_current_log_level()) {
  1084. get_handler_ref()->log(stringstream_.str(), level_);
  1085. }
  1086. #endif
  1087. }
  1088. //
  1089. template <typename T> logger &operator<<(T const &value) {
  1090. #ifdef CROW_ENABLE_LOGGING
  1091. if (level_ >= get_current_log_level()) { stringstream_ << value; }
  1092. #endif
  1093. return *this;
  1094. }
  1095. //
  1096. static void setLogLevel(LogLevel level) { get_log_level_ref() = level; }
  1097. static void setHandler(ILogHandler *handler) { get_handler_ref() = handler; }
  1098. static LogLevel get_current_log_level() { return get_log_level_ref(); }
  1099. private:
  1100. //
  1101. static LogLevel &get_log_level_ref() {
  1102. static LogLevel current_level = static_cast<LogLevel>(CROW_LOG_LEVEL);
  1103. return current_level;
  1104. }
  1105. static ILogHandler *&get_handler_ref() {
  1106. static CerrLogHandler default_handler;
  1107. static ILogHandler *current_handler = &default_handler;
  1108. return current_handler;
  1109. }
  1110. //
  1111. std::ostringstream stringstream_;
  1112. LogLevel level_;
  1113. };
  1114. } // namespace crow
  1115. #define CROW_LOG_CRITICAL \
  1116. if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
  1117. crow::logger(crow::LogLevel::Critical)
  1118. #define CROW_LOG_ERROR \
  1119. if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
  1120. crow::logger(crow::LogLevel::Error)
  1121. #define CROW_LOG_WARNING \
  1122. if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
  1123. crow::logger(crow::LogLevel::Warning)
  1124. #define CROW_LOG_INFO \
  1125. if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
  1126. crow::logger(crow::LogLevel::Info)
  1127. #define CROW_LOG_DEBUG \
  1128. if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
  1129. crow::logger(crow::LogLevel::Debug)
  1130. #include <string>
  1131. namespace crow {
  1132. /// An abstract class that allows any other class to be returned by a handler.
  1133. struct returnable {
  1134. std::string content_type;
  1135. virtual std::string dump() const = 0;
  1136. returnable(std::string ctype) : content_type{ctype} {}
  1137. virtual ~returnable() {}
  1138. };
  1139. } // namespace crow
  1140. #ifdef CROW_USE_BOOST
  1141. #include <boost/asio.hpp>
  1142. #ifdef CROW_ENABLE_SSL
  1143. #include <boost/asio/ssl.hpp>
  1144. #endif
  1145. #else
  1146. #ifndef ASIO_STANDALONE
  1147. #define ASIO_STANDALONE
  1148. #endif
  1149. #include <asio.hpp>
  1150. #ifdef CROW_ENABLE_SSL
  1151. #include <asio/ssl.hpp>
  1152. #endif
  1153. #endif
  1154. namespace crow {
  1155. #ifdef CROW_USE_BOOST
  1156. namespace asio = boost::asio;
  1157. using error_code = boost::system::error_code;
  1158. #else
  1159. using error_code = asio::error_code;
  1160. #endif
  1161. using tcp = asio::ip::tcp;
  1162. using stream_protocol = asio::local::stream_protocol;
  1163. struct TCPAcceptor {
  1164. using endpoint = tcp::endpoint;
  1165. tcp::acceptor acceptor_;
  1166. TCPAcceptor(asio::io_context &io_context) : acceptor_(io_context) {}
  1167. int16_t port() const { return acceptor_.local_endpoint().port(); }
  1168. std::string address() const {
  1169. return acceptor_.local_endpoint().address().to_string();
  1170. }
  1171. std::string url_display(bool ssl_used) const {
  1172. auto address = acceptor_.local_endpoint().address();
  1173. return (ssl_used ? "https://" : "http://") +
  1174. (address.is_v4() ? address.to_string()
  1175. : "[" + address.to_string() + "]") +
  1176. ":" + std::to_string(acceptor_.local_endpoint().port());
  1177. }
  1178. tcp::acceptor &raw_acceptor() { return acceptor_; }
  1179. endpoint local_endpoint() const { return acceptor_.local_endpoint(); }
  1180. inline static tcp::acceptor::reuse_address reuse_address_option() {
  1181. return tcp::acceptor::reuse_address(true);
  1182. }
  1183. };
  1184. struct UnixSocketAcceptor {
  1185. using endpoint = stream_protocol::endpoint;
  1186. stream_protocol::acceptor acceptor_;
  1187. UnixSocketAcceptor(asio::io_context &io_context) : acceptor_(io_context) {}
  1188. int16_t port() const { return 0; }
  1189. std::string address() const { return acceptor_.local_endpoint().path(); }
  1190. std::string url_display(bool) const {
  1191. return acceptor_.local_endpoint().path();
  1192. }
  1193. stream_protocol::acceptor &raw_acceptor() { return acceptor_; }
  1194. endpoint local_endpoint() const { return acceptor_.local_endpoint(); }
  1195. inline static stream_protocol::acceptor::reuse_address
  1196. reuse_address_option() {
  1197. // reuse addr must be false
  1198. // (https://github.com/chriskohlhoff/asio/issues/622)
  1199. return stream_protocol::acceptor::reuse_address(false);
  1200. }
  1201. };
  1202. } // namespace crow
  1203. #include <algorithm>
  1204. #include <cctype>
  1205. #include <cstdint>
  1206. #include <cstring>
  1207. #include <functional>
  1208. #include <random>
  1209. #include <sstream>
  1210. #include <stdexcept>
  1211. #include <string>
  1212. #include <string_view>
  1213. #include <tuple>
  1214. #include <type_traits>
  1215. #include <unordered_map>
  1216. #include <filesystem>
  1217. // TODO(EDev): Adding C++20's [[likely]] and [[unlikely]] attributes might be
  1218. // useful
  1219. #if defined(__GNUG__) || defined(__clang__)
  1220. #define CROW_LIKELY(X) __builtin_expect(!!(X), 1)
  1221. #define CROW_UNLIKELY(X) __builtin_expect(!!(X), 0)
  1222. #else
  1223. #define CROW_LIKELY(X) (X)
  1224. #define CROW_UNLIKELY(X) (X)
  1225. #endif
  1226. namespace crow {
  1227. /// @cond SKIP
  1228. namespace black_magic {
  1229. #ifndef CROW_MSVC_WORKAROUND
  1230. /// Out of Range Exception for const_str
  1231. struct OutOfRange {
  1232. OutOfRange(unsigned /*pos*/, unsigned /*length*/) {}
  1233. };
  1234. /// Helper function to throw an exception if i is larger than len
  1235. constexpr unsigned requires_in_range(unsigned i, unsigned len) {
  1236. return i >= len ? throw OutOfRange(i, len) : i;
  1237. }
  1238. /// A constant string implementation.
  1239. class const_str {
  1240. const char *const begin_;
  1241. unsigned size_;
  1242. public:
  1243. template <unsigned N>
  1244. constexpr const_str(const char (&arr)[N]) : begin_(arr), size_(N - 1) {
  1245. static_assert(N >= 1, "not a string literal");
  1246. }
  1247. constexpr char operator[](unsigned i) const {
  1248. return requires_in_range(i, size_), begin_[i];
  1249. }
  1250. constexpr operator const char *() const { return begin_; }
  1251. constexpr const char *begin() const { return begin_; }
  1252. constexpr const char *end() const { return begin_ + size_; }
  1253. constexpr unsigned size() const { return size_; }
  1254. };
  1255. constexpr unsigned find_closing_tag(const_str s, unsigned p) {
  1256. return s[p] == '>' ? p : find_closing_tag(s, p + 1);
  1257. }
  1258. /// Check that the CROW_ROUTE string is valid
  1259. constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0) {
  1260. return i == s.size() ? f == 0
  1261. : f < 0 || f >= 2 ? false
  1262. : s[i] == '<' ? is_valid(s, i + 1, f + 1)
  1263. : s[i] == '>' ? is_valid(s, i + 1, f - 1)
  1264. : is_valid(s, i + 1, f);
  1265. }
  1266. constexpr bool is_equ_p(const char *a, const char *b, unsigned n) {
  1267. return *a == 0 && *b == 0 && n == 0 ? true
  1268. : (*a == 0 || *b == 0) ? false
  1269. : n == 0 ? true
  1270. : *a != *b ? false
  1271. : is_equ_p(a + 1, b + 1, n - 1);
  1272. }
  1273. constexpr bool is_equ_n(const_str a, unsigned ai, const_str b, unsigned bi,
  1274. unsigned n) {
  1275. return ai + n > a.size() || bi + n > b.size() ? false
  1276. : n == 0 ? true
  1277. : a[ai] != b[bi] ? false
  1278. : is_equ_n(a, ai + 1, b, bi + 1, n - 1);
  1279. }
  1280. constexpr bool is_int(const_str s, unsigned i) {
  1281. return is_equ_n(s, i, "<int>", 0, 5);
  1282. }
  1283. constexpr bool is_uint(const_str s, unsigned i) {
  1284. return is_equ_n(s, i, "<uint>", 0, 6);
  1285. }
  1286. constexpr bool is_float(const_str s, unsigned i) {
  1287. return is_equ_n(s, i, "<float>", 0, 7) || is_equ_n(s, i, "<double>", 0, 8);
  1288. }
  1289. constexpr bool is_str(const_str s, unsigned i) {
  1290. return is_equ_n(s, i, "<str>", 0, 5) || is_equ_n(s, i, "<string>", 0, 8);
  1291. }
  1292. constexpr bool is_path(const_str s, unsigned i) {
  1293. return is_equ_n(s, i, "<path>", 0, 6);
  1294. }
  1295. #endif
  1296. template <typename T> struct parameter_tag {
  1297. static const int value = 0;
  1298. };
  1299. #define CROW_INTERNAL_PARAMETER_TAG(t, i) \
  1300. template <> struct parameter_tag<t> { \
  1301. static const int value = i; \
  1302. }
  1303. CROW_INTERNAL_PARAMETER_TAG(int, 1);
  1304. CROW_INTERNAL_PARAMETER_TAG(char, 1);
  1305. CROW_INTERNAL_PARAMETER_TAG(short, 1);
  1306. CROW_INTERNAL_PARAMETER_TAG(long, 1);
  1307. CROW_INTERNAL_PARAMETER_TAG(long long, 1);
  1308. CROW_INTERNAL_PARAMETER_TAG(unsigned int, 2);
  1309. CROW_INTERNAL_PARAMETER_TAG(unsigned char, 2);
  1310. CROW_INTERNAL_PARAMETER_TAG(unsigned short, 2);
  1311. CROW_INTERNAL_PARAMETER_TAG(unsigned long, 2);
  1312. CROW_INTERNAL_PARAMETER_TAG(unsigned long long, 2);
  1313. CROW_INTERNAL_PARAMETER_TAG(double, 3);
  1314. CROW_INTERNAL_PARAMETER_TAG(std::string, 4);
  1315. #undef CROW_INTERNAL_PARAMETER_TAG
  1316. template <typename... Args> struct compute_parameter_tag_from_args_list;
  1317. template <> struct compute_parameter_tag_from_args_list<> {
  1318. static const int value = 0;
  1319. };
  1320. template <typename Arg, typename... Args>
  1321. struct compute_parameter_tag_from_args_list<Arg, Args...> {
  1322. static const int sub_value =
  1323. compute_parameter_tag_from_args_list<Args...>::value;
  1324. static const int value =
  1325. parameter_tag<typename std::decay<Arg>::type>::value
  1326. ? sub_value * 6 + parameter_tag<typename std::decay<Arg>::type>::value
  1327. : sub_value;
  1328. };
  1329. static inline bool is_parameter_tag_compatible(uint64_t a, uint64_t b) {
  1330. if (a == 0) return b == 0;
  1331. if (b == 0) return a == 0;
  1332. int sa = a % 6;
  1333. int sb = a % 6;
  1334. if (sa == 5) sa = 4;
  1335. if (sb == 5) sb = 4;
  1336. if (sa != sb) return false;
  1337. return is_parameter_tag_compatible(a / 6, b / 6);
  1338. }
  1339. static inline unsigned find_closing_tag_runtime(const char *s, unsigned p) {
  1340. return s[p] == 0 ? throw std::runtime_error("unmatched tag <")
  1341. : s[p] == '>' ? p
  1342. : find_closing_tag_runtime(s, p + 1);
  1343. }
  1344. static inline uint64_t get_parameter_tag_runtime(const char *s,
  1345. unsigned p = 0) {
  1346. return s[p] == 0 ? 0
  1347. : s[p] == '<'
  1348. ? (std::strncmp(s + p, "<int>", 5) == 0
  1349. ? get_parameter_tag_runtime(
  1350. s, find_closing_tag_runtime(s, p)) *
  1351. 6 +
  1352. 1
  1353. : std::strncmp(s + p, "<uint>", 6) == 0
  1354. ? get_parameter_tag_runtime(
  1355. s, find_closing_tag_runtime(s, p)) *
  1356. 6 +
  1357. 2
  1358. : (std::strncmp(s + p, "<float>", 7) == 0 ||
  1359. std::strncmp(s + p, "<double>", 8) == 0)
  1360. ? get_parameter_tag_runtime(
  1361. s, find_closing_tag_runtime(s, p)) *
  1362. 6 +
  1363. 3
  1364. : (std::strncmp(s + p, "<str>", 5) == 0 ||
  1365. std::strncmp(s + p, "<string>", 8) == 0)
  1366. ? get_parameter_tag_runtime(
  1367. s, find_closing_tag_runtime(s, p)) *
  1368. 6 +
  1369. 4
  1370. : std::strncmp(s + p, "<path>", 6) == 0
  1371. ? get_parameter_tag_runtime(
  1372. s, find_closing_tag_runtime(s, p)) *
  1373. 6 +
  1374. 5
  1375. : throw std::runtime_error("invalid parameter type"))
  1376. : get_parameter_tag_runtime(s, p + 1);
  1377. }
  1378. #ifndef CROW_MSVC_WORKAROUND
  1379. constexpr uint64_t get_parameter_tag(const_str s, unsigned p = 0) {
  1380. return p == s.size() ? 0
  1381. : s[p] == '<'
  1382. ? (is_int(s, p)
  1383. ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 1
  1384. : is_uint(s, p)
  1385. ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 2
  1386. : is_float(s, p)
  1387. ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 3
  1388. : is_str(s, p)
  1389. ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 4
  1390. : is_path(s, p)
  1391. ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 5
  1392. : throw std::runtime_error("invalid parameter type"))
  1393. : get_parameter_tag(s, p + 1);
  1394. }
  1395. #endif
  1396. template <typename... T> struct S {
  1397. template <typename U> using push = S<U, T...>;
  1398. template <typename U> using push_back = S<T..., U>;
  1399. template <template <typename... Args> class U> using rebind = U<T...>;
  1400. };
  1401. // Check whether the template function can be called with specific arguments
  1402. template <typename F, typename Set> struct CallHelper;
  1403. template <typename F, typename... Args> struct CallHelper<F, S<Args...>> {
  1404. template <typename F1, typename... Args1,
  1405. typename = decltype(std::declval<F1>()(std::declval<Args1>()...))>
  1406. static char __test(int);
  1407. template <typename...> static int __test(...);
  1408. static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
  1409. };
  1410. // Check Tuple contains type T
  1411. template <typename T, typename Tuple> struct has_type;
  1412. template <typename T> struct has_type<T, std::tuple<>> : std::false_type {};
  1413. template <typename T, typename U, typename... Ts>
  1414. struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};
  1415. template <typename T, typename... Ts>
  1416. struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
  1417. // Find index of type in tuple
  1418. template <class T, class Tuple> struct tuple_index;
  1419. template <class T, class... Types>
  1420. struct tuple_index<T, std::tuple<T, Types...>> {
  1421. static const int value = 0;
  1422. };
  1423. template <class T, class U, class... Types>
  1424. struct tuple_index<T, std::tuple<U, Types...>> {
  1425. static const int value = 1 + tuple_index<T, std::tuple<Types...>>::value;
  1426. };
  1427. // Extract element from forward tuple or get default
  1428. template <typename T, typename Tup>
  1429. typename std::enable_if<has_type<T &, Tup>::value,
  1430. typename std::decay<T>::type &&>::type
  1431. tuple_extract(Tup &tup) {
  1432. return std::move(std::get<T &>(tup));
  1433. }
  1434. template <typename T, typename Tup>
  1435. typename std::enable_if<!has_type<T &, Tup>::value, T>::type
  1436. tuple_extract(Tup &) {
  1437. return T{};
  1438. }
  1439. // Kind of fold expressions in C++11
  1440. template <bool...> struct bool_pack;
  1441. template <bool... bs>
  1442. using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
  1443. template <int N> struct single_tag_to_type {};
  1444. template <> struct single_tag_to_type<1> {
  1445. using type = int64_t;
  1446. };
  1447. template <> struct single_tag_to_type<2> {
  1448. using type = uint64_t;
  1449. };
  1450. template <> struct single_tag_to_type<3> {
  1451. using type = double;
  1452. };
  1453. template <> struct single_tag_to_type<4> {
  1454. using type = std::string;
  1455. };
  1456. template <> struct single_tag_to_type<5> {
  1457. using type = std::string;
  1458. };
  1459. template <uint64_t Tag> struct arguments {
  1460. using subarguments = typename arguments<Tag / 6>::type;
  1461. using type = typename subarguments::template push<
  1462. typename single_tag_to_type<Tag % 6>::type>;
  1463. };
  1464. template <> struct arguments<0> {
  1465. using type = S<>;
  1466. };
  1467. template <typename... T> struct last_element_type {
  1468. using type =
  1469. typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type;
  1470. };
  1471. template <> struct last_element_type<> {};
  1472. // from
  1473. // http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth
  1474. template <class T> using Invoke = typename T::type;
  1475. template <unsigned...> struct seq {
  1476. using type = seq;
  1477. };
  1478. template <class S1, class S2> struct concat;
  1479. template <unsigned... I1, unsigned... I2>
  1480. struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1) + I2)...> {};
  1481. template <class S1, class S2> using Concat = Invoke<concat<S1, S2>>;
  1482. template <unsigned N> struct gen_seq;
  1483. template <unsigned N> using GenSeq = Invoke<gen_seq<N>>;
  1484. template <unsigned N>
  1485. struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {};
  1486. template <> struct gen_seq<0> : seq<> {};
  1487. template <> struct gen_seq<1> : seq<0> {};
  1488. template <typename Seq, typename Tuple> struct pop_back_helper;
  1489. template <unsigned... N, typename Tuple>
  1490. struct pop_back_helper<seq<N...>, Tuple> {
  1491. template <template <typename... Args> class U>
  1492. using rebind = U<typename std::tuple_element<N, Tuple>::type...>;
  1493. };
  1494. template <typename... T>
  1495. struct pop_back //: public pop_back_helper<typename
  1496. //: gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>
  1497. {
  1498. template <template <typename... Args> class U>
  1499. using rebind =
  1500. typename pop_back_helper<typename gen_seq<sizeof...(T) - 1>::type,
  1501. std::tuple<T...>>::template rebind<U>;
  1502. };
  1503. template <> struct pop_back<> {
  1504. template <template <typename... Args> class U> using rebind = U<>;
  1505. };
  1506. // from
  1507. // http://stackoverflow.com/questions/2118541/check-if-c0x-parameter-pack-contains-a-type
  1508. template <typename Tp, typename... List> struct contains : std::true_type {};
  1509. template <typename Tp, typename Head, typename... Rest>
  1510. struct contains<Tp, Head, Rest...>
  1511. : std::conditional<std::is_same<Tp, Head>::value, std::true_type,
  1512. contains<Tp, Rest...>>::type {};
  1513. template <typename Tp> struct contains<Tp> : std::false_type {};
  1514. template <typename T> struct empty_context {};
  1515. template <typename T> struct promote {
  1516. using type = T;
  1517. };
  1518. #define CROW_INTERNAL_PROMOTE_TYPE(t1, t2) \
  1519. template <> struct promote<t1> { \
  1520. using type = t2; \
  1521. }
  1522. CROW_INTERNAL_PROMOTE_TYPE(char, int64_t);
  1523. CROW_INTERNAL_PROMOTE_TYPE(short, int64_t);
  1524. CROW_INTERNAL_PROMOTE_TYPE(int, int64_t);
  1525. CROW_INTERNAL_PROMOTE_TYPE(long, int64_t);
  1526. CROW_INTERNAL_PROMOTE_TYPE(long long, int64_t);
  1527. CROW_INTERNAL_PROMOTE_TYPE(unsigned char, uint64_t);
  1528. CROW_INTERNAL_PROMOTE_TYPE(unsigned short, uint64_t);
  1529. CROW_INTERNAL_PROMOTE_TYPE(unsigned int, uint64_t);
  1530. CROW_INTERNAL_PROMOTE_TYPE(unsigned long, uint64_t);
  1531. CROW_INTERNAL_PROMOTE_TYPE(unsigned long long, uint64_t);
  1532. CROW_INTERNAL_PROMOTE_TYPE(float, double);
  1533. #undef CROW_INTERNAL_PROMOTE_TYPE
  1534. template <typename T> using promote_t = typename promote<T>::type;
  1535. } // namespace black_magic
  1536. namespace detail {
  1537. template <class T, std::size_t N, class... Args>
  1538. struct get_index_of_element_from_tuple_by_type_impl {
  1539. static constexpr auto value = N;
  1540. };
  1541. template <class T, std::size_t N, class... Args>
  1542. struct get_index_of_element_from_tuple_by_type_impl<T, N, T, Args...> {
  1543. static constexpr auto value = N;
  1544. };
  1545. template <class T, std::size_t N, class U, class... Args>
  1546. struct get_index_of_element_from_tuple_by_type_impl<T, N, U, Args...> {
  1547. static constexpr auto value =
  1548. get_index_of_element_from_tuple_by_type_impl<T, N + 1, Args...>::value;
  1549. };
  1550. } // namespace detail
  1551. namespace utility {
  1552. template <class T, class... Args>
  1553. T &get_element_by_type(std::tuple<Args...> &t) {
  1554. return std::get<detail::get_index_of_element_from_tuple_by_type_impl<
  1555. T, 0, Args...>::value>(t);
  1556. }
  1557. template <typename T> struct function_traits;
  1558. #ifndef CROW_MSVC_WORKAROUND
  1559. template <typename T>
  1560. struct function_traits : public function_traits<decltype(&T::operator())> {
  1561. using parent_t = function_traits<decltype(&T::operator())>;
  1562. static const size_t arity = parent_t::arity;
  1563. using result_type = typename parent_t::result_type;
  1564. template <size_t i> using arg = typename parent_t::template arg<i>;
  1565. };
  1566. #endif
  1567. template <typename ClassType, typename R, typename... Args>
  1568. struct function_traits<R (ClassType::*)(Args...) const> {
  1569. static const size_t arity = sizeof...(Args);
  1570. typedef R result_type;
  1571. template <size_t i>
  1572. using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
  1573. };
  1574. template <typename ClassType, typename R, typename... Args>
  1575. struct function_traits<R (ClassType::*)(Args...)> {
  1576. static const size_t arity = sizeof...(Args);
  1577. typedef R result_type;
  1578. template <size_t i>
  1579. using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
  1580. };
  1581. template <typename R, typename... Args>
  1582. struct function_traits<std::function<R(Args...)>> {
  1583. static const size_t arity = sizeof...(Args);
  1584. typedef R result_type;
  1585. template <size_t i>
  1586. using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
  1587. };
  1588. /// @endcond
  1589. inline static std::string base64encode(
  1590. const unsigned char *data, size_t size,
  1591. const char *key =
  1592. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") {
  1593. std::string ret;
  1594. ret.resize((size + 2) / 3 * 4);
  1595. auto it = ret.begin();
  1596. while (size >= 3) {
  1597. *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
  1598. unsigned char h = (static_cast<unsigned char>(*data++) & 0x03) << 4;
  1599. *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)];
  1600. h = (static_cast<unsigned char>(*data++) & 0x0F) << 2;
  1601. *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xC0) >> 6)];
  1602. *it++ = key[static_cast<unsigned char>(*data++) & 0x3F];
  1603. size -= 3;
  1604. }
  1605. if (size == 1) {
  1606. *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
  1607. unsigned char h = (static_cast<unsigned char>(*data++) & 0x03) << 4;
  1608. *it++ = key[h];
  1609. *it++ = '=';
  1610. *it++ = '=';
  1611. } else if (size == 2) {
  1612. *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
  1613. unsigned char h = (static_cast<unsigned char>(*data++) & 0x03) << 4;
  1614. *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)];
  1615. h = (static_cast<unsigned char>(*data++) & 0x0F) << 2;
  1616. *it++ = key[h];
  1617. *it++ = '=';
  1618. }
  1619. return ret;
  1620. }
  1621. inline static std::string base64encode(
  1622. std::string data, size_t size,
  1623. const char *key =
  1624. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") {
  1625. return base64encode((const unsigned char *)data.c_str(), size, key);
  1626. }
  1627. inline static std::string base64encode_urlsafe(const unsigned char *data,
  1628. size_t size) {
  1629. return base64encode(
  1630. data, size,
  1631. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
  1632. }
  1633. inline static std::string base64encode_urlsafe(std::string data, size_t size) {
  1634. return base64encode(
  1635. (const unsigned char *)data.c_str(), size,
  1636. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
  1637. }
  1638. inline static std::string base64decode(const char *data, size_t size) {
  1639. // We accept both regular and url encoding here, as there does not seem to be
  1640. // any downside to that. If we want to distinguish that we should use +/ for
  1641. // non-url and -_ for url.
  1642. // Mapping logic from characters to [0-63]
  1643. auto key = [](char c) -> unsigned char {
  1644. if ((c >= 'A') && (c <= 'Z')) return c - 'A';
  1645. if ((c >= 'a') && (c <= 'z')) return c - 'a' + 26;
  1646. if ((c >= '0') && (c <= '9')) return c - '0' + 52;
  1647. if ((c == '+') || (c == '-')) return 62;
  1648. if ((c == '/') || (c == '_')) return 63;
  1649. return 0;
  1650. };
  1651. // Not padded
  1652. if (size % 4 == 2) // missing last 2 characters
  1653. size = (size / 4 * 3) + 1; // Not subtracting extra characters because
  1654. // they're truncated in int division
  1655. else if (size % 4 == 3) // missing last character
  1656. size = (size / 4 * 3) + 2; // Not subtracting extra characters because
  1657. // they're truncated in int division
  1658. // Padded
  1659. else if (size >= 2 && data[size - 2] == '=') // padded with '=='
  1660. size = (size / 4 * 3) - 2; // == padding means the last block only has 1
  1661. // character instead of 3, hence the '-2'
  1662. else if (size >= 1 && data[size - 1] == '=') // padded with '='
  1663. size = (size / 4 * 3) - 1; // = padding means the last block only has 2
  1664. // character instead of 3, hence the '-1'
  1665. // Padding not needed
  1666. else
  1667. size = size / 4 * 3;
  1668. std::string ret;
  1669. ret.resize(size);
  1670. auto it = ret.begin();
  1671. // These will be used to decode 1 character at a time
  1672. unsigned char odd; // char1 and char3
  1673. unsigned char even; // char2 and char4
  1674. // Take 4 character blocks to turn into 3
  1675. while (size >= 3) {
  1676. // dec_char1 = (char1 shifted 2 bits to the left) OR ((char2 AND 00110000)
  1677. // shifted 4 bits to the right))
  1678. odd = key(*data++);
  1679. even = key(*data++);
  1680. *it++ = (odd << 2) | ((even & 0x30) >> 4);
  1681. // dec_char2 = ((char2 AND 00001111) shifted 4 bits left) OR ((char3 AND
  1682. // 00111100) shifted 2 bits right))
  1683. odd = key(*data++);
  1684. *it++ = ((even & 0x0F) << 4) | ((odd & 0x3C) >> 2);
  1685. // dec_char3 = ((char3 AND 00000011) shifted 6 bits left) OR (char4)
  1686. even = key(*data++);
  1687. *it++ = ((odd & 0x03) << 6) | (even);
  1688. size -= 3;
  1689. }
  1690. if (size == 2) {
  1691. // d_char1 = (char1 shifted 2 bits to the left) OR ((char2 AND 00110000)
  1692. // shifted 4 bits to the right))
  1693. odd = key(*data++);
  1694. even = key(*data++);
  1695. *it++ = (odd << 2) | ((even & 0x30) >> 4);
  1696. // d_char2 = ((char2 AND 00001111) shifted 4 bits left) OR ((char3 AND
  1697. // 00111100) shifted 2 bits right))
  1698. odd = key(*data++);
  1699. *it++ = ((even & 0x0F) << 4) | ((odd & 0x3C) >> 2);
  1700. } else if (size == 1) {
  1701. // d_char1 = (char1 shifted 2 bits to the left) OR ((char2 AND 00110000)
  1702. // shifted 4 bits to the right))
  1703. odd = key(*data++);
  1704. even = key(*data++);
  1705. *it++ = (odd << 2) | ((even & 0x30) >> 4);
  1706. }
  1707. return ret;
  1708. }
  1709. inline static std::string base64decode(const std::string &data, size_t size) {
  1710. return base64decode(data.data(), size);
  1711. }
  1712. inline static std::string base64decode(const std::string &data) {
  1713. return base64decode(data.data(), data.length());
  1714. }
  1715. inline static std::string normalize_path(const std::string &directoryPath) {
  1716. std::string normalizedPath = directoryPath;
  1717. std::replace(normalizedPath.begin(), normalizedPath.end(), '\\', '/');
  1718. if (!normalizedPath.empty() && normalizedPath.back() != '/')
  1719. normalizedPath += '/';
  1720. return normalizedPath;
  1721. }
  1722. inline static void sanitize_filename(std::string &data,
  1723. char replacement = '_') {
  1724. if (data.length() > 255) data.resize(255);
  1725. static const auto toUpper = [](char c) {
  1726. return ((c >= 'a') && (c <= 'z')) ? (c - ('a' - 'A')) : c;
  1727. };
  1728. // Check for special device names. The Windows behavior is really odd here, it
  1729. // will consider both AUX and AUX.txt a special device. Thus we search for the
  1730. // string (case-insensitive), and then check if the string ends or if is has a
  1731. // dangerous follow up character (.:\/)
  1732. auto sanitizeSpecialFile = [](std::string &source, unsigned ofs,
  1733. const char *pattern, bool includeNumber,
  1734. char replacement_) {
  1735. unsigned i = ofs;
  1736. size_t len = source.length();
  1737. const char *p = pattern;
  1738. while (*p) {
  1739. if (i >= len) return;
  1740. if (toUpper(source[i]) != *p) return;
  1741. ++i;
  1742. ++p;
  1743. }
  1744. if (includeNumber) {
  1745. if ((i >= len) || (source[i] < '1') || (source[i] > '9')) return;
  1746. ++i;
  1747. }
  1748. if ((i >= len) || (source[i] == '.') || (source[i] == ':') ||
  1749. (source[i] == '/') || (source[i] == '\\')) {
  1750. source.erase(ofs + 1, (i - ofs) - 1);
  1751. source[ofs] = replacement_;
  1752. }
  1753. };
  1754. bool checkForSpecialEntries = true;
  1755. for (unsigned i = 0; i < data.length(); ++i) {
  1756. // Recognize directory traversals and the special devices
  1757. // CON/PRN/AUX/NULL/COM[1-]/LPT[1-9]
  1758. if (checkForSpecialEntries) {
  1759. checkForSpecialEntries = false;
  1760. switch (toUpper(data[i])) {
  1761. case 'A': sanitizeSpecialFile(data, i, "AUX", false, replacement); break;
  1762. case 'C':
  1763. sanitizeSpecialFile(data, i, "CON", false, replacement);
  1764. sanitizeSpecialFile(data, i, "COM", true, replacement);
  1765. break;
  1766. case 'L': sanitizeSpecialFile(data, i, "LPT", true, replacement); break;
  1767. case 'N': sanitizeSpecialFile(data, i, "NUL", false, replacement); break;
  1768. case 'P': sanitizeSpecialFile(data, i, "PRN", false, replacement); break;
  1769. case '.': sanitizeSpecialFile(data, i, "..", false, replacement); break;
  1770. }
  1771. }
  1772. // Sanitize individual characters
  1773. unsigned char c = data[i];
  1774. if ((c < ' ') || ((c >= 0x80) && (c <= 0x9F)) || (c == '?') || (c == '<') ||
  1775. (c == '>') || (c == ':') || (c == '*') || (c == '|') || (c == '\"')) {
  1776. data[i] = replacement;
  1777. } else if ((c == '/') || (c == '\\')) {
  1778. if (CROW_UNLIKELY(i ==
  1779. 0)) // Prevent Unix Absolute Paths (Windows Absolute
  1780. // Paths are prevented with `(c == ':')`)
  1781. {
  1782. data[i] = replacement;
  1783. } else {
  1784. checkForSpecialEntries = true;
  1785. }
  1786. }
  1787. }
  1788. }
  1789. inline static std::string random_alphanum(std::size_t size) {
  1790. static const char alphabet[] =
  1791. "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  1792. std::random_device dev;
  1793. std::mt19937 rng(dev());
  1794. std::uniform_int_distribution<std::mt19937::result_type> dist(
  1795. 0, sizeof(alphabet) - 2);
  1796. std::string out;
  1797. out.reserve(size);
  1798. for (std::size_t i = 0; i < size; i++)
  1799. out.push_back(alphabet[dist(rng)]);
  1800. return out;
  1801. }
  1802. inline static std::string join_path(std::string path,
  1803. const std::string &fname) {
  1804. return (std::filesystem::path(path) / fname).string();
  1805. }
  1806. /**
  1807. * @brief Checks two string for equality.
  1808. * Always returns false if strings differ in size.
  1809. * Defaults to case-insensitive comparison.
  1810. */
  1811. inline static bool string_equals(const std::string_view l,
  1812. const std::string_view r,
  1813. bool case_sensitive = false) {
  1814. if (l.length() != r.length()) return false;
  1815. for (size_t i = 0; i < l.length(); i++) {
  1816. if (case_sensitive) {
  1817. if (l[i] != r[i]) return false;
  1818. } else {
  1819. if (std::toupper(l[i]) != std::toupper(r[i])) return false;
  1820. }
  1821. }
  1822. return true;
  1823. }
  1824. template <typename T, typename U> inline static T lexical_cast(const U &v) {
  1825. std::stringstream stream;
  1826. T res;
  1827. stream << v;
  1828. stream >> res;
  1829. return res;
  1830. }
  1831. template <typename T>
  1832. inline static T lexical_cast(const char *v, size_t count) {
  1833. std::stringstream stream;
  1834. T res;
  1835. stream.write(v, count);
  1836. stream >> res;
  1837. return res;
  1838. }
  1839. /// Return string view of the given string view with its
  1840. /// leading and trailing whitespaces removed.
  1841. inline static std::string_view trim(const std::string_view sv) {
  1842. const size_t first = sv.find_first_not_of(" \t\n\r\f\v"); // same as isspace
  1843. if (std::string_view::npos == first) { return sv.substr(0, 0); }
  1844. const size_t last = sv.find_last_not_of(" \t\n\r\f\v");
  1845. return sv.substr(first, (last - first + 1));
  1846. }
  1847. /**
  1848. * @brief splits a string based on a separator
  1849. */
  1850. inline static std::vector<std::string> split(const std::string &v,
  1851. const std::string &separator) {
  1852. std::vector<std::string> result;
  1853. size_t startPos = 0;
  1854. for (size_t foundPos = v.find(separator); foundPos != std::string::npos;
  1855. foundPos = v.find(separator, startPos)) {
  1856. result.push_back(v.substr(startPos, foundPos - startPos));
  1857. startPos = foundPos + separator.size();
  1858. }
  1859. result.push_back(v.substr(startPos));
  1860. return result;
  1861. }
  1862. /**
  1863. * @brief Returns the first occurence that matches between two ranges of
  1864. * iterators
  1865. * @param first1 begin() iterator of the first range
  1866. * @param last1 end() iterator of the first range
  1867. * @param first2 begin() iterator of the second range
  1868. * @param last2 end() iterator of the second range
  1869. * @return first occurence that matches between two ranges of iterators
  1870. */
  1871. template <typename Iter1, typename Iter2>
  1872. inline static Iter1 find_first_of(Iter1 first1, Iter1 last1, Iter2 first2,
  1873. Iter2 last2) {
  1874. for (; first1 != last1; ++first1) {
  1875. if (std::find(first2, last2, *first1) != last2) { return first1; }
  1876. }
  1877. return last1;
  1878. }
  1879. } // namespace utility
  1880. } // namespace crow
  1881. // #define CROW_JSON_NO_ERROR_CHECK
  1882. // #define CROW_JSON_USE_MAP
  1883. #include <string>
  1884. #ifdef CROW_JSON_USE_MAP
  1885. #include <map>
  1886. #else
  1887. #include <unordered_map>
  1888. #endif
  1889. #include <algorithm>
  1890. #include <cfloat>
  1891. #include <cmath>
  1892. #include <iostream>
  1893. #include <memory>
  1894. #include <vector>
  1895. using std::isinf;
  1896. using std::isnan;
  1897. namespace crow // NOTE: Already documented in "crow/app.h"
  1898. {
  1899. namespace mustache {
  1900. class template_t;
  1901. }
  1902. namespace json {
  1903. static inline char to_hex(char c) {
  1904. c = c & 0xf;
  1905. if (c < 10) return '0' + c;
  1906. return 'a' + c - 10;
  1907. }
  1908. inline void escape(const std::string &str, std::string &ret) {
  1909. ret.reserve(ret.size() + str.size() + str.size() / 4);
  1910. for (auto c : str) {
  1911. switch (c) {
  1912. case '"': ret += "\\\""; break;
  1913. case '\\': ret += "\\\\"; break;
  1914. case '\n': ret += "\\n"; break;
  1915. case '\b': ret += "\\b"; break;
  1916. case '\f': ret += "\\f"; break;
  1917. case '\r': ret += "\\r"; break;
  1918. case '\t': ret += "\\t"; break;
  1919. default:
  1920. if (c >= 0 && c < 0x20) {
  1921. ret += "\\u00";
  1922. ret += to_hex(c / 16);
  1923. ret += to_hex(c % 16);
  1924. } else
  1925. ret += c;
  1926. break;
  1927. }
  1928. }
  1929. }
  1930. inline std::string escape(const std::string &str) {
  1931. std::string ret;
  1932. escape(str, ret);
  1933. return ret;
  1934. }
  1935. enum class type : char {
  1936. Null,
  1937. False,
  1938. True,
  1939. Number,
  1940. String,
  1941. List,
  1942. Object,
  1943. Function
  1944. };
  1945. inline const char *get_type_str(type t) {
  1946. switch (t) {
  1947. case type::Number: return "Number";
  1948. case type::False: return "False";
  1949. case type::True: return "True";
  1950. case type::List: return "List";
  1951. case type::String: return "String";
  1952. case type::Object: return "Object";
  1953. case type::Function: return "Function";
  1954. default: return "Unknown";
  1955. }
  1956. }
  1957. enum class num_type : char {
  1958. Signed_integer,
  1959. Unsigned_integer,
  1960. Floating_point,
  1961. Null,
  1962. Double_precision_floating_point
  1963. };
  1964. class rvalue;
  1965. rvalue load(const char *data, size_t size);
  1966. namespace detail {
  1967. /// A read string implementation with comparison functionality.
  1968. struct r_string {
  1969. r_string() {}
  1970. r_string(char *s, char *e) : s_(s), e_(e) {}
  1971. ~r_string() {
  1972. if (owned_) delete[] s_;
  1973. }
  1974. r_string(const r_string &r) { *this = r; }
  1975. r_string(r_string &&r) { *this = r; }
  1976. r_string &operator=(r_string &&r) {
  1977. s_ = r.s_;
  1978. e_ = r.e_;
  1979. owned_ = r.owned_;
  1980. if (r.owned_) r.owned_ = 0;
  1981. return *this;
  1982. }
  1983. r_string &operator=(const r_string &r) {
  1984. s_ = r.s_;
  1985. e_ = r.e_;
  1986. owned_ = 0;
  1987. return *this;
  1988. }
  1989. operator std::string() const { return std::string(s_, e_); }
  1990. const char *begin() const { return s_; }
  1991. const char *end() const { return e_; }
  1992. size_t size() const { return end() - begin(); }
  1993. using iterator = const char *;
  1994. using const_iterator = const char *;
  1995. char *s_; ///< Start.
  1996. mutable char *e_; ///< End.
  1997. uint8_t owned_{0};
  1998. friend std::ostream &operator<<(std::ostream &os, const r_string &s) {
  1999. os << static_cast<std::string>(s);
  2000. return os;
  2001. }
  2002. private:
  2003. void force(char *s, uint32_t length) {
  2004. s_ = s;
  2005. e_ = s_ + length;
  2006. owned_ = 1;
  2007. }
  2008. friend rvalue crow::json::load(const char *data, size_t size);
  2009. friend bool operator==(const r_string &l, const r_string &r);
  2010. friend bool operator==(const std::string &l, const r_string &r);
  2011. friend bool operator==(const r_string &l, const std::string &r);
  2012. template <typename T, typename U>
  2013. inline static bool equals(const T &l, const U &r) {
  2014. if (l.size() != r.size()) return false;
  2015. for (size_t i = 0; i < l.size(); i++) {
  2016. if (*(l.begin() + i) != *(r.begin() + i)) return false;
  2017. }
  2018. return true;
  2019. }
  2020. };
  2021. inline bool operator<(const r_string &l, const r_string &r) {
  2022. return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
  2023. }
  2024. inline bool operator<(const r_string &l, const std::string &r) {
  2025. return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
  2026. }
  2027. inline bool operator<(const std::string &l, const r_string &r) {
  2028. return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
  2029. }
  2030. inline bool operator>(const r_string &l, const r_string &r) {
  2031. return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
  2032. }
  2033. inline bool operator>(const r_string &l, const std::string &r) {
  2034. return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
  2035. }
  2036. inline bool operator>(const std::string &l, const r_string &r) {
  2037. return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
  2038. }
  2039. inline bool operator==(const r_string &l, const r_string &r) {
  2040. return r_string::equals(l, r);
  2041. }
  2042. inline bool operator==(const r_string &l, const std::string &r) {
  2043. return r_string::equals(l, r);
  2044. }
  2045. inline bool operator==(const std::string &l, const r_string &r) {
  2046. return r_string::equals(l, r);
  2047. }
  2048. inline bool operator!=(const r_string &l, const r_string &r) {
  2049. return !(l == r);
  2050. }
  2051. inline bool operator!=(const r_string &l, const std::string &r) {
  2052. return !(l == r);
  2053. }
  2054. inline bool operator!=(const std::string &l, const r_string &r) {
  2055. return !(l == r);
  2056. }
  2057. } // namespace detail
  2058. /// JSON read value.
  2059. ///
  2060. /// Value can mean any json value, including a JSON object.
  2061. /// Read means this class is used to primarily read strings into a JSON value.
  2062. class rvalue {
  2063. static const int cached_bit = 2;
  2064. static const int error_bit = 4;
  2065. public:
  2066. rvalue() noexcept : option_{error_bit} {}
  2067. rvalue(type t) noexcept : lsize_{}, lremain_{}, t_{t} {}
  2068. rvalue(type t, char *s, char *e) noexcept : start_{s}, end_{e}, t_{t} {
  2069. determine_num_type();
  2070. }
  2071. rvalue(const rvalue &r)
  2072. : start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_),
  2073. option_(r.option_) {
  2074. copy_l(r);
  2075. }
  2076. rvalue(rvalue &&r) noexcept { *this = std::move(r); }
  2077. rvalue &operator=(const rvalue &r) {
  2078. start_ = r.start_;
  2079. end_ = r.end_;
  2080. key_ = r.key_;
  2081. t_ = r.t_;
  2082. nt_ = r.nt_;
  2083. option_ = r.option_;
  2084. copy_l(r);
  2085. return *this;
  2086. }
  2087. rvalue &operator=(rvalue &&r) noexcept {
  2088. start_ = r.start_;
  2089. end_ = r.end_;
  2090. key_ = std::move(r.key_);
  2091. l_ = std::move(r.l_);
  2092. lsize_ = r.lsize_;
  2093. lremain_ = r.lremain_;
  2094. t_ = r.t_;
  2095. nt_ = r.nt_;
  2096. option_ = r.option_;
  2097. return *this;
  2098. }
  2099. explicit operator bool() const noexcept { return (option_ & error_bit) == 0; }
  2100. explicit operator int64_t() const { return i(); }
  2101. explicit operator uint64_t() const { return u(); }
  2102. explicit operator int() const { return static_cast<int>(i()); }
  2103. /// Return any json value (not object or list) as a string.
  2104. explicit operator std::string() const {
  2105. #ifndef CROW_JSON_NO_ERROR_CHECK
  2106. if (t() == type::Object || t() == type::List)
  2107. throw std::runtime_error("json type container");
  2108. #endif
  2109. switch (t()) {
  2110. case type::String: return std::string(s());
  2111. case type::Null: return std::string("null");
  2112. case type::True: return std::string("true");
  2113. case type::False: return std::string("false");
  2114. default: return std::string(start_, end_ - start_);
  2115. }
  2116. }
  2117. /// The type of the JSON value.
  2118. type t() const {
  2119. #ifndef CROW_JSON_NO_ERROR_CHECK
  2120. if (option_ & error_bit) {
  2121. throw std::runtime_error("invalid json object");
  2122. }
  2123. #endif
  2124. return t_;
  2125. }
  2126. /// The number type of the JSON value.
  2127. num_type nt() const {
  2128. #ifndef CROW_JSON_NO_ERROR_CHECK
  2129. if (option_ & error_bit) {
  2130. throw std::runtime_error("invalid json object");
  2131. }
  2132. #endif
  2133. return nt_;
  2134. }
  2135. /// The integer value.
  2136. int64_t i() const {
  2137. #ifndef CROW_JSON_NO_ERROR_CHECK
  2138. switch (t()) {
  2139. case type::Number:
  2140. case type::String:
  2141. return utility::lexical_cast<int64_t>(start_, end_ - start_);
  2142. default:
  2143. const std::string msg =
  2144. "expected number, got: " + std::string(get_type_str(t()));
  2145. throw std::runtime_error(msg);
  2146. }
  2147. #endif
  2148. return utility::lexical_cast<int64_t>(start_, end_ - start_);
  2149. }
  2150. /// The unsigned integer value.
  2151. uint64_t u() const {
  2152. #ifndef CROW_JSON_NO_ERROR_CHECK
  2153. switch (t()) {
  2154. case type::Number:
  2155. case type::String:
  2156. return utility::lexical_cast<uint64_t>(start_, end_ - start_);
  2157. default:
  2158. throw std::runtime_error(std::string("expected number, got: ") +
  2159. get_type_str(t()));
  2160. }
  2161. #endif
  2162. return utility::lexical_cast<uint64_t>(start_, end_ - start_);
  2163. }
  2164. /// The double precision floating-point number value.
  2165. double d() const {
  2166. #ifndef CROW_JSON_NO_ERROR_CHECK
  2167. if (t() != type::Number) throw std::runtime_error("value is not number");
  2168. #endif
  2169. return utility::lexical_cast<double>(start_, end_ - start_);
  2170. }
  2171. /// The boolean value.
  2172. bool b() const {
  2173. #ifndef CROW_JSON_NO_ERROR_CHECK
  2174. if (t() != type::True && t() != type::False)
  2175. throw std::runtime_error("value is not boolean");
  2176. #endif
  2177. return t() == type::True;
  2178. }
  2179. /// The string value.
  2180. detail::r_string s() const {
  2181. #ifndef CROW_JSON_NO_ERROR_CHECK
  2182. if (t() != type::String) throw std::runtime_error("value is not string");
  2183. #endif
  2184. unescape();
  2185. return detail::r_string{start_, end_};
  2186. }
  2187. /// The list or object value
  2188. std::vector<rvalue> lo() const {
  2189. #ifndef CROW_JSON_NO_ERROR_CHECK
  2190. if (t() != type::Object && t() != type::List)
  2191. throw std::runtime_error("value is not a container");
  2192. #endif
  2193. std::vector<rvalue> ret;
  2194. ret.reserve(lsize_);
  2195. for (uint32_t i = 0; i < lsize_; i++) {
  2196. ret.emplace_back(l_[i]);
  2197. }
  2198. return ret;
  2199. }
  2200. /// Convert escaped string character to their original form ("\\n" -> '\n').
  2201. void unescape() const {
  2202. if (*(start_ - 1)) {
  2203. char *head = start_;
  2204. char *tail = start_;
  2205. while (head != end_) {
  2206. if (*head == '\\') {
  2207. switch (*++head) {
  2208. case '"': *tail++ = '"'; break;
  2209. case '\\': *tail++ = '\\'; break;
  2210. case '/': *tail++ = '/'; break;
  2211. case 'b': *tail++ = '\b'; break;
  2212. case 'f': *tail++ = '\f'; break;
  2213. case 'n': *tail++ = '\n'; break;
  2214. case 'r': *tail++ = '\r'; break;
  2215. case 't': *tail++ = '\t'; break;
  2216. case 'u': {
  2217. auto from_hex = [](char c) {
  2218. if (c >= 'a') return c - 'a' + 10;
  2219. if (c >= 'A') return c - 'A' + 10;
  2220. return c - '0';
  2221. };
  2222. unsigned int code = (from_hex(head[1]) << 12) +
  2223. (from_hex(head[2]) << 8) +
  2224. (from_hex(head[3]) << 4) + from_hex(head[4]);
  2225. if (code >= 0x800) {
  2226. *tail++ = 0xE0 | (code >> 12);
  2227. *tail++ = 0x80 | ((code >> 6) & 0x3F);
  2228. *tail++ = 0x80 | (code & 0x3F);
  2229. } else if (code >= 0x80) {
  2230. *tail++ = 0xC0 | (code >> 6);
  2231. *tail++ = 0x80 | (code & 0x3F);
  2232. } else {
  2233. *tail++ = code;
  2234. }
  2235. head += 4;
  2236. } break;
  2237. }
  2238. } else
  2239. *tail++ = *head;
  2240. head++;
  2241. }
  2242. end_ = tail;
  2243. *end_ = 0;
  2244. *(start_ - 1) = 0;
  2245. }
  2246. }
  2247. /// Check if the json object has the passed string as a key.
  2248. bool has(const char *str) const { return has(std::string(str)); }
  2249. bool has(const std::string &str) const {
  2250. struct Pred {
  2251. bool operator()(const rvalue &l, const rvalue &r) const {
  2252. return l.key_ < r.key_;
  2253. }
  2254. bool operator()(const rvalue &l, const std::string &r) const {
  2255. return l.key_ < r;
  2256. }
  2257. bool operator()(const std::string &l, const rvalue &r) const {
  2258. return l < r.key_;
  2259. }
  2260. };
  2261. if (!is_cached()) {
  2262. std::sort(begin(), end(), Pred());
  2263. set_cached();
  2264. }
  2265. auto it = lower_bound(begin(), end(), str, Pred());
  2266. return it != end() && it->key_ == str;
  2267. }
  2268. int count(const std::string &str) const { return has(str) ? 1 : 0; }
  2269. rvalue *begin() const {
  2270. #ifndef CROW_JSON_NO_ERROR_CHECK
  2271. if (t() != type::Object && t() != type::List)
  2272. throw std::runtime_error("value is not a container");
  2273. #endif
  2274. return l_.get();
  2275. }
  2276. rvalue *end() const {
  2277. #ifndef CROW_JSON_NO_ERROR_CHECK
  2278. if (t() != type::Object && t() != type::List)
  2279. throw std::runtime_error("value is not a container");
  2280. #endif
  2281. return l_.get() + lsize_;
  2282. }
  2283. const detail::r_string &key() const { return key_; }
  2284. size_t size() const {
  2285. if (t() == type::String) return s().size();
  2286. #ifndef CROW_JSON_NO_ERROR_CHECK
  2287. if (t() != type::Object && t() != type::List)
  2288. throw std::runtime_error("value is not a container");
  2289. #endif
  2290. return lsize_;
  2291. }
  2292. const rvalue &operator[](int index) const {
  2293. #ifndef CROW_JSON_NO_ERROR_CHECK
  2294. if (t() != type::List) throw std::runtime_error("value is not a list");
  2295. if (index >= static_cast<int>(lsize_) || index < 0)
  2296. throw std::runtime_error("list out of bound");
  2297. #endif
  2298. return l_[index];
  2299. }
  2300. const rvalue &operator[](size_t index) const {
  2301. #ifndef CROW_JSON_NO_ERROR_CHECK
  2302. if (t() != type::List) throw std::runtime_error("value is not a list");
  2303. if (index >= lsize_) throw std::runtime_error("list out of bound");
  2304. #endif
  2305. return l_[index];
  2306. }
  2307. const rvalue &operator[](const char *str) const {
  2308. return this->operator[](std::string(str));
  2309. }
  2310. const rvalue &operator[](const std::string &str) const {
  2311. #ifndef CROW_JSON_NO_ERROR_CHECK
  2312. if (t() != type::Object) throw std::runtime_error("value is not an object");
  2313. #endif
  2314. struct Pred {
  2315. bool operator()(const rvalue &l, const rvalue &r) const {
  2316. return l.key_ < r.key_;
  2317. }
  2318. bool operator()(const rvalue &l, const std::string &r) const {
  2319. return l.key_ < r;
  2320. }
  2321. bool operator()(const std::string &l, const rvalue &r) const {
  2322. return l < r.key_;
  2323. }
  2324. };
  2325. if (!is_cached()) {
  2326. std::sort(begin(), end(), Pred());
  2327. set_cached();
  2328. }
  2329. auto it = lower_bound(begin(), end(), str, Pred());
  2330. if (it != end() && it->key_ == str) return *it;
  2331. #ifndef CROW_JSON_NO_ERROR_CHECK
  2332. throw std::runtime_error("cannot find key: " + str);
  2333. #else
  2334. static rvalue nullValue;
  2335. return nullValue;
  2336. #endif
  2337. }
  2338. void set_error() { option_ |= error_bit; }
  2339. bool error() const { return (option_ & error_bit) != 0; }
  2340. std::vector<std::string> keys() const {
  2341. #ifndef CROW_JSON_NO_ERROR_CHECK
  2342. if (t() != type::Object) throw std::runtime_error("value is not an object");
  2343. #endif
  2344. std::vector<std::string> ret;
  2345. ret.reserve(lsize_);
  2346. for (uint32_t i = 0; i < lsize_; i++) {
  2347. ret.emplace_back(std::string(l_[i].key()));
  2348. }
  2349. return ret;
  2350. }
  2351. private:
  2352. bool is_cached() const { return (option_ & cached_bit) != 0; }
  2353. void set_cached() const { option_ |= cached_bit; }
  2354. void copy_l(const rvalue &r) {
  2355. if (r.t() != type::Object && r.t() != type::List) return;
  2356. lsize_ = r.lsize_;
  2357. lremain_ = 0;
  2358. l_.reset(new rvalue[lsize_]);
  2359. std::copy(r.begin(), r.end(), begin());
  2360. }
  2361. void emplace_back(rvalue &&v) {
  2362. if (!lremain_) {
  2363. int new_size = lsize_ + lsize_;
  2364. if (new_size - lsize_ > 60000) new_size = lsize_ + 60000;
  2365. if (new_size < 4) new_size = 4;
  2366. rvalue *p = new rvalue[new_size];
  2367. rvalue *p2 = p;
  2368. for (auto &x : *this)
  2369. *p2++ = std::move(x);
  2370. l_.reset(p);
  2371. lremain_ = new_size - lsize_;
  2372. }
  2373. l_[lsize_++] = std::move(v);
  2374. lremain_--;
  2375. }
  2376. /// Determines num_type from the string.
  2377. void determine_num_type() {
  2378. if (t_ != type::Number) {
  2379. nt_ = num_type::Null;
  2380. return;
  2381. }
  2382. const std::size_t len = end_ - start_;
  2383. const bool has_minus = std::memchr(start_, '-', len) != nullptr;
  2384. const bool has_e = std::memchr(start_, 'e', len) != nullptr ||
  2385. std::memchr(start_, 'E', len) != nullptr;
  2386. const bool has_dec_sep = std::memchr(start_, '.', len) != nullptr;
  2387. if (has_dec_sep || has_e)
  2388. nt_ = num_type::Floating_point;
  2389. else if (has_minus)
  2390. nt_ = num_type::Signed_integer;
  2391. else
  2392. nt_ = num_type::Unsigned_integer;
  2393. }
  2394. mutable char *start_;
  2395. mutable char *end_;
  2396. detail::r_string key_;
  2397. std::unique_ptr<rvalue[]> l_;
  2398. uint32_t lsize_;
  2399. uint16_t lremain_;
  2400. type t_;
  2401. num_type nt_{num_type::Null};
  2402. mutable uint8_t option_{0};
  2403. friend rvalue load_nocopy_internal(char *data, size_t size);
  2404. friend rvalue load(const char *data, size_t size);
  2405. friend std::ostream &operator<<(std::ostream &os, const rvalue &r) {
  2406. switch (r.t_) {
  2407. case type::Null: os << "null"; break;
  2408. case type::False: os << "false"; break;
  2409. case type::True: os << "true"; break;
  2410. case type::Number: {
  2411. switch (r.nt()) {
  2412. case num_type::Floating_point: os << r.d(); break;
  2413. case num_type::Double_precision_floating_point: os << r.d(); break;
  2414. case num_type::Signed_integer: os << r.i(); break;
  2415. case num_type::Unsigned_integer: os << r.u(); break;
  2416. case num_type::Null:
  2417. throw std::runtime_error("Number with num_type Null");
  2418. }
  2419. } break;
  2420. case type::String: os << '"' << r.s() << '"'; break;
  2421. case type::List: {
  2422. os << '[';
  2423. bool first = true;
  2424. for (auto &x : r) {
  2425. if (!first) os << ',';
  2426. first = false;
  2427. os << x;
  2428. }
  2429. os << ']';
  2430. } break;
  2431. case type::Object: {
  2432. os << '{';
  2433. bool first = true;
  2434. for (auto &x : r) {
  2435. if (!first) os << ',';
  2436. os << '"' << escape(x.key_) << "\":";
  2437. first = false;
  2438. os << x;
  2439. }
  2440. os << '}';
  2441. } break;
  2442. case type::Function: os << "custom function"; break;
  2443. }
  2444. return os;
  2445. }
  2446. };
  2447. namespace detail {}
  2448. inline bool operator==(const rvalue &l, const std::string &r) {
  2449. return l.s() == r;
  2450. }
  2451. inline bool operator==(const std::string &l, const rvalue &r) {
  2452. return l == r.s();
  2453. }
  2454. inline bool operator!=(const rvalue &l, const std::string &r) {
  2455. return l.s() != r;
  2456. }
  2457. inline bool operator!=(const std::string &l, const rvalue &r) {
  2458. return l != r.s();
  2459. }
  2460. inline bool operator==(const rvalue &l, const int &r) { return l.i() == r; }
  2461. inline bool operator==(const int &l, const rvalue &r) { return l == r.i(); }
  2462. inline bool operator!=(const rvalue &l, const int &r) { return l.i() != r; }
  2463. inline bool operator!=(const int &l, const rvalue &r) { return l != r.i(); }
  2464. inline rvalue load_nocopy_internal(char *data, size_t size) {
  2465. // Defend against excessive recursion
  2466. static constexpr unsigned max_depth = 10000;
  2467. // static const char* escaped = "\"\\/\b\f\n\r\t";
  2468. struct Parser {
  2469. Parser(char *data_, size_t /*size*/) : data(data_) {}
  2470. bool consume(char c) {
  2471. if (CROW_UNLIKELY(*data != c)) return false;
  2472. data++;
  2473. return true;
  2474. }
  2475. void ws_skip() {
  2476. while (*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n')
  2477. ++data;
  2478. }
  2479. rvalue decode_string() {
  2480. if (CROW_UNLIKELY(!consume('"'))) return {};
  2481. char *start = data;
  2482. uint8_t has_escaping = 0;
  2483. while (1) {
  2484. if (CROW_LIKELY(*data != '"' && *data != '\\' && *data != '\0')) {
  2485. data++;
  2486. } else if (*data == '"') {
  2487. *data = 0;
  2488. *(start - 1) = has_escaping;
  2489. data++;
  2490. return {type::String, start, data - 1};
  2491. } else if (*data == '\\') {
  2492. has_escaping = 1;
  2493. data++;
  2494. switch (*data) {
  2495. case 'u': {
  2496. auto check = [](char c) {
  2497. return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
  2498. ('A' <= c && c <= 'F');
  2499. };
  2500. if (!(check(*(data + 1)) && check(*(data + 2)) &&
  2501. check(*(data + 3)) && check(*(data + 4))))
  2502. return {};
  2503. }
  2504. data += 5;
  2505. break;
  2506. case '"':
  2507. case '\\':
  2508. case '/':
  2509. case 'b':
  2510. case 'f':
  2511. case 'n':
  2512. case 'r':
  2513. case 't': data++; break;
  2514. default: return {};
  2515. }
  2516. } else
  2517. return {};
  2518. }
  2519. return {};
  2520. }
  2521. rvalue decode_list(unsigned depth) {
  2522. rvalue ret(type::List);
  2523. if (CROW_UNLIKELY(!consume('[')) || CROW_UNLIKELY(depth > max_depth)) {
  2524. ret.set_error();
  2525. return ret;
  2526. }
  2527. ws_skip();
  2528. if (CROW_UNLIKELY(*data == ']')) {
  2529. data++;
  2530. return ret;
  2531. }
  2532. while (1) {
  2533. auto v = decode_value(depth + 1);
  2534. if (CROW_UNLIKELY(!v)) {
  2535. ret.set_error();
  2536. break;
  2537. }
  2538. ws_skip();
  2539. ret.emplace_back(std::move(v));
  2540. if (*data == ']') {
  2541. data++;
  2542. break;
  2543. }
  2544. if (CROW_UNLIKELY(!consume(','))) {
  2545. ret.set_error();
  2546. break;
  2547. }
  2548. ws_skip();
  2549. }
  2550. return ret;
  2551. }
  2552. rvalue decode_number() {
  2553. char *start = data;
  2554. enum NumberParsingState {
  2555. Minus,
  2556. AfterMinus,
  2557. ZeroFirst,
  2558. Digits,
  2559. DigitsAfterPoints,
  2560. E,
  2561. DigitsAfterE,
  2562. Invalid,
  2563. } state{Minus};
  2564. while (CROW_LIKELY(state != Invalid)) {
  2565. switch (*data) {
  2566. case '0':
  2567. state = static_cast<NumberParsingState>("\2\2\7\3\4\6\6"[state]);
  2568. /*if (state == NumberParsingState::Minus || state ==
  2569. NumberParsingState::AfterMinus)
  2570. {
  2571. state = NumberParsingState::ZeroFirst;
  2572. }
  2573. else if (state == NumberParsingState::Digits ||
  2574. state == NumberParsingState::DigitsAfterE ||
  2575. state == NumberParsingState::DigitsAfterPoints)
  2576. {
  2577. // ok; pass
  2578. }
  2579. else if (state == NumberParsingState::E)
  2580. {
  2581. state = NumberParsingState::DigitsAfterE;
  2582. }
  2583. else
  2584. return {};*/
  2585. break;
  2586. case '1':
  2587. case '2':
  2588. case '3':
  2589. case '4':
  2590. case '5':
  2591. case '6':
  2592. case '7':
  2593. case '8':
  2594. case '9':
  2595. state = static_cast<NumberParsingState>("\3\3\7\3\4\6\6"[state]);
  2596. while (*(data + 1) >= '0' && *(data + 1) <= '9')
  2597. data++;
  2598. /*if (state == NumberParsingState::Minus || state ==
  2599. NumberParsingState::AfterMinus)
  2600. {
  2601. state = NumberParsingState::Digits;
  2602. }
  2603. else if (state == NumberParsingState::Digits ||
  2604. state == NumberParsingState::DigitsAfterE ||
  2605. state == NumberParsingState::DigitsAfterPoints)
  2606. {
  2607. // ok; pass
  2608. }
  2609. else if (state == NumberParsingState::E)
  2610. {
  2611. state = NumberParsingState::DigitsAfterE;
  2612. }
  2613. else
  2614. return {};*/
  2615. break;
  2616. case '.':
  2617. state = static_cast<NumberParsingState>("\7\7\4\4\7\7\7"[state]);
  2618. /*
  2619. if (state == NumberParsingState::Digits || state ==
  2620. NumberParsingState::ZeroFirst)
  2621. {
  2622. state = NumberParsingState::DigitsAfterPoints;
  2623. }
  2624. else
  2625. return {};
  2626. */
  2627. break;
  2628. case '-':
  2629. state = static_cast<NumberParsingState>("\1\7\7\7\7\6\7"[state]);
  2630. /*if (state == NumberParsingState::Minus)
  2631. {
  2632. state = NumberParsingState::AfterMinus;
  2633. }
  2634. else if (state == NumberParsingState::E)
  2635. {
  2636. state = NumberParsingState::DigitsAfterE;
  2637. }
  2638. else
  2639. return {};*/
  2640. break;
  2641. case '+':
  2642. state = static_cast<NumberParsingState>("\7\7\7\7\7\6\7"[state]);
  2643. /*if (state == NumberParsingState::E)
  2644. {
  2645. state = NumberParsingState::DigitsAfterE;
  2646. }
  2647. else
  2648. return {};*/
  2649. break;
  2650. case 'e':
  2651. case 'E':
  2652. state = static_cast<NumberParsingState>("\7\7\7\5\5\7\7"[state]);
  2653. /*if (state == NumberParsingState::Digits ||
  2654. state == NumberParsingState::DigitsAfterPoints)
  2655. {
  2656. state = NumberParsingState::E;
  2657. }
  2658. else
  2659. return {};*/
  2660. break;
  2661. default:
  2662. if (CROW_LIKELY(state == NumberParsingState::ZeroFirst ||
  2663. state == NumberParsingState::Digits ||
  2664. state == NumberParsingState::DigitsAfterPoints ||
  2665. state == NumberParsingState::DigitsAfterE))
  2666. return {type::Number, start, data};
  2667. else
  2668. return {};
  2669. }
  2670. data++;
  2671. }
  2672. return {};
  2673. }
  2674. rvalue decode_value(unsigned depth) {
  2675. switch (*data) {
  2676. case '[': return decode_list(depth + 1);
  2677. case '{': return decode_object(depth + 1);
  2678. case '"': return decode_string();
  2679. case 't':
  2680. if ( // e-data >= 4 &&
  2681. data[1] == 'r' && data[2] == 'u' && data[3] == 'e') {
  2682. data += 4;
  2683. return {type::True};
  2684. } else
  2685. return {};
  2686. case 'f':
  2687. if ( // e-data >= 5 &&
  2688. data[1] == 'a' && data[2] == 'l' && data[3] == 's' &&
  2689. data[4] == 'e') {
  2690. data += 5;
  2691. return {type::False};
  2692. } else
  2693. return {};
  2694. case 'n':
  2695. if ( // e-data >= 4 &&
  2696. data[1] == 'u' && data[2] == 'l' && data[3] == 'l') {
  2697. data += 4;
  2698. return {type::Null};
  2699. } else
  2700. return {};
  2701. // case '1': case '2': case '3':
  2702. // case '4': case '5': case '6':
  2703. // case '7': case '8': case '9':
  2704. // case '0': case '-':
  2705. default: return decode_number();
  2706. }
  2707. return {};
  2708. }
  2709. rvalue decode_object(unsigned depth) {
  2710. rvalue ret(type::Object);
  2711. if (CROW_UNLIKELY(!consume('{')) || CROW_UNLIKELY(depth > max_depth)) {
  2712. ret.set_error();
  2713. return ret;
  2714. }
  2715. ws_skip();
  2716. if (CROW_UNLIKELY(*data == '}')) {
  2717. data++;
  2718. return ret;
  2719. }
  2720. while (1) {
  2721. auto t = decode_string();
  2722. if (CROW_UNLIKELY(!t)) {
  2723. ret.set_error();
  2724. break;
  2725. }
  2726. ws_skip();
  2727. if (CROW_UNLIKELY(!consume(':'))) {
  2728. ret.set_error();
  2729. break;
  2730. }
  2731. // TODO(ipkn) caching key to speed up (flyweight?)
  2732. // I have no idea how flyweight could apply here, but maybe some speedup
  2733. // can happen if we stopped checking type since decode_string returns a
  2734. // string anyway
  2735. auto key = t.s();
  2736. ws_skip();
  2737. auto v = decode_value(depth + 1);
  2738. if (CROW_UNLIKELY(!v)) {
  2739. ret.set_error();
  2740. break;
  2741. }
  2742. ws_skip();
  2743. v.key_ = std::move(key);
  2744. ret.emplace_back(std::move(v));
  2745. if (CROW_UNLIKELY(*data == '}')) {
  2746. data++;
  2747. break;
  2748. }
  2749. if (CROW_UNLIKELY(!consume(','))) {
  2750. ret.set_error();
  2751. break;
  2752. }
  2753. ws_skip();
  2754. }
  2755. return ret;
  2756. }
  2757. rvalue parse() {
  2758. ws_skip();
  2759. auto ret = decode_value(0); // or decode object?
  2760. ws_skip();
  2761. if (ret && *data != '\0') ret.set_error();
  2762. return ret;
  2763. }
  2764. char *data;
  2765. };
  2766. return Parser(data, size).parse();
  2767. }
  2768. inline rvalue load(const char *data, size_t size) {
  2769. char *s = new char[size + 1];
  2770. memcpy(s, data, size);
  2771. s[size] = 0;
  2772. auto ret = load_nocopy_internal(s, size);
  2773. if (ret)
  2774. ret.key_.force(s, size);
  2775. else
  2776. delete[] s;
  2777. return ret;
  2778. }
  2779. inline rvalue load(const char *data) { return load(data, strlen(data)); }
  2780. inline rvalue load(const std::string &str) {
  2781. return load(str.data(), str.size());
  2782. }
  2783. struct wvalue_reader;
  2784. /// JSON write value.
  2785. ///
  2786. /// Value can mean any json value, including a JSON object.<br>
  2787. /// Write means this class is used to primarily assemble JSON objects using keys
  2788. /// and values and export those into a string.
  2789. class wvalue : public returnable {
  2790. friend class crow::mustache::template_t;
  2791. friend struct wvalue_reader;
  2792. public:
  2793. using object =
  2794. #ifdef CROW_JSON_USE_MAP
  2795. std::map<std::string, wvalue>;
  2796. #else
  2797. std::unordered_map<std::string, wvalue>;
  2798. #endif
  2799. using list = std::vector<wvalue>;
  2800. type t() const { return t_; }
  2801. /// Create an empty json value (outputs "{}" instead of a "null" string)
  2802. static crow::json::wvalue empty_object() {
  2803. return crow::json::wvalue::object();
  2804. }
  2805. private:
  2806. type t_{type::Null}; ///< The type of the value.
  2807. num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_
  2808. ///< is a number.
  2809. union number {
  2810. double d;
  2811. int64_t si;
  2812. uint64_t ui;
  2813. public:
  2814. constexpr number() noexcept
  2815. : ui() {} /* default constructor initializes unsigned integer. */
  2816. constexpr number(std::uint64_t value) noexcept : ui(value) {}
  2817. constexpr number(std::int64_t value) noexcept : si(value) {}
  2818. explicit constexpr number(double value) noexcept : d(value) {}
  2819. explicit constexpr number(float value) noexcept : d(value) {}
  2820. } num; ///< Value if type is a number.
  2821. std::string s; ///< Value if type is a string.
  2822. std::unique_ptr<list> l; ///< Value if type is a list.
  2823. std::unique_ptr<object> o; ///< Value if type is a JSON object.
  2824. std::function<std::string(std::string &)>
  2825. f; ///< Value if type is a function (C++ lambda)
  2826. public:
  2827. wvalue() : returnable("application/json") {}
  2828. wvalue(std::nullptr_t) : returnable("application/json"), t_(type::Null) {}
  2829. wvalue(bool value)
  2830. : returnable("application/json"), t_(value ? type::True : type::False) {}
  2831. wvalue(std::uint8_t value)
  2832. : returnable("application/json"), t_(type::Number),
  2833. nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {
  2834. }
  2835. wvalue(std::uint16_t value)
  2836. : returnable("application/json"), t_(type::Number),
  2837. nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {
  2838. }
  2839. wvalue(std::uint32_t value)
  2840. : returnable("application/json"), t_(type::Number),
  2841. nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {
  2842. }
  2843. wvalue(std::uint64_t value)
  2844. : returnable("application/json"), t_(type::Number),
  2845. nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {
  2846. }
  2847. wvalue(std::int8_t value)
  2848. : returnable("application/json"), t_(type::Number),
  2849. nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
  2850. wvalue(std::int16_t value)
  2851. : returnable("application/json"), t_(type::Number),
  2852. nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
  2853. wvalue(std::int32_t value)
  2854. : returnable("application/json"), t_(type::Number),
  2855. nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
  2856. wvalue(std::int64_t value)
  2857. : returnable("application/json"), t_(type::Number),
  2858. nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
  2859. wvalue(float value)
  2860. : returnable("application/json"), t_(type::Number),
  2861. nt(num_type::Floating_point), num(static_cast<double>(value)) {}
  2862. wvalue(double value)
  2863. : returnable("application/json"), t_(type::Number),
  2864. nt(num_type::Double_precision_floating_point),
  2865. num(static_cast<double>(value)) {}
  2866. wvalue(char const *value)
  2867. : returnable("application/json"), t_(type::String), s(value) {}
  2868. wvalue(std::string const &value)
  2869. : returnable("application/json"), t_(type::String), s(value) {}
  2870. wvalue(std::string &&value)
  2871. : returnable("application/json"), t_(type::String), s(std::move(value)) {}
  2872. wvalue(std::initializer_list<std::pair<std::string const, wvalue>>
  2873. initializer_list)
  2874. : returnable("application/json"), t_(type::Object),
  2875. o(new object(initializer_list)) {}
  2876. wvalue(object const &value)
  2877. : returnable("application/json"), t_(type::Object), o(new object(value)) {
  2878. }
  2879. wvalue(object &&value)
  2880. : returnable("application/json"), t_(type::Object),
  2881. o(new object(std::move(value))) {}
  2882. wvalue(const list &r) : returnable("application/json") {
  2883. t_ = type::List;
  2884. l = std::unique_ptr<list>(new list{});
  2885. l->reserve(r.size());
  2886. for (auto it = r.begin(); it != r.end(); ++it)
  2887. l->emplace_back(*it);
  2888. }
  2889. wvalue(list &r) : returnable("application/json") {
  2890. t_ = type::List;
  2891. l = std::unique_ptr<list>(new list{});
  2892. l->reserve(r.size());
  2893. for (auto it = r.begin(); it != r.end(); ++it)
  2894. l->emplace_back(*it);
  2895. }
  2896. /// Create a write value from a read value (useful for editing JSON strings).
  2897. wvalue(const rvalue &r) : returnable("application/json") {
  2898. t_ = r.t();
  2899. switch (r.t()) {
  2900. case type::Null:
  2901. case type::False:
  2902. case type::True:
  2903. case type::Function: return;
  2904. case type::Number:
  2905. nt = r.nt();
  2906. if (nt == num_type::Floating_point ||
  2907. nt == num_type::Double_precision_floating_point)
  2908. num.d = r.d();
  2909. else if (nt == num_type::Signed_integer)
  2910. num.si = r.i();
  2911. else
  2912. num.ui = r.u();
  2913. return;
  2914. case type::String: s = r.s(); return;
  2915. case type::List:
  2916. l = std::unique_ptr<list>(new list{});
  2917. l->reserve(r.size());
  2918. for (auto it = r.begin(); it != r.end(); ++it)
  2919. l->emplace_back(*it);
  2920. return;
  2921. case type::Object:
  2922. o = std::unique_ptr<object>(new object{});
  2923. for (auto it = r.begin(); it != r.end(); ++it)
  2924. o->emplace(it->key(), *it);
  2925. return;
  2926. }
  2927. }
  2928. wvalue(const wvalue &r) : returnable("application/json") {
  2929. t_ = r.t();
  2930. switch (r.t()) {
  2931. case type::Null:
  2932. case type::False:
  2933. case type::True: return;
  2934. case type::Number:
  2935. nt = r.nt;
  2936. if (nt == num_type::Floating_point ||
  2937. nt == num_type::Double_precision_floating_point)
  2938. num.d = r.num.d;
  2939. else if (nt == num_type::Signed_integer)
  2940. num.si = r.num.si;
  2941. else
  2942. num.ui = r.num.ui;
  2943. return;
  2944. case type::String: s = r.s; return;
  2945. case type::List:
  2946. l = std::unique_ptr<list>(new list{});
  2947. l->reserve(r.size());
  2948. for (auto it = r.l->begin(); it != r.l->end(); ++it)
  2949. l->emplace_back(*it);
  2950. return;
  2951. case type::Object:
  2952. o = std::unique_ptr<object>(new object{});
  2953. o->insert(r.o->begin(), r.o->end());
  2954. return;
  2955. case type::Function: f = r.f;
  2956. }
  2957. }
  2958. wvalue(wvalue &&r) : returnable("application/json") { *this = std::move(r); }
  2959. wvalue &operator=(wvalue &&r) {
  2960. t_ = r.t_;
  2961. nt = r.nt;
  2962. num = r.num;
  2963. s = std::move(r.s);
  2964. l = std::move(r.l);
  2965. o = std::move(r.o);
  2966. return *this;
  2967. }
  2968. /// Used for compatibility, same as \ref reset()
  2969. void clear() { reset(); }
  2970. void reset() {
  2971. t_ = type::Null;
  2972. l.reset();
  2973. o.reset();
  2974. }
  2975. wvalue &operator=(std::nullptr_t) {
  2976. reset();
  2977. return *this;
  2978. }
  2979. wvalue &operator=(bool value) {
  2980. reset();
  2981. if (value)
  2982. t_ = type::True;
  2983. else
  2984. t_ = type::False;
  2985. return *this;
  2986. }
  2987. wvalue &operator=(float value) {
  2988. reset();
  2989. t_ = type::Number;
  2990. num.d = value;
  2991. nt = num_type::Floating_point;
  2992. return *this;
  2993. }
  2994. wvalue &operator=(double value) {
  2995. reset();
  2996. t_ = type::Number;
  2997. num.d = value;
  2998. nt = num_type::Double_precision_floating_point;
  2999. return *this;
  3000. }
  3001. wvalue &operator=(unsigned short value) {
  3002. reset();
  3003. t_ = type::Number;
  3004. num.ui = value;
  3005. nt = num_type::Unsigned_integer;
  3006. return *this;
  3007. }
  3008. wvalue &operator=(short value) {
  3009. reset();
  3010. t_ = type::Number;
  3011. num.si = value;
  3012. nt = num_type::Signed_integer;
  3013. return *this;
  3014. }
  3015. wvalue &operator=(long long value) {
  3016. reset();
  3017. t_ = type::Number;
  3018. num.si = value;
  3019. nt = num_type::Signed_integer;
  3020. return *this;
  3021. }
  3022. wvalue &operator=(long value) {
  3023. reset();
  3024. t_ = type::Number;
  3025. num.si = value;
  3026. nt = num_type::Signed_integer;
  3027. return *this;
  3028. }
  3029. wvalue &operator=(int value) {
  3030. reset();
  3031. t_ = type::Number;
  3032. num.si = value;
  3033. nt = num_type::Signed_integer;
  3034. return *this;
  3035. }
  3036. wvalue &operator=(unsigned long long value) {
  3037. reset();
  3038. t_ = type::Number;
  3039. num.ui = value;
  3040. nt = num_type::Unsigned_integer;
  3041. return *this;
  3042. }
  3043. wvalue &operator=(unsigned long value) {
  3044. reset();
  3045. t_ = type::Number;
  3046. num.ui = value;
  3047. nt = num_type::Unsigned_integer;
  3048. return *this;
  3049. }
  3050. wvalue &operator=(unsigned int value) {
  3051. reset();
  3052. t_ = type::Number;
  3053. num.ui = value;
  3054. nt = num_type::Unsigned_integer;
  3055. return *this;
  3056. }
  3057. wvalue &operator=(const char *str) {
  3058. reset();
  3059. t_ = type::String;
  3060. s = str;
  3061. return *this;
  3062. }
  3063. wvalue &operator=(const std::string &str) {
  3064. reset();
  3065. t_ = type::String;
  3066. s = str;
  3067. return *this;
  3068. }
  3069. wvalue &operator=(list &&v) {
  3070. if (t_ != type::List) reset();
  3071. t_ = type::List;
  3072. if (!l) l = std::unique_ptr<list>(new list{});
  3073. l->clear();
  3074. l->resize(v.size());
  3075. size_t idx = 0;
  3076. for (auto &x : v) {
  3077. (*l)[idx++] = std::move(x);
  3078. }
  3079. return *this;
  3080. }
  3081. template <typename T> wvalue &operator=(const std::vector<T> &v) {
  3082. if (t_ != type::List) reset();
  3083. t_ = type::List;
  3084. if (!l) l = std::unique_ptr<list>(new list{});
  3085. l->clear();
  3086. l->resize(v.size());
  3087. size_t idx = 0;
  3088. for (auto &x : v) {
  3089. (*l)[idx++] = x;
  3090. }
  3091. return *this;
  3092. }
  3093. wvalue &operator=(std::initializer_list<std::pair<std::string const, wvalue>>
  3094. initializer_list) {
  3095. if (t_ != type::Object) {
  3096. reset();
  3097. t_ = type::Object;
  3098. o = std::unique_ptr<object>(new object(initializer_list));
  3099. } else {
  3100. #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || \
  3101. defined(__ANDROID__) || defined(_LIBCPP_VERSION)
  3102. o = std::unique_ptr<object>(new object(initializer_list));
  3103. #else
  3104. (*o) = initializer_list;
  3105. #endif
  3106. }
  3107. return *this;
  3108. }
  3109. wvalue &operator=(object const &value) {
  3110. if (t_ != type::Object) {
  3111. reset();
  3112. t_ = type::Object;
  3113. o = std::unique_ptr<object>(new object(value));
  3114. } else {
  3115. #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || \
  3116. defined(__ANDROID__) || defined(_LIBCPP_VERSION)
  3117. o = std::unique_ptr<object>(new object(value));
  3118. #else
  3119. (*o) = value;
  3120. #endif
  3121. }
  3122. return *this;
  3123. }
  3124. wvalue &operator=(object &&value) {
  3125. if (t_ != type::Object) {
  3126. reset();
  3127. t_ = type::Object;
  3128. o = std::unique_ptr<object>(new object(std::move(value)));
  3129. } else {
  3130. (*o) = std::move(value);
  3131. }
  3132. return *this;
  3133. }
  3134. wvalue &operator=(std::function<std::string(std::string &)> &&func) {
  3135. reset();
  3136. t_ = type::Function;
  3137. f = std::move(func);
  3138. return *this;
  3139. }
  3140. wvalue &operator[](unsigned index) {
  3141. if (t_ != type::List) reset();
  3142. t_ = type::List;
  3143. if (!l) l = std::unique_ptr<list>(new list{});
  3144. if (l->size() < index + 1) l->resize(index + 1);
  3145. return (*l)[index];
  3146. }
  3147. const wvalue &operator[](unsigned index) const {
  3148. return const_cast<wvalue *>(this)->operator[](index);
  3149. }
  3150. int count(const std::string &str) const {
  3151. if (t_ != type::Object) return 0;
  3152. if (!o) return 0;
  3153. return o->count(str);
  3154. }
  3155. wvalue &operator[](const std::string &str) {
  3156. if (t_ != type::Object) reset();
  3157. t_ = type::Object;
  3158. if (!o) o = std::unique_ptr<object>(new object{});
  3159. return (*o)[str];
  3160. }
  3161. const wvalue &operator[](const std::string &str) const {
  3162. return const_cast<wvalue *>(this)->operator[](str);
  3163. }
  3164. std::vector<std::string> keys() const {
  3165. if (t_ != type::Object) return {};
  3166. std::vector<std::string> result;
  3167. for (auto &kv : *o) {
  3168. result.push_back(kv.first);
  3169. }
  3170. return result;
  3171. }
  3172. std::string
  3173. execute(std::string txt = "") const // Not using reference because it cannot
  3174. // be used with a default rvalue
  3175. {
  3176. if (t_ != type::Function) return "";
  3177. return f(txt);
  3178. }
  3179. /// If the wvalue is a list, it returns the length of the list, otherwise it
  3180. /// returns 1.
  3181. std::size_t size() const {
  3182. if (t_ != type::List) return 1;
  3183. return l->size();
  3184. }
  3185. /// Returns an estimated size of the value in bytes.
  3186. size_t estimate_length() const {
  3187. switch (t_) {
  3188. case type::Null: return 4;
  3189. case type::False: return 5;
  3190. case type::True: return 4;
  3191. case type::Number: return 30;
  3192. case type::String: return 2 + s.size() + s.size() / 2;
  3193. case type::List: {
  3194. size_t sum{};
  3195. if (l) {
  3196. for (auto &x : *l) {
  3197. sum += 1;
  3198. sum += x.estimate_length();
  3199. }
  3200. }
  3201. return sum + 2;
  3202. }
  3203. case type::Object: {
  3204. size_t sum{};
  3205. if (o) {
  3206. for (auto &kv : *o) {
  3207. sum += 2;
  3208. sum += 2 + kv.first.size() + kv.first.size() / 2;
  3209. sum += kv.second.estimate_length();
  3210. }
  3211. }
  3212. return sum + 2;
  3213. }
  3214. case type::Function: return 0;
  3215. }
  3216. return 1;
  3217. }
  3218. private:
  3219. inline void dump_string(const std::string &str, std::string &out) const {
  3220. out.push_back('"');
  3221. escape(str, out);
  3222. out.push_back('"');
  3223. }
  3224. inline void dump_indentation_part(std::string &out, const int indent,
  3225. const char separator,
  3226. const int indent_level) const {
  3227. out.push_back('\n');
  3228. out.append(indent_level * indent, separator);
  3229. }
  3230. inline void dump_internal(const wvalue &v, std::string &out, const int indent,
  3231. const char separator,
  3232. const int indent_level = 0) const {
  3233. switch (v.t_) {
  3234. case type::Null: out += "null"; break;
  3235. case type::False: out += "false"; break;
  3236. case type::True: out += "true"; break;
  3237. case type::Number: {
  3238. if (v.nt == num_type::Floating_point ||
  3239. v.nt == num_type::Double_precision_floating_point) {
  3240. if (isnan(v.num.d) || isinf(v.num.d)) {
  3241. out += "null";
  3242. CROW_LOG_WARNING << "Invalid JSON value detected (" << v.num.d
  3243. << "), value set to null";
  3244. break;
  3245. }
  3246. enum {
  3247. start,
  3248. decp, // Decimal point
  3249. zero
  3250. } f_state;
  3251. char outbuf[128];
  3252. if (v.nt == num_type::Double_precision_floating_point) {
  3253. #ifdef _MSC_VER
  3254. sprintf_s(outbuf, sizeof(outbuf), "%.*g", DBL_DECIMAL_DIG, v.num.d);
  3255. #else
  3256. snprintf(outbuf, sizeof(outbuf), "%.*g", DBL_DECIMAL_DIG, v.num.d);
  3257. #endif
  3258. } else {
  3259. #ifdef _MSC_VER
  3260. sprintf_s(outbuf, sizeof(outbuf), "%f", v.num.d);
  3261. #else
  3262. snprintf(outbuf, sizeof(outbuf), "%f", v.num.d);
  3263. #endif
  3264. }
  3265. char *p = &outbuf[0];
  3266. char *pos_first_trailing_0 = nullptr;
  3267. f_state = start;
  3268. while (*p != '\0') {
  3269. // std::cout << *p << std::endl;
  3270. char ch = *p;
  3271. switch (f_state) {
  3272. case start: // Loop and lookahead until a decimal point is found
  3273. if (ch == '.') {
  3274. char fch = *(p + 1);
  3275. // if the first character is 0, leave it be (this is so that
  3276. // "1.00000" becomes "1.0" and not "1.")
  3277. if (fch != '\0' && fch == '0') p++;
  3278. f_state = decp;
  3279. }
  3280. p++;
  3281. break;
  3282. case decp: // Loop until a 0 is found, if found, record its position
  3283. if (ch == '0') {
  3284. f_state = zero;
  3285. pos_first_trailing_0 = p;
  3286. }
  3287. p++;
  3288. break;
  3289. case zero: // if a non 0 is found (e.g. 1.00004) remove the earlier
  3290. // recorded 0 position and look for more trailing 0s
  3291. if (ch != '0') {
  3292. pos_first_trailing_0 = nullptr;
  3293. f_state = decp;
  3294. }
  3295. p++;
  3296. break;
  3297. }
  3298. }
  3299. if (pos_first_trailing_0 !=
  3300. nullptr) // if any trailing 0s are found, terminate the string where
  3301. // they begin
  3302. *pos_first_trailing_0 = '\0';
  3303. out += outbuf;
  3304. } else if (v.nt == num_type::Signed_integer) {
  3305. out += std::to_string(v.num.si);
  3306. } else {
  3307. out += std::to_string(v.num.ui);
  3308. }
  3309. } break;
  3310. case type::String: dump_string(v.s, out); break;
  3311. case type::List: {
  3312. out.push_back('[');
  3313. if (indent >= 0) {
  3314. dump_indentation_part(out, indent, separator, indent_level + 1);
  3315. }
  3316. if (v.l) {
  3317. bool first = true;
  3318. for (auto &x : *v.l) {
  3319. if (!first) {
  3320. out.push_back(',');
  3321. if (indent >= 0) {
  3322. dump_indentation_part(out, indent, separator, indent_level + 1);
  3323. }
  3324. }
  3325. first = false;
  3326. dump_internal(x, out, indent, separator, indent_level + 1);
  3327. }
  3328. }
  3329. if (indent >= 0) {
  3330. dump_indentation_part(out, indent, separator, indent_level);
  3331. }
  3332. out.push_back(']');
  3333. } break;
  3334. case type::Object: {
  3335. out.push_back('{');
  3336. if (indent >= 0) {
  3337. dump_indentation_part(out, indent, separator, indent_level + 1);
  3338. }
  3339. if (v.o) {
  3340. bool first = true;
  3341. for (auto &kv : *v.o) {
  3342. if (!first) {
  3343. out.push_back(',');
  3344. if (indent >= 0) {
  3345. dump_indentation_part(out, indent, separator, indent_level + 1);
  3346. }
  3347. }
  3348. first = false;
  3349. dump_string(kv.first, out);
  3350. out.push_back(':');
  3351. if (indent >= 0) { out.push_back(' '); }
  3352. dump_internal(kv.second, out, indent, separator, indent_level + 1);
  3353. }
  3354. }
  3355. if (indent >= 0) {
  3356. dump_indentation_part(out, indent, separator, indent_level);
  3357. }
  3358. out.push_back('}');
  3359. } break;
  3360. case type::Function: out += "custom function"; break;
  3361. }
  3362. }
  3363. public:
  3364. std::string dump(const int indent, const char separator = ' ') const {
  3365. std::string ret;
  3366. ret.reserve(estimate_length());
  3367. dump_internal(*this, ret, indent, separator);
  3368. return ret;
  3369. }
  3370. std::string dump() const override {
  3371. static constexpr int DontIndent = -1;
  3372. return dump(DontIndent);
  3373. }
  3374. };
  3375. // Used for accessing the internals of a wvalue
  3376. struct wvalue_reader {
  3377. int64_t get(int64_t fallback) {
  3378. if (ref.t() != type::Number || ref.nt == num_type::Floating_point ||
  3379. ref.nt == num_type::Double_precision_floating_point)
  3380. return fallback;
  3381. return ref.num.si;
  3382. }
  3383. double get(double fallback) {
  3384. if (ref.t() != type::Number || ref.nt != num_type::Floating_point ||
  3385. ref.nt == num_type::Double_precision_floating_point)
  3386. return fallback;
  3387. return ref.num.d;
  3388. }
  3389. bool get(bool fallback) {
  3390. if (ref.t() == type::True) return true;
  3391. if (ref.t() == type::False) return false;
  3392. return fallback;
  3393. }
  3394. std::string get(const std::string &fallback) {
  3395. if (ref.t() != type::String) return fallback;
  3396. return ref.s;
  3397. }
  3398. const wvalue &ref;
  3399. };
  3400. // std::vector<asio::const_buffer> dump_ref(wvalue& v)
  3401. //{
  3402. // }
  3403. } // namespace json
  3404. } // namespace crow
  3405. #include <locale>
  3406. #include <string_view>
  3407. #include <unordered_map>
  3408. namespace crow {
  3409. /// Hashing function for ci_map (unordered_multimap).
  3410. struct ci_hash {
  3411. size_t operator()(const std::string_view key) const {
  3412. std::size_t seed = 0;
  3413. std::locale locale;
  3414. for (auto c : key)
  3415. hash_combine(seed, std::toupper(c, locale));
  3416. return seed;
  3417. }
  3418. private:
  3419. static inline void hash_combine(std::size_t &seed, char v) {
  3420. std::hash<char> hasher;
  3421. seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  3422. }
  3423. };
  3424. /// Equals function for ci_map (unordered_multimap).
  3425. struct ci_key_eq {
  3426. bool operator()(const std::string_view l, const std::string_view r) const {
  3427. return utility::string_equals(l, r);
  3428. }
  3429. };
  3430. using ci_map =
  3431. std::unordered_multimap<std::string, std::string, ci_hash, ci_key_eq>;
  3432. } // namespace crow
  3433. #include <iostream>
  3434. #include <stdexcept>
  3435. #include <string>
  3436. #include <vector>
  3437. namespace crow {
  3438. const char cr = '\r';
  3439. const char lf = '\n';
  3440. const std::string crlf("\r\n");
  3441. enum class HTTPMethod : char {
  3442. #ifndef DELETE
  3443. DELETE = 0,
  3444. GET,
  3445. HEAD,
  3446. POST,
  3447. PUT,
  3448. CONNECT,
  3449. OPTIONS,
  3450. TRACE,
  3451. PATCH,
  3452. PURGE,
  3453. COPY,
  3454. LOCK,
  3455. MKCOL,
  3456. MOVE,
  3457. PROPFIND,
  3458. PROPPATCH,
  3459. SEARCH,
  3460. UNLOCK,
  3461. BIND,
  3462. REBIND,
  3463. UNBIND,
  3464. ACL,
  3465. REPORT,
  3466. MKACTIVITY,
  3467. CHECKOUT,
  3468. MERGE,
  3469. MSEARCH,
  3470. NOTIFY,
  3471. SUBSCRIBE,
  3472. UNSUBSCRIBE,
  3473. MKCALENDAR,
  3474. LINK,
  3475. UNLINK,
  3476. SOURCE,
  3477. #endif
  3478. Delete = 0,
  3479. Get,
  3480. Head,
  3481. Post,
  3482. Put,
  3483. Connect,
  3484. Options,
  3485. Trace,
  3486. Patch,
  3487. Purge,
  3488. Copy,
  3489. Lock,
  3490. MkCol,
  3491. Move,
  3492. Propfind,
  3493. Proppatch,
  3494. Search,
  3495. Unlock,
  3496. Bind,
  3497. Rebind,
  3498. Unbind,
  3499. Acl,
  3500. Report,
  3501. MkActivity,
  3502. Checkout,
  3503. Merge,
  3504. MSearch,
  3505. Notify,
  3506. Subscribe,
  3507. Unsubscribe,
  3508. MkCalendar,
  3509. Link,
  3510. Unlink,
  3511. Source,
  3512. InternalMethodCount,
  3513. // should not add an item below this line: used for array count
  3514. };
  3515. constexpr const char *method_strings[] = {
  3516. "DELETE", "GET", "HEAD", "POST", "PUT",
  3517. "CONNECT", "OPTIONS", "TRACE",
  3518. "PATCH", "PURGE",
  3519. "COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND",
  3520. "PROPPATCH", "SEARCH", "UNLOCK", "BIND", "REBIND",
  3521. "UNBIND", "ACL",
  3522. "REPORT", "MKACTIVITY", "CHECKOUT", "MERGE",
  3523. "M-SEARCH", "NOTIFY", "SUBSCRIBE", "UNSUBSCRIBE",
  3524. "MKCALENDAR",
  3525. "LINK", "UNLINK",
  3526. "SOURCE"};
  3527. inline std::string method_name(HTTPMethod method) {
  3528. if (CROW_LIKELY(method < HTTPMethod::InternalMethodCount)) {
  3529. return method_strings[static_cast<unsigned int>(method)];
  3530. }
  3531. return "invalid";
  3532. }
  3533. // clang-format off
  3534. enum status
  3535. {
  3536. CONTINUE = 100,
  3537. SWITCHING_PROTOCOLS = 101,
  3538. OK = 200,
  3539. CREATED = 201,
  3540. ACCEPTED = 202,
  3541. NON_AUTHORITATIVE_INFORMATION = 203,
  3542. NO_CONTENT = 204,
  3543. RESET_CONTENT = 205,
  3544. PARTIAL_CONTENT = 206,
  3545. WEBDAV_MULTI_STATUS = 207,
  3546. MULTIPLE_CHOICES = 300,
  3547. MOVED_PERMANENTLY = 301,
  3548. FOUND = 302,
  3549. SEE_OTHER = 303,
  3550. NOT_MODIFIED = 304,
  3551. TEMPORARY_REDIRECT = 307,
  3552. PERMANENT_REDIRECT = 308,
  3553. BAD_REQUEST = 400,
  3554. UNAUTHORIZED = 401,
  3555. FORBIDDEN = 403,
  3556. NOT_FOUND = 404,
  3557. METHOD_NOT_ALLOWED = 405,
  3558. NOT_ACCEPTABLE = 406,
  3559. PROXY_AUTHENTICATION_REQUIRED = 407,
  3560. CONFLICT = 409,
  3561. GONE = 410,
  3562. PAYLOAD_TOO_LARGE = 413,
  3563. UNSUPPORTED_MEDIA_TYPE = 415,
  3564. RANGE_NOT_SATISFIABLE = 416,
  3565. EXPECTATION_FAILED = 417,
  3566. WEBDAV_PRECONDITION_FAILED = 412,
  3567. WEBDAV_REQUEST_URI_TOO_LONG = 414,
  3568. WEBDAV_UNPROCESSABLE_ENTITY = 422,
  3569. WEBDAV_LOCKED = 423,
  3570. WEBDAV_FAILED_DEPENDENCY = 424,
  3571. PRECONDITION_REQUIRED = 428,
  3572. TOO_MANY_REQUESTS = 429,
  3573. UNAVAILABLE_FOR_LEGAL_REASONS = 451,
  3574. INTERNAL_SERVER_ERROR = 500,
  3575. NOT_IMPLEMENTED = 501,
  3576. BAD_GATEWAY = 502,
  3577. SERVICE_UNAVAILABLE = 503,
  3578. GATEWAY_TIMEOUT = 504,
  3579. VARIANT_ALSO_NEGOTIATES = 506,
  3580. WEBDAV_INSUFFICIENT_STORAGE = 507
  3581. };
  3582. // clang-format on
  3583. enum class ParamType : char {
  3584. INT,
  3585. UINT,
  3586. DOUBLE,
  3587. STRING,
  3588. PATH,
  3589. MAX
  3590. };
  3591. /// @cond SKIP
  3592. struct routing_params {
  3593. std::vector<int64_t> int_params;
  3594. std::vector<uint64_t> uint_params;
  3595. std::vector<double> double_params;
  3596. std::vector<std::string> string_params;
  3597. void debug_print() const {
  3598. std::cerr << "routing_params" << std::endl;
  3599. for (auto i : int_params)
  3600. std::cerr << i << ", ";
  3601. std::cerr << std::endl;
  3602. for (auto i : uint_params)
  3603. std::cerr << i << ", ";
  3604. std::cerr << std::endl;
  3605. for (auto i : double_params)
  3606. std::cerr << i << ", ";
  3607. std::cerr << std::endl;
  3608. for (auto &i : string_params)
  3609. std::cerr << i << ", ";
  3610. std::cerr << std::endl;
  3611. }
  3612. template <typename T> T get(unsigned) const;
  3613. };
  3614. template <> inline int64_t routing_params::get<int64_t>(unsigned index) const {
  3615. return int_params[index];
  3616. }
  3617. template <>
  3618. inline uint64_t routing_params::get<uint64_t>(unsigned index) const {
  3619. return uint_params[index];
  3620. }
  3621. template <> inline double routing_params::get<double>(unsigned index) const {
  3622. return double_params[index];
  3623. }
  3624. template <>
  3625. inline std::string routing_params::get<std::string>(unsigned index) const {
  3626. return string_params[index];
  3627. }
  3628. /// @endcond
  3629. struct routing_handle_result {
  3630. bool catch_all{false};
  3631. size_t rule_index;
  3632. std::vector<size_t> blueprint_indices;
  3633. routing_params r_params;
  3634. HTTPMethod method;
  3635. routing_handle_result() {}
  3636. routing_handle_result(size_t rule_index_,
  3637. std::vector<size_t> blueprint_indices_,
  3638. routing_params r_params_)
  3639. : rule_index(rule_index_), blueprint_indices(blueprint_indices_),
  3640. r_params(r_params_) {}
  3641. routing_handle_result(size_t rule_index_,
  3642. std::vector<size_t> blueprint_indices_,
  3643. routing_params r_params_, HTTPMethod method_)
  3644. : rule_index(rule_index_), blueprint_indices(blueprint_indices_),
  3645. r_params(r_params_), method(method_) {}
  3646. };
  3647. } // namespace crow
  3648. // clang-format off
  3649. #ifndef CROW_MSVC_WORKAROUND
  3650. constexpr crow::HTTPMethod method_from_string(const char* str)
  3651. {
  3652. return crow::black_magic::is_equ_p(str, "GET", 3) ? crow::HTTPMethod::Get :
  3653. crow::black_magic::is_equ_p(str, "DELETE", 6) ? crow::HTTPMethod::Delete :
  3654. crow::black_magic::is_equ_p(str, "HEAD", 4) ? crow::HTTPMethod::Head :
  3655. crow::black_magic::is_equ_p(str, "POST", 4) ? crow::HTTPMethod::Post :
  3656. crow::black_magic::is_equ_p(str, "PUT", 3) ? crow::HTTPMethod::Put :
  3657. crow::black_magic::is_equ_p(str, "OPTIONS", 7) ? crow::HTTPMethod::Options :
  3658. crow::black_magic::is_equ_p(str, "CONNECT", 7) ? crow::HTTPMethod::Connect :
  3659. crow::black_magic::is_equ_p(str, "TRACE", 5) ? crow::HTTPMethod::Trace :
  3660. crow::black_magic::is_equ_p(str, "PATCH", 5) ? crow::HTTPMethod::Patch :
  3661. crow::black_magic::is_equ_p(str, "PURGE", 5) ? crow::HTTPMethod::Purge :
  3662. crow::black_magic::is_equ_p(str, "COPY", 4) ? crow::HTTPMethod::Copy :
  3663. crow::black_magic::is_equ_p(str, "LOCK", 4) ? crow::HTTPMethod::Lock :
  3664. crow::black_magic::is_equ_p(str, "MKCOL", 5) ? crow::HTTPMethod::MkCol :
  3665. crow::black_magic::is_equ_p(str, "MOVE", 4) ? crow::HTTPMethod::Move :
  3666. crow::black_magic::is_equ_p(str, "PROPFIND", 8) ? crow::HTTPMethod::Propfind :
  3667. crow::black_magic::is_equ_p(str, "PROPPATCH", 9) ? crow::HTTPMethod::Proppatch :
  3668. crow::black_magic::is_equ_p(str, "SEARCH", 6) ? crow::HTTPMethod::Search :
  3669. crow::black_magic::is_equ_p(str, "UNLOCK", 6) ? crow::HTTPMethod::Unlock :
  3670. crow::black_magic::is_equ_p(str, "BIND", 4) ? crow::HTTPMethod::Bind :
  3671. crow::black_magic::is_equ_p(str, "REBIND", 6) ? crow::HTTPMethod::Rebind :
  3672. crow::black_magic::is_equ_p(str, "UNBIND", 6) ? crow::HTTPMethod::Unbind :
  3673. crow::black_magic::is_equ_p(str, "ACL", 3) ? crow::HTTPMethod::Acl :
  3674. crow::black_magic::is_equ_p(str, "REPORT", 6) ? crow::HTTPMethod::Report :
  3675. crow::black_magic::is_equ_p(str, "MKACTIVITY", 10) ? crow::HTTPMethod::MkActivity :
  3676. crow::black_magic::is_equ_p(str, "CHECKOUT", 8) ? crow::HTTPMethod::Checkout :
  3677. crow::black_magic::is_equ_p(str, "MERGE", 5) ? crow::HTTPMethod::Merge :
  3678. crow::black_magic::is_equ_p(str, "MSEARCH", 7) ? crow::HTTPMethod::MSearch :
  3679. crow::black_magic::is_equ_p(str, "NOTIFY", 6) ? crow::HTTPMethod::Notify :
  3680. crow::black_magic::is_equ_p(str, "SUBSCRIBE", 9) ? crow::HTTPMethod::Subscribe :
  3681. crow::black_magic::is_equ_p(str, "UNSUBSCRIBE", 11) ? crow::HTTPMethod::Unsubscribe :
  3682. crow::black_magic::is_equ_p(str, "MKCALENDAR", 10) ? crow::HTTPMethod::MkCalendar :
  3683. crow::black_magic::is_equ_p(str, "LINK", 4) ? crow::HTTPMethod::Link :
  3684. crow::black_magic::is_equ_p(str, "UNLINK", 6) ? crow::HTTPMethod::Unlink :
  3685. crow::black_magic::is_equ_p(str, "SOURCE", 6) ? crow::HTTPMethod::Source :
  3686. throw std::runtime_error("invalid http method");
  3687. }
  3688. constexpr crow::HTTPMethod operator""_method(const char* str, size_t /*len*/)
  3689. {
  3690. return method_from_string( str );
  3691. }
  3692. #endif
  3693. // clang-format on
  3694. /* merged revision: 5b951d74bd66ec9d38448e0a85b1cf8b85d97db3 */
  3695. /* updated to : e13b274770da9b82a1085dec29182acfea72e7a7 (beyond v2.9.5) */
  3696. /* commits not included:
  3697. * 091ebb87783a58b249062540bbea07de2a11e9cf
  3698. * 6132d1fefa03f769a3979355d1f5da0b8889cad2
  3699. * 7ba312397c2a6c851a4b5efe6c1603b1e1bda6ff
  3700. * d7675453a6c03180572f084e95eea0d02df39164
  3701. * dff604db203986e532e5a679bafd0e7382c6bdd9 (Might be useful to actually add
  3702. * [upgrade requests with a body]) e01811e7f4894d7f0f7f4bd8492cccec6f6b4038
  3703. * (related to above) 05525c5fde1fc562481f6ae08fa7056185325daf (also related to
  3704. * above) 350258965909f249f9c59823aac240313e0d0120 (cannot be implemented due to
  3705. * upgrade)
  3706. */
  3707. // clang-format off
  3708. extern "C" {
  3709. #include <stddef.h>
  3710. #if defined(_WIN32) && !defined(__MINGW32__) && \
  3711. (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
  3712. #include <BaseTsd.h>
  3713. typedef __int8 int8_t;
  3714. typedef unsigned __int8 uint8_t;
  3715. typedef __int16 int16_t;
  3716. typedef unsigned __int16 uint16_t;
  3717. typedef __int32 int32_t;
  3718. typedef unsigned __int32 uint32_t;
  3719. typedef __int64 int64_t;
  3720. typedef unsigned __int64 uint64_t;
  3721. #elif (defined(__sun) || defined(__sun__)) && defined(__SunOS_5_9)
  3722. #include <sys/inttypes.h>
  3723. #else
  3724. #include <stdint.h>
  3725. #endif
  3726. #include <assert.h>
  3727. #include <ctype.h>
  3728. #include <string.h>
  3729. #include <limits.h>
  3730. }
  3731. namespace crow
  3732. {
  3733. /* Maximium header size allowed. If the macro is not defined
  3734. * before including this header then the default is used. To
  3735. * change the maximum header size, define the macro in the build
  3736. * environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
  3737. * the effective limit on the size of the header, define the macro
  3738. * to a very large number (e.g. -DCROW_HTTP_MAX_HEADER_SIZE=0x7fffffff)
  3739. */
  3740. #ifndef CROW_HTTP_MAX_HEADER_SIZE
  3741. # define CROW_HTTP_MAX_HEADER_SIZE (80*1024)
  3742. #endif
  3743. typedef struct http_parser http_parser;
  3744. typedef struct http_parser_settings http_parser_settings;
  3745. /* Callbacks should return non-zero to indicate an error. The parser will
  3746. * then halt execution.
  3747. *
  3748. * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
  3749. * returning '1' from on_headers_complete will tell the parser that it
  3750. * should not expect a body. This is used when receiving a response to a
  3751. * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
  3752. * chunked' headers that indicate the presence of a body.
  3753. *
  3754. * Returning `2` from on_headers_complete will tell parser that it should not
  3755. * expect neither a body nor any futher responses on this connection. This is
  3756. * useful for handling responses to a CONNECT request which may not contain
  3757. * `Upgrade` or `Connection: upgrade` headers.
  3758. *
  3759. * http_data_cb does not return data chunks. It will be called arbitrarally
  3760. * many times for each string. E.G. you might get 10 callbacks for "on_url"
  3761. * each providing just a few characters more data.
  3762. */
  3763. typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
  3764. typedef int (*http_cb) (http_parser*);
  3765. /* Flag values for http_parser.flags field */
  3766. enum http_connection_flags // This is basically 7 booleans placed into 1 integer. Uses 4 bytes instead of n bytes (7 currently).
  3767. { F_CHUNKED = 1 << 0 // 00000000 00000000 00000000 00000001
  3768. , F_CONNECTION_KEEP_ALIVE = 1 << 1 // 00000000 00000000 00000000 00000010
  3769. , F_CONNECTION_CLOSE = 1 << 2 // 00000000 00000000 00000000 00000100
  3770. , F_TRAILING = 1 << 3 // 00000000 00000000 00000000 00001000
  3771. , F_UPGRADE = 1 << 4 // 00000000 00000000 00000000 00010000
  3772. , F_SKIPBODY = 1 << 5 // 00000000 00000000 00000000 00100000
  3773. , F_CONTENTLENGTH = 1 << 6 // 00000000 00000000 00000000 01000000
  3774. };
  3775. /* Map for errno-related constants
  3776. *
  3777. * The provided argument should be a macro that takes 2 arguments.
  3778. */
  3779. #define CROW_HTTP_ERRNO_MAP(CROW_XX) \
  3780. /* No error */ \
  3781. CROW_XX(OK, "success") \
  3782. \
  3783. /* Callback-related errors */ \
  3784. CROW_XX(CB_message_begin, "the on_message_begin callback failed") \
  3785. CROW_XX(CB_method, "the on_method callback failed") \
  3786. CROW_XX(CB_url, "the \"on_url\" callback failed") \
  3787. CROW_XX(CB_header_field, "the \"on_header_field\" callback failed") \
  3788. CROW_XX(CB_header_value, "the \"on_header_value\" callback failed") \
  3789. CROW_XX(CB_headers_complete, "the \"on_headers_complete\" callback failed") \
  3790. CROW_XX(CB_body, "the \"on_body\" callback failed") \
  3791. CROW_XX(CB_message_complete, "the \"on_message_complete\" callback failed") \
  3792. CROW_XX(CB_status, "the \"on_status\" callback failed") \
  3793. \
  3794. /* Parsing-related errors */ \
  3795. CROW_XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
  3796. CROW_XX(HEADER_OVERFLOW, "too many header bytes seen; overflow detected") \
  3797. CROW_XX(CLOSED_CONNECTION, "data received after completed connection: close message") \
  3798. CROW_XX(INVALID_VERSION, "invalid HTTP version") \
  3799. CROW_XX(INVALID_STATUS, "invalid HTTP status code") \
  3800. CROW_XX(INVALID_METHOD, "invalid HTTP method") \
  3801. CROW_XX(INVALID_URL, "invalid URL") \
  3802. CROW_XX(INVALID_HOST, "invalid host") \
  3803. CROW_XX(INVALID_PORT, "invalid port") \
  3804. CROW_XX(INVALID_PATH, "invalid path") \
  3805. CROW_XX(INVALID_QUERY_STRING, "invalid query string") \
  3806. CROW_XX(INVALID_FRAGMENT, "invalid fragment") \
  3807. CROW_XX(LF_EXPECTED, "LF character expected") \
  3808. CROW_XX(INVALID_HEADER_TOKEN, "invalid character in header") \
  3809. CROW_XX(INVALID_CONTENT_LENGTH, "invalid character in content-length header") \
  3810. CROW_XX(UNEXPECTED_CONTENT_LENGTH, "unexpected content-length header") \
  3811. CROW_XX(INVALID_CHUNK_SIZE, "invalid character in chunk size header") \
  3812. CROW_XX(INVALID_CONSTANT, "invalid constant string") \
  3813. CROW_XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state") \
  3814. CROW_XX(STRICT, "strict mode assertion failed") \
  3815. CROW_XX(UNKNOWN, "an unknown error occurred") \
  3816. CROW_XX(INVALID_TRANSFER_ENCODING, "request has invalid transfer-encoding") \
  3817. /* Define CHPE_* values for each errno value above */
  3818. #define CROW_HTTP_ERRNO_GEN(n, s) CHPE_##n,
  3819. enum http_errno {
  3820. CROW_HTTP_ERRNO_MAP(CROW_HTTP_ERRNO_GEN)
  3821. };
  3822. #undef CROW_HTTP_ERRNO_GEN
  3823. /* Get an http_errno value from an http_parser */
  3824. #define CROW_HTTP_PARSER_ERRNO(p) ((enum http_errno)(p)->http_errno)
  3825. struct http_parser
  3826. {
  3827. /** PRIVATE **/
  3828. unsigned int flags : 7; /* F_* values from 'flags' enum; semi-public */
  3829. unsigned int state : 8; /* enum state from http_parser.c */
  3830. unsigned int header_state : 7; /* enum header_state from http_parser.c */
  3831. unsigned int index : 5; /* index into current matcher */
  3832. unsigned int uses_transfer_encoding : 1; /* Transfer-Encoding header is present */
  3833. unsigned int allow_chunked_length : 1; /* Allow headers with both `Content-Length` and `Transfer-Encoding: chunked` set */
  3834. unsigned int lenient_http_headers : 1;
  3835. uint32_t nread; /* # bytes read in various scenarios */
  3836. uint64_t content_length; /* # bytes in body. `(uint64_t) -1` (all bits one) if no Content-Length header. */
  3837. unsigned long qs_point;
  3838. /** READ-ONLY **/
  3839. unsigned char http_major;
  3840. unsigned char http_minor;
  3841. unsigned int method : 8; /* requests only */
  3842. unsigned int http_errno : 7;
  3843. /* 1 = Upgrade header was present and the parser has exited because of that.
  3844. * 0 = No upgrade header present.
  3845. * Should be checked when http_parser_execute() returns in addition to
  3846. * error checking.
  3847. */
  3848. unsigned int upgrade : 1;
  3849. /** PUBLIC **/
  3850. void* data; /* A pointer to get hook to the "connection" or "socket" object */
  3851. };
  3852. struct http_parser_settings
  3853. {
  3854. http_cb on_message_begin;
  3855. http_cb on_method;
  3856. http_data_cb on_url;
  3857. http_data_cb on_header_field;
  3858. http_data_cb on_header_value;
  3859. http_cb on_headers_complete;
  3860. http_data_cb on_body;
  3861. http_cb on_message_complete;
  3862. };
  3863. // SOURCE (.c) CODE
  3864. static uint32_t max_header_size = CROW_HTTP_MAX_HEADER_SIZE;
  3865. #ifndef CROW_ULLONG_MAX
  3866. # define CROW_ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
  3867. #endif
  3868. #ifndef CROW_MIN
  3869. # define CROW_MIN(a,b) ((a) < (b) ? (a) : (b))
  3870. #endif
  3871. #ifndef CROW_ARRAY_SIZE
  3872. # define CROW_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  3873. #endif
  3874. #ifndef CROW_BIT_AT
  3875. # define CROW_BIT_AT(a, i) \
  3876. (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \
  3877. (1 << ((unsigned int) (i) & 7))))
  3878. #endif
  3879. #define CROW_SET_ERRNO(e) \
  3880. do { \
  3881. parser->nread = nread; \
  3882. parser->http_errno = (e); \
  3883. } while(0)
  3884. /* Run the notify callback FOR, returning ER if it fails */
  3885. #define CROW_CALLBACK_NOTIFY_(FOR, ER) \
  3886. do { \
  3887. assert(CROW_HTTP_PARSER_ERRNO(parser) == CHPE_OK); \
  3888. \
  3889. if (CROW_LIKELY(settings->on_##FOR)) { \
  3890. if (CROW_UNLIKELY(0 != settings->on_##FOR(parser))) { \
  3891. CROW_SET_ERRNO(CHPE_CB_##FOR); \
  3892. } \
  3893. \
  3894. /* We either errored above or got paused; get out */ \
  3895. if (CROW_UNLIKELY(CROW_HTTP_PARSER_ERRNO(parser) != CHPE_OK)) { \
  3896. return (ER); \
  3897. } \
  3898. } \
  3899. } while (0)
  3900. /* Run the notify callback FOR and consume the current byte */
  3901. #define CROW_CALLBACK_NOTIFY(FOR) CROW_CALLBACK_NOTIFY_(FOR, p - data + 1)
  3902. /* Run the notify callback FOR and don't consume the current byte */
  3903. #define CROW_CALLBACK_NOTIFY_NOADVANCE(FOR) CROW_CALLBACK_NOTIFY_(FOR, p - data)
  3904. /* Run data callback FOR with LEN bytes, returning ER if it fails */
  3905. #define CROW_CALLBACK_DATA_(FOR, LEN, ER) \
  3906. do { \
  3907. assert(CROW_HTTP_PARSER_ERRNO(parser) == CHPE_OK); \
  3908. \
  3909. if (FOR##_mark) { \
  3910. if (CROW_LIKELY(settings->on_##FOR)) { \
  3911. if (CROW_UNLIKELY(0 != \
  3912. settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
  3913. CROW_SET_ERRNO(CHPE_CB_##FOR); \
  3914. } \
  3915. \
  3916. /* We either errored above or got paused; get out */ \
  3917. if (CROW_UNLIKELY(CROW_HTTP_PARSER_ERRNO(parser) != CHPE_OK)) {\
  3918. return (ER); \
  3919. } \
  3920. } \
  3921. FOR##_mark = NULL; \
  3922. } \
  3923. } while (0)
  3924. /* Run the data callback FOR and consume the current byte */
  3925. #define CROW_CALLBACK_DATA(FOR) \
  3926. CROW_CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
  3927. /* Run the data callback FOR and don't consume the current byte */
  3928. #define CROW_CALLBACK_DATA_NOADVANCE(FOR) \
  3929. CROW_CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
  3930. /* Set the mark FOR; non-destructive if mark is already set */
  3931. #define CROW_MARK(FOR) \
  3932. do { \
  3933. if (!FOR##_mark) { \
  3934. FOR##_mark = p; \
  3935. } \
  3936. } while (0)
  3937. /* Don't allow the total size of the HTTP headers (including the status
  3938. * line) to exceed max_header_size. This check is here to protect
  3939. * embedders against denial-of-service attacks where the attacker feeds
  3940. * us a never-ending header that the embedder keeps buffering.
  3941. *
  3942. * This check is arguably the responsibility of embedders but we're doing
  3943. * it on the embedder's behalf because most won't bother and this way we
  3944. * make the web a little safer. max_header_size is still far bigger
  3945. * than any reasonable request or response so this should never affect
  3946. * day-to-day operation.
  3947. */
  3948. #define CROW_COUNT_HEADER_SIZE(V) \
  3949. do { \
  3950. nread += (uint32_t)(V); \
  3951. if (CROW_UNLIKELY(nread > max_header_size)) { \
  3952. CROW_SET_ERRNO(CHPE_HEADER_OVERFLOW); \
  3953. goto error; \
  3954. } \
  3955. } while (0)
  3956. #define CROW_REEXECUTE() \
  3957. goto reexecute; \
  3958. #define CROW_PROXY_CONNECTION "proxy-connection"
  3959. #define CROW_CONNECTION "connection"
  3960. #define CROW_CONTENT_LENGTH "content-length"
  3961. #define CROW_TRANSFER_ENCODING "transfer-encoding"
  3962. #define CROW_UPGRADE "upgrade"
  3963. #define CROW_CHUNKED "chunked"
  3964. #define CROW_KEEP_ALIVE "keep-alive"
  3965. #define CROW_CLOSE "close"
  3966. enum state
  3967. {
  3968. s_dead = 1 /* important that this is > 0 */
  3969. ,
  3970. s_start_req
  3971. ,
  3972. s_req_method,
  3973. s_req_spaces_before_url,
  3974. s_req_schema,
  3975. s_req_schema_slash,
  3976. s_req_schema_slash_slash,
  3977. s_req_server_start,
  3978. s_req_server, // }
  3979. s_req_server_with_at, // |
  3980. s_req_path, // | The parser recognizes how to switch between these states,
  3981. s_req_query_string_start, // | however it doesn't process them any differently.
  3982. s_req_query_string, // }
  3983. s_req_http_start,
  3984. s_req_http_H,
  3985. s_req_http_HT,
  3986. s_req_http_HTT,
  3987. s_req_http_HTTP,
  3988. s_req_http_I,
  3989. s_req_http_IC,
  3990. s_req_http_major,
  3991. s_req_http_dot,
  3992. s_req_http_minor,
  3993. s_req_http_end,
  3994. s_req_line_almost_done
  3995. ,
  3996. s_header_field_start,
  3997. s_header_field,
  3998. s_header_value_discard_ws,
  3999. s_header_value_discard_ws_almost_done,
  4000. s_header_value_discard_lws,
  4001. s_header_value_start,
  4002. s_header_value,
  4003. s_header_value_lws
  4004. ,
  4005. s_header_almost_done
  4006. ,
  4007. s_chunk_size_start,
  4008. s_chunk_size,
  4009. s_chunk_parameters,
  4010. s_chunk_size_almost_done
  4011. ,
  4012. s_headers_almost_done,
  4013. s_headers_done
  4014. /* Important: 's_headers_done' must be the last 'header' state. All
  4015. * states beyond this must be 'body' states. It is used for overflow
  4016. * checking. See the CROW_PARSING_HEADER() macro.
  4017. */
  4018. ,
  4019. s_chunk_data,
  4020. s_chunk_data_almost_done,
  4021. s_chunk_data_done
  4022. ,
  4023. s_body_identity,
  4024. s_body_identity_eof
  4025. ,
  4026. s_message_done
  4027. };
  4028. #define CROW_PARSING_HEADER(state) (state <= s_headers_done)
  4029. enum header_states
  4030. { h_general = 0
  4031. , h_C
  4032. , h_CO
  4033. , h_CON
  4034. , h_matching_connection
  4035. , h_matching_proxy_connection
  4036. , h_matching_content_length
  4037. , h_matching_transfer_encoding
  4038. , h_matching_upgrade
  4039. , h_connection
  4040. , h_content_length
  4041. , h_content_length_num
  4042. , h_content_length_ws
  4043. , h_transfer_encoding
  4044. , h_upgrade
  4045. , h_matching_transfer_encoding_token_start
  4046. , h_matching_transfer_encoding_chunked
  4047. , h_matching_transfer_encoding_token
  4048. , h_matching_connection_keep_alive
  4049. , h_matching_connection_close
  4050. , h_transfer_encoding_chunked
  4051. , h_connection_keep_alive
  4052. , h_connection_close
  4053. };
  4054. enum http_host_state
  4055. {
  4056. s_http_host_dead = 1
  4057. , s_http_userinfo_start
  4058. , s_http_userinfo
  4059. , s_http_host_start
  4060. , s_http_host_v6_start
  4061. , s_http_host
  4062. , s_http_host_v6
  4063. , s_http_host_v6_end
  4064. , s_http_host_v6_zone_start
  4065. , s_http_host_v6_zone
  4066. , s_http_host_port_start
  4067. , s_http_host_port
  4068. };
  4069. /* Macros for character classes; depends on strict-mode */
  4070. #define CROW_LOWER(c) (unsigned char)(c | 0x20)
  4071. #define CROW_IS_ALPHA(c) (CROW_LOWER(c) >= 'a' && CROW_LOWER(c) <= 'z')
  4072. #define CROW_IS_NUM(c) ((c) >= '0' && (c) <= '9')
  4073. #define CROW_IS_ALPHANUM(c) (CROW_IS_ALPHA(c) || CROW_IS_NUM(c))
  4074. //#define CROW_IS_HEX(c) (CROW_IS_NUM(c) || (CROW_LOWER(c) >= 'a' && CROW_LOWER(c) <= 'f'))
  4075. #define CROW_IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \
  4076. (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
  4077. (c) == ')')
  4078. #define CROW_IS_USERINFO_CHAR(c) (CROW_IS_ALPHANUM(c) || CROW_IS_MARK(c) || (c) == '%' || \
  4079. (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
  4080. (c) == '$' || (c) == ',')
  4081. #define CROW_TOKEN(c) (tokens[(unsigned char)c])
  4082. #define CROW_IS_URL_CHAR(c) (CROW_BIT_AT(normal_url_char, (unsigned char)c))
  4083. //#define CROW_IS_HOST_CHAR(c) (CROW_IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
  4084. /**
  4085. * Verify that a char is a valid visible (printable) US-ASCII
  4086. * character or %x80-FF
  4087. **/
  4088. #define CROW_IS_HEADER_CHAR(ch) \
  4089. (ch == cr || ch == lf || ch == 9 || ((unsigned char)ch > 31 && ch != 127))
  4090. #define CROW_start_state s_start_req
  4091. # define CROW_STRICT_CHECK(cond) \
  4092. do { \
  4093. if (cond) { \
  4094. CROW_SET_ERRNO(CHPE_STRICT); \
  4095. goto error; \
  4096. } \
  4097. } while (0)
  4098. #define CROW_NEW_MESSAGE() (CROW_start_state)
  4099. /* Our URL parser.
  4100. *
  4101. * This is designed to be shared by http_parser_execute() for URL validation,
  4102. * hence it has a state transition + byte-for-byte interface. In addition, it
  4103. * is meant to be embedded in http_parser_parse_url(), which does the dirty
  4104. * work of turning state transitions URL components for its API.
  4105. *
  4106. * This function should only be invoked with non-space characters. It is
  4107. * assumed that the caller cares about (and can detect) the transition between
  4108. * URL and non-URL states by looking for these.
  4109. */
  4110. inline enum state
  4111. parse_url_char(enum state s, const char ch, http_parser *parser, const char* url_mark, const char* p)
  4112. {
  4113. # define CROW_T(v) 0
  4114. static const uint8_t normal_url_char[32] = {
  4115. /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
  4116. 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
  4117. /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
  4118. 0 |CROW_T(2)| 0 | 0 |CROW_T(16)| 0 | 0 | 0,
  4119. /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
  4120. 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
  4121. /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
  4122. 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
  4123. /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
  4124. 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128,
  4125. /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
  4126. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4127. /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
  4128. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4129. /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
  4130. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0,
  4131. /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
  4132. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4133. /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
  4134. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4135. /* 80 P 81 Q 82 R 83 S 84 CROW_T 85 U 86 V 87 W */
  4136. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4137. /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
  4138. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4139. /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
  4140. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4141. /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
  4142. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4143. /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
  4144. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
  4145. /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
  4146. 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, };
  4147. #undef CROW_T
  4148. if (ch == ' ' || ch == '\r' || ch == '\n') {
  4149. return s_dead;
  4150. }
  4151. if (ch == '\t' || ch == '\f') {
  4152. return s_dead;
  4153. }
  4154. switch (s) {
  4155. case s_req_spaces_before_url:
  4156. /* Proxied requests are followed by scheme of an absolute URI (alpha).
  4157. * All methods except CONNECT are followed by '/' or '*'.
  4158. */
  4159. if (ch == '/' || ch == '*') {
  4160. return s_req_path;
  4161. }
  4162. if (CROW_IS_ALPHA(ch)) {
  4163. return s_req_schema;
  4164. }
  4165. break;
  4166. case s_req_schema:
  4167. if (CROW_IS_ALPHA(ch)) {
  4168. return s;
  4169. }
  4170. if (ch == ':') {
  4171. return s_req_schema_slash;
  4172. }
  4173. break;
  4174. case s_req_schema_slash:
  4175. if (ch == '/') {
  4176. return s_req_schema_slash_slash;
  4177. }
  4178. break;
  4179. case s_req_schema_slash_slash:
  4180. if (ch == '/') {
  4181. return s_req_server_start;
  4182. }
  4183. break;
  4184. case s_req_server_with_at:
  4185. if (ch == '@') {
  4186. return s_dead;
  4187. }
  4188. /* fall through */
  4189. case s_req_server_start:
  4190. case s_req_server:
  4191. if (ch == '/') {
  4192. return s_req_path;
  4193. }
  4194. if (ch == '?') {
  4195. parser->qs_point = p - url_mark;
  4196. return s_req_query_string_start;
  4197. }
  4198. if (ch == '@') {
  4199. return s_req_server_with_at;
  4200. }
  4201. if (CROW_IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
  4202. return s_req_server;
  4203. }
  4204. break;
  4205. case s_req_path:
  4206. if (CROW_IS_URL_CHAR(ch)) {
  4207. return s;
  4208. }
  4209. else if (ch == '?')
  4210. {
  4211. parser->qs_point = p - url_mark;
  4212. return s_req_query_string_start;
  4213. }
  4214. break;
  4215. case s_req_query_string_start:
  4216. case s_req_query_string:
  4217. if (CROW_IS_URL_CHAR(ch)) {
  4218. return s_req_query_string;
  4219. }
  4220. else if (ch == '?')
  4221. {
  4222. return s_req_query_string;
  4223. }
  4224. break;
  4225. default:
  4226. break;
  4227. }
  4228. /* We should never fall out of the switch above unless there's an error */
  4229. return s_dead;
  4230. }
  4231. inline size_t http_parser_execute (http_parser *parser,
  4232. const http_parser_settings *settings,
  4233. const char *data,
  4234. size_t len)
  4235. {
  4236. /* Tokens as defined by rfc 2616. Also lowercases them.
  4237. * token = 1*<any CHAR except CTLs or separators>
  4238. * separators = "(" | ")" | "<" | ">" | "@"
  4239. * | "," | ";" | ":" | "\" | <">
  4240. * | "/" | "[" | "]" | "?" | "="
  4241. * | "{" | "}" | SP | HT
  4242. */
  4243. static const char tokens[256] = {
  4244. /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
  4245. 0, 0, 0, 0, 0, 0, 0, 0,
  4246. /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
  4247. 0, 0, 0, 0, 0, 0, 0, 0,
  4248. /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
  4249. 0, 0, 0, 0, 0, 0, 0, 0,
  4250. /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
  4251. 0, 0, 0, 0, 0, 0, 0, 0,
  4252. /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
  4253. 0, '!', 0, '#', '$', '%', '&', '\'',
  4254. /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
  4255. 0, 0, '*', '+', 0, '-', '.', 0,
  4256. /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
  4257. '0', '1', '2', '3', '4', '5', '6', '7',
  4258. /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
  4259. '8', '9', 0, 0, 0, 0, 0, 0,
  4260. /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
  4261. 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  4262. /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
  4263. 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  4264. /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
  4265. 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  4266. /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
  4267. 'x', 'y', 'z', 0, 0, 0, '^', '_',
  4268. /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
  4269. '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  4270. /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
  4271. 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  4272. /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
  4273. 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  4274. /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
  4275. 'x', 'y', 'z', 0, '|', 0, '~', 0 };
  4276. static const int8_t unhex[256] =
  4277. {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4278. ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4279. ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4280. , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
  4281. ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4282. ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4283. ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4284. ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  4285. };
  4286. char c, ch;
  4287. int8_t unhex_val;
  4288. const char *p = data;
  4289. const char *header_field_mark = 0;
  4290. const char *header_value_mark = 0;
  4291. const char *url_mark = 0;
  4292. const char *url_start_mark = 0;
  4293. const char *body_mark = 0;
  4294. const unsigned int lenient = parser->lenient_http_headers;
  4295. const unsigned int allow_chunked_length = parser->allow_chunked_length;
  4296. uint32_t nread = parser->nread;
  4297. /* We're in an error state. Don't bother doing anything. */
  4298. if (CROW_HTTP_PARSER_ERRNO(parser) != CHPE_OK) {
  4299. return 0;
  4300. }
  4301. if (len == 0) {
  4302. switch (parser->state) {
  4303. case s_body_identity_eof:
  4304. /* Use of CROW_CALLBACK_NOTIFY() here would erroneously return 1 byte read if we got paused. */
  4305. CROW_CALLBACK_NOTIFY_NOADVANCE(message_complete);
  4306. return 0;
  4307. case s_dead:
  4308. case s_start_req:
  4309. return 0;
  4310. default:
  4311. CROW_SET_ERRNO(CHPE_INVALID_EOF_STATE);
  4312. return 1;
  4313. }
  4314. }
  4315. if (parser->state == s_header_field)
  4316. header_field_mark = data;
  4317. if (parser->state == s_header_value)
  4318. header_value_mark = data;
  4319. switch (parser->state) {
  4320. case s_req_path:
  4321. case s_req_schema:
  4322. case s_req_schema_slash:
  4323. case s_req_schema_slash_slash:
  4324. case s_req_server_start:
  4325. case s_req_server:
  4326. case s_req_server_with_at:
  4327. case s_req_query_string_start:
  4328. case s_req_query_string:
  4329. url_mark = data;
  4330. break;
  4331. default:
  4332. break;
  4333. }
  4334. for (p=data; p != data + len; p++) {
  4335. ch = *p;
  4336. if (CROW_PARSING_HEADER(parser->state))
  4337. CROW_COUNT_HEADER_SIZE(1);
  4338. reexecute:
  4339. switch (parser->state) {
  4340. case s_dead:
  4341. /* this state is used after a 'Connection: close' message
  4342. * the parser will error out if it reads another message
  4343. */
  4344. if (CROW_LIKELY(ch == cr || ch == lf))
  4345. break;
  4346. CROW_SET_ERRNO(CHPE_CLOSED_CONNECTION);
  4347. goto error;
  4348. case s_start_req:
  4349. {
  4350. if (ch == cr || ch == lf)
  4351. break;
  4352. parser->flags = 0;
  4353. parser->uses_transfer_encoding = 0;
  4354. parser->content_length = CROW_ULLONG_MAX;
  4355. if (CROW_UNLIKELY(!CROW_IS_ALPHA(ch))) {
  4356. CROW_SET_ERRNO(CHPE_INVALID_METHOD);
  4357. goto error;
  4358. }
  4359. parser->method = 0;
  4360. parser->index = 1;
  4361. switch (ch) {
  4362. case 'A': parser->method = (unsigned)HTTPMethod::Acl; break;
  4363. case 'B': parser->method = (unsigned)HTTPMethod::Bind; break;
  4364. case 'C': parser->method = (unsigned)HTTPMethod::Connect; /* or COPY, CHECKOUT */ break;
  4365. case 'D': parser->method = (unsigned)HTTPMethod::Delete; break;
  4366. case 'G': parser->method = (unsigned)HTTPMethod::Get; break;
  4367. case 'H': parser->method = (unsigned)HTTPMethod::Head; break;
  4368. case 'L': parser->method = (unsigned)HTTPMethod::Lock; /* or LINK */ break;
  4369. case 'M': parser->method = (unsigned)HTTPMethod::MkCol; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
  4370. case 'N': parser->method = (unsigned)HTTPMethod::Notify; break;
  4371. case 'O': parser->method = (unsigned)HTTPMethod::Options; break;
  4372. case 'P': parser->method = (unsigned)HTTPMethod::Post; /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ break;
  4373. case 'R': parser->method = (unsigned)HTTPMethod::Report; /* or REBIND */ break;
  4374. case 'S': parser->method = (unsigned)HTTPMethod::Subscribe; /* or SEARCH, SOURCE */ break;
  4375. case 'T': parser->method = (unsigned)HTTPMethod::Trace; break;
  4376. case 'U': parser->method = (unsigned)HTTPMethod::Unlock; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break;
  4377. default:
  4378. CROW_SET_ERRNO(CHPE_INVALID_METHOD);
  4379. goto error;
  4380. }
  4381. parser->state = s_req_method;
  4382. CROW_CALLBACK_NOTIFY(message_begin);
  4383. break;
  4384. }
  4385. case s_req_method:
  4386. {
  4387. const char *matcher;
  4388. if (CROW_UNLIKELY(ch == '\0')) {
  4389. CROW_SET_ERRNO(CHPE_INVALID_METHOD);
  4390. goto error;
  4391. }
  4392. matcher = method_strings[parser->method];
  4393. if (ch == ' ' && matcher[parser->index] == '\0') {
  4394. parser->state = s_req_spaces_before_url;
  4395. } else if (ch == matcher[parser->index]) {
  4396. ; /* nada */
  4397. } else if ((ch >= 'A' && ch <= 'Z') || ch == '-') {
  4398. switch (parser->method << 16 | parser->index << 8 | ch) {
  4399. #define CROW_XX(meth, pos, ch, new_meth) \
  4400. case ((unsigned)HTTPMethod::meth << 16 | pos << 8 | ch): \
  4401. parser->method = (unsigned)HTTPMethod::new_meth; break;
  4402. CROW_XX(Post, 1, 'U', Put)
  4403. CROW_XX(Post, 1, 'A', Patch)
  4404. CROW_XX(Post, 1, 'R', Propfind)
  4405. CROW_XX(Put, 2, 'R', Purge)
  4406. CROW_XX(Connect, 1, 'H', Checkout)
  4407. CROW_XX(Connect, 2, 'P', Copy)
  4408. CROW_XX(MkCol, 1, 'O', Move)
  4409. CROW_XX(MkCol, 1, 'E', Merge)
  4410. CROW_XX(MkCol, 1, '-', MSearch)
  4411. CROW_XX(MkCol, 2, 'A', MkActivity)
  4412. CROW_XX(MkCol, 3, 'A', MkCalendar)
  4413. CROW_XX(Subscribe, 1, 'E', Search)
  4414. CROW_XX(Subscribe, 1, 'O', Source)
  4415. CROW_XX(Report, 2, 'B', Rebind)
  4416. CROW_XX(Propfind, 4, 'P', Proppatch)
  4417. CROW_XX(Lock, 1, 'I', Link)
  4418. CROW_XX(Unlock, 2, 'S', Unsubscribe)
  4419. CROW_XX(Unlock, 2, 'B', Unbind)
  4420. CROW_XX(Unlock, 3, 'I', Unlink)
  4421. #undef CROW_XX
  4422. default:
  4423. CROW_SET_ERRNO(CHPE_INVALID_METHOD);
  4424. goto error;
  4425. }
  4426. } else {
  4427. CROW_SET_ERRNO(CHPE_INVALID_METHOD);
  4428. goto error;
  4429. }
  4430. CROW_CALLBACK_NOTIFY_NOADVANCE(method);
  4431. ++parser->index;
  4432. break;
  4433. }
  4434. case s_req_spaces_before_url:
  4435. {
  4436. if (ch == ' ') break;
  4437. CROW_MARK(url);
  4438. CROW_MARK(url_start);
  4439. if (parser->method == (unsigned)HTTPMethod::Connect) {
  4440. parser->state = s_req_server_start;
  4441. }
  4442. parser->state = parse_url_char(static_cast<state>(parser->state), ch, parser, url_start_mark, p);
  4443. if (CROW_UNLIKELY(parser->state == s_dead)) {
  4444. CROW_SET_ERRNO(CHPE_INVALID_URL);
  4445. goto error;
  4446. }
  4447. break;
  4448. }
  4449. case s_req_schema:
  4450. case s_req_schema_slash:
  4451. case s_req_schema_slash_slash:
  4452. case s_req_server_start:
  4453. {
  4454. switch (ch) {
  4455. /* No whitespace allowed here */
  4456. case ' ':
  4457. case cr:
  4458. case lf:
  4459. CROW_SET_ERRNO(CHPE_INVALID_URL);
  4460. goto error;
  4461. default:
  4462. parser->state = parse_url_char(static_cast<state>(parser->state), ch, parser, url_start_mark, p);
  4463. if (CROW_UNLIKELY(parser->state == s_dead)) {
  4464. CROW_SET_ERRNO(CHPE_INVALID_URL);
  4465. goto error;
  4466. }
  4467. }
  4468. break;
  4469. }
  4470. case s_req_server:
  4471. case s_req_server_with_at:
  4472. case s_req_path:
  4473. case s_req_query_string_start:
  4474. case s_req_query_string:
  4475. {
  4476. switch (ch) {
  4477. case ' ':
  4478. parser->state = s_req_http_start;
  4479. CROW_CALLBACK_DATA(url);
  4480. break;
  4481. case cr: // No space after URL means no HTTP version. Which means the request is using HTTP/0.9
  4482. case lf:
  4483. if (CROW_UNLIKELY(parser->method != (unsigned)HTTPMethod::Get)) // HTTP/0.9 doesn't define any method other than GET
  4484. {
  4485. parser->state = s_dead;
  4486. CROW_SET_ERRNO(CHPE_INVALID_VERSION);
  4487. goto error;
  4488. }
  4489. parser->http_major = 0;
  4490. parser->http_minor = 9;
  4491. parser->state = (ch == cr) ?
  4492. s_req_line_almost_done :
  4493. s_header_field_start;
  4494. CROW_CALLBACK_DATA(url);
  4495. break;
  4496. default:
  4497. parser->state = parse_url_char(static_cast<state>(parser->state), ch, parser, url_start_mark, p);
  4498. if (CROW_UNLIKELY(parser->state == s_dead)) {
  4499. CROW_SET_ERRNO(CHPE_INVALID_URL);
  4500. goto error;
  4501. }
  4502. }
  4503. break;
  4504. }
  4505. case s_req_http_start:
  4506. switch (ch) {
  4507. case ' ':
  4508. break;
  4509. case 'H':
  4510. parser->state = s_req_http_H;
  4511. break;
  4512. case 'I':
  4513. if (parser->method == (unsigned)HTTPMethod::Source) {
  4514. parser->state = s_req_http_I;
  4515. break;
  4516. }
  4517. /* fall through */
  4518. default:
  4519. CROW_SET_ERRNO(CHPE_INVALID_CONSTANT);
  4520. goto error;
  4521. }
  4522. break;
  4523. case s_req_http_H:
  4524. CROW_STRICT_CHECK(ch != 'T');
  4525. parser->state = s_req_http_HT;
  4526. break;
  4527. case s_req_http_HT:
  4528. CROW_STRICT_CHECK(ch != 'T');
  4529. parser->state = s_req_http_HTT;
  4530. break;
  4531. case s_req_http_HTT:
  4532. CROW_STRICT_CHECK(ch != 'P');
  4533. parser->state = s_req_http_HTTP;
  4534. break;
  4535. case s_req_http_I:
  4536. CROW_STRICT_CHECK(ch != 'C');
  4537. parser->state = s_req_http_IC;
  4538. break;
  4539. case s_req_http_IC:
  4540. CROW_STRICT_CHECK(ch != 'E');
  4541. parser->state = s_req_http_HTTP; /* Treat "ICE" as "HTTP". */
  4542. break;
  4543. case s_req_http_HTTP:
  4544. CROW_STRICT_CHECK(ch != '/');
  4545. parser->state = s_req_http_major;
  4546. break;
  4547. /* dot */
  4548. case s_req_http_major:
  4549. if (CROW_UNLIKELY(!CROW_IS_NUM(ch))) {
  4550. CROW_SET_ERRNO(CHPE_INVALID_VERSION);
  4551. goto error;
  4552. }
  4553. parser->http_major = ch - '0';
  4554. parser->state = s_req_http_dot;
  4555. break;
  4556. case s_req_http_dot:
  4557. {
  4558. if (CROW_UNLIKELY(ch != '.')) {
  4559. CROW_SET_ERRNO(CHPE_INVALID_VERSION);
  4560. goto error;
  4561. }
  4562. parser->state = s_req_http_minor;
  4563. break;
  4564. }
  4565. /* minor HTTP version */
  4566. case s_req_http_minor:
  4567. if (CROW_UNLIKELY(!CROW_IS_NUM(ch))) {
  4568. CROW_SET_ERRNO(CHPE_INVALID_VERSION);
  4569. goto error;
  4570. }
  4571. parser->http_minor = ch - '0';
  4572. parser->state = s_req_http_end;
  4573. break;
  4574. /* end of request line */
  4575. case s_req_http_end:
  4576. {
  4577. if (ch == cr) {
  4578. parser->state = s_req_line_almost_done;
  4579. break;
  4580. }
  4581. if (ch == lf) {
  4582. parser->state = s_header_field_start;
  4583. break;
  4584. }
  4585. CROW_SET_ERRNO(CHPE_INVALID_VERSION);
  4586. goto error;
  4587. break;
  4588. }
  4589. /* end of request line */
  4590. case s_req_line_almost_done:
  4591. {
  4592. if (CROW_UNLIKELY(ch != lf)) {
  4593. CROW_SET_ERRNO(CHPE_LF_EXPECTED);
  4594. goto error;
  4595. }
  4596. parser->state = s_header_field_start;
  4597. break;
  4598. }
  4599. case s_header_field_start:
  4600. {
  4601. if (ch == cr) {
  4602. parser->state = s_headers_almost_done;
  4603. break;
  4604. }
  4605. if (ch == lf) {
  4606. /* they might be just sending \n instead of \r\n so this would be
  4607. * the second \n to denote the end of headers*/
  4608. parser->state = s_headers_almost_done;
  4609. CROW_REEXECUTE();
  4610. }
  4611. c = CROW_TOKEN(ch);
  4612. if (CROW_UNLIKELY(!c)) {
  4613. CROW_SET_ERRNO(CHPE_INVALID_HEADER_TOKEN);
  4614. goto error;
  4615. }
  4616. CROW_MARK(header_field);
  4617. parser->index = 0;
  4618. parser->state = s_header_field;
  4619. switch (c) {
  4620. case 'c':
  4621. parser->header_state = h_C;
  4622. break;
  4623. case 'p':
  4624. parser->header_state = h_matching_proxy_connection;
  4625. break;
  4626. case 't':
  4627. parser->header_state = h_matching_transfer_encoding;
  4628. break;
  4629. case 'u':
  4630. parser->header_state = h_matching_upgrade;
  4631. break;
  4632. default:
  4633. parser->header_state = h_general;
  4634. break;
  4635. }
  4636. break;
  4637. }
  4638. case s_header_field:
  4639. {
  4640. const char* start = p;
  4641. for (; p != data + len; p++) {
  4642. ch = *p;
  4643. c = CROW_TOKEN(ch);
  4644. if (!c)
  4645. break;
  4646. switch (parser->header_state) {
  4647. case h_general: {
  4648. size_t left = data + len - p;
  4649. const char* pe = p + CROW_MIN(left, max_header_size);
  4650. while (p+1 < pe && CROW_TOKEN(p[1])) {
  4651. p++;
  4652. }
  4653. break;
  4654. }
  4655. case h_C:
  4656. parser->index++;
  4657. parser->header_state = (c == 'o' ? h_CO : h_general);
  4658. break;
  4659. case h_CO:
  4660. parser->index++;
  4661. parser->header_state = (c == 'n' ? h_CON : h_general);
  4662. break;
  4663. case h_CON:
  4664. parser->index++;
  4665. switch (c) {
  4666. case 'n':
  4667. parser->header_state = h_matching_connection;
  4668. break;
  4669. case 't':
  4670. parser->header_state = h_matching_content_length;
  4671. break;
  4672. default:
  4673. parser->header_state = h_general;
  4674. break;
  4675. }
  4676. break;
  4677. /* connection */
  4678. case h_matching_connection:
  4679. parser->index++;
  4680. if (parser->index > sizeof(CROW_CONNECTION)-1 || c != CROW_CONNECTION[parser->index]) {
  4681. parser->header_state = h_general;
  4682. } else if (parser->index == sizeof(CROW_CONNECTION)-2) {
  4683. parser->header_state = h_connection;
  4684. }
  4685. break;
  4686. /* proxy-connection */
  4687. case h_matching_proxy_connection:
  4688. parser->index++;
  4689. if (parser->index > sizeof(CROW_PROXY_CONNECTION)-1 || c != CROW_PROXY_CONNECTION[parser->index]) {
  4690. parser->header_state = h_general;
  4691. } else if (parser->index == sizeof(CROW_PROXY_CONNECTION)-2) {
  4692. parser->header_state = h_connection;
  4693. }
  4694. break;
  4695. /* content-length */
  4696. case h_matching_content_length:
  4697. parser->index++;
  4698. if (parser->index > sizeof(CROW_CONTENT_LENGTH)-1 || c != CROW_CONTENT_LENGTH[parser->index]) {
  4699. parser->header_state = h_general;
  4700. } else if (parser->index == sizeof(CROW_CONTENT_LENGTH)-2) {
  4701. parser->header_state = h_content_length;
  4702. }
  4703. break;
  4704. /* transfer-encoding */
  4705. case h_matching_transfer_encoding:
  4706. parser->index++;
  4707. if (parser->index > sizeof(CROW_TRANSFER_ENCODING)-1 || c != CROW_TRANSFER_ENCODING[parser->index]) {
  4708. parser->header_state = h_general;
  4709. } else if (parser->index == sizeof(CROW_TRANSFER_ENCODING)-2) {
  4710. parser->header_state = h_transfer_encoding;
  4711. parser->uses_transfer_encoding = 1;
  4712. }
  4713. break;
  4714. /* upgrade */
  4715. case h_matching_upgrade:
  4716. parser->index++;
  4717. if (parser->index > sizeof(CROW_UPGRADE)-1 || c != CROW_UPGRADE[parser->index]) {
  4718. parser->header_state = h_general;
  4719. } else if (parser->index == sizeof(CROW_UPGRADE)-2) {
  4720. parser->header_state = h_upgrade;
  4721. }
  4722. break;
  4723. case h_connection:
  4724. case h_content_length:
  4725. case h_transfer_encoding:
  4726. case h_upgrade:
  4727. if (ch != ' ') parser->header_state = h_general;
  4728. break;
  4729. default:
  4730. assert(0 && "Unknown header_state");
  4731. break;
  4732. }
  4733. }
  4734. if (p == data + len) {
  4735. --p;
  4736. CROW_COUNT_HEADER_SIZE(p - start);
  4737. break;
  4738. }
  4739. CROW_COUNT_HEADER_SIZE(p - start);
  4740. if (ch == ':') {
  4741. parser->state = s_header_value_discard_ws;
  4742. CROW_CALLBACK_DATA(header_field);
  4743. break;
  4744. }
  4745. /* RFC-7230 Sec 3.2.4 expressly forbids line-folding in header field-names.
  4746. if (ch == cr) {
  4747. parser->state = s_header_almost_done;
  4748. CROW_CALLBACK_DATA(header_field);
  4749. break;
  4750. }
  4751. if (ch == lf) {
  4752. parser->state = s_header_field_start;
  4753. CROW_CALLBACK_DATA(header_field);
  4754. break;
  4755. }
  4756. */
  4757. CROW_SET_ERRNO(CHPE_INVALID_HEADER_TOKEN);
  4758. goto error;
  4759. }
  4760. case s_header_value_discard_ws:
  4761. if (ch == ' ' || ch == '\t') break;
  4762. if (ch == cr) {
  4763. parser->state = s_header_value_discard_ws_almost_done;
  4764. break;
  4765. }
  4766. if (ch == lf) {
  4767. parser->state = s_header_value_discard_lws;
  4768. break;
  4769. }
  4770. /* fall through */
  4771. case s_header_value_start:
  4772. {
  4773. CROW_MARK(header_value);
  4774. parser->state = s_header_value;
  4775. parser->index = 0;
  4776. c = CROW_LOWER(ch);
  4777. switch (parser->header_state) {
  4778. case h_upgrade:
  4779. // Crow does not support HTTP/2 at the moment.
  4780. // According to the RFC https://datatracker.ietf.org/doc/html/rfc7540#section-3.2
  4781. // "A server that does not support HTTP/2 can respond to the request as though the Upgrade header field were absent"
  4782. // => `F_UPGRADE` is not set if the header starts by "h2".
  4783. // This prevents the parser from skipping the request body.
  4784. if (ch != 'h' || p+1 == (data + len) || *(p+1) != '2') {
  4785. parser->flags |= F_UPGRADE;
  4786. }
  4787. parser->header_state = h_general;
  4788. break;
  4789. case h_transfer_encoding:
  4790. /* looking for 'Transfer-Encoding: chunked' */
  4791. if ('c' == c) {
  4792. parser->header_state = h_matching_transfer_encoding_chunked;
  4793. } else {
  4794. parser->header_state = h_matching_transfer_encoding_token;
  4795. }
  4796. break;
  4797. /* Multi-value `Transfer-Encoding` header */
  4798. case h_matching_transfer_encoding_token_start:
  4799. break;
  4800. case h_content_length:
  4801. if (CROW_UNLIKELY(!CROW_IS_NUM(ch))) {
  4802. CROW_SET_ERRNO(CHPE_INVALID_CONTENT_LENGTH);
  4803. goto error;
  4804. }
  4805. if (parser->flags & F_CONTENTLENGTH) {
  4806. CROW_SET_ERRNO(CHPE_UNEXPECTED_CONTENT_LENGTH);
  4807. goto error;
  4808. }
  4809. parser->flags |= F_CONTENTLENGTH;
  4810. parser->content_length = ch - '0';
  4811. parser->header_state = h_content_length_num;
  4812. break;
  4813. /* when obsolete line folding is encountered for content length
  4814. * continue to the s_header_value state */
  4815. case h_content_length_ws:
  4816. break;
  4817. case h_connection:
  4818. /* looking for 'Connection: keep-alive' */
  4819. if (c == 'k') {
  4820. parser->header_state = h_matching_connection_keep_alive;
  4821. /* looking for 'Connection: close' */
  4822. } else if (c == 'c') {
  4823. parser->header_state = h_matching_connection_close;
  4824. } else if (c == ' ' || c == '\t') {
  4825. /* Skip lws */
  4826. } else {
  4827. parser->header_state = h_general;
  4828. }
  4829. break;
  4830. default:
  4831. parser->header_state = h_general;
  4832. break;
  4833. }
  4834. break;
  4835. }
  4836. case s_header_value:
  4837. {
  4838. const char* start = p;
  4839. enum header_states h_state = static_cast<header_states>(parser->header_state);
  4840. for (; p != data + len; p++) {
  4841. ch = *p;
  4842. if (ch == cr) {
  4843. parser->state = s_header_almost_done;
  4844. parser->header_state = h_state;
  4845. CROW_CALLBACK_DATA(header_value);
  4846. break;
  4847. }
  4848. if (ch == lf) {
  4849. parser->state = s_header_almost_done;
  4850. CROW_COUNT_HEADER_SIZE(p - start);
  4851. parser->header_state = h_state;
  4852. CROW_CALLBACK_DATA_NOADVANCE(header_value);
  4853. CROW_REEXECUTE();
  4854. }
  4855. if (!lenient && !CROW_IS_HEADER_CHAR(ch)) {
  4856. CROW_SET_ERRNO(CHPE_INVALID_HEADER_TOKEN);
  4857. goto error;
  4858. }
  4859. c = CROW_LOWER(ch);
  4860. switch (h_state) {
  4861. case h_general:
  4862. {
  4863. size_t left = data + len - p;
  4864. const char* pe = p + CROW_MIN(left, max_header_size);
  4865. for (; p != pe; p++) {
  4866. ch = *p;
  4867. if (ch == cr || ch == lf) {
  4868. --p;
  4869. break;
  4870. }
  4871. if (!lenient && !CROW_IS_HEADER_CHAR(ch)) {
  4872. CROW_SET_ERRNO(CHPE_INVALID_HEADER_TOKEN);
  4873. goto error;
  4874. }
  4875. }
  4876. if (p == data + len)
  4877. --p;
  4878. break;
  4879. }
  4880. case h_connection:
  4881. case h_transfer_encoding:
  4882. assert(0 && "Shouldn't get here.");
  4883. break;
  4884. case h_content_length:
  4885. if (ch == ' ') break;
  4886. h_state = h_content_length_num;
  4887. /* fall through */
  4888. case h_content_length_num:
  4889. {
  4890. uint64_t t;
  4891. if (ch == ' ') {
  4892. h_state = h_content_length_ws;
  4893. break;
  4894. }
  4895. if (CROW_UNLIKELY(!CROW_IS_NUM(ch))) {
  4896. CROW_SET_ERRNO(CHPE_INVALID_CONTENT_LENGTH);
  4897. parser->header_state = h_state;
  4898. goto error;
  4899. }
  4900. t = parser->content_length;
  4901. t *= 10;
  4902. t += ch - '0';
  4903. /* Overflow? Test against a conservative limit for simplicity. */
  4904. if (CROW_UNLIKELY((CROW_ULLONG_MAX - 10) / 10 < parser->content_length)) {
  4905. CROW_SET_ERRNO(CHPE_INVALID_CONTENT_LENGTH);
  4906. parser->header_state = h_state;
  4907. goto error;
  4908. }
  4909. parser->content_length = t;
  4910. break;
  4911. }
  4912. case h_content_length_ws:
  4913. if (ch == ' ') break;
  4914. CROW_SET_ERRNO(CHPE_INVALID_CONTENT_LENGTH);
  4915. parser->header_state = h_state;
  4916. goto error;
  4917. /* Transfer-Encoding: chunked */
  4918. case h_matching_transfer_encoding_token_start:
  4919. /* looking for 'Transfer-Encoding: chunked' */
  4920. if ('c' == c) {
  4921. h_state = h_matching_transfer_encoding_chunked;
  4922. } else if (CROW_TOKEN(c)) {
  4923. /* TODO(indutny): similar code below does this, but why?
  4924. * At the very least it seems to be inconsistent given that
  4925. * h_matching_transfer_encoding_token does not check for
  4926. * `STRICT_TOKEN`
  4927. */
  4928. h_state = h_matching_transfer_encoding_token;
  4929. } else if (c == ' ' || c == '\t') {
  4930. /* Skip lws */
  4931. } else {
  4932. h_state = h_general;
  4933. }
  4934. break;
  4935. case h_matching_transfer_encoding_chunked:
  4936. parser->index++;
  4937. if (parser->index > sizeof(CROW_CHUNKED)-1 || c != CROW_CHUNKED[parser->index]) {
  4938. h_state = h_matching_transfer_encoding_token;
  4939. } else if (parser->index == sizeof(CROW_CHUNKED)-2) {
  4940. h_state = h_transfer_encoding_chunked;
  4941. }
  4942. break;
  4943. case h_matching_transfer_encoding_token:
  4944. if (ch == ',') {
  4945. h_state = h_matching_transfer_encoding_token_start;
  4946. parser->index = 0;
  4947. }
  4948. break;
  4949. /* looking for 'Connection: keep-alive' */
  4950. case h_matching_connection_keep_alive:
  4951. parser->index++;
  4952. if (parser->index > sizeof(CROW_KEEP_ALIVE)-1 || c != CROW_KEEP_ALIVE[parser->index]) {
  4953. h_state = h_general;
  4954. } else if (parser->index == sizeof(CROW_KEEP_ALIVE)-2) {
  4955. h_state = h_connection_keep_alive;
  4956. }
  4957. break;
  4958. /* looking for 'Connection: close' */
  4959. case h_matching_connection_close:
  4960. parser->index++;
  4961. if (parser->index > sizeof(CROW_CLOSE)-1 || c != CROW_CLOSE[parser->index]) {
  4962. h_state = h_general;
  4963. } else if (parser->index == sizeof(CROW_CLOSE)-2) {
  4964. h_state = h_connection_close;
  4965. }
  4966. break;
  4967. // Edited from original (because of commits that werent included)
  4968. case h_transfer_encoding_chunked:
  4969. if (ch != ' ') h_state = h_matching_transfer_encoding_token;
  4970. break;
  4971. case h_connection_keep_alive:
  4972. case h_connection_close:
  4973. if (ch != ' ') h_state = h_general;
  4974. break;
  4975. default:
  4976. parser->state = s_header_value;
  4977. h_state = h_general;
  4978. break;
  4979. }
  4980. }
  4981. parser->header_state = h_state;
  4982. if (p == data + len)
  4983. --p;
  4984. CROW_COUNT_HEADER_SIZE(p - start);
  4985. break;
  4986. }
  4987. case s_header_almost_done:
  4988. {
  4989. if (CROW_UNLIKELY(ch != lf)) {
  4990. CROW_SET_ERRNO(CHPE_LF_EXPECTED);
  4991. goto error;
  4992. }
  4993. parser->state = s_header_value_lws;
  4994. break;
  4995. }
  4996. case s_header_value_lws:
  4997. {
  4998. if (ch == ' ' || ch == '\t') {
  4999. if (parser->header_state == h_content_length_num) {
  5000. /* treat obsolete line folding as space */
  5001. parser->header_state = h_content_length_ws;
  5002. }
  5003. parser->state = s_header_value_start;
  5004. CROW_REEXECUTE();
  5005. }
  5006. /* finished the header */
  5007. switch (parser->header_state) {
  5008. case h_connection_keep_alive:
  5009. parser->flags |= F_CONNECTION_KEEP_ALIVE;
  5010. break;
  5011. case h_connection_close:
  5012. parser->flags |= F_CONNECTION_CLOSE;
  5013. break;
  5014. case h_transfer_encoding_chunked:
  5015. parser->flags |= F_CHUNKED;
  5016. break;
  5017. default:
  5018. break;
  5019. }
  5020. parser->state = s_header_field_start;
  5021. CROW_REEXECUTE();
  5022. }
  5023. case s_header_value_discard_ws_almost_done:
  5024. {
  5025. CROW_STRICT_CHECK(ch != lf);
  5026. parser->state = s_header_value_discard_lws;
  5027. break;
  5028. }
  5029. case s_header_value_discard_lws:
  5030. {
  5031. if (ch == ' ' || ch == '\t') {
  5032. parser->state = s_header_value_discard_ws;
  5033. break;
  5034. } else {
  5035. /* header value was empty */
  5036. CROW_MARK(header_value);
  5037. parser->state = s_header_field_start;
  5038. CROW_CALLBACK_DATA_NOADVANCE(header_value);
  5039. CROW_REEXECUTE();
  5040. }
  5041. }
  5042. case s_headers_almost_done:
  5043. {
  5044. CROW_STRICT_CHECK(ch != lf);
  5045. if (parser->flags & F_TRAILING) {
  5046. /* End of a chunked request */
  5047. CROW_CALLBACK_NOTIFY(message_complete);
  5048. break;
  5049. }
  5050. /* Cannot use transfer-encoding and a content-length header together
  5051. per the HTTP specification. (RFC 7230 Section 3.3.3) */
  5052. if ((parser->uses_transfer_encoding == 1) &&
  5053. (parser->flags & F_CONTENTLENGTH)) {
  5054. /* Allow it for lenient parsing as long as `Transfer-Encoding` is
  5055. * not `chunked` or allow_length_with_encoding is set
  5056. */
  5057. if (parser->flags & F_CHUNKED) {
  5058. if (!allow_chunked_length) {
  5059. CROW_SET_ERRNO(CHPE_UNEXPECTED_CONTENT_LENGTH);
  5060. goto error;
  5061. }
  5062. } else if (!lenient) {
  5063. CROW_SET_ERRNO(CHPE_UNEXPECTED_CONTENT_LENGTH);
  5064. goto error;
  5065. }
  5066. }
  5067. parser->state = s_headers_done;
  5068. /* Set this here so that on_headers_complete() callbacks can see it */
  5069. parser->upgrade =
  5070. (parser->flags & F_UPGRADE || parser->method == (unsigned)HTTPMethod::Connect);
  5071. /* Here we call the headers_complete callback. This is somewhat
  5072. * different than other callbacks because if the user returns 1, we
  5073. * will interpret that as saying that this message has no body. This
  5074. * is needed for the annoying case of recieving a response to a HEAD
  5075. * request.
  5076. *
  5077. * We'd like to use CROW_CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
  5078. * we have to simulate it by handling a change in errno below.
  5079. */
  5080. if (settings->on_headers_complete) {
  5081. switch (settings->on_headers_complete(parser)) {
  5082. case 0:
  5083. break;
  5084. case 2:
  5085. parser->upgrade = 1;
  5086. //break;
  5087. /* fall through */
  5088. case 1:
  5089. parser->flags |= F_SKIPBODY;
  5090. break;
  5091. default:
  5092. CROW_SET_ERRNO(CHPE_CB_headers_complete);
  5093. parser->nread = nread;
  5094. return p - data; /* Error */
  5095. }
  5096. }
  5097. if (CROW_HTTP_PARSER_ERRNO(parser) != CHPE_OK) {
  5098. parser->nread = nread;
  5099. return p - data;
  5100. }
  5101. CROW_REEXECUTE();
  5102. }
  5103. case s_headers_done:
  5104. {
  5105. CROW_STRICT_CHECK(ch != lf);
  5106. parser->nread = 0;
  5107. nread = 0;
  5108. /* Exit, the rest of the connect is in a different protocol. */
  5109. if (parser->upgrade) {
  5110. CROW_CALLBACK_NOTIFY(message_complete);
  5111. parser->nread = nread;
  5112. return (p - data) + 1;
  5113. }
  5114. if (parser->flags & F_SKIPBODY) {
  5115. CROW_CALLBACK_NOTIFY(message_complete);
  5116. } else if (parser->flags & F_CHUNKED) {
  5117. /* chunked encoding - ignore Content-Length header,
  5118. * prepare for a chunk */
  5119. parser->state = s_chunk_size_start;
  5120. }
  5121. else if (parser->uses_transfer_encoding == 1)
  5122. {
  5123. if (!lenient)
  5124. {
  5125. /* RFC 7230 3.3.3 */
  5126. /* If a Transfer-Encoding header field
  5127. * is present in a request and the chunked transfer coding is not
  5128. * the final encoding, the message body length cannot be determined
  5129. * reliably; the server MUST respond with the 400 (Bad Request)
  5130. * status code and then close the connection.
  5131. */
  5132. CROW_SET_ERRNO(CHPE_INVALID_TRANSFER_ENCODING);
  5133. parser->nread = nread;
  5134. return (p - data); /* Error */
  5135. }
  5136. else
  5137. {
  5138. /* RFC 7230 3.3.3 */
  5139. /* If a Transfer-Encoding header field is present in a response and
  5140. * the chunked transfer coding is not the final encoding, the
  5141. * message body length is determined by reading the connection until
  5142. * it is closed by the server.
  5143. */
  5144. parser->state = s_body_identity_eof;
  5145. }
  5146. }
  5147. else
  5148. {
  5149. if (parser->content_length == 0)
  5150. {
  5151. /* Content-Length header given but zero: Content-Length: 0\r\n */
  5152. CROW_CALLBACK_NOTIFY(message_complete);
  5153. }
  5154. else if (parser->content_length != CROW_ULLONG_MAX)
  5155. {
  5156. /* Content-Length header given and non-zero */
  5157. parser->state = s_body_identity;
  5158. }
  5159. else
  5160. {
  5161. /* Assume content-length 0 - read the next */
  5162. CROW_CALLBACK_NOTIFY(message_complete);
  5163. }
  5164. }
  5165. break;
  5166. }
  5167. case s_body_identity:
  5168. {
  5169. uint64_t to_read = CROW_MIN(parser->content_length,
  5170. (uint64_t) ((data + len) - p));
  5171. assert(parser->content_length != 0
  5172. && parser->content_length != CROW_ULLONG_MAX);
  5173. /* The difference between advancing content_length and p is because
  5174. * the latter will automaticaly advance on the next loop iteration.
  5175. * Further, if content_length ends up at 0, we want to see the last
  5176. * byte again for our message complete callback.
  5177. */
  5178. CROW_MARK(body);
  5179. parser->content_length -= to_read;
  5180. p += to_read - 1;
  5181. if (parser->content_length == 0) {
  5182. parser->state = s_message_done;
  5183. /* Mimic CROW_CALLBACK_DATA_NOADVANCE() but with one extra byte.
  5184. *
  5185. * The alternative to doing this is to wait for the next byte to
  5186. * trigger the data callback, just as in every other case. The
  5187. * problem with this is that this makes it difficult for the test
  5188. * harness to distinguish between complete-on-EOF and
  5189. * complete-on-length. It's not clear that this distinction is
  5190. * important for applications, but let's keep it for now.
  5191. */
  5192. CROW_CALLBACK_DATA_(body, p - body_mark + 1, p - data);
  5193. CROW_REEXECUTE();
  5194. }
  5195. break;
  5196. }
  5197. /* read until EOF */
  5198. case s_body_identity_eof:
  5199. CROW_MARK(body);
  5200. p = data + len - 1;
  5201. break;
  5202. case s_message_done:
  5203. CROW_CALLBACK_NOTIFY(message_complete);
  5204. break;
  5205. case s_chunk_size_start:
  5206. {
  5207. assert(nread == 1);
  5208. assert(parser->flags & F_CHUNKED);
  5209. unhex_val = unhex[static_cast<unsigned char>(ch)];
  5210. if (CROW_UNLIKELY(unhex_val == -1)) {
  5211. CROW_SET_ERRNO(CHPE_INVALID_CHUNK_SIZE);
  5212. goto error;
  5213. }
  5214. parser->content_length = unhex_val;
  5215. parser->state = s_chunk_size;
  5216. break;
  5217. }
  5218. case s_chunk_size:
  5219. {
  5220. uint64_t t;
  5221. assert(parser->flags & F_CHUNKED);
  5222. if (ch == cr) {
  5223. parser->state = s_chunk_size_almost_done;
  5224. break;
  5225. }
  5226. unhex_val = unhex[static_cast<unsigned char>(ch)];
  5227. if (unhex_val == -1) {
  5228. if (ch == ';' || ch == ' ') {
  5229. parser->state = s_chunk_parameters;
  5230. break;
  5231. }
  5232. CROW_SET_ERRNO(CHPE_INVALID_CHUNK_SIZE);
  5233. goto error;
  5234. }
  5235. t = parser->content_length;
  5236. t *= 16;
  5237. t += unhex_val;
  5238. /* Overflow? Test against a conservative limit for simplicity. */
  5239. if (CROW_UNLIKELY((CROW_ULLONG_MAX - 16) / 16 < parser->content_length)) {
  5240. CROW_SET_ERRNO(CHPE_INVALID_CONTENT_LENGTH);
  5241. goto error;
  5242. }
  5243. parser->content_length = t;
  5244. break;
  5245. }
  5246. case s_chunk_parameters:
  5247. {
  5248. assert(parser->flags & F_CHUNKED);
  5249. /* just ignore this shit. TODO check for overflow */
  5250. if (ch == cr) {
  5251. parser->state = s_chunk_size_almost_done;
  5252. break;
  5253. }
  5254. break;
  5255. }
  5256. case s_chunk_size_almost_done:
  5257. {
  5258. assert(parser->flags & F_CHUNKED);
  5259. CROW_STRICT_CHECK(ch != lf);
  5260. parser->nread = 0;
  5261. nread = 0;
  5262. if (parser->content_length == 0) {
  5263. parser->flags |= F_TRAILING;
  5264. parser->state = s_header_field_start;
  5265. } else {
  5266. parser->state = s_chunk_data;
  5267. }
  5268. break;
  5269. }
  5270. case s_chunk_data:
  5271. {
  5272. uint64_t to_read = CROW_MIN(parser->content_length,
  5273. (uint64_t) ((data + len) - p));
  5274. assert(parser->flags & F_CHUNKED);
  5275. assert(parser->content_length != 0
  5276. && parser->content_length != CROW_ULLONG_MAX);
  5277. /* See the explanation in s_body_identity for why the content
  5278. * length and data pointers are managed this way.
  5279. */
  5280. CROW_MARK(body);
  5281. parser->content_length -= to_read;
  5282. p += to_read - 1;
  5283. if (parser->content_length == 0) {
  5284. parser->state = s_chunk_data_almost_done;
  5285. }
  5286. break;
  5287. }
  5288. case s_chunk_data_almost_done:
  5289. assert(parser->flags & F_CHUNKED);
  5290. assert(parser->content_length == 0);
  5291. CROW_STRICT_CHECK(ch != cr);
  5292. parser->state = s_chunk_data_done;
  5293. CROW_CALLBACK_DATA(body);
  5294. break;
  5295. case s_chunk_data_done:
  5296. assert(parser->flags & F_CHUNKED);
  5297. CROW_STRICT_CHECK(ch != lf);
  5298. parser->nread = 0;
  5299. nread = 0;
  5300. parser->state = s_chunk_size_start;
  5301. break;
  5302. default:
  5303. assert(0 && "unhandled state");
  5304. CROW_SET_ERRNO(CHPE_INVALID_INTERNAL_STATE);
  5305. goto error;
  5306. }
  5307. }
  5308. /* Run callbacks for any marks that we have leftover after we ran out of
  5309. * bytes. There should be at most one of these set, so it's OK to invoke
  5310. * them in series (unset marks will not result in callbacks).
  5311. *
  5312. * We use the NOADVANCE() variety of callbacks here because 'p' has already
  5313. * overflowed 'data' and this allows us to correct for the off-by-one that
  5314. * we'd otherwise have (since CROW_CALLBACK_DATA() is meant to be run with a 'p'
  5315. * value that's in-bounds).
  5316. */
  5317. assert(((header_field_mark ? 1 : 0) +
  5318. (header_value_mark ? 1 : 0) +
  5319. (url_mark ? 1 : 0) +
  5320. (body_mark ? 1 : 0)) <= 1);
  5321. CROW_CALLBACK_DATA_NOADVANCE(header_field);
  5322. CROW_CALLBACK_DATA_NOADVANCE(header_value);
  5323. CROW_CALLBACK_DATA_NOADVANCE(url);
  5324. CROW_CALLBACK_DATA_NOADVANCE(body);
  5325. parser->nread = nread;
  5326. return len;
  5327. error:
  5328. if (CROW_HTTP_PARSER_ERRNO(parser) == CHPE_OK) {
  5329. CROW_SET_ERRNO(CHPE_UNKNOWN);
  5330. }
  5331. parser->nread = nread;
  5332. return (p - data);
  5333. }
  5334. inline void
  5335. http_parser_init(http_parser* parser)
  5336. {
  5337. void *data = parser->data; /* preserve application data */
  5338. memset(parser, 0, sizeof(*parser));
  5339. parser->data = data;
  5340. parser->state = s_start_req;
  5341. parser->http_errno = CHPE_OK;
  5342. }
  5343. /* Return a string name of the given error */
  5344. inline const char *
  5345. http_errno_name(enum http_errno err) {
  5346. /* Map errno values to strings for human-readable output */
  5347. #define CROW_HTTP_STRERROR_GEN(n, s) { "CHPE_" #n, s },
  5348. static struct {
  5349. const char *name;
  5350. const char *description;
  5351. } http_strerror_tab[] = {
  5352. CROW_HTTP_ERRNO_MAP(CROW_HTTP_STRERROR_GEN)
  5353. };
  5354. #undef CROW_HTTP_STRERROR_GEN
  5355. assert(((size_t) err) < CROW_ARRAY_SIZE(http_strerror_tab));
  5356. return http_strerror_tab[err].name;
  5357. }
  5358. /* Return a string description of the given error */
  5359. inline const char *
  5360. http_errno_description(enum http_errno err) {
  5361. /* Map errno values to strings for human-readable output */
  5362. #define CROW_HTTP_STRERROR_GEN(n, s) { "CHPE_" #n, s },
  5363. static struct {
  5364. const char *name;
  5365. const char *description;
  5366. } http_strerror_tab[] = {
  5367. CROW_HTTP_ERRNO_MAP(CROW_HTTP_STRERROR_GEN)
  5368. };
  5369. #undef CROW_HTTP_STRERROR_GEN
  5370. assert(((size_t) err) < CROW_ARRAY_SIZE(http_strerror_tab));
  5371. return http_strerror_tab[err].description;
  5372. }
  5373. /* Checks if this is the final chunk of the body. */
  5374. inline int
  5375. http_body_is_final(const struct http_parser *parser) {
  5376. return parser->state == s_message_done;
  5377. }
  5378. /* Change the maximum header size provided at compile time. */
  5379. inline void
  5380. http_parser_set_max_header_size(uint32_t size) {
  5381. max_header_size = size;
  5382. }
  5383. #undef CROW_HTTP_ERRNO_MAP
  5384. #undef CROW_SET_ERRNO
  5385. #undef CROW_CALLBACK_NOTIFY_
  5386. #undef CROW_CALLBACK_NOTIFY
  5387. #undef CROW_CALLBACK_NOTIFY_NOADVANCE
  5388. #undef CROW_CALLBACK_DATA_
  5389. #undef CROW_CALLBACK_DATA
  5390. #undef CROW_CALLBACK_DATA_NOADVANCE
  5391. #undef CROW_MARK
  5392. #undef CROW_PROXY_CONNECTION
  5393. #undef CROW_CONNECTION
  5394. #undef CROW_CONTENT_LENGTH
  5395. #undef CROW_TRANSFER_ENCODING
  5396. #undef CROW_UPGRADE
  5397. #undef CROW_CHUNKED
  5398. #undef CROW_KEEP_ALIVE
  5399. #undef CROW_CLOSE
  5400. #undef CROW_PARSING_HEADER
  5401. #undef CROW_LOWER
  5402. #undef CROW_IS_ALPHA
  5403. #undef CROW_IS_NUM
  5404. #undef CROW_IS_ALPHANUM
  5405. //#undef CROW_IS_HEX
  5406. #undef CROW_IS_MARK
  5407. #undef CROW_IS_USERINFO_CHAR
  5408. #undef CROW_TOKEN
  5409. #undef CROW_IS_URL_CHAR
  5410. //#undef CROW_IS_HOST_CHAR
  5411. #undef CROW_STRICT_CHECK
  5412. }
  5413. // clang-format on
  5414. #ifdef CROW_USE_BOOST
  5415. #include <boost/asio.hpp>
  5416. #include <boost/asio/basic_waitable_timer.hpp>
  5417. #else
  5418. #ifndef ASIO_STANDALONE
  5419. #define ASIO_STANDALONE
  5420. #endif
  5421. #include <asio.hpp>
  5422. #include <asio/basic_waitable_timer.hpp>
  5423. #endif
  5424. #include <chrono>
  5425. #include <functional>
  5426. #include <map>
  5427. #include <vector>
  5428. namespace crow {
  5429. #ifdef CROW_USE_BOOST
  5430. namespace asio = boost::asio;
  5431. using error_code = boost::system::error_code;
  5432. #else
  5433. using error_code = asio::error_code;
  5434. #endif
  5435. namespace detail {
  5436. /// A class for scheduling functions to be called after a specific
  5437. /// amount of ticks. Ther tick length can be handed over in constructor,
  5438. /// the default tick length is equal to 1 second.
  5439. class task_timer {
  5440. public:
  5441. using task_type = std::function<void()>;
  5442. using identifier_type = size_t;
  5443. private:
  5444. using clock_type = std::chrono::steady_clock;
  5445. using time_type = clock_type::time_point;
  5446. public:
  5447. task_timer(
  5448. asio::io_context &io_context,
  5449. const std::chrono::milliseconds tick_length = std::chrono::seconds(1))
  5450. : io_context_(io_context), timer_(io_context_),
  5451. tick_length_ms_(tick_length) {
  5452. timer_.expires_after(tick_length_ms_);
  5453. timer_.async_wait(
  5454. std::bind(&task_timer::tick_handler, this, std::placeholders::_1));
  5455. }
  5456. ~task_timer() { timer_.cancel(); }
  5457. /// Cancel the scheduling of the given task
  5458. ///
  5459. /// \param identifier_type task identifier of the task to cancel.
  5460. void cancel(identifier_type id) {
  5461. tasks_.erase(id);
  5462. CROW_LOG_DEBUG << "task_timer task cancelled: " << this << ' ' << id;
  5463. }
  5464. /// Schedule the given task to be executed after the default amount
  5465. /// of ticks.
  5466. ///
  5467. /// \return identifier_type Used to cancel the thread.
  5468. /// It is not bound to this task_timer instance and in some cases
  5469. /// could lead to undefined behavior if used with other task_timer
  5470. /// objects or after the task has been successfully executed.
  5471. identifier_type schedule(const task_type &task) {
  5472. return schedule(task, get_default_timeout());
  5473. }
  5474. /// Schedule the given task to be executed after the given time.
  5475. ///
  5476. /// \param timeout The amount of ticks to wait before execution.
  5477. ///
  5478. /// \return identifier_type Used to cancel the thread.
  5479. /// It is not bound to this task_timer instance and in some cases
  5480. /// could lead to undefined behavior if used with other task_timer
  5481. /// objects or after the task has been successfully executed.
  5482. identifier_type schedule(const task_type &task, uint8_t timeout) {
  5483. tasks_.insert({++highest_id_,
  5484. {clock_type::now() + (timeout * tick_length_ms_), task}});
  5485. CROW_LOG_DEBUG << "task_timer scheduled: " << this << ' ' << highest_id_;
  5486. return highest_id_;
  5487. }
  5488. /// Set the default timeout for this task_timer instance.
  5489. /// (Default: 5)
  5490. ///
  5491. /// \param timeout The amount of ticks to wait before
  5492. /// execution.
  5493. /// For tick length \see tick_length_ms_
  5494. void set_default_timeout(uint8_t timeout) { default_timeout_ = timeout; }
  5495. /// Get the default timeout. (Default: 5)
  5496. uint8_t get_default_timeout() const { return default_timeout_; }
  5497. /// returns the length of one tick.
  5498. std::chrono::milliseconds get_tick_length() const { return tick_length_ms_; }
  5499. private:
  5500. void process_tasks() {
  5501. time_type current_time = clock_type::now();
  5502. std::vector<identifier_type> finished_tasks;
  5503. for (const auto &task : tasks_) {
  5504. if (task.second.first < current_time) {
  5505. (task.second.second)();
  5506. finished_tasks.push_back(task.first);
  5507. CROW_LOG_DEBUG << "task_timer called: " << this << ' ' << task.first;
  5508. }
  5509. }
  5510. for (const auto &task : finished_tasks)
  5511. tasks_.erase(task);
  5512. // If no task is currently scheduled, reset the issued ids back
  5513. // to 0.
  5514. if (tasks_.empty()) highest_id_ = 0;
  5515. }
  5516. void tick_handler(const error_code &ec) {
  5517. if (ec) return;
  5518. process_tasks();
  5519. timer_.expires_after(tick_length_ms_);
  5520. timer_.async_wait(
  5521. std::bind(&task_timer::tick_handler, this, std::placeholders::_1));
  5522. }
  5523. private:
  5524. asio::io_context &io_context_;
  5525. asio::basic_waitable_timer<clock_type> timer_;
  5526. std::map<identifier_type, std::pair<time_type, task_type>> tasks_;
  5527. // A continuously increasing number to be issued to threads to
  5528. // identify them. If no tasks are scheduled, it will be reset to 0.
  5529. identifier_type highest_id_{0};
  5530. std::chrono::milliseconds tick_length_ms_;
  5531. uint8_t default_timeout_{5};
  5532. };
  5533. } // namespace detail
  5534. } // namespace crow
  5535. #ifdef CROW_USE_BOOST
  5536. #include <boost/asio.hpp>
  5537. #else
  5538. #ifndef ASIO_STANDALONE
  5539. #define ASIO_STANDALONE
  5540. #endif
  5541. #include <asio.hpp>
  5542. #endif
  5543. namespace crow // NOTE: Already documented in "crow/app.h"
  5544. {
  5545. #ifdef CROW_USE_BOOST
  5546. namespace asio = boost::asio;
  5547. #endif
  5548. /// Find and return the value associated with the key. (returns an empty string
  5549. /// if nothing is found)
  5550. inline const std::string &get_header_value(const ci_map &headers,
  5551. const std::string &key) {
  5552. static const std::string EMPTY;
  5553. const auto it = headers.find(key);
  5554. if (it != headers.end()) {
  5555. return it->second;
  5556. } else {
  5557. return EMPTY;
  5558. }
  5559. }
  5560. /// An HTTP request.
  5561. struct request {
  5562. HTTPMethod method;
  5563. std::string raw_url; ///< The full URL containing the `?` and URL parameters.
  5564. std::string url; ///< The endpoint without any parameters.
  5565. query_string url_params; ///< The parameters associated with the request.
  5566. ///< (everything after the `?` in the URL)
  5567. ci_map headers;
  5568. std::string body;
  5569. std::string
  5570. remote_ip_address; ///< The IP address from which the request was sent.
  5571. unsigned char http_ver_major, http_ver_minor;
  5572. bool keep_alive, ///< Whether or not the server should send a `connection:
  5573. ///< Keep-Alive` header to the client.
  5574. close_connection, ///< Whether or not the server should shut down the TCP
  5575. ///< connection once a response is sent.
  5576. upgrade; ///< Whether or noth the server should change the HTTP connection
  5577. ///< to a different connection.
  5578. void *middleware_context{};
  5579. void *middleware_container{};
  5580. asio::io_context *io_context{};
  5581. /// Construct an empty request. (sets the method to `GET`)
  5582. request() : method(HTTPMethod::Get) {}
  5583. /// Construct a request with all values assigned.
  5584. request(HTTPMethod method_, std::string raw_url_, std::string url_,
  5585. query_string url_params_, ci_map headers_, std::string body_,
  5586. unsigned char http_major, unsigned char http_minor,
  5587. bool has_keep_alive, bool has_close_connection, bool is_upgrade)
  5588. : method(method_), raw_url(std::move(raw_url_)), url(std::move(url_)),
  5589. url_params(std::move(url_params_)), headers(std::move(headers_)),
  5590. body(std::move(body_)), http_ver_major(http_major),
  5591. http_ver_minor(http_minor), keep_alive(has_keep_alive),
  5592. close_connection(has_close_connection), upgrade(is_upgrade) {}
  5593. void add_header(std::string key, std::string value) {
  5594. headers.emplace(std::move(key), std::move(value));
  5595. }
  5596. const std::string &get_header_value(const std::string &key) const {
  5597. return crow::get_header_value(headers, key);
  5598. }
  5599. bool check_version(unsigned char major, unsigned char minor) const {
  5600. return http_ver_major == major && http_ver_minor == minor;
  5601. }
  5602. /// Get the body as parameters in QS format.
  5603. ///
  5604. /// This is meant to be used with requests of type
  5605. /// "application/x-www-form-urlencoded"
  5606. const query_string get_body_params() const {
  5607. return query_string(body, false);
  5608. }
  5609. /// Send data to whoever made this request with a completion handler and
  5610. /// return immediately.
  5611. template <typename CompletionHandler> void post(CompletionHandler handler) {
  5612. asio::post(io_context, handler);
  5613. }
  5614. /// Send data to whoever made this request with a completion handler.
  5615. template <typename CompletionHandler>
  5616. void dispatch(CompletionHandler handler) {
  5617. asio::dispatch(io_context, handler);
  5618. }
  5619. };
  5620. } // namespace crow
  5621. #include <algorithm>
  5622. #include <string>
  5623. #include <unordered_map>
  5624. namespace crow {
  5625. /// A wrapper for `nodejs/http-parser`.
  5626. ///
  5627. /// Used to generate a \ref crow.request from the TCP socket buffer.
  5628. template <typename Handler> struct HTTPParser : public http_parser {
  5629. static int on_message_begin(http_parser *) { return 0; }
  5630. static int on_method(http_parser *self_) {
  5631. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5632. self->req.method = static_cast<HTTPMethod>(self->method);
  5633. return 0;
  5634. }
  5635. static int on_url(http_parser *self_, const char *at, size_t length) {
  5636. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5637. self->req.raw_url.insert(self->req.raw_url.end(), at, at + length);
  5638. self->req.url_params = query_string(self->req.raw_url);
  5639. self->req.url = self->req.raw_url.substr(
  5640. 0, self->qs_point != 0 ? self->qs_point : std::string::npos);
  5641. self->process_url();
  5642. return 0;
  5643. }
  5644. static int on_header_field(http_parser *self_, const char *at,
  5645. size_t length) {
  5646. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5647. switch (self->header_building_state) {
  5648. case 0:
  5649. if (!self->header_value.empty()) {
  5650. self->req.headers.emplace(std::move(self->header_field),
  5651. std::move(self->header_value));
  5652. }
  5653. self->header_field.assign(at, at + length);
  5654. self->header_building_state = 1;
  5655. break;
  5656. case 1:
  5657. self->header_field.insert(self->header_field.end(), at, at + length);
  5658. break;
  5659. }
  5660. return 0;
  5661. }
  5662. static int on_header_value(http_parser *self_, const char *at,
  5663. size_t length) {
  5664. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5665. switch (self->header_building_state) {
  5666. case 0:
  5667. self->header_value.insert(self->header_value.end(), at, at + length);
  5668. break;
  5669. case 1:
  5670. self->header_building_state = 0;
  5671. self->header_value.assign(at, at + length);
  5672. break;
  5673. }
  5674. return 0;
  5675. }
  5676. static int on_headers_complete(http_parser *self_) {
  5677. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5678. if (!self->header_field.empty()) {
  5679. self->req.headers.emplace(std::move(self->header_field),
  5680. std::move(self->header_value));
  5681. }
  5682. self->set_connection_parameters();
  5683. self->process_header();
  5684. return 0;
  5685. }
  5686. static int on_body(http_parser *self_, const char *at, size_t length) {
  5687. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5688. self->req.body.insert(self->req.body.end(), at, at + length);
  5689. return 0;
  5690. }
  5691. static int on_message_complete(http_parser *self_) {
  5692. HTTPParser *self = static_cast<HTTPParser *>(self_);
  5693. self->message_complete = true;
  5694. self->process_message();
  5695. return 0;
  5696. }
  5697. HTTPParser(Handler *handler) : http_parser(), handler_(handler) {
  5698. http_parser_init(this);
  5699. }
  5700. // return false on error
  5701. /// Parse a buffer into the different sections of an HTTP request.
  5702. bool feed(const char *buffer, int length) {
  5703. if (message_complete) return true;
  5704. const static http_parser_settings settings_{
  5705. on_message_begin, on_method, on_url, on_header_field,
  5706. on_header_value, on_headers_complete, on_body, on_message_complete,
  5707. };
  5708. int nparsed = http_parser_execute(this, &settings_, buffer, length);
  5709. if (http_errno != CHPE_OK) { return false; }
  5710. return nparsed == length;
  5711. }
  5712. bool done() { return feed(nullptr, 0); }
  5713. void clear() {
  5714. req = crow::request();
  5715. header_field.clear();
  5716. header_value.clear();
  5717. header_building_state = 0;
  5718. qs_point = 0;
  5719. message_complete = false;
  5720. state = CROW_NEW_MESSAGE();
  5721. }
  5722. inline void process_url() { handler_->handle_url(); }
  5723. inline void process_header() { handler_->handle_header(); }
  5724. inline void process_message() { handler_->handle(); }
  5725. inline void set_connection_parameters() {
  5726. req.http_ver_major = http_major;
  5727. req.http_ver_minor = http_minor;
  5728. // NOTE(EDev): it seems that the problem is with crow's policy on closing
  5729. // the connection for HTTP_VERSION < 1.0, the behaviour for that in crow is
  5730. // "don't close the connection, but don't send a keep-alive either"
  5731. // HTTP1.1 = always send keep_alive, HTTP1.0 = only send if header exists,
  5732. // HTTP?.? = never send
  5733. req.keep_alive =
  5734. (http_major == 1 && http_minor == 0)
  5735. ? ((flags & F_CONNECTION_KEEP_ALIVE) ? true : false)
  5736. : ((http_major == 1 && http_minor == 1) ? true : false);
  5737. // HTTP1.1 = only close if close header exists, HTTP1.0 = always close
  5738. // unless keep_alive header exists, HTTP?.?= never close
  5739. req.close_connection =
  5740. (http_major == 1 && http_minor == 0)
  5741. ? ((flags & F_CONNECTION_KEEP_ALIVE) ? false : true)
  5742. : ((http_major == 1 && http_minor == 1)
  5743. ? ((flags & F_CONNECTION_CLOSE) ? true : false)
  5744. : false);
  5745. req.upgrade = static_cast<bool>(upgrade);
  5746. }
  5747. /// The final request that this parser outputs.
  5748. ///
  5749. /// Data parsed is put directly into this object as soon as the related
  5750. /// callback returns. (e.g. the request will have the cooorect method as soon
  5751. /// as on_method() returns)
  5752. request req;
  5753. private:
  5754. int header_building_state = 0;
  5755. bool message_complete = false;
  5756. std::string header_field;
  5757. std::string header_value;
  5758. Handler *handler_; ///< This is currently an HTTP connection object (\ref
  5759. ///< crow.Connection).
  5760. };
  5761. } // namespace crow
  5762. #undef CROW_NEW_MESSAGE
  5763. #undef CROW_start_state
  5764. /**
  5765. * \file crow/mustache.h
  5766. * \brief This file includes the definition of the crow::mustache
  5767. * namespace and its members.
  5768. */
  5769. #include <fstream>
  5770. #include <functional>
  5771. #include <iterator>
  5772. #include <string>
  5773. #include <vector>
  5774. namespace crow // NOTE: Already documented in "crow/app.h"
  5775. {
  5776. /**
  5777. * \namespace crow::mustache
  5778. * \brief In this namespace is defined most of the functions and
  5779. * classes related to template rendering.
  5780. *
  5781. * If you are here you might want to read these functions and
  5782. * classes:
  5783. *
  5784. * - \ref template_t
  5785. * - \ref load_text
  5786. * - \ref load_text_unsafe
  5787. * - \ref load
  5788. * - \ref load_unsafe
  5789. *
  5790. * As name suggest, crow uses
  5791. * [mustache](https://en.wikipedia.org/wiki/Mustache_(template_system)) as main
  5792. * template rendering system.
  5793. *
  5794. * You may be interested in taking a look at the [Templating guide
  5795. * page](https://crowcpp.org/master/guides/templating/).
  5796. */
  5797. namespace mustache {
  5798. using context = json::wvalue;
  5799. template_t load(const std::string &filename);
  5800. /**
  5801. * \class invalid_template_exception
  5802. * \brief Represents compilation error of an template. Throwed
  5803. * specially at mustache compile time.
  5804. */
  5805. class invalid_template_exception : public std::exception {
  5806. public:
  5807. invalid_template_exception(const std::string &msg_)
  5808. : msg("crow::mustache error: " + msg_) {}
  5809. virtual const char *what() const throw() override { return msg.c_str(); }
  5810. std::string msg;
  5811. };
  5812. /**
  5813. * \struct rendered_template
  5814. * \brief Returned object after call the
  5815. * \ref template_t::render() method. Its intended to be
  5816. * returned during a **rule declaration**.
  5817. *
  5818. * \see \ref CROW_ROUTE
  5819. * \see \ref CROW_BP_ROUTE
  5820. */
  5821. struct rendered_template : returnable {
  5822. rendered_template() : returnable("text/html") {}
  5823. rendered_template(std::string &body)
  5824. : returnable("text/html"), body_(std::move(body)) {}
  5825. std::string body_;
  5826. std::string dump() const override { return body_; }
  5827. };
  5828. /**
  5829. * \enum ActionType
  5830. * \brief Used in \ref Action to represent different parsing
  5831. * behaviors.
  5832. *
  5833. * \see \ref Action
  5834. */
  5835. enum class ActionType {
  5836. Ignore,
  5837. Tag,
  5838. UnescapeTag,
  5839. OpenBlock,
  5840. CloseBlock,
  5841. ElseBlock,
  5842. Partial,
  5843. };
  5844. /**
  5845. * \struct Action
  5846. * \brief Used during mustache template compilation to
  5847. * represent parsing actions.
  5848. *
  5849. * \see \ref compile
  5850. * \see \ref template_t
  5851. */
  5852. struct Action {
  5853. bool has_end_match;
  5854. char tag_char;
  5855. int start;
  5856. int end;
  5857. int pos;
  5858. ActionType t;
  5859. Action(char tag_char_, ActionType t_, size_t start_, size_t end_,
  5860. size_t pos_ = 0)
  5861. : has_end_match(false), tag_char(tag_char_),
  5862. start(static_cast<int>(start_)), end(static_cast<int>(end_)),
  5863. pos(static_cast<int>(pos_)), t(t_) {}
  5864. bool missing_end_pair() const {
  5865. switch (t) {
  5866. case ActionType::Ignore:
  5867. case ActionType::Tag:
  5868. case ActionType::UnescapeTag:
  5869. case ActionType::CloseBlock:
  5870. case ActionType::Partial: return false;
  5871. // requires a match
  5872. case ActionType::OpenBlock:
  5873. case ActionType::ElseBlock: return !has_end_match;
  5874. default: throw std::logic_error("invalid type");
  5875. }
  5876. }
  5877. };
  5878. /**
  5879. * \class template_t
  5880. * \brief Compiled mustache template object.
  5881. *
  5882. * \warning Use \ref compile instead.
  5883. */
  5884. class template_t {
  5885. public:
  5886. template_t(std::string body) : body_(std::move(body)) {
  5887. // {{ {{# {{/ {{^ {{! {{> {{=
  5888. parse();
  5889. }
  5890. private:
  5891. std::string tag_name(const Action &action) const {
  5892. return body_.substr(action.start, action.end - action.start);
  5893. }
  5894. auto find_context(const std::string &name,
  5895. const std::vector<const context *> &stack,
  5896. bool shouldUseOnlyFirstStackValue = false) const
  5897. -> std::pair<bool, const context &> {
  5898. if (name == ".") { return {true, *stack.back()}; }
  5899. static json::wvalue empty_str;
  5900. empty_str = "";
  5901. int dotPosition = name.find(".");
  5902. if (dotPosition == static_cast<int>(name.npos)) {
  5903. for (auto it = stack.rbegin(); it != stack.rend(); ++it) {
  5904. if ((*it)->t() == json::type::Object) {
  5905. if ((*it)->count(name)) return {true, (**it)[name]};
  5906. }
  5907. }
  5908. } else {
  5909. std::vector<int> dotPositions;
  5910. dotPositions.push_back(-1);
  5911. while (dotPosition != static_cast<int>(name.npos)) {
  5912. dotPositions.push_back(dotPosition);
  5913. dotPosition = name.find(".", dotPosition + 1);
  5914. }
  5915. dotPositions.push_back(name.size());
  5916. std::vector<std::string> names;
  5917. names.reserve(dotPositions.size() - 1);
  5918. for (int i = 1; i < static_cast<int>(dotPositions.size()); i++)
  5919. names.emplace_back(
  5920. name.substr(dotPositions[i - 1] + 1,
  5921. dotPositions[i] - dotPositions[i - 1] - 1));
  5922. for (auto it = stack.rbegin(); it != stack.rend(); ++it) {
  5923. const context *view = *it;
  5924. bool found = true;
  5925. for (auto jt = names.begin(); jt != names.end(); ++jt) {
  5926. if (view->t() == json::type::Object && view->count(*jt)) {
  5927. view = &(*view)[*jt];
  5928. } else {
  5929. if (shouldUseOnlyFirstStackValue) { return {false, empty_str}; }
  5930. found = false;
  5931. break;
  5932. }
  5933. }
  5934. if (found) return {true, *view};
  5935. }
  5936. }
  5937. return {false, empty_str};
  5938. }
  5939. void escape(const std::string &in, std::string &out) const {
  5940. out.reserve(out.size() + in.size());
  5941. for (auto it = in.begin(); it != in.end(); ++it) {
  5942. switch (*it) {
  5943. case '&': out += "&amp;"; break;
  5944. case '<': out += "&lt;"; break;
  5945. case '>': out += "&gt;"; break;
  5946. case '"': out += "&quot;"; break;
  5947. case '\'': out += "&#39;"; break;
  5948. case '/': out += "&#x2F;"; break;
  5949. case '`': out += "&#x60;"; break;
  5950. case '=': out += "&#x3D;"; break;
  5951. default: out += *it; break;
  5952. }
  5953. }
  5954. }
  5955. bool isTagInsideObjectBlock(const int &current,
  5956. const std::vector<const context *> &stack) const {
  5957. int openedBlock = 0;
  5958. for (int i = current; i > 0; --i) {
  5959. auto &action = actions_[i - 1];
  5960. if (action.t == ActionType::OpenBlock) {
  5961. if (openedBlock == 0 && (*stack.rbegin())->t() == json::type::Object) {
  5962. return true;
  5963. }
  5964. --openedBlock;
  5965. } else if (action.t == ActionType::CloseBlock) {
  5966. ++openedBlock;
  5967. }
  5968. }
  5969. return false;
  5970. }
  5971. void render_internal(int actionBegin, int actionEnd,
  5972. std::vector<const context *> &stack, std::string &out,
  5973. int indent) const {
  5974. int current = actionBegin;
  5975. if (indent) out.insert(out.size(), indent, ' ');
  5976. while (current < actionEnd) {
  5977. auto &fragment = fragments_[current];
  5978. auto &action = actions_[current];
  5979. render_fragment(fragment, indent, out);
  5980. switch (action.t) {
  5981. case ActionType::Ignore:
  5982. // do nothing
  5983. break;
  5984. case ActionType::Partial: {
  5985. std::string partial_name = tag_name(action);
  5986. auto partial_templ = load(partial_name);
  5987. int partial_indent = action.pos;
  5988. partial_templ.render_internal(
  5989. 0, partial_templ.fragments_.size() - 1, stack, out,
  5990. partial_indent ? indent + partial_indent : 0);
  5991. } break;
  5992. case ActionType::UnescapeTag:
  5993. case ActionType::Tag: {
  5994. bool shouldUseOnlyFirstStackValue = false;
  5995. if (isTagInsideObjectBlock(current, stack)) {
  5996. shouldUseOnlyFirstStackValue = true;
  5997. }
  5998. auto optional_ctx =
  5999. find_context(tag_name(action), stack, shouldUseOnlyFirstStackValue);
  6000. auto &ctx = optional_ctx.second;
  6001. switch (ctx.t()) {
  6002. case json::type::False:
  6003. case json::type::True:
  6004. case json::type::Number: out += ctx.dump(); break;
  6005. case json::type::String:
  6006. if (action.t == ActionType::Tag)
  6007. escape(ctx.s, out);
  6008. else
  6009. out += ctx.s;
  6010. break;
  6011. case json::type::Function: {
  6012. std::string execute_result = ctx.execute();
  6013. while (execute_result.find("{{") != std::string::npos) {
  6014. template_t result_plug(execute_result);
  6015. execute_result = result_plug.render_string(*(stack[0]));
  6016. }
  6017. if (action.t == ActionType::Tag)
  6018. escape(execute_result, out);
  6019. else
  6020. out += execute_result;
  6021. } break;
  6022. default:
  6023. throw std::runtime_error(
  6024. "not implemented tag type" +
  6025. utility::lexical_cast<std::string>(static_cast<int>(ctx.t())));
  6026. }
  6027. } break;
  6028. case ActionType::ElseBlock: {
  6029. static context nullContext;
  6030. auto optional_ctx = find_context(tag_name(action), stack);
  6031. if (!optional_ctx.first) {
  6032. stack.emplace_back(&nullContext);
  6033. break;
  6034. }
  6035. auto &ctx = optional_ctx.second;
  6036. switch (ctx.t()) {
  6037. case json::type::List:
  6038. if (ctx.l && !ctx.l->empty())
  6039. current = action.pos;
  6040. else
  6041. stack.emplace_back(&nullContext);
  6042. break;
  6043. case json::type::False:
  6044. case json::type::Null: stack.emplace_back(&nullContext); break;
  6045. default: current = action.pos; break;
  6046. }
  6047. break;
  6048. }
  6049. case ActionType::OpenBlock: {
  6050. auto optional_ctx = find_context(tag_name(action), stack);
  6051. if (!optional_ctx.first) {
  6052. current = action.pos;
  6053. break;
  6054. }
  6055. auto &ctx = optional_ctx.second;
  6056. switch (ctx.t()) {
  6057. case json::type::List:
  6058. if (ctx.l)
  6059. for (auto it = ctx.l->begin(); it != ctx.l->end(); ++it) {
  6060. stack.push_back(&*it);
  6061. render_internal(current + 1, action.pos, stack, out, indent);
  6062. stack.pop_back();
  6063. }
  6064. current = action.pos;
  6065. break;
  6066. case json::type::Number:
  6067. case json::type::String:
  6068. case json::type::Object:
  6069. case json::type::True: stack.push_back(&ctx); break;
  6070. case json::type::False:
  6071. case json::type::Null: current = action.pos; break;
  6072. default:
  6073. throw std::runtime_error(
  6074. "{{#: not implemented context type: " +
  6075. utility::lexical_cast<std::string>(static_cast<int>(ctx.t())));
  6076. break;
  6077. }
  6078. break;
  6079. }
  6080. case ActionType::CloseBlock: stack.pop_back(); break;
  6081. default:
  6082. throw std::runtime_error(
  6083. "not implemented " +
  6084. utility::lexical_cast<std::string>(static_cast<int>(action.t)));
  6085. }
  6086. current++;
  6087. }
  6088. auto &fragment = fragments_[actionEnd];
  6089. render_fragment(fragment, indent, out);
  6090. }
  6091. void render_fragment(const std::pair<int, int> fragment, int indent,
  6092. std::string &out) const {
  6093. if (indent) {
  6094. for (int i = fragment.first; i < fragment.second; i++) {
  6095. out += body_[i];
  6096. if (body_[i] == '\n' && i + 1 != static_cast<int>(body_.size()))
  6097. out.insert(out.size(), indent, ' ');
  6098. }
  6099. } else
  6100. out.insert(out.size(), body_, fragment.first,
  6101. fragment.second - fragment.first);
  6102. }
  6103. public:
  6104. /// Output a returnable template from this mustache template
  6105. rendered_template render() const {
  6106. context empty_ctx;
  6107. std::vector<const context *> stack;
  6108. stack.emplace_back(&empty_ctx);
  6109. std::string ret;
  6110. render_internal(0, fragments_.size() - 1, stack, ret, 0);
  6111. return rendered_template(ret);
  6112. }
  6113. /// Apply the values from the context provided and output a returnable
  6114. /// template from this mustache template
  6115. rendered_template render(const context &ctx) const {
  6116. std::vector<const context *> stack;
  6117. stack.emplace_back(&ctx);
  6118. std::string ret;
  6119. render_internal(0, fragments_.size() - 1, stack, ret, 0);
  6120. return rendered_template(ret);
  6121. }
  6122. /// Apply the values from the context provided and output a returnable
  6123. /// template from this mustache template
  6124. rendered_template render(const context &&ctx) const { return render(ctx); }
  6125. /// Output a returnable template from this mustache template
  6126. std::string render_string() const {
  6127. context empty_ctx;
  6128. std::vector<const context *> stack;
  6129. stack.emplace_back(&empty_ctx);
  6130. std::string ret;
  6131. render_internal(0, fragments_.size() - 1, stack, ret, 0);
  6132. return ret;
  6133. }
  6134. /// Apply the values from the context provided and output a returnable
  6135. /// template from this mustache template
  6136. std::string render_string(const context &ctx) const {
  6137. std::vector<const context *> stack;
  6138. stack.emplace_back(&ctx);
  6139. std::string ret;
  6140. render_internal(0, fragments_.size() - 1, stack, ret, 0);
  6141. return ret;
  6142. }
  6143. private:
  6144. void parse() {
  6145. std::string tag_open = "{{";
  6146. std::string tag_close = "}}";
  6147. std::vector<int> blockPositions;
  6148. size_t current = 0;
  6149. while (1) {
  6150. size_t idx = body_.find(tag_open, current);
  6151. if (idx == body_.npos) {
  6152. fragments_.emplace_back(static_cast<int>(current),
  6153. static_cast<int>(body_.size()));
  6154. actions_.emplace_back('!', ActionType::Ignore, 0, 0);
  6155. break;
  6156. }
  6157. fragments_.emplace_back(static_cast<int>(current), static_cast<int>(idx));
  6158. idx += tag_open.size();
  6159. size_t endIdx = body_.find(tag_close, idx);
  6160. if (endIdx == idx) {
  6161. throw invalid_template_exception("empty tag is not allowed");
  6162. }
  6163. if (endIdx == body_.npos) {
  6164. // error, no matching tag
  6165. throw invalid_template_exception("not matched opening tag");
  6166. }
  6167. current = endIdx + tag_close.size();
  6168. char tag_char = body_[idx];
  6169. switch (tag_char) {
  6170. case '#':
  6171. idx++;
  6172. while (body_[idx] == ' ')
  6173. idx++;
  6174. while (body_[endIdx - 1] == ' ')
  6175. endIdx--;
  6176. blockPositions.emplace_back(static_cast<int>(actions_.size()));
  6177. actions_.emplace_back(tag_char, ActionType::OpenBlock, idx, endIdx);
  6178. break;
  6179. case '/':
  6180. idx++;
  6181. while (body_[idx] == ' ')
  6182. idx++;
  6183. while (body_[endIdx - 1] == ' ')
  6184. endIdx--;
  6185. {
  6186. if (blockPositions.empty()) {
  6187. throw invalid_template_exception(
  6188. std::string("unexpected closing tag: ") +
  6189. body_.substr(idx, endIdx - idx));
  6190. }
  6191. auto &matched = actions_[blockPositions.back()];
  6192. if (body_.compare(idx, endIdx - idx, body_, matched.start,
  6193. matched.end - matched.start) != 0) {
  6194. throw invalid_template_exception(
  6195. std::string("not matched {{") + matched.tag_char +
  6196. "{{/ pair: " +
  6197. body_.substr(matched.start, matched.end - matched.start) +
  6198. ", " + body_.substr(idx, endIdx - idx));
  6199. }
  6200. matched.pos = static_cast<int>(actions_.size());
  6201. matched.has_end_match = true;
  6202. }
  6203. actions_.emplace_back(tag_char, ActionType::CloseBlock, idx, endIdx,
  6204. blockPositions.back());
  6205. blockPositions.pop_back();
  6206. break;
  6207. case '^':
  6208. idx++;
  6209. while (body_[idx] == ' ')
  6210. idx++;
  6211. while (body_[endIdx - 1] == ' ')
  6212. endIdx--;
  6213. blockPositions.emplace_back(static_cast<int>(actions_.size()));
  6214. actions_.emplace_back(tag_char, ActionType::ElseBlock, idx, endIdx);
  6215. break;
  6216. case '!':
  6217. // do nothing action
  6218. actions_.emplace_back(tag_char, ActionType::Ignore, idx + 1, endIdx);
  6219. break;
  6220. case '>': // partial
  6221. idx++;
  6222. while (body_[idx] == ' ')
  6223. idx++;
  6224. while (body_[endIdx - 1] == ' ')
  6225. endIdx--;
  6226. actions_.emplace_back(tag_char, ActionType::Partial, idx, endIdx);
  6227. break;
  6228. case '{':
  6229. if (tag_open != "{{" || tag_close != "}}")
  6230. throw invalid_template_exception(
  6231. "cannot use triple mustache when delimiter changed");
  6232. idx++;
  6233. if (body_[endIdx + 2] != '}') {
  6234. throw invalid_template_exception("{{{: }}} not matched");
  6235. }
  6236. while (body_[idx] == ' ')
  6237. idx++;
  6238. while (body_[endIdx - 1] == ' ')
  6239. endIdx--;
  6240. actions_.emplace_back(tag_char, ActionType::UnescapeTag, idx, endIdx);
  6241. current++;
  6242. break;
  6243. case '&':
  6244. idx++;
  6245. while (body_[idx] == ' ')
  6246. idx++;
  6247. while (body_[endIdx - 1] == ' ')
  6248. endIdx--;
  6249. actions_.emplace_back(tag_char, ActionType::UnescapeTag, idx, endIdx);
  6250. break;
  6251. case '=':
  6252. // tag itself is no-op
  6253. idx++;
  6254. actions_.emplace_back(tag_char, ActionType::Ignore, idx, endIdx);
  6255. endIdx--;
  6256. if (body_[endIdx] != '=')
  6257. throw invalid_template_exception("{{=: not matching = tag: " +
  6258. body_.substr(idx, endIdx - idx));
  6259. endIdx--;
  6260. while (body_[idx] == ' ')
  6261. idx++;
  6262. while (body_[endIdx] == ' ')
  6263. endIdx--;
  6264. endIdx++;
  6265. {
  6266. bool succeeded = false;
  6267. for (size_t i = idx; i < endIdx; i++) {
  6268. if (body_[i] == ' ') {
  6269. tag_open = body_.substr(idx, i - idx);
  6270. while (body_[i] == ' ')
  6271. i++;
  6272. tag_close = body_.substr(i, endIdx - i);
  6273. if (tag_open.empty())
  6274. throw invalid_template_exception("{{=: empty open tag");
  6275. if (tag_close.empty())
  6276. throw invalid_template_exception("{{=: empty close tag");
  6277. if (tag_close.find(" ") != tag_close.npos)
  6278. throw invalid_template_exception(
  6279. "{{=: invalid open/close tag: " + tag_open + " " +
  6280. tag_close);
  6281. succeeded = true;
  6282. break;
  6283. }
  6284. }
  6285. if (!succeeded)
  6286. throw invalid_template_exception(
  6287. "{{=: cannot find space between new open/close tags");
  6288. }
  6289. break;
  6290. default:
  6291. // normal tag case;
  6292. while (body_[idx] == ' ')
  6293. idx++;
  6294. while (body_[endIdx - 1] == ' ')
  6295. endIdx--;
  6296. actions_.emplace_back(tag_char, ActionType::Tag, idx, endIdx);
  6297. break;
  6298. }
  6299. }
  6300. // ensure no unmatched tags
  6301. for (int i = 0; i < static_cast<int>(actions_.size()); i++) {
  6302. if (actions_[i].missing_end_pair()) {
  6303. throw invalid_template_exception(
  6304. std::string("open tag has no matching end tag {{") +
  6305. actions_[i].tag_char + " {{/ pair: " +
  6306. body_.substr(actions_[i].start,
  6307. actions_[i].end - actions_[i].start));
  6308. }
  6309. }
  6310. // removing standalones
  6311. for (int i = static_cast<int>(actions_.size()) - 2; i >= 0; i--) {
  6312. if (actions_[i].t == ActionType::Tag ||
  6313. actions_[i].t == ActionType::UnescapeTag)
  6314. continue;
  6315. auto &fragment_before = fragments_[i];
  6316. auto &fragment_after = fragments_[i + 1];
  6317. bool is_last_action = i == static_cast<int>(actions_.size()) - 2;
  6318. bool all_space_before = true;
  6319. int j, k;
  6320. for (j = fragment_before.second - 1; j >= fragment_before.first; j--) {
  6321. if (body_[j] != ' ') {
  6322. all_space_before = false;
  6323. break;
  6324. }
  6325. }
  6326. if (all_space_before && i > 0) continue;
  6327. if (!all_space_before && body_[j] != '\n') continue;
  6328. bool all_space_after = true;
  6329. for (k = fragment_after.first;
  6330. k < static_cast<int>(body_.size()) && k < fragment_after.second;
  6331. k++) {
  6332. if (body_[k] != ' ') {
  6333. all_space_after = false;
  6334. break;
  6335. }
  6336. }
  6337. if (all_space_after && !is_last_action) continue;
  6338. if (!all_space_after &&
  6339. !(body_[k] == '\n' ||
  6340. (body_[k] == '\r' && k + 1 < static_cast<int>(body_.size()) &&
  6341. body_[k + 1] == '\n')))
  6342. continue;
  6343. if (actions_[i].t == ActionType::Partial) {
  6344. actions_[i].pos = fragment_before.second - j - 1;
  6345. }
  6346. fragment_before.second = j + 1;
  6347. if (!all_space_after) {
  6348. if (body_[k] == '\n')
  6349. k++;
  6350. else
  6351. k += 2;
  6352. fragment_after.first = k;
  6353. }
  6354. }
  6355. }
  6356. std::vector<std::pair<int, int>> fragments_;
  6357. std::vector<Action> actions_;
  6358. std::string body_;
  6359. };
  6360. /// \brief The function that compiles a source into a mustache
  6361. /// template.
  6362. inline template_t compile(const std::string &body) { return template_t(body); }
  6363. namespace detail {
  6364. inline std::string &get_template_base_directory_ref() {
  6365. static std::string template_base_directory = "templates";
  6366. return template_base_directory;
  6367. }
  6368. /// A base directory not related to any blueprint
  6369. inline std::string &get_global_template_base_directory_ref() {
  6370. static std::string template_base_directory = "templates";
  6371. return template_base_directory;
  6372. }
  6373. } // namespace detail
  6374. /// \brief The default way that \ref load, \ref load_unsafe,
  6375. /// \ref load_text and \ref load_text_unsafe use to read the
  6376. /// contents of a file.
  6377. inline std::string default_loader(const std::string &filename) {
  6378. std::string path = detail::get_template_base_directory_ref();
  6379. std::ifstream inf(utility::join_path(path, filename));
  6380. if (!inf) {
  6381. CROW_LOG_WARNING << "Template \"" << filename << "\" not found.";
  6382. return {};
  6383. }
  6384. return {std::istreambuf_iterator<char>(inf),
  6385. std::istreambuf_iterator<char>()};
  6386. }
  6387. namespace detail {
  6388. inline std::function<std::string(std::string)> &get_loader_ref() {
  6389. static std::function<std::string(std::string)> loader = default_loader;
  6390. return loader;
  6391. }
  6392. } // namespace detail
  6393. /// \brief Defines the templates directory path at **route
  6394. /// level**. By default is `templates/`.
  6395. inline void set_base(const std::string &path) {
  6396. auto &base = detail::get_template_base_directory_ref();
  6397. base = path;
  6398. if (base.back() != '\\' && base.back() != '/') { base += '/'; }
  6399. }
  6400. /// \brief Defines the templates directory path at **global
  6401. /// level**. By default is `templates/`.
  6402. inline void set_global_base(const std::string &path) {
  6403. auto &base = detail::get_global_template_base_directory_ref();
  6404. base = path;
  6405. if (base.back() != '\\' && base.back() != '/') { base += '/'; }
  6406. }
  6407. /// \brief Change the way that \ref load, \ref load_unsafe,
  6408. /// \ref load_text and \ref load_text_unsafe reads a file.
  6409. ///
  6410. /// By default, the previously mentioned functions load files
  6411. /// using \ref default_loader, that only reads a file and
  6412. /// returns a std::string.
  6413. inline void set_loader(std::function<std::string(std::string)> loader) {
  6414. detail::get_loader_ref() = std::move(loader);
  6415. }
  6416. /// \brief Open, read and sanitize a file but returns a
  6417. /// std::string without a previous rendering process.
  6418. ///
  6419. /// Except for the **sanitize process** this function does the
  6420. /// almost the same thing that \ref load_text_unsafe.
  6421. inline std::string load_text(const std::string &filename) {
  6422. std::string filename_sanitized(filename);
  6423. utility::sanitize_filename(filename_sanitized);
  6424. return detail::get_loader_ref()(filename_sanitized);
  6425. }
  6426. /// \brief Open and read a file but returns a std::string
  6427. /// without a previous rendering process.
  6428. ///
  6429. /// This function is more like a helper to reduce code like
  6430. /// this...
  6431. ///
  6432. /// ```cpp
  6433. /// std::ifstream file("home.html");
  6434. /// return std::string({std::istreambuf_iterator<char>(file),
  6435. /// std::istreambuf_iterator<char>()});
  6436. /// ```
  6437. ///
  6438. /// ... Into this...
  6439. ///
  6440. /// ```cpp
  6441. /// return load("home.html");
  6442. /// ```
  6443. ///
  6444. /// \warning Usually \ref load_text is more recommended to use
  6445. /// instead because it may prevent some [XSS
  6446. /// Attacks](https://en.wikipedia.org/wiki/Cross-site_scripting).
  6447. /// **Never blindly trust your users!**
  6448. inline std::string load_text_unsafe(const std::string &filename) {
  6449. return detail::get_loader_ref()(filename);
  6450. }
  6451. /// \brief Open, read and renders a file using a mustache
  6452. /// compiler. It also sanitize the input before compilation.
  6453. inline template_t load(const std::string &filename) {
  6454. std::string filename_sanitized(filename);
  6455. utility::sanitize_filename(filename_sanitized);
  6456. return compile(detail::get_loader_ref()(filename_sanitized));
  6457. }
  6458. /// \brief Open, read and renders a file using a mustache
  6459. /// compiler. But it **do not** sanitize the input before
  6460. /// compilation.
  6461. ///
  6462. /// \warning Usually \ref load is more recommended to use
  6463. /// instead because it may prevent some [XSS
  6464. /// Attacks](https://en.wikipedia.org/wiki/Cross-site_scripting).
  6465. /// **Never blindly trust your users!**
  6466. inline template_t load_unsafe(const std::string &filename) {
  6467. return compile(detail::get_loader_ref()(filename));
  6468. }
  6469. } // namespace mustache
  6470. } // namespace crow
  6471. #include <stdexcept>
  6472. namespace crow {
  6473. struct bad_request : public std::runtime_error {
  6474. bad_request(const std::string &what_arg) : std::runtime_error(what_arg) {}
  6475. bad_request(const char *what_arg) : std::runtime_error(what_arg) {}
  6476. };
  6477. } // namespace crow
  6478. #include <sstream>
  6479. #include <string>
  6480. #include <vector>
  6481. namespace crow {
  6482. /// Encapsulates anything related to processing and organizing `multipart/xyz`
  6483. /// messages
  6484. namespace multipart {
  6485. const std::string dd = "--";
  6486. /// The first part in a section, contains metadata about the part
  6487. struct header {
  6488. std::string value; ///< The first part of the header, usually `Content-Type`
  6489. ///< or `Content-Disposition`
  6490. std::unordered_map<std::string, std::string>
  6491. params; ///< The parameters of the header, come after the `value`
  6492. operator int() const {
  6493. return std::stoi(value);
  6494. } ///< Returns \ref value as integer
  6495. operator double() const {
  6496. return std::stod(value);
  6497. } ///< Returns \ref value as double
  6498. };
  6499. /// Multipart header map (key is header key).
  6500. using mph_map =
  6501. std::unordered_multimap<std::string, header, ci_hash, ci_key_eq>;
  6502. /// Find and return the value object associated with the key. (returns an empty
  6503. /// class if nothing is found)
  6504. template <typename O, typename T>
  6505. inline const O &get_header_value_object(const T &headers,
  6506. const std::string &key) {
  6507. if (headers.count(key)) { return headers.find(key)->second; }
  6508. static O empty;
  6509. return empty;
  6510. }
  6511. /// Same as \ref get_header_value_object() but for \ref multipart.header
  6512. template <typename T>
  6513. inline const header &get_header_object(const T &headers,
  6514. const std::string &key) {
  6515. return get_header_value_object<header>(headers, key);
  6516. }
  6517. /// One part of the multipart message
  6518. ///
  6519. /// It is usually separated from other sections by a `boundary`
  6520. struct part {
  6521. mph_map headers; ///< (optional) The first part before the data, Contains
  6522. ///< information regarding the type of data and encoding
  6523. std::string body; ///< The actual data in the part
  6524. operator int() const {
  6525. return std::stoi(body);
  6526. } ///< Returns \ref body as integer
  6527. operator double() const {
  6528. return std::stod(body);
  6529. } ///< Returns \ref body as double
  6530. const header &get_header_object(const std::string &key) const {
  6531. return multipart::get_header_object(headers, key);
  6532. }
  6533. };
  6534. /// Multipart map (key is the name parameter).
  6535. using mp_map = std::unordered_multimap<std::string, part, ci_hash, ci_key_eq>;
  6536. /// The parsed multipart request/response
  6537. struct message : public returnable {
  6538. ci_map headers; ///< The request/response headers
  6539. std::string boundary; ///< The text boundary that separates different `parts`
  6540. std::vector<part> parts; ///< The individual parts of the message
  6541. mp_map part_map; ///< The individual parts of the message, organized in a map
  6542. ///< with the `name` header parameter being the key
  6543. const std::string &get_header_value(const std::string &key) const {
  6544. return crow::get_header_value(headers, key);
  6545. }
  6546. part get_part_by_name(const std::string &name) {
  6547. mp_map::iterator result = part_map.find(name);
  6548. if (result != part_map.end())
  6549. return result->second;
  6550. else
  6551. return {};
  6552. }
  6553. /// Represent all parts as a string (**does not include message headers**)
  6554. std::string dump() const override {
  6555. std::stringstream str;
  6556. std::string delimiter = dd + boundary;
  6557. for (unsigned i = 0; i < parts.size(); i++) {
  6558. str << delimiter << crlf;
  6559. str << dump(i);
  6560. }
  6561. str << delimiter << dd << crlf;
  6562. return str.str();
  6563. }
  6564. /// Represent an individual part as a string
  6565. std::string dump(int part_) const {
  6566. std::stringstream str;
  6567. part item = parts[part_];
  6568. for (auto &item_h : item.headers) {
  6569. str << item_h.first << ": " << item_h.second.value;
  6570. for (auto &it : item_h.second.params) {
  6571. str << "; " << it.first << '=' << pad(it.second);
  6572. }
  6573. str << crlf;
  6574. }
  6575. str << crlf;
  6576. str << item.body << crlf;
  6577. return str.str();
  6578. }
  6579. /// Default constructor using default values
  6580. message(const ci_map &headers_, const std::string &boundary_,
  6581. const std::vector<part> &sections)
  6582. : returnable("multipart/form-data; boundary=CROW-BOUNDARY"),
  6583. headers(headers_), boundary(boundary_), parts(sections) {
  6584. if (!boundary.empty())
  6585. content_type = "multipart/form-data; boundary=" + boundary;
  6586. for (auto &item : parts) {
  6587. part_map.emplace((get_header_object(item.headers, "Content-Disposition")
  6588. .params.find("name")
  6589. ->second),
  6590. item);
  6591. }
  6592. }
  6593. /// Create a multipart message from a request data
  6594. explicit message(const request &req)
  6595. : returnable("multipart/form-data; boundary=CROW-BOUNDARY"),
  6596. headers(req.headers),
  6597. boundary(get_boundary(get_header_value("Content-Type"))) {
  6598. if (!boundary.empty()) {
  6599. content_type = "multipart/form-data; boundary=" + boundary;
  6600. parse_body(req.body);
  6601. } else {
  6602. throw bad_request("Empty boundary in multipart message");
  6603. }
  6604. }
  6605. private:
  6606. std::string get_boundary(const std::string &header) const {
  6607. constexpr char boundary_text[] = "boundary=";
  6608. size_t found = header.find(boundary_text);
  6609. if (found != std::string::npos) {
  6610. std::string to_return(header.substr(found + strlen(boundary_text)));
  6611. if (to_return[0] == '\"') {
  6612. to_return = to_return.substr(1, to_return.length() - 2);
  6613. }
  6614. return to_return;
  6615. }
  6616. return std::string();
  6617. }
  6618. void parse_body(std::string body) {
  6619. std::string delimiter = dd + boundary;
  6620. // TODO(EDev): Exit on error
  6621. while (body != (crlf)) {
  6622. size_t found = body.find(delimiter);
  6623. if (found == std::string::npos) {
  6624. // did not find delimiter; probably an ill-formed body; throw to
  6625. // indicate the issue to user
  6626. throw bad_request("Unable to find delimiter in multipart message. "
  6627. "Probably ill-formed body");
  6628. }
  6629. std::string section = body.substr(0, found);
  6630. // +2 is the CRLF.
  6631. // We don't check it and delete it so that the same delimiter can be used
  6632. // for The last delimiter (--delimiter--CRLF).
  6633. body.erase(0, found + delimiter.length() + 2);
  6634. if (!section.empty()) {
  6635. part parsed_section(parse_section(section));
  6636. part_map.emplace(
  6637. (get_header_object(parsed_section.headers, "Content-Disposition")
  6638. .params.find("name")
  6639. ->second),
  6640. parsed_section);
  6641. parts.push_back(std::move(parsed_section));
  6642. }
  6643. }
  6644. }
  6645. part parse_section(std::string &section) {
  6646. struct part to_return;
  6647. size_t found = section.find(crlf + crlf);
  6648. std::string head_line = section.substr(0, found + 2);
  6649. section.erase(0, found + 4);
  6650. parse_section_head(head_line, to_return);
  6651. to_return.body = section.substr(0, section.length() - 2);
  6652. return to_return;
  6653. }
  6654. void parse_section_head(std::string &lines, part &part) {
  6655. while (!lines.empty()) {
  6656. header to_add;
  6657. const size_t found_crlf = lines.find(crlf);
  6658. std::string line = lines.substr(0, found_crlf);
  6659. std::string key;
  6660. lines.erase(0, found_crlf + 2);
  6661. // Add the header if available
  6662. if (!line.empty()) {
  6663. const size_t found_semicolon = line.find("; ");
  6664. std::string header = line.substr(0, found_semicolon);
  6665. if (found_semicolon != std::string::npos)
  6666. line.erase(0, found_semicolon + 2);
  6667. else
  6668. line = std::string();
  6669. size_t header_split = header.find(": ");
  6670. key = header.substr(0, header_split);
  6671. to_add.value = header.substr(header_split + 2);
  6672. }
  6673. // Add the parameters
  6674. while (!line.empty()) {
  6675. const size_t found_semicolon = line.find("; ");
  6676. std::string param = line.substr(0, found_semicolon);
  6677. if (found_semicolon != std::string::npos)
  6678. line.erase(0, found_semicolon + 2);
  6679. else
  6680. line = std::string();
  6681. size_t param_split = param.find('=');
  6682. std::string value = param.substr(param_split + 1);
  6683. to_add.params.emplace(param.substr(0, param_split), trim(value));
  6684. }
  6685. part.headers.emplace(key, to_add);
  6686. }
  6687. }
  6688. inline std::string trim(std::string &string, const char &excess = '"') const {
  6689. if (string.length() > 1 && string[0] == excess &&
  6690. string[string.length() - 1] == excess)
  6691. return string.substr(1, string.length() - 2);
  6692. return string;
  6693. }
  6694. inline std::string pad(std::string &string, const char &padding = '"') const {
  6695. return (padding + string + padding);
  6696. }
  6697. };
  6698. } // namespace multipart
  6699. } // namespace crow
  6700. #include <charconv>
  6701. #include <sstream>
  6702. #include <string>
  6703. #include <string_view>
  6704. #include <vector>
  6705. // for crow::multipart::dd
  6706. namespace crow {
  6707. /// Encapsulates anything related to processing and organizing `multipart/xyz`
  6708. /// messages
  6709. namespace multipart {
  6710. /// The first part in a section, contains metadata about the part
  6711. struct header_view {
  6712. std::string_view value; ///< The first part of the header, usually
  6713. ///< `Content-Type` or `Content-Disposition`
  6714. std::unordered_map<std::string_view, std::string_view>
  6715. params; ///< The parameters of the header, come after the `value`
  6716. /// Returns \ref value as integer
  6717. operator int() const {
  6718. int result = 0;
  6719. std::from_chars(value.data(), value.data() + value.size(), result);
  6720. return result;
  6721. }
  6722. /// Returns \ref value as double
  6723. operator double() const {
  6724. // There's no std::from_chars for floating-point types in a lot of STLs
  6725. return std::stod(static_cast<std::string>(value));
  6726. }
  6727. };
  6728. /// Multipart header map (key is header key).
  6729. using mph_view_map =
  6730. std::unordered_multimap<std::string_view, header_view, ci_hash, ci_key_eq>;
  6731. /// Finds and returns the header with the specified key. (returns an empty
  6732. /// header if nothing is found)
  6733. inline const header_view &get_header_object(const mph_view_map &headers,
  6734. const std::string_view key) {
  6735. const auto header = headers.find(key);
  6736. if (header != headers.cend()) { return header->second; }
  6737. static header_view empty;
  6738. return empty;
  6739. }
  6740. /// String padded with the specified padding (double quotes by default)
  6741. struct padded {
  6742. std::string_view value; ///< String to pad
  6743. const char padding = '"'; ///< Padding to use
  6744. /// Outputs padded value to the stream
  6745. friend std::ostream &operator<<(std::ostream &stream, const padded value_) {
  6746. return stream << value_.padding << value_.value << value_.padding;
  6747. }
  6748. };
  6749. /// One part of the multipart message
  6750. ///
  6751. /// It is usually separated from other sections by a `boundary`
  6752. struct part_view {
  6753. mph_view_map headers; ///< (optional) The first part before the data, Contains
  6754. ///< information regarding the type of data and encoding
  6755. std::string_view body; ///< The actual data in the part
  6756. /// Returns \ref body as integer
  6757. operator int() const {
  6758. int result = 0;
  6759. std::from_chars(body.data(), body.data() + body.size(), result);
  6760. return result;
  6761. }
  6762. /// Returns \ref body as double
  6763. operator double() const {
  6764. // There's no std::from_chars for floating-point types in a lot of STLs
  6765. return std::stod(static_cast<std::string>(body));
  6766. }
  6767. const header_view &get_header_object(const std::string_view key) const {
  6768. return multipart::get_header_object(headers, key);
  6769. }
  6770. friend std::ostream &operator<<(std::ostream &stream, const part_view &part) {
  6771. for (const auto &[header_key, header_value] : part.headers) {
  6772. stream << header_key << ": " << header_value.value;
  6773. for (const auto &[param_key, param_value] : header_value.params) {
  6774. stream << "; " << param_key << '=' << padded{param_value};
  6775. }
  6776. stream << crlf;
  6777. }
  6778. stream << crlf;
  6779. stream << part.body << crlf;
  6780. return stream;
  6781. }
  6782. };
  6783. /// Multipart map (key is the name parameter).
  6784. using mp_view_map =
  6785. std::unordered_multimap<std::string_view, part_view, ci_hash, ci_key_eq>;
  6786. /// The parsed multipart request/response
  6787. struct message_view {
  6788. std::reference_wrapper<const ci_map>
  6789. headers; ///< The request/response headers
  6790. std::string boundary; ///< The text boundary that separates different `parts`
  6791. std::vector<part_view> parts; ///< The individual parts of the message
  6792. mp_view_map part_map; ///< The individual parts of the message, organized in a
  6793. ///< map with the `name` header parameter being the key
  6794. const std::string &get_header_value(const std::string &key) const {
  6795. return crow::get_header_value(headers.get(), key);
  6796. }
  6797. part_view get_part_by_name(const std::string_view name) {
  6798. mp_view_map::iterator result = part_map.find(name);
  6799. if (result != part_map.end())
  6800. return result->second;
  6801. else
  6802. return {};
  6803. }
  6804. friend std::ostream &operator<<(std::ostream &stream,
  6805. const message_view message) {
  6806. std::string delimiter = dd + message.boundary;
  6807. for (const part_view &part : message.parts) {
  6808. stream << delimiter << crlf;
  6809. stream << part;
  6810. }
  6811. stream << delimiter << dd << crlf;
  6812. return stream;
  6813. }
  6814. /// Represent all parts as a string (**does not include message headers**)
  6815. std::string dump() const {
  6816. std::ostringstream str;
  6817. str << *this;
  6818. return std::move(str).str();
  6819. }
  6820. /// Represent an individual part as a string
  6821. std::string dump(int part_) const {
  6822. std::ostringstream str;
  6823. str << parts.at(part_);
  6824. return std::move(str).str();
  6825. }
  6826. /// Default constructor using default values
  6827. message_view(const ci_map &headers_, const std::string &boundary_,
  6828. const std::vector<part_view> &sections)
  6829. : headers(headers_), boundary(boundary_), parts(sections) {
  6830. for (const part_view &item : parts) {
  6831. part_map.emplace((get_header_object(item.headers, "Content-Disposition")
  6832. .params.find("name")
  6833. ->second),
  6834. item);
  6835. }
  6836. }
  6837. /// Create a multipart message from a request data
  6838. explicit message_view(const request &req)
  6839. : headers(req.headers),
  6840. boundary(get_boundary(get_header_value("Content-Type"))) {
  6841. parse_body(req.body);
  6842. }
  6843. private:
  6844. std::string_view get_boundary(const std::string_view header) const {
  6845. constexpr std::string_view boundary_text = "boundary=";
  6846. const size_t found = header.find(boundary_text);
  6847. if (found == std::string_view::npos) { return std::string_view(); }
  6848. const std::string_view to_return =
  6849. header.substr(found + boundary_text.size());
  6850. if (to_return[0] == '\"') {
  6851. return to_return.substr(1, to_return.length() - 2);
  6852. }
  6853. return to_return;
  6854. }
  6855. void parse_body(std::string_view body) {
  6856. const std::string delimiter = dd + boundary;
  6857. // TODO(EDev): Exit on error
  6858. while (body != (crlf)) {
  6859. const size_t found = body.find(delimiter);
  6860. if (found == std::string_view::npos) {
  6861. // did not find delimiter; probably an ill-formed body; ignore the rest
  6862. break;
  6863. }
  6864. const std::string_view section = body.substr(0, found);
  6865. // +2 is the CRLF.
  6866. // We don't check it and delete it so that the same delimiter can be used
  6867. // for The last delimiter (--delimiter--CRLF).
  6868. body = body.substr(found + delimiter.length() + 2);
  6869. if (!section.empty()) {
  6870. part_view parsed_section = parse_section(section);
  6871. part_map.emplace(
  6872. (get_header_object(parsed_section.headers, "Content-Disposition")
  6873. .params.find("name")
  6874. ->second),
  6875. parsed_section);
  6876. parts.push_back(std::move(parsed_section));
  6877. }
  6878. }
  6879. }
  6880. part_view parse_section(std::string_view section) {
  6881. constexpr static std::string_view crlf2 = "\r\n\r\n";
  6882. const size_t found = section.find(crlf2);
  6883. const std::string_view head_line = section.substr(0, found + 2);
  6884. section = section.substr(found + 4);
  6885. return part_view{
  6886. parse_section_head(head_line),
  6887. section.substr(0, section.length() - 2),
  6888. };
  6889. }
  6890. mph_view_map parse_section_head(std::string_view lines) {
  6891. mph_view_map result;
  6892. while (!lines.empty()) {
  6893. header_view to_add;
  6894. const size_t found_crlf = lines.find(crlf);
  6895. std::string_view line = lines.substr(0, found_crlf);
  6896. std::string_view key;
  6897. lines = lines.substr(found_crlf + 2);
  6898. // Add the header if available
  6899. if (!line.empty()) {
  6900. const size_t found_semicolon = line.find("; ");
  6901. std::string_view header = line.substr(0, found_semicolon);
  6902. if (found_semicolon != std::string_view::npos)
  6903. line = line.substr(found_semicolon + 2);
  6904. else
  6905. line = std::string_view();
  6906. const size_t header_split = header.find(": ");
  6907. key = header.substr(0, header_split);
  6908. to_add.value = header.substr(header_split + 2);
  6909. }
  6910. // Add the parameters
  6911. while (!line.empty()) {
  6912. const size_t found_semicolon = line.find("; ");
  6913. std::string_view param = line.substr(0, found_semicolon);
  6914. if (found_semicolon != std::string_view::npos)
  6915. line = line.substr(found_semicolon + 2);
  6916. else
  6917. line = std::string_view();
  6918. const size_t param_split = param.find('=');
  6919. const std::string_view value = param.substr(param_split + 1);
  6920. to_add.params.emplace(param.substr(0, param_split), trim(value));
  6921. }
  6922. result.emplace(key, to_add);
  6923. }
  6924. return result;
  6925. }
  6926. inline std::string_view trim(const std::string_view string,
  6927. const char excess = '"') const {
  6928. if (string.length() > 1 && string[0] == excess &&
  6929. string[string.length() - 1] == excess)
  6930. return string.substr(1, string.length() - 2);
  6931. return string;
  6932. }
  6933. };
  6934. } // namespace multipart
  6935. } // namespace crow
  6936. #include <fstream>
  6937. #include <ios>
  6938. #include <sstream>
  6939. #include <string>
  6940. #include <unordered_map>
  6941. // S_ISREG is not defined for windows
  6942. // This defines it like suggested in https://stackoverflow.com/a/62371749
  6943. #if defined(_MSC_VER)
  6944. #define _CRT_INTERNAL_NONSTDC_NAMES 1
  6945. #endif
  6946. #include <sys/stat.h>
  6947. #if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
  6948. #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
  6949. #endif
  6950. namespace crow {
  6951. template <typename Adaptor, typename Handler, typename... Middlewares>
  6952. class Connection;
  6953. namespace websocket {
  6954. template <typename Adaptor, typename Handler> class Connection;
  6955. }
  6956. class Router;
  6957. /// HTTP response
  6958. struct response {
  6959. template <typename Adaptor, typename Handler, typename... Middlewares>
  6960. friend class crow::Connection;
  6961. template <typename Adaptor, typename Handler>
  6962. friend class websocket::Connection;
  6963. friend class Router;
  6964. int code{200}; ///< The Status code for the response.
  6965. std::string body; ///< The actual payload containing the response data.
  6966. ci_map headers; ///< HTTP headers.
  6967. #ifdef CROW_ENABLE_COMPRESSION
  6968. bool compressed = true; ///< If compression is enabled and this is false, the
  6969. ///< individual response will not be compressed.
  6970. #endif
  6971. bool skip_body = false; ///< Whether this is a response to a HEAD request.
  6972. bool manual_length_header = false; ///< Whether Crow should automatically add
  6973. ///< a "Content-Length" header.
  6974. /// Set the value of an existing header in the response.
  6975. void set_header(std::string key, std::string value) {
  6976. headers.erase(key);
  6977. headers.emplace(std::move(key), std::move(value));
  6978. }
  6979. /// Add a new header to the response.
  6980. void add_header(std::string key, std::string value) {
  6981. headers.emplace(std::move(key), std::move(value));
  6982. }
  6983. const std::string &get_header_value(const std::string &key) {
  6984. return crow::get_header_value(headers, key);
  6985. }
  6986. // naive validation of a mime-type string
  6987. static bool validate_mime_type(const std::string &candidate) noexcept {
  6988. // Here we simply check that the candidate type starts with
  6989. // a valid parent type, and has at least one character afterwards.
  6990. std::array<std::string, 10> valid_parent_types = {
  6991. "application/", "audio/", "font/", "example/", "image/",
  6992. "message/", "model/", "multipart/", "text/", "video/"};
  6993. for (const std::string &parent : valid_parent_types) {
  6994. // ensure the candidate is *longer* than the parent,
  6995. // to avoid unnecessary string comparison and to
  6996. // reject zero-length subtypes.
  6997. if (candidate.size() <= parent.size()) { continue; }
  6998. // strncmp is used rather than substr to avoid allocation,
  6999. // but a string_view approach would be better if Crow
  7000. // migrates to C++17.
  7001. if (strncmp(parent.c_str(), candidate.c_str(), parent.size()) == 0) {
  7002. return true;
  7003. }
  7004. }
  7005. return false;
  7006. }
  7007. // Find the mime type from the content type either by lookup,
  7008. // or by the content type itself, if it is a valid a mime type.
  7009. // Defaults to text/plain.
  7010. static std::string get_mime_type(const std::string &contentType) {
  7011. const auto mimeTypeIterator = mime_types.find(contentType);
  7012. if (mimeTypeIterator != mime_types.end()) {
  7013. return mimeTypeIterator->second;
  7014. } else if (validate_mime_type(contentType)) {
  7015. return contentType;
  7016. } else {
  7017. CROW_LOG_WARNING << "Unable to interpret mime type for content type '"
  7018. << contentType << "'. Defaulting to text/plain.";
  7019. return "text/plain";
  7020. }
  7021. }
  7022. // clang-format off
  7023. response() {}
  7024. explicit response(int code_) : code(code_) {}
  7025. response(std::string body_) : body(std::move(body_)) {}
  7026. response(int code_, std::string body_) : code(code_), body(std::move(body_)) {}
  7027. // clang-format on
  7028. response(returnable &&value) {
  7029. body = value.dump();
  7030. set_header("Content-Type", value.content_type);
  7031. }
  7032. response(returnable &value) {
  7033. body = value.dump();
  7034. set_header("Content-Type", value.content_type);
  7035. }
  7036. response(int code_, returnable &value) : code(code_) {
  7037. body = value.dump();
  7038. set_header("Content-Type", value.content_type);
  7039. }
  7040. response(int code_, returnable &&value) : code(code_), body(value.dump()) {
  7041. set_header("Content-Type", std::move(value.content_type));
  7042. }
  7043. response(response &&r) { *this = std::move(r); }
  7044. response(std::string contentType, std::string body_)
  7045. : body(std::move(body_)) {
  7046. set_header("Content-Type", get_mime_type(contentType));
  7047. }
  7048. response(int code_, std::string contentType, std::string body_)
  7049. : code(code_), body(std::move(body_)) {
  7050. set_header("Content-Type", get_mime_type(contentType));
  7051. }
  7052. response &operator=(const response &r) = delete;
  7053. response &operator=(response &&r) noexcept {
  7054. body = std::move(r.body);
  7055. code = r.code;
  7056. headers = std::move(r.headers);
  7057. completed_ = r.completed_;
  7058. file_info = std::move(r.file_info);
  7059. return *this;
  7060. }
  7061. /// Check if the response has completed (whether response.end() has been
  7062. /// called)
  7063. bool is_completed() const noexcept { return completed_; }
  7064. void clear() {
  7065. body.clear();
  7066. code = 200;
  7067. headers.clear();
  7068. completed_ = false;
  7069. file_info = static_file_info{};
  7070. }
  7071. /// Return a "Temporary Redirect" response.
  7072. ///
  7073. /// Location can either be a route or a full URL.
  7074. void redirect(const std::string &location) {
  7075. code = 307;
  7076. set_header("Location", location);
  7077. }
  7078. /// Return a "Permanent Redirect" response.
  7079. ///
  7080. /// Location can either be a route or a full URL.
  7081. void redirect_perm(const std::string &location) {
  7082. code = 308;
  7083. set_header("Location", location);
  7084. }
  7085. /// Return a "Found (Moved Temporarily)" response.
  7086. ///
  7087. /// Location can either be a route or a full URL.
  7088. void moved(const std::string &location) {
  7089. code = 302;
  7090. set_header("Location", location);
  7091. }
  7092. /// Return a "Moved Permanently" response.
  7093. ///
  7094. /// Location can either be a route or a full URL.
  7095. void moved_perm(const std::string &location) {
  7096. code = 301;
  7097. set_header("Location", location);
  7098. }
  7099. void write(const std::string &body_part) { body += body_part; }
  7100. /// Set the response completion flag and call the handler (to send the
  7101. /// response).
  7102. void end() {
  7103. if (!completed_) {
  7104. completed_ = true;
  7105. if (skip_body) {
  7106. set_header("Content-Length", std::to_string(body.size()));
  7107. body = "";
  7108. manual_length_header = true;
  7109. }
  7110. if (complete_request_handler_) {
  7111. complete_request_handler_();
  7112. manual_length_header = false;
  7113. skip_body = false;
  7114. }
  7115. }
  7116. }
  7117. /// Same as end() except it adds a body part right before ending.
  7118. void end(const std::string &body_part) {
  7119. body += body_part;
  7120. end();
  7121. }
  7122. /// Check if the connection is still alive (usually by checking the socket
  7123. /// status).
  7124. bool is_alive() { return is_alive_helper_ && is_alive_helper_(); }
  7125. /// Check whether the response has a static file defined.
  7126. bool is_static_type() { return file_info.path.size(); }
  7127. /// This constains metadata (coming from the `stat` command) related to any
  7128. /// static files associated with this response.
  7129. ///
  7130. /// Either a static file or a string body can be returned as 1 response.
  7131. struct static_file_info {
  7132. std::string path = "";
  7133. struct stat statbuf;
  7134. int statResult;
  7135. };
  7136. /// Return a static file as the response body, the content_type may be
  7137. /// specified explicitly.
  7138. void set_static_file_info(std::string path, std::string content_type = "") {
  7139. utility::sanitize_filename(path);
  7140. set_static_file_info_unsafe(path, content_type);
  7141. }
  7142. /// Return a static file as the response body without sanitizing the path (use
  7143. /// set_static_file_info instead), the content_type may be specified
  7144. /// explicitly.
  7145. void set_static_file_info_unsafe(std::string path,
  7146. std::string content_type = "") {
  7147. file_info.path = path;
  7148. file_info.statResult = stat(file_info.path.c_str(), &file_info.statbuf);
  7149. #ifdef CROW_ENABLE_COMPRESSION
  7150. compressed = false;
  7151. #endif
  7152. if (file_info.statResult == 0 && S_ISREG(file_info.statbuf.st_mode)) {
  7153. code = 200;
  7154. this->add_header("Content-Length",
  7155. std::to_string(file_info.statbuf.st_size));
  7156. if (content_type.empty()) {
  7157. std::size_t last_dot = path.find_last_of('.');
  7158. std::string extension = path.substr(last_dot + 1);
  7159. if (!extension.empty()) {
  7160. this->add_header("Content-Type", get_mime_type(extension));
  7161. }
  7162. } else {
  7163. this->add_header("Content-Type", content_type);
  7164. }
  7165. } else {
  7166. code = 404;
  7167. file_info.path.clear();
  7168. }
  7169. }
  7170. private:
  7171. void write_header_into_buffer(std::vector<asio::const_buffer> &buffers,
  7172. std::string &content_length_buffer,
  7173. bool add_keep_alive,
  7174. const std::string &server_name) {
  7175. // TODO(EDev): HTTP version in status codes should be dynamic
  7176. // Keep in sync with common.h/status
  7177. static std::unordered_map<int, std::string> statusCodes = {
  7178. {status::CONTINUE, "HTTP/1.1 100 Continue\r\n"},
  7179. {status::SWITCHING_PROTOCOLS, "HTTP/1.1 101 Switching Protocols\r\n"},
  7180. {status::OK, "HTTP/1.1 200 OK\r\n"},
  7181. {status::CREATED, "HTTP/1.1 201 Created\r\n"},
  7182. {status::ACCEPTED, "HTTP/1.1 202 Accepted\r\n"},
  7183. {status::NON_AUTHORITATIVE_INFORMATION,
  7184. "HTTP/1.1 203 Non-Authoritative Information\r\n"},
  7185. {status::NO_CONTENT, "HTTP/1.1 204 No Content\r\n"},
  7186. {status::RESET_CONTENT, "HTTP/1.1 205 Reset Content\r\n"},
  7187. {status::PARTIAL_CONTENT, "HTTP/1.1 206 Partial Content\r\n"},
  7188. {status::WEBDAV_MULTI_STATUS, "HTTP/1.1 207 Multi-Status\r\n"},
  7189. {status::MULTIPLE_CHOICES, "HTTP/1.1 300 Multiple Choices\r\n"},
  7190. {status::MOVED_PERMANENTLY, "HTTP/1.1 301 Moved Permanently\r\n"},
  7191. {status::FOUND, "HTTP/1.1 302 Found\r\n"},
  7192. {status::SEE_OTHER, "HTTP/1.1 303 See Other\r\n"},
  7193. {status::NOT_MODIFIED, "HTTP/1.1 304 Not Modified\r\n"},
  7194. {status::TEMPORARY_REDIRECT, "HTTP/1.1 307 Temporary Redirect\r\n"},
  7195. {status::PERMANENT_REDIRECT, "HTTP/1.1 308 Permanent Redirect\r\n"},
  7196. {status::BAD_REQUEST, "HTTP/1.1 400 Bad Request\r\n"},
  7197. {status::UNAUTHORIZED, "HTTP/1.1 401 Unauthorized\r\n"},
  7198. {status::FORBIDDEN, "HTTP/1.1 403 Forbidden\r\n"},
  7199. {status::NOT_FOUND, "HTTP/1.1 404 Not Found\r\n"},
  7200. {status::METHOD_NOT_ALLOWED, "HTTP/1.1 405 Method Not Allowed\r\n"},
  7201. {status::NOT_ACCEPTABLE, "HTTP/1.1 406 Not Acceptable\r\n"},
  7202. {status::PROXY_AUTHENTICATION_REQUIRED,
  7203. "HTTP/1.1 407 Proxy Authentication Required\r\n"},
  7204. {status::CONFLICT, "HTTP/1.1 409 Conflict\r\n"},
  7205. {status::GONE, "HTTP/1.1 410 Gone\r\n"},
  7206. {status::PAYLOAD_TOO_LARGE, "HTTP/1.1 413 Payload Too Large\r\n"},
  7207. {status::UNSUPPORTED_MEDIA_TYPE,
  7208. "HTTP/1.1 415 Unsupported Media Type\r\n"},
  7209. {status::RANGE_NOT_SATISFIABLE,
  7210. "HTTP/1.1 416 Range Not Satisfiable\r\n"},
  7211. {status::EXPECTATION_FAILED, "HTTP/1.1 417 Expectation Failed\r\n"},
  7212. {status::WEBDAV_PRECONDITION_FAILED,
  7213. "HTTP/1.1 412 Precondition Failed\r\n"},
  7214. {status::WEBDAV_REQUEST_URI_TOO_LONG,
  7215. "HTTP/1.1 414 Request-URI Too Long\r\n"},
  7216. {status::WEBDAV_UNPROCESSABLE_ENTITY,
  7217. "HTTP/1.1 422 Unprocessable Entity\r\n"},
  7218. {status::WEBDAV_LOCKED, "HTTP/1.1 423 Locked\r\n"},
  7219. {status::WEBDAV_FAILED_DEPENDENCY,
  7220. "HTTP/1.1 424 Failed Dependency\r\n"},
  7221. {status::PRECONDITION_REQUIRED,
  7222. "HTTP/1.1 428 Precondition Required\r\n"},
  7223. {status::TOO_MANY_REQUESTS, "HTTP/1.1 429 Too Many Requests\r\n"},
  7224. {status::UNAVAILABLE_FOR_LEGAL_REASONS,
  7225. "HTTP/1.1 451 Unavailable For Legal Reasons\r\n"},
  7226. {status::INTERNAL_SERVER_ERROR,
  7227. "HTTP/1.1 500 Internal Server Error\r\n"},
  7228. {status::NOT_IMPLEMENTED, "HTTP/1.1 501 Not Implemented\r\n"},
  7229. {status::BAD_GATEWAY, "HTTP/1.1 502 Bad Gateway\r\n"},
  7230. {status::SERVICE_UNAVAILABLE, "HTTP/1.1 503 Service Unavailable\r\n"},
  7231. {status::GATEWAY_TIMEOUT, "HTTP/1.1 504 Gateway Timeout\r\n"},
  7232. {status::VARIANT_ALSO_NEGOTIATES,
  7233. "HTTP/1.1 506 Variant Also Negotiates\r\n"},
  7234. {status::WEBDAV_INSUFFICIENT_STORAGE,
  7235. "HTTP/1.1 507 Insufficient Storage\r\n"},
  7236. };
  7237. static const std::string seperator = ": ";
  7238. buffers.clear();
  7239. buffers.reserve(4 * (headers.size() + 5) + 3);
  7240. if (!statusCodes.count(code)) {
  7241. CROW_LOG_WARNING << this << " status code "
  7242. << "(" << code << ")"
  7243. << " not defined, returning 500 instead";
  7244. code = 500;
  7245. }
  7246. auto &status = statusCodes.find(code)->second;
  7247. buffers.emplace_back(status.data(), status.size());
  7248. if (code >= 400 && body.empty()) body = statusCodes[code].substr(9);
  7249. for (auto &kv : headers) {
  7250. buffers.emplace_back(kv.first.data(), kv.first.size());
  7251. buffers.emplace_back(seperator.data(), seperator.size());
  7252. buffers.emplace_back(kv.second.data(), kv.second.size());
  7253. buffers.emplace_back(crlf.data(), crlf.size());
  7254. }
  7255. if (!manual_length_header && !headers.count("content-length")) {
  7256. content_length_buffer = std::to_string(body.size());
  7257. static std::string content_length_tag = "Content-Length: ";
  7258. buffers.emplace_back(content_length_tag.data(),
  7259. content_length_tag.size());
  7260. buffers.emplace_back(content_length_buffer.data(),
  7261. content_length_buffer.size());
  7262. buffers.emplace_back(crlf.data(), crlf.size());
  7263. }
  7264. if (!headers.count("server") && !server_name.empty()) {
  7265. static std::string server_tag = "Server: ";
  7266. buffers.emplace_back(server_tag.data(), server_tag.size());
  7267. buffers.emplace_back(server_name.data(), server_name.size());
  7268. buffers.emplace_back(crlf.data(), crlf.size());
  7269. }
  7270. /*if (!headers.count("date"))
  7271. {
  7272. static std::string date_tag = "Date: ";
  7273. date_str_ = get_cached_date_str();
  7274. buffers.emplace_back(date_tag.data(), date_tag.size());
  7275. buffers.emplace_back(date_str_.data(), date_str_.size());
  7276. buffers.emplace_back(crlf.data(), crlf.size());
  7277. }*/
  7278. if (add_keep_alive) {
  7279. static std::string keep_alive_tag = "Connection: Keep-Alive";
  7280. buffers.emplace_back(keep_alive_tag.data(), keep_alive_tag.size());
  7281. buffers.emplace_back(crlf.data(), crlf.size());
  7282. }
  7283. buffers.emplace_back(crlf.data(), crlf.size());
  7284. }
  7285. bool completed_{};
  7286. std::function<void()> complete_request_handler_;
  7287. std::function<bool()> is_alive_helper_;
  7288. static_file_info file_info;
  7289. };
  7290. } // namespace crow
  7291. #include <iomanip>
  7292. #include <memory>
  7293. namespace crow {
  7294. // Any middleware requires following 3 members:
  7295. // struct context;
  7296. // storing data for the middleware; can be read from another middleware or
  7297. // handlers
  7298. // before_handle
  7299. // called before handling the request.
  7300. // if res.end() is called, the operation is halted.
  7301. // (still call after_handle of this middleware)
  7302. // 2 signatures:
  7303. // void before_handle(request& req, response& res, context& ctx)
  7304. // if you only need to access this middlewares context.
  7305. // template <typename AllContext>
  7306. // void before_handle(request& req, response& res, context& ctx,
  7307. // AllContext& all_ctx)
  7308. // you can access another middlewares' context by calling
  7309. // `all_ctx.template get<MW>()' ctx == all_ctx.template
  7310. // get<CurrentMiddleware>()
  7311. // after_handle
  7312. // called after handling the request.
  7313. // void after_handle(request& req, response& res, context& ctx)
  7314. // template <typename AllContext>
  7315. // void after_handle(request& req, response& res, context& ctx, AllContext&
  7316. // all_ctx)
  7317. struct CookieParser {
  7318. // Cookie stores key, value and attributes
  7319. struct Cookie {
  7320. enum class SameSitePolicy { Strict, Lax, None };
  7321. template <typename U> Cookie(const std::string &key, U &&value) : Cookie() {
  7322. key_ = key;
  7323. value_ = std::forward<U>(value);
  7324. }
  7325. Cookie(const std::string &key) : Cookie(key, "") {}
  7326. // format cookie to HTTP header format
  7327. std::string dump() const {
  7328. const static char *HTTP_DATE_FORMAT = "%a, %d %b %Y %H:%M:%S GMT";
  7329. std::stringstream ss;
  7330. ss << key_ << '=';
  7331. ss << (value_.empty() ? "\"\"" : value_);
  7332. dumpString(ss, !domain_.empty(), "Domain=", domain_);
  7333. dumpString(ss, !path_.empty(), "Path=", path_);
  7334. dumpString(ss, secure_, "Secure");
  7335. dumpString(ss, httponly_, "HttpOnly");
  7336. if (expires_at_) {
  7337. ss << DIVIDER
  7338. << "Expires=" << std::put_time(expires_at_.get(), HTTP_DATE_FORMAT);
  7339. }
  7340. if (max_age_) { ss << DIVIDER << "Max-Age=" << *max_age_; }
  7341. if (same_site_) {
  7342. ss << DIVIDER << "SameSite=";
  7343. switch (*same_site_) {
  7344. case SameSitePolicy::Strict: ss << "Strict"; break;
  7345. case SameSitePolicy::Lax: ss << "Lax"; break;
  7346. case SameSitePolicy::None: ss << "None"; break;
  7347. }
  7348. }
  7349. return ss.str();
  7350. }
  7351. const std::string &name() { return key_; }
  7352. template <typename U> Cookie &value(U &&value) {
  7353. value_ = std::forward<U>(value);
  7354. return *this;
  7355. }
  7356. // Expires attribute
  7357. Cookie &expires(const std::tm &time) {
  7358. expires_at_ = std::unique_ptr<std::tm>(new std::tm(time));
  7359. return *this;
  7360. }
  7361. // Max-Age attribute
  7362. Cookie &max_age(long long seconds) {
  7363. max_age_ = std::unique_ptr<long long>(new long long(seconds));
  7364. return *this;
  7365. }
  7366. // Domain attribute
  7367. Cookie &domain(const std::string &name) {
  7368. domain_ = name;
  7369. return *this;
  7370. }
  7371. // Path attribute
  7372. Cookie &path(const std::string &path) {
  7373. path_ = path;
  7374. return *this;
  7375. }
  7376. // Secured attribute
  7377. Cookie &secure() {
  7378. secure_ = true;
  7379. return *this;
  7380. }
  7381. // HttpOnly attribute
  7382. Cookie &httponly() {
  7383. httponly_ = true;
  7384. return *this;
  7385. }
  7386. // SameSite attribute
  7387. Cookie &same_site(SameSitePolicy ssp) {
  7388. same_site_ = std::unique_ptr<SameSitePolicy>(new SameSitePolicy(ssp));
  7389. return *this;
  7390. }
  7391. Cookie(const Cookie &c)
  7392. : key_(c.key_), value_(c.value_), domain_(c.domain_), path_(c.path_),
  7393. secure_(c.secure_), httponly_(c.httponly_) {
  7394. if (c.max_age_)
  7395. max_age_ = std::unique_ptr<long long>(new long long(*c.max_age_));
  7396. if (c.expires_at_)
  7397. expires_at_ = std::unique_ptr<std::tm>(new std::tm(*c.expires_at_));
  7398. if (c.same_site_)
  7399. same_site_ =
  7400. std::unique_ptr<SameSitePolicy>(new SameSitePolicy(*c.same_site_));
  7401. }
  7402. private:
  7403. Cookie() = default;
  7404. static void dumpString(std::stringstream &ss, bool cond, const char *prefix,
  7405. const std::string &value = "") {
  7406. if (cond) { ss << DIVIDER << prefix << value; }
  7407. }
  7408. private:
  7409. std::string key_;
  7410. std::string value_;
  7411. std::unique_ptr<long long> max_age_{};
  7412. std::string domain_ = "";
  7413. std::string path_ = "";
  7414. bool secure_ = false;
  7415. bool httponly_ = false;
  7416. std::unique_ptr<std::tm> expires_at_{};
  7417. std::unique_ptr<SameSitePolicy> same_site_{};
  7418. static constexpr const char *DIVIDER = "; ";
  7419. };
  7420. struct context {
  7421. std::unordered_map<std::string, std::string> jar;
  7422. std::string get_cookie(const std::string &key) const {
  7423. auto cookie = jar.find(key);
  7424. if (cookie != jar.end()) return cookie->second;
  7425. return {};
  7426. }
  7427. template <typename U>
  7428. Cookie &set_cookie(const std::string &key, U &&value) {
  7429. cookies_to_add.emplace_back(key, std::forward<U>(value));
  7430. return cookies_to_add.back();
  7431. }
  7432. Cookie &set_cookie(Cookie cookie) {
  7433. cookies_to_add.push_back(std::move(cookie));
  7434. return cookies_to_add.back();
  7435. }
  7436. private:
  7437. friend struct CookieParser;
  7438. std::vector<Cookie> cookies_to_add;
  7439. };
  7440. void before_handle(request &req, response &res, context &ctx) {
  7441. const int count = req.headers.count("Cookie");
  7442. if (!count) return;
  7443. if (count > 1) {
  7444. res.code = 400;
  7445. res.end();
  7446. return;
  7447. }
  7448. const std::string_view cookies_sv = req.get_header_value("Cookie");
  7449. size_t pos = 0;
  7450. while (pos < cookies_sv.size()) {
  7451. const size_t pos_equal = cookies_sv.find('=', pos);
  7452. if (pos_equal == std::string_view::npos) { break; }
  7453. std::string_view name_sv = cookies_sv.substr(pos, pos_equal - pos);
  7454. name_sv = utility::trim(name_sv);
  7455. pos = pos_equal + 1;
  7456. if (pos == cookies_sv.size()) { break; }
  7457. const size_t pos_semicolon = cookies_sv.find(';', pos);
  7458. std::string_view value_sv;
  7459. if (pos_semicolon == std::string_view::npos) {
  7460. value_sv = cookies_sv.substr(pos);
  7461. pos = cookies_sv.size();
  7462. } else {
  7463. value_sv = cookies_sv.substr(pos, pos_semicolon - pos);
  7464. pos = pos_semicolon + 1;
  7465. }
  7466. value_sv = utility::trim(value_sv);
  7467. if (!value_sv.empty() && value_sv.front() == '"' &&
  7468. value_sv.back() == '"') {
  7469. if (value_sv.size() >= 2) {
  7470. value_sv.remove_prefix(1);
  7471. value_sv.remove_suffix(1);
  7472. } else {
  7473. value_sv = value_sv.substr(0, 0);
  7474. }
  7475. }
  7476. ctx.jar.emplace(std::string(name_sv), std::string(value_sv));
  7477. }
  7478. }
  7479. void after_handle(request & /*req*/, response &res, context &ctx) {
  7480. for (const auto &cookie : ctx.cookies_to_add) {
  7481. res.add_header("Set-Cookie", cookie.dump());
  7482. }
  7483. }
  7484. };
  7485. /*
  7486. App<CookieParser, AnotherJarMW> app;
  7487. A B C
  7488. A::context
  7489. int aa;
  7490. ctx1 : public A::context
  7491. ctx2 : public ctx1, public B::context
  7492. ctx3 : public ctx2, public C::context
  7493. C depends on A
  7494. C::handle
  7495. context.aaa
  7496. App::context : private CookieParser::context, ...
  7497. {
  7498. jar
  7499. }
  7500. SimpleApp
  7501. */
  7502. } // namespace crow
  7503. namespace crow {
  7504. struct UTF8 {
  7505. struct context {};
  7506. void before_handle(request & /*req*/, response & /*res*/, context & /*ctx*/) {
  7507. }
  7508. void after_handle(request & /*req*/, response &res, context & /*ctx*/) {
  7509. if (get_header_value(res.headers, "Content-Type").empty()) {
  7510. res.set_header("Content-Type", "text/plain; charset=utf-8");
  7511. }
  7512. }
  7513. };
  7514. } // namespace crow
  7515. #include <queue>
  7516. #include <set>
  7517. #include <unordered_map>
  7518. #include <unordered_set>
  7519. #include <cstdio>
  7520. #include <memory>
  7521. #include <mutex>
  7522. #include <string>
  7523. #include <fstream>
  7524. #include <sstream>
  7525. #include <chrono>
  7526. #include <functional>
  7527. #include <type_traits>
  7528. #include <variant>
  7529. namespace {
  7530. // convert all integer values to int64_t
  7531. template <typename T>
  7532. using wrap_integral_t =
  7533. typename std::conditional<std::is_integral<T>::value &&
  7534. !std::is_same<bool, T>::value
  7535. // except for uint64_t because that could lead
  7536. // to overflow on conversion
  7537. && !std::is_same<uint64_t, T>::value,
  7538. int64_t, T>::type;
  7539. // convert char[]/char* to std::string
  7540. template <typename T>
  7541. using wrap_char_t = typename std::conditional<
  7542. std::is_same<typename std::decay<T>::type, char *>::value, std::string,
  7543. T>::type;
  7544. // Upgrade to correct type for multi_variant use
  7545. template <typename T> using wrap_mv_t = wrap_char_t<wrap_integral_t<T>>;
  7546. } // namespace
  7547. namespace crow {
  7548. namespace session {
  7549. using multi_value_types = black_magic::S<bool, int64_t, double, std::string>;
  7550. /// A multi_value is a safe variant wrapper with json conversion support
  7551. struct multi_value {
  7552. json::wvalue json() const {
  7553. // clang-format off
  7554. return std::visit([](auto arg) {
  7555. return json::wvalue(arg);
  7556. }, v_);
  7557. // clang-format on
  7558. }
  7559. static multi_value from_json(const json::rvalue &);
  7560. std::string string() const {
  7561. // clang-format off
  7562. return std::visit([](auto arg) {
  7563. if constexpr (std::is_same_v<decltype(arg), std::string>)
  7564. return arg;
  7565. else
  7566. return std::to_string(arg);
  7567. }, v_);
  7568. // clang-format on
  7569. }
  7570. template <typename T, typename RT = wrap_mv_t<T>> RT get(const T &fallback) {
  7571. if (const RT *val = std::get_if<RT>(&v_)) return *val;
  7572. return fallback;
  7573. }
  7574. template <typename T, typename RT = wrap_mv_t<T>> void set(T val) {
  7575. v_ = RT(std::move(val));
  7576. }
  7577. typename multi_value_types::rebind<std::variant> v_;
  7578. };
  7579. inline multi_value multi_value::from_json(const json::rvalue &rv) {
  7580. using namespace json;
  7581. switch (rv.t()) {
  7582. case type::Number: {
  7583. if (rv.nt() == num_type::Floating_point ||
  7584. rv.nt() == num_type::Double_precision_floating_point)
  7585. return multi_value{rv.d()};
  7586. else if (rv.nt() == num_type::Unsigned_integer)
  7587. return multi_value{int64_t(rv.u())};
  7588. else
  7589. return multi_value{rv.i()};
  7590. }
  7591. case type::False: return multi_value{false};
  7592. case type::True: return multi_value{true};
  7593. case type::String: return multi_value{std::string(rv)};
  7594. default: return multi_value{false};
  7595. }
  7596. }
  7597. /// Expiration tracker keeps track of soonest-to-expire keys
  7598. struct ExpirationTracker {
  7599. using DataPair = std::pair<uint64_t /*time*/, std::string /*key*/>;
  7600. /// Add key with time to tracker.
  7601. /// If the key is already present, it will be updated
  7602. void add(std::string key, uint64_t time) {
  7603. auto it = times_.find(key);
  7604. if (it != times_.end()) remove(key);
  7605. times_[key] = time;
  7606. queue_.insert({time, std::move(key)});
  7607. }
  7608. void remove(const std::string &key) {
  7609. auto it = times_.find(key);
  7610. if (it != times_.end()) {
  7611. queue_.erase({it->second, key});
  7612. times_.erase(it);
  7613. }
  7614. }
  7615. /// Get expiration time of soonest-to-expire entry
  7616. uint64_t peek_first() const {
  7617. if (queue_.empty()) return std::numeric_limits<uint64_t>::max();
  7618. return queue_.begin()->first;
  7619. }
  7620. std::string pop_first() {
  7621. auto it = times_.find(queue_.begin()->second);
  7622. auto key = it->first;
  7623. times_.erase(it);
  7624. queue_.erase(queue_.begin());
  7625. return key;
  7626. }
  7627. using iterator = typename std::set<DataPair>::const_iterator;
  7628. iterator begin() const { return queue_.cbegin(); }
  7629. iterator end() const { return queue_.cend(); }
  7630. private:
  7631. std::set<DataPair> queue_;
  7632. std::unordered_map<std::string, uint64_t> times_;
  7633. };
  7634. /// CachedSessions are shared across requests
  7635. struct CachedSession {
  7636. std::string session_id;
  7637. std::string requested_session_id; // session hasn't been created yet, but a
  7638. // key was requested
  7639. std::unordered_map<std::string, multi_value> entries;
  7640. std::unordered_set<std::string>
  7641. dirty; // values that were changed after last load
  7642. void *store_data;
  7643. bool requested_refresh;
  7644. // number of references held - used for correctly destroying the cache.
  7645. // No need to be atomic, all SessionMiddleware accesses are synchronized
  7646. int referrers;
  7647. std::recursive_mutex mutex;
  7648. };
  7649. } // namespace session
  7650. // SessionMiddleware allows storing securely and easily small snippets of user
  7651. // information
  7652. template <typename Store> struct SessionMiddleware {
  7653. using lock = std::scoped_lock<std::mutex>;
  7654. using rc_lock = std::scoped_lock<std::recursive_mutex>;
  7655. struct context {
  7656. // Get a mutex for locking this session
  7657. std::recursive_mutex &mutex() {
  7658. check_node();
  7659. return node->mutex;
  7660. }
  7661. // Check whether this session is already present
  7662. bool exists() { return bool(node); }
  7663. // Get a value by key or fallback if it doesn't exist or is of another type
  7664. template <typename F>
  7665. auto get(const std::string &key, const F &fallback = F())
  7666. // This trick lets the multi_value deduce the return type from the
  7667. // fallback which allows both:
  7668. // context.get<std::string>("key")
  7669. // context.get("key", "") -> char[] is transformed into string by
  7670. // multivalue
  7671. // to return a string
  7672. -> decltype(std::declval<session::multi_value>().get<F>(
  7673. std::declval<F>())) {
  7674. if (!node) return fallback;
  7675. rc_lock l(node->mutex);
  7676. auto it = node->entries.find(key);
  7677. if (it != node->entries.end()) return it->second.get<F>(fallback);
  7678. return fallback;
  7679. }
  7680. // Set a value by key
  7681. template <typename T> void set(const std::string &key, T value) {
  7682. check_node();
  7683. rc_lock l(node->mutex);
  7684. node->dirty.insert(key);
  7685. node->entries[key].set(std::move(value));
  7686. }
  7687. bool contains(const std::string &key) {
  7688. if (!node) return false;
  7689. return node->entries.find(key) != node->entries.end();
  7690. }
  7691. // Atomically mutate a value with a function
  7692. template <typename Func> void apply(const std::string &key, const Func &f) {
  7693. using traits = utility::function_traits<Func>;
  7694. using arg = typename std::decay<typename traits::template arg<0>>::type;
  7695. using retv = typename std::decay<typename traits::result_type>::type;
  7696. check_node();
  7697. rc_lock l(node->mutex);
  7698. node->dirty.insert(key);
  7699. node->entries[key].set<retv>(f(node->entries[key].get(arg{})));
  7700. }
  7701. // Remove a value from the session
  7702. void remove(const std::string &key) {
  7703. if (!node) return;
  7704. rc_lock l(node->mutex);
  7705. node->dirty.insert(key);
  7706. node->entries.erase(key);
  7707. }
  7708. // Format value by key as a string
  7709. std::string string(const std::string &key) {
  7710. if (!node) return "";
  7711. rc_lock l(node->mutex);
  7712. auto it = node->entries.find(key);
  7713. if (it != node->entries.end()) return it->second.string();
  7714. return "";
  7715. }
  7716. // Get a list of keys present in session
  7717. std::vector<std::string> keys() {
  7718. if (!node) return {};
  7719. rc_lock l(node->mutex);
  7720. std::vector<std::string> out;
  7721. for (const auto &p : node->entries)
  7722. out.push_back(p.first);
  7723. return out;
  7724. }
  7725. // Delay expiration by issuing another cookie with an updated expiration
  7726. // time and notifying the store
  7727. void refresh_expiration() {
  7728. if (!node) return;
  7729. node->requested_refresh = true;
  7730. }
  7731. private:
  7732. friend struct SessionMiddleware;
  7733. void check_node() {
  7734. if (!node) node = std::make_shared<session::CachedSession>();
  7735. }
  7736. std::shared_ptr<session::CachedSession> node;
  7737. };
  7738. template <typename... Ts>
  7739. SessionMiddleware(CookieParser::Cookie cookie, int id_length, Ts... ts)
  7740. : id_length_(id_length), cookie_(cookie), store_(std::forward<Ts>(ts)...),
  7741. mutex_(new std::mutex{}) {}
  7742. template <typename... Ts>
  7743. SessionMiddleware(Ts... ts)
  7744. : SessionMiddleware(
  7745. CookieParser::Cookie("session").path("/").max_age(/*month*/ 30 *
  7746. 24 * 60 * 60),
  7747. /*id_length */ 20, // around 10^34 possible combinations, but small
  7748. // enough to fit into SSO
  7749. std::forward<Ts>(ts)...) {}
  7750. template <typename AllContext>
  7751. void before_handle(request & /*req*/, response & /*res*/, context &ctx,
  7752. AllContext &all_ctx) {
  7753. lock l(*mutex_);
  7754. auto &cookies = all_ctx.template get<CookieParser>();
  7755. auto session_id = load_id(cookies);
  7756. if (session_id == "") return;
  7757. // search entry in cache
  7758. auto it = cache_.find(session_id);
  7759. if (it != cache_.end()) {
  7760. it->second->referrers++;
  7761. ctx.node = it->second;
  7762. return;
  7763. }
  7764. // check this is a valid entry before loading
  7765. if (!store_.contains(session_id)) return;
  7766. auto node = std::make_shared<session::CachedSession>();
  7767. node->session_id = session_id;
  7768. node->referrers = 1;
  7769. try {
  7770. store_.load(*node);
  7771. } catch (...) {
  7772. CROW_LOG_ERROR << "Exception occurred during session load";
  7773. return;
  7774. }
  7775. ctx.node = node;
  7776. cache_[session_id] = node;
  7777. }
  7778. template <typename AllContext>
  7779. void after_handle(request & /*req*/, response & /*res*/, context &ctx,
  7780. AllContext &all_ctx) {
  7781. lock l(*mutex_);
  7782. if (!ctx.node || --ctx.node->referrers > 0) return;
  7783. ctx.node->requested_refresh |= ctx.node->session_id == "";
  7784. // generate new id
  7785. if (ctx.node->session_id == "") {
  7786. // check for requested id
  7787. ctx.node->session_id = std::move(ctx.node->requested_session_id);
  7788. if (ctx.node->session_id == "") {
  7789. ctx.node->session_id = utility::random_alphanum(id_length_);
  7790. }
  7791. } else {
  7792. cache_.erase(ctx.node->session_id);
  7793. }
  7794. if (ctx.node->requested_refresh) {
  7795. auto &cookies = all_ctx.template get<CookieParser>();
  7796. store_id(cookies, ctx.node->session_id);
  7797. }
  7798. try {
  7799. store_.save(*ctx.node);
  7800. } catch (...) {
  7801. CROW_LOG_ERROR << "Exception occurred during session save";
  7802. return;
  7803. }
  7804. }
  7805. private:
  7806. std::string next_id() {
  7807. std::string id;
  7808. do {
  7809. id = utility::random_alphanum(id_length_);
  7810. } while (store_.contains(id));
  7811. return id;
  7812. }
  7813. std::string load_id(const CookieParser::context &cookies) {
  7814. return cookies.get_cookie(cookie_.name());
  7815. }
  7816. void store_id(CookieParser::context &cookies, const std::string &session_id) {
  7817. cookie_.value(session_id);
  7818. cookies.set_cookie(cookie_);
  7819. }
  7820. private:
  7821. int id_length_;
  7822. // prototype for cookie
  7823. CookieParser::Cookie cookie_;
  7824. Store store_;
  7825. // mutexes are immovable
  7826. std::unique_ptr<std::mutex> mutex_;
  7827. std::unordered_map<std::string, std::shared_ptr<session::CachedSession>>
  7828. cache_;
  7829. };
  7830. /// InMemoryStore stores all entries in memory
  7831. struct InMemoryStore {
  7832. // Load a value into the session cache.
  7833. // A load is always followed by a save, no loads happen consecutively
  7834. void load(session::CachedSession &cn) {
  7835. // load & stores happen sequentially, so moving is safe
  7836. cn.entries = std::move(entries[cn.session_id]);
  7837. }
  7838. // Persist session data
  7839. void save(session::CachedSession &cn) {
  7840. entries[cn.session_id] = std::move(cn.entries);
  7841. // cn.dirty is a list of changed keys since the last load
  7842. }
  7843. bool contains(const std::string &key) { return entries.count(key) > 0; }
  7844. std::unordered_map<std::string,
  7845. std::unordered_map<std::string, session::multi_value>>
  7846. entries;
  7847. };
  7848. // FileStore stores all data as json files in a folder.
  7849. // Files are deleted after expiration. Expiration refreshes are automatically
  7850. // picked up.
  7851. struct FileStore {
  7852. FileStore(const std::string &folder,
  7853. uint64_t expiration_seconds = /*month*/ 30 * 24 * 60 * 60)
  7854. : path_(folder), expiration_seconds_(expiration_seconds) {
  7855. std::ifstream ifs(get_filename(".expirations", false));
  7856. auto current_ts = chrono_time();
  7857. std::string key;
  7858. uint64_t time;
  7859. while (ifs >> key >> time) {
  7860. if (current_ts > time) {
  7861. evict(key);
  7862. } else if (contains(key)) {
  7863. expirations_.add(key, time);
  7864. }
  7865. }
  7866. }
  7867. ~FileStore() {
  7868. std::ofstream ofs(get_filename(".expirations", false), std::ios::trunc);
  7869. for (const auto &p : expirations_)
  7870. ofs << p.second << " " << p.first << "\n";
  7871. }
  7872. // Delete expired entries
  7873. // At most 3 to prevent freezes
  7874. void handle_expired() {
  7875. int deleted = 0;
  7876. auto current_ts = chrono_time();
  7877. while (current_ts > expirations_.peek_first() && deleted < 3) {
  7878. evict(expirations_.pop_first());
  7879. deleted++;
  7880. }
  7881. }
  7882. void load(session::CachedSession &cn) {
  7883. handle_expired();
  7884. std::ifstream file(get_filename(cn.session_id));
  7885. std::stringstream buffer;
  7886. buffer << file.rdbuf() << std::endl;
  7887. for (const auto &p : json::load(buffer.str()))
  7888. cn.entries[p.key()] = session::multi_value::from_json(p);
  7889. }
  7890. void save(session::CachedSession &cn) {
  7891. if (cn.requested_refresh)
  7892. expirations_.add(cn.session_id, chrono_time() + expiration_seconds_);
  7893. if (cn.dirty.empty()) return;
  7894. std::ofstream file(get_filename(cn.session_id));
  7895. json::wvalue jw;
  7896. for (const auto &p : cn.entries)
  7897. jw[p.first] = p.second.json();
  7898. file << jw.dump() << std::flush;
  7899. }
  7900. std::string get_filename(const std::string &key, bool suffix = true) {
  7901. return utility::join_path(path_, key + (suffix ? ".json" : ""));
  7902. }
  7903. bool contains(const std::string &key) {
  7904. std::ifstream file(get_filename(key));
  7905. return file.good();
  7906. }
  7907. void evict(const std::string &key) { std::remove(get_filename(key).c_str()); }
  7908. uint64_t chrono_time() const {
  7909. return std::chrono::duration_cast<std::chrono::seconds>(
  7910. std::chrono::steady_clock::now().time_since_epoch())
  7911. .count();
  7912. }
  7913. std::string path_;
  7914. uint64_t expiration_seconds_;
  7915. session::ExpirationTracker expirations_;
  7916. };
  7917. } // namespace crow
  7918. #include <iostream>
  7919. #include <tuple>
  7920. #include <type_traits>
  7921. #include <utility>
  7922. namespace crow // NOTE: Already documented in "crow/app.h"
  7923. {
  7924. /// Local middleware should extend ILocalMiddleware
  7925. struct ILocalMiddleware {
  7926. using call_global = std::false_type;
  7927. };
  7928. namespace detail {
  7929. template <typename MW> struct check_before_handle_arity_3_const {
  7930. template <typename T,
  7931. void (T::*)(request &, response &, typename MW::context &) const =
  7932. &T::before_handle>
  7933. struct get {};
  7934. };
  7935. template <typename MW> struct check_before_handle_arity_3 {
  7936. template <typename T, void (T::*)(request &, response &,
  7937. typename MW::context &) = &T::before_handle>
  7938. struct get {};
  7939. };
  7940. template <typename MW> struct check_after_handle_arity_3_const {
  7941. template <typename T,
  7942. void (T::*)(request &, response &, typename MW::context &) const =
  7943. &T::after_handle>
  7944. struct get {};
  7945. };
  7946. template <typename MW> struct check_after_handle_arity_3 {
  7947. template <typename T, void (T::*)(request &, response &,
  7948. typename MW::context &) = &T::after_handle>
  7949. struct get {};
  7950. };
  7951. template <typename MW> struct check_global_call_false {
  7952. template <typename T, typename std::enable_if<T::call_global::value == false,
  7953. bool>::type = true>
  7954. struct get {};
  7955. };
  7956. template <typename T> struct is_before_handle_arity_3_impl {
  7957. template <typename C>
  7958. static std::true_type
  7959. f(typename check_before_handle_arity_3_const<T>::template get<C> *);
  7960. template <typename C>
  7961. static std::true_type
  7962. f(typename check_before_handle_arity_3<T>::template get<C> *);
  7963. template <typename C> static std::false_type f(...);
  7964. public:
  7965. static const bool value = decltype(f<T>(nullptr))::value;
  7966. };
  7967. template <typename T> struct is_after_handle_arity_3_impl {
  7968. template <typename C>
  7969. static std::true_type
  7970. f(typename check_after_handle_arity_3_const<T>::template get<C> *);
  7971. template <typename C>
  7972. static std::true_type
  7973. f(typename check_after_handle_arity_3<T>::template get<C> *);
  7974. template <typename C> static std::false_type f(...);
  7975. public:
  7976. static constexpr bool value = decltype(f<T>(nullptr))::value;
  7977. };
  7978. template <typename MW> struct is_middleware_global {
  7979. template <typename C>
  7980. static std::false_type
  7981. f(typename check_global_call_false<MW>::template get<C> *);
  7982. template <typename C> static std::true_type f(...);
  7983. static const bool value = decltype(f<MW>(nullptr))::value;
  7984. };
  7985. template <typename MW, typename Context, typename ParentContext>
  7986. typename std::enable_if<!is_before_handle_arity_3_impl<MW>::value>::type
  7987. before_handler_call(MW &mw, request &req, response &res, Context &ctx,
  7988. ParentContext & /*parent_ctx*/) {
  7989. mw.before_handle(req, res, ctx.template get<MW>(), ctx);
  7990. }
  7991. template <typename MW, typename Context, typename ParentContext>
  7992. typename std::enable_if<is_before_handle_arity_3_impl<MW>::value>::type
  7993. before_handler_call(MW &mw, request &req, response &res, Context &ctx,
  7994. ParentContext & /*parent_ctx*/) {
  7995. mw.before_handle(req, res, ctx.template get<MW>());
  7996. }
  7997. template <typename MW, typename Context, typename ParentContext>
  7998. typename std::enable_if<!is_after_handle_arity_3_impl<MW>::value>::type
  7999. after_handler_call(MW &mw, request &req, response &res, Context &ctx,
  8000. ParentContext & /*parent_ctx*/) {
  8001. mw.after_handle(req, res, ctx.template get<MW>(), ctx);
  8002. }
  8003. template <typename MW, typename Context, typename ParentContext>
  8004. typename std::enable_if<is_after_handle_arity_3_impl<MW>::value>::type
  8005. after_handler_call(MW &mw, request &req, response &res, Context &ctx,
  8006. ParentContext & /*parent_ctx*/) {
  8007. mw.after_handle(req, res, ctx.template get<MW>());
  8008. }
  8009. template <typename CallCriteria, int N, typename Context, typename Container>
  8010. typename std::enable_if<
  8011. (N <
  8012. std::tuple_size<typename std::remove_reference<Container>::type>::value),
  8013. bool>::type
  8014. middleware_call_helper(const CallCriteria &cc, Container &middlewares,
  8015. request &req, response &res, Context &ctx) {
  8016. using CurrentMW = typename std::tuple_element<
  8017. N, typename std::remove_reference<Container>::type>::type;
  8018. if (!cc.template enabled<CurrentMW>(N)) {
  8019. return middleware_call_helper<CallCriteria, N + 1, Context, Container>(
  8020. cc, middlewares, req, res, ctx);
  8021. }
  8022. using parent_context_t = typename Context::template partial<N - 1>;
  8023. before_handler_call<CurrentMW, Context, parent_context_t>(
  8024. std::get<N>(middlewares), req, res, ctx,
  8025. static_cast<parent_context_t &>(ctx));
  8026. if (res.is_completed()) {
  8027. after_handler_call<CurrentMW, Context, parent_context_t>(
  8028. std::get<N>(middlewares), req, res, ctx,
  8029. static_cast<parent_context_t &>(ctx));
  8030. return true;
  8031. }
  8032. if (middleware_call_helper<CallCriteria, N + 1, Context, Container>(
  8033. cc, middlewares, req, res, ctx)) {
  8034. after_handler_call<CurrentMW, Context, parent_context_t>(
  8035. std::get<N>(middlewares), req, res, ctx,
  8036. static_cast<parent_context_t &>(ctx));
  8037. return true;
  8038. }
  8039. return false;
  8040. }
  8041. template <typename CallCriteria, int N, typename Context, typename Container>
  8042. typename std::enable_if<
  8043. (N >=
  8044. std::tuple_size<typename std::remove_reference<Container>::type>::value),
  8045. bool>::type
  8046. middleware_call_helper(const CallCriteria & /*cc*/, Container & /*middlewares*/,
  8047. request & /*req*/, response & /*res*/,
  8048. Context & /*ctx*/) {
  8049. return false;
  8050. }
  8051. template <typename CallCriteria, int N, typename Context, typename Container>
  8052. typename std::enable_if<(N < 0)>::type
  8053. after_handlers_call_helper(const CallCriteria & /*cc*/,
  8054. Container & /*middlewares*/, Context & /*context*/,
  8055. request & /*req*/, response & /*res*/) {}
  8056. template <typename CallCriteria, int N, typename Context, typename Container>
  8057. typename std::enable_if<(N == 0)>::type
  8058. after_handlers_call_helper(const CallCriteria &cc, Container &middlewares,
  8059. Context &ctx, request &req, response &res) {
  8060. using parent_context_t = typename Context::template partial<N - 1>;
  8061. using CurrentMW = typename std::tuple_element<
  8062. N, typename std::remove_reference<Container>::type>::type;
  8063. if (cc.template enabled<CurrentMW>(N)) {
  8064. after_handler_call<CurrentMW, Context, parent_context_t>(
  8065. std::get<N>(middlewares), req, res, ctx,
  8066. static_cast<parent_context_t &>(ctx));
  8067. }
  8068. }
  8069. template <typename CallCriteria, int N, typename Context, typename Container>
  8070. typename std::enable_if<(N > 0)>::type
  8071. after_handlers_call_helper(const CallCriteria &cc, Container &middlewares,
  8072. Context &ctx, request &req, response &res) {
  8073. using parent_context_t = typename Context::template partial<N - 1>;
  8074. using CurrentMW = typename std::tuple_element<
  8075. N, typename std::remove_reference<Container>::type>::type;
  8076. if (cc.template enabled<CurrentMW>(N)) {
  8077. after_handler_call<CurrentMW, Context, parent_context_t>(
  8078. std::get<N>(middlewares), req, res, ctx,
  8079. static_cast<parent_context_t &>(ctx));
  8080. }
  8081. after_handlers_call_helper<CallCriteria, N - 1, Context, Container>(
  8082. cc, middlewares, ctx, req, res);
  8083. }
  8084. // A CallCriteria that accepts only global middleware
  8085. struct middleware_call_criteria_only_global {
  8086. template <typename MW> constexpr bool enabled(int) const {
  8087. return is_middleware_global<MW>::value;
  8088. }
  8089. };
  8090. template <typename F, typename... Args>
  8091. typename std::enable_if<
  8092. black_magic::CallHelper<F, black_magic::S<Args...>>::value, void>::type
  8093. wrapped_handler_call(crow::request & /*req*/, crow::response &res, const F &f,
  8094. Args &&...args) {
  8095. static_assert(
  8096. !std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
  8097. "Handler function cannot have void return type; valid return types: "
  8098. "string, int, crow::response, crow::returnable");
  8099. res = crow::response(f(std::forward<Args>(args)...));
  8100. res.end();
  8101. }
  8102. template <typename F, typename... Args>
  8103. typename std::enable_if<
  8104. !black_magic::CallHelper<F, black_magic::S<Args...>>::value &&
  8105. black_magic::CallHelper<
  8106. F, black_magic::S<crow::request &, Args...>>::value,
  8107. void>::type
  8108. wrapped_handler_call(crow::request &req, crow::response &res, const F &f,
  8109. Args &&...args) {
  8110. static_assert(
  8111. !std::is_same<void, decltype(f(std::declval<crow::request>(),
  8112. std::declval<Args>()...))>::value,
  8113. "Handler function cannot have void return type; valid return types: "
  8114. "string, int, crow::response, crow::returnable");
  8115. res = crow::response(f(req, std::forward<Args>(args)...));
  8116. res.end();
  8117. }
  8118. template <typename F, typename... Args>
  8119. typename std::enable_if<
  8120. !black_magic::CallHelper<F, black_magic::S<Args...>>::value &&
  8121. !black_magic::CallHelper<
  8122. F, black_magic::S<crow::request &, Args...>>::value &&
  8123. black_magic::CallHelper<
  8124. F, black_magic::S<crow::response &, Args...>>::value,
  8125. void>::type
  8126. wrapped_handler_call(crow::request & /*req*/, crow::response &res, const F &f,
  8127. Args &&...args) {
  8128. static_assert(
  8129. std::is_same<void, decltype(f(std::declval<crow::response &>(),
  8130. std::declval<Args>()...))>::value,
  8131. "Handler function with response argument should have void return type");
  8132. f(res, std::forward<Args>(args)...);
  8133. }
  8134. template <typename F, typename... Args>
  8135. typename std::enable_if<
  8136. !black_magic::CallHelper<F, black_magic::S<Args...>>::value &&
  8137. !black_magic::CallHelper<
  8138. F, black_magic::S<crow::request &, Args...>>::value &&
  8139. !black_magic::CallHelper<
  8140. F, black_magic::S<crow::response &, Args...>>::value &&
  8141. black_magic::CallHelper<
  8142. F, black_magic::S<const crow::request &, crow::response &,
  8143. Args...>>::value,
  8144. void>::type
  8145. wrapped_handler_call(crow::request &req, crow::response &res, const F &f,
  8146. Args &&...args) {
  8147. static_assert(
  8148. std::is_same<void, decltype(f(std::declval<crow::request &>(),
  8149. std::declval<crow::response &>(),
  8150. std::declval<Args>()...))>::value,
  8151. "Handler function with response argument should have void return type");
  8152. f(req, res, std::forward<Args>(args)...);
  8153. }
  8154. // wrapped_handler_call transparently wraps a handler call behind (req, res,
  8155. // args...)
  8156. template <typename F, typename... Args>
  8157. typename std::enable_if<
  8158. !black_magic::CallHelper<F, black_magic::S<Args...>>::value &&
  8159. !black_magic::CallHelper<
  8160. F, black_magic::S<crow::request &, Args...>>::value &&
  8161. !black_magic::CallHelper<
  8162. F, black_magic::S<crow::response &, Args...>>::value &&
  8163. !black_magic::CallHelper<
  8164. F, black_magic::S<const crow::request &, crow::response &,
  8165. Args...>>::value,
  8166. void>::type
  8167. wrapped_handler_call(crow::request &req, crow::response &res, const F &f,
  8168. Args &&...args) {
  8169. static_assert(
  8170. std::is_same<void, decltype(f(std::declval<crow::request &>(),
  8171. std::declval<crow::response &>(),
  8172. std::declval<Args>()...))>::value,
  8173. "Handler function with response argument should have void return type");
  8174. f(req, res, std::forward<Args>(args)...);
  8175. }
  8176. template <bool Reversed> struct middleware_call_criteria_dynamic {};
  8177. template <> struct middleware_call_criteria_dynamic<false> {
  8178. middleware_call_criteria_dynamic(const std::vector<int> &indices_)
  8179. : indices(indices_), slider(0) {}
  8180. template <typename> bool enabled(int mw_index) const {
  8181. if (slider < int(indices.size()) && indices[slider] == mw_index) {
  8182. slider++;
  8183. return true;
  8184. }
  8185. return false;
  8186. }
  8187. private:
  8188. const std::vector<int> &indices;
  8189. mutable int slider;
  8190. };
  8191. template <> struct middleware_call_criteria_dynamic<true> {
  8192. middleware_call_criteria_dynamic(const std::vector<int> &indices_)
  8193. : indices(indices_), slider(int(indices_.size()) - 1) {}
  8194. template <typename> bool enabled(int mw_index) const {
  8195. if (slider >= 0 && indices[slider] == mw_index) {
  8196. slider--;
  8197. return true;
  8198. }
  8199. return false;
  8200. }
  8201. private:
  8202. const std::vector<int> &indices;
  8203. mutable int slider;
  8204. };
  8205. } // namespace detail
  8206. } // namespace crow
  8207. namespace crow {
  8208. namespace detail {
  8209. template <typename... Middlewares>
  8210. struct partial_context
  8211. : public black_magic::pop_back<Middlewares...>::template rebind<
  8212. partial_context>,
  8213. public black_magic::last_element_type<Middlewares...>::type::context {
  8214. using parent_context = typename black_magic::pop_back<
  8215. Middlewares...>::template rebind<::crow::detail::partial_context>;
  8216. template <int N>
  8217. using partial = typename std::conditional<
  8218. N == sizeof...(Middlewares) - 1, partial_context,
  8219. typename parent_context::template partial<N>>::type;
  8220. template <typename T> typename T::context &get() {
  8221. return static_cast<typename T::context &>(*this);
  8222. }
  8223. };
  8224. template <> struct partial_context<> {
  8225. template <int> using partial = partial_context;
  8226. };
  8227. template <typename... Middlewares>
  8228. struct context : private partial_context<Middlewares...>
  8229. // struct context : private Middlewares::context... // simple but less type-safe
  8230. {
  8231. template <typename CallCriteria, int N, typename Context, typename Container>
  8232. friend typename std::enable_if<(N == 0)>::type
  8233. after_handlers_call_helper(const CallCriteria &cc, Container &middlewares,
  8234. Context &ctx, request &req, response &res);
  8235. template <typename CallCriteria, int N, typename Context, typename Container>
  8236. friend typename std::enable_if<(N > 0)>::type
  8237. after_handlers_call_helper(const CallCriteria &cc, Container &middlewares,
  8238. Context &ctx, request &req, response &res);
  8239. template <typename CallCriteria, int N, typename Context, typename Container>
  8240. friend typename std::enable_if<
  8241. (N <
  8242. std::tuple_size<typename std::remove_reference<Container>::type>::value),
  8243. bool>::type
  8244. middleware_call_helper(const CallCriteria &cc, Container &middlewares,
  8245. request &req, response &res, Context &ctx);
  8246. template <typename T> typename T::context &get() {
  8247. return static_cast<typename T::context &>(*this);
  8248. }
  8249. template <int N>
  8250. using partial = typename partial_context<Middlewares...>::template partial<N>;
  8251. };
  8252. } // namespace detail
  8253. } // namespace crow
  8254. #ifdef CROW_USE_BOOST
  8255. #include <boost/asio.hpp>
  8256. #else
  8257. #ifndef ASIO_STANDALONE
  8258. #define ASIO_STANDALONE
  8259. #endif
  8260. #include <asio.hpp>
  8261. #endif
  8262. #include <algorithm>
  8263. #include <atomic>
  8264. #include <chrono>
  8265. #include <memory>
  8266. #include <vector>
  8267. namespace crow {
  8268. #ifdef CROW_USE_BOOST
  8269. namespace asio = boost::asio;
  8270. using error_code = boost::system::error_code;
  8271. #else
  8272. using error_code = asio::error_code;
  8273. #endif
  8274. using tcp = asio::ip::tcp;
  8275. #ifdef CROW_ENABLE_DEBUG
  8276. static std::atomic<int> connectionCount;
  8277. #endif
  8278. /// An HTTP connection.
  8279. template <typename Adaptor, typename Handler, typename... Middlewares>
  8280. class Connection : public std::enable_shared_from_this<
  8281. Connection<Adaptor, Handler, Middlewares...>> {
  8282. friend struct crow::response;
  8283. public:
  8284. Connection(asio::io_context &io_context, Handler *handler,
  8285. const std::string &server_name,
  8286. std::tuple<Middlewares...> *middlewares,
  8287. std::function<std::string()> &get_cached_date_str_f,
  8288. detail::task_timer &task_timer,
  8289. typename Adaptor::context *adaptor_ctx_,
  8290. std::atomic<unsigned int> &queue_length)
  8291. : adaptor_(io_context, adaptor_ctx_), handler_(handler), parser_(this),
  8292. req_(parser_.req), server_name_(server_name), middlewares_(middlewares),
  8293. get_cached_date_str(get_cached_date_str_f), task_timer_(task_timer),
  8294. res_stream_threshold_(handler->stream_threshold()),
  8295. queue_length_(queue_length) {
  8296. queue_length_++;
  8297. #ifdef CROW_ENABLE_DEBUG
  8298. connectionCount++;
  8299. CROW_LOG_DEBUG << "Connection (" << this
  8300. << ") allocated, total: " << connectionCount;
  8301. #endif
  8302. }
  8303. ~Connection() {
  8304. queue_length_--;
  8305. #ifdef CROW_ENABLE_DEBUG
  8306. connectionCount--;
  8307. CROW_LOG_DEBUG << "Connection (" << this
  8308. << ") freed, total: " << connectionCount;
  8309. #endif
  8310. }
  8311. /// The TCP socket on top of which the connection is established.
  8312. decltype(std::declval<Adaptor>().raw_socket()) &socket() {
  8313. return adaptor_.raw_socket();
  8314. }
  8315. void start() {
  8316. auto self = this->shared_from_this();
  8317. adaptor_.start([self](const error_code &ec) {
  8318. if (!ec) {
  8319. self->start_deadline();
  8320. self->parser_.clear();
  8321. self->do_read();
  8322. } else {
  8323. CROW_LOG_ERROR << "Could not start adaptor: " << ec.message();
  8324. }
  8325. });
  8326. }
  8327. void handle_url() {
  8328. routing_handle_result_ = handler_->handle_initial(req_, res);
  8329. // if no route is found for the request method, return the response without
  8330. // parsing or processing anything further.
  8331. if (!routing_handle_result_->rule_index &&
  8332. !routing_handle_result_->catch_all) {
  8333. parser_.done();
  8334. need_to_call_after_handlers_ = true;
  8335. complete_request();
  8336. }
  8337. }
  8338. void handle_header() {
  8339. // HTTP 1.1 Expect: 100-continue
  8340. if (req_.http_ver_major == 1 && req_.http_ver_minor == 1 &&
  8341. get_header_value(req_.headers, "expect") == "100-continue") {
  8342. continue_requested = true;
  8343. buffers_.clear();
  8344. static const std::string expect_100_continue =
  8345. "HTTP/1.1 100 Continue\r\n\r\n";
  8346. buffers_.emplace_back(expect_100_continue.data(),
  8347. expect_100_continue.size());
  8348. error_code ec = do_write_sync(buffers_);
  8349. if (ec) {
  8350. CROW_LOG_ERROR << ec
  8351. << " buffer write error happened while handling sending "
  8352. "continuation buffer header";
  8353. }
  8354. }
  8355. }
  8356. void handle() {
  8357. // TODO(EDev): cancel_deadline_timer should be looked into, it might be a
  8358. // good idea to add it to handle_url() and then restart the timer once
  8359. // everything passes
  8360. cancel_deadline_timer();
  8361. bool is_invalid_request = false;
  8362. add_keep_alive_ = false;
  8363. // Create context
  8364. ctx_ = detail::context<Middlewares...>();
  8365. req_.middleware_context = static_cast<void *>(&ctx_);
  8366. req_.middleware_container = static_cast<void *>(middlewares_);
  8367. req_.io_context = &adaptor_.get_io_context();
  8368. req_.remote_ip_address = adaptor_.address();
  8369. add_keep_alive_ = req_.keep_alive;
  8370. close_connection_ = req_.close_connection;
  8371. if (req_.check_version(1, 1)) // HTTP/1.1
  8372. {
  8373. if (!req_.headers.count("host")) {
  8374. is_invalid_request = true;
  8375. res = response(400);
  8376. } else if (req_.upgrade) {
  8377. // h2 or h2c headers
  8378. if (req_.get_header_value("upgrade").find("h2") == 0) {
  8379. // TODO(ipkn): HTTP/2
  8380. // currently, ignore upgrade header
  8381. } else {
  8382. detail::middleware_call_helper<
  8383. detail::middleware_call_criteria_only_global, 0, decltype(ctx_),
  8384. decltype(*middlewares_)>({}, *middlewares_, req_, res, ctx_);
  8385. close_connection_ = true;
  8386. handler_->handle_upgrade(req_, res, std::move(adaptor_));
  8387. return;
  8388. }
  8389. }
  8390. }
  8391. CROW_LOG_INFO << "Request: "
  8392. << utility::lexical_cast<std::string>(
  8393. adaptor_.remote_endpoint())
  8394. << " " << this << " HTTP/"
  8395. << (char)(req_.http_ver_major + '0') << "."
  8396. << (char)(req_.http_ver_minor + '0') << ' '
  8397. << method_name(req_.method) << " " << req_.url;
  8398. need_to_call_after_handlers_ = false;
  8399. if (!is_invalid_request) {
  8400. res.complete_request_handler_ = nullptr;
  8401. auto self = this->shared_from_this();
  8402. res.is_alive_helper_ = [self]() -> bool {
  8403. return self->adaptor_.is_open();
  8404. };
  8405. detail::middleware_call_helper<
  8406. detail::middleware_call_criteria_only_global, 0, decltype(ctx_),
  8407. decltype(*middlewares_)>({}, *middlewares_, req_, res, ctx_);
  8408. if (!res.completed_) {
  8409. res.complete_request_handler_ = [self] { self->complete_request(); };
  8410. need_to_call_after_handlers_ = true;
  8411. handler_->handle(req_, res, routing_handle_result_);
  8412. if (add_keep_alive_) res.set_header("connection", "Keep-Alive");
  8413. } else {
  8414. complete_request();
  8415. }
  8416. } else {
  8417. complete_request();
  8418. }
  8419. }
  8420. /// Call the after handle middleware and send the write the response to the
  8421. /// connection.
  8422. void complete_request() {
  8423. CROW_LOG_INFO << "Response: " << this << ' ' << req_.raw_url << ' '
  8424. << res.code << ' ' << close_connection_;
  8425. res.is_alive_helper_ = nullptr;
  8426. if (need_to_call_after_handlers_) {
  8427. need_to_call_after_handlers_ = false;
  8428. // call all after_handler of middlewares
  8429. detail::after_handlers_call_helper<
  8430. detail::middleware_call_criteria_only_global,
  8431. (static_cast<int>(sizeof...(Middlewares)) - 1), decltype(ctx_),
  8432. decltype(*middlewares_)>({}, *middlewares_, ctx_, req_, res);
  8433. }
  8434. #ifdef CROW_ENABLE_COMPRESSION
  8435. if (!res.body.empty() && handler_->compression_used()) {
  8436. std::string accept_encoding = req_.get_header_value("Accept-Encoding");
  8437. if (!accept_encoding.empty() && res.compressed) {
  8438. switch (handler_->compression_algorithm()) {
  8439. case compression::DEFLATE:
  8440. if (accept_encoding.find("deflate") != std::string::npos) {
  8441. res.body = compression::compress_string(
  8442. res.body, compression::algorithm::DEFLATE);
  8443. res.set_header("Content-Encoding", "deflate");
  8444. }
  8445. break;
  8446. case compression::GZIP:
  8447. if (accept_encoding.find("gzip") != std::string::npos) {
  8448. res.body = compression::compress_string(
  8449. res.body, compression::algorithm::GZIP);
  8450. res.set_header("Content-Encoding", "gzip");
  8451. }
  8452. break;
  8453. default: break;
  8454. }
  8455. }
  8456. }
  8457. #endif
  8458. prepare_buffers();
  8459. if (res.is_static_type()) {
  8460. do_write_static();
  8461. } else {
  8462. do_write_general();
  8463. }
  8464. }
  8465. private:
  8466. void prepare_buffers() {
  8467. res.complete_request_handler_ = nullptr;
  8468. res.is_alive_helper_ = nullptr;
  8469. if (!adaptor_.is_open()) {
  8470. // CROW_LOG_DEBUG << this << " delete (socket is closed) " << is_reading
  8471. // << ' ' << is_writing; delete this;
  8472. return;
  8473. }
  8474. res.write_header_into_buffer(buffers_, content_length_, add_keep_alive_,
  8475. server_name_);
  8476. }
  8477. void do_write_static() {
  8478. asio::write(adaptor_.socket(), buffers_);
  8479. if (res.file_info.statResult == 0) {
  8480. std::ifstream is(res.file_info.path.c_str(),
  8481. std::ios::in | std::ios::binary);
  8482. std::vector<asio::const_buffer> buffers{1};
  8483. char buf[16384];
  8484. is.read(buf, sizeof(buf));
  8485. while (is.gcount() > 0) {
  8486. buffers[0] = asio::buffer(buf, is.gcount());
  8487. error_code ec = do_write_sync(buffers);
  8488. if (ec) {
  8489. CROW_LOG_ERROR
  8490. << ec
  8491. << " - buffer write error happened while sending content of file "
  8492. << res.file_info.path << ". Writing stopped premature.";
  8493. break;
  8494. }
  8495. is.read(buf, sizeof(buf));
  8496. }
  8497. }
  8498. if (close_connection_) {
  8499. adaptor_.shutdown_readwrite();
  8500. adaptor_.close();
  8501. CROW_LOG_DEBUG << this << " from write (static)";
  8502. }
  8503. res.end();
  8504. res.clear();
  8505. buffers_.clear();
  8506. parser_.clear();
  8507. }
  8508. void do_write_general() {
  8509. error_code ec;
  8510. if (res.body.length() < res_stream_threshold_) {
  8511. res_body_copy_.swap(res.body);
  8512. buffers_.emplace_back(res_body_copy_.data(), res_body_copy_.size());
  8513. ec = do_write_sync(buffers_);
  8514. if (ec) {
  8515. CROW_LOG_ERROR << ec
  8516. << " - buffer write error happened while sending "
  8517. "response. Writing stopped premature.";
  8518. }
  8519. if (need_to_start_read_after_complete_) {
  8520. need_to_start_read_after_complete_ = false;
  8521. start_deadline();
  8522. do_read();
  8523. }
  8524. } else {
  8525. asio::write(adaptor_.socket(), buffers_,
  8526. ec); // Write the response start / headers
  8527. if (ec) {
  8528. CROW_LOG_ERROR
  8529. << ec
  8530. << "- buffer write error happened while sending response start / "
  8531. "headers. Writing stopped premature.";
  8532. }
  8533. cancel_deadline_timer();
  8534. if (res.body.length() > 0) {
  8535. std::vector<asio::const_buffer> buffers{1};
  8536. const uint8_t *data =
  8537. reinterpret_cast<const uint8_t *>(res.body.data());
  8538. size_t length = res.body.length();
  8539. for (size_t transferred = 0; transferred < length;) {
  8540. size_t to_transfer = CROW_MIN(16384UL, length - transferred);
  8541. buffers[0] = asio::const_buffer(data + transferred, to_transfer);
  8542. ec = do_write_sync(buffers);
  8543. if (ec) {
  8544. CROW_LOG_ERROR << ec << " - " << transferred
  8545. << " - buffer write error happened while sending "
  8546. "response. Writing stopped premature.";
  8547. break;
  8548. }
  8549. transferred += to_transfer;
  8550. }
  8551. }
  8552. if (close_connection_) {
  8553. adaptor_.shutdown_readwrite();
  8554. adaptor_.close();
  8555. CROW_LOG_DEBUG << this << " from write (res_stream)";
  8556. }
  8557. res.end();
  8558. res.clear();
  8559. buffers_.clear();
  8560. parser_.clear();
  8561. }
  8562. }
  8563. void do_read() {
  8564. auto self = this->shared_from_this();
  8565. adaptor_.socket().async_read_some(
  8566. asio::buffer(buffer_),
  8567. [self](const error_code &ec, std::size_t bytes_transferred) {
  8568. bool error_while_reading = true;
  8569. if (!ec) {
  8570. bool ret =
  8571. self->parser_.feed(self->buffer_.data(), bytes_transferred);
  8572. if (ret && self->adaptor_.is_open()) {
  8573. error_while_reading = false;
  8574. }
  8575. }
  8576. if (error_while_reading) {
  8577. self->cancel_deadline_timer();
  8578. self->parser_.done();
  8579. self->adaptor_.shutdown_read();
  8580. self->adaptor_.close();
  8581. CROW_LOG_DEBUG << self << " from read(1) with description: \""
  8582. << http_errno_description(static_cast<http_errno>(
  8583. self->parser_.http_errno))
  8584. << '\"';
  8585. } else if (self->close_connection_) {
  8586. self->cancel_deadline_timer();
  8587. self->parser_.done();
  8588. // adaptor will close after write
  8589. } else if (!self->need_to_call_after_handlers_) {
  8590. self->start_deadline();
  8591. self->do_read();
  8592. } else {
  8593. // res will be completed later by user
  8594. self->need_to_start_read_after_complete_ = true;
  8595. }
  8596. });
  8597. }
  8598. void do_write() {
  8599. auto self = this->shared_from_this();
  8600. asio::async_write(
  8601. adaptor_.socket(), buffers_,
  8602. [self](const error_code &ec, std::size_t /*bytes_transferred*/) {
  8603. self->res.clear();
  8604. self->res_body_copy_.clear();
  8605. if (!self->continue_requested) {
  8606. self->parser_.clear();
  8607. } else {
  8608. self->continue_requested = false;
  8609. }
  8610. if (!ec) {
  8611. if (self->close_connection_) {
  8612. self->adaptor_.shutdown_write();
  8613. self->adaptor_.close();
  8614. CROW_LOG_DEBUG << self << " from write(1)";
  8615. }
  8616. } else {
  8617. CROW_LOG_DEBUG << self << " from write(2)";
  8618. }
  8619. });
  8620. }
  8621. inline error_code do_write_sync(std::vector<asio::const_buffer> &buffers) {
  8622. error_code ec;
  8623. asio::write(adaptor_.socket(), buffers, ec);
  8624. if (ec) {
  8625. // CROW_LOG_ERROR << ec << " - happened while sending buffers";
  8626. CROW_LOG_DEBUG << this << " from write (sync)(2)";
  8627. }
  8628. this->res.clear();
  8629. this->res_body_copy_.clear();
  8630. if (this->continue_requested) {
  8631. this->continue_requested = false;
  8632. } else {
  8633. this->parser_.clear();
  8634. }
  8635. return ec;
  8636. }
  8637. void cancel_deadline_timer() {
  8638. CROW_LOG_DEBUG << this << " timer cancelled: " << &task_timer_ << ' '
  8639. << task_id_;
  8640. task_timer_.cancel(task_id_);
  8641. }
  8642. void start_deadline(/*int timeout = 5*/) {
  8643. cancel_deadline_timer();
  8644. auto self = this->shared_from_this();
  8645. task_id_ = task_timer_.schedule([self] {
  8646. if (!self->adaptor_.is_open()) { return; }
  8647. self->adaptor_.shutdown_readwrite();
  8648. self->adaptor_.close();
  8649. });
  8650. CROW_LOG_DEBUG << this << " timer added: " << &task_timer_ << ' '
  8651. << task_id_;
  8652. }
  8653. private:
  8654. Adaptor adaptor_;
  8655. Handler *handler_;
  8656. std::array<char, 4096> buffer_;
  8657. HTTPParser<Connection> parser_;
  8658. std::unique_ptr<routing_handle_result> routing_handle_result_;
  8659. request &req_;
  8660. response res;
  8661. bool close_connection_ = false;
  8662. const std::string &server_name_;
  8663. std::vector<asio::const_buffer> buffers_;
  8664. std::string content_length_;
  8665. std::string date_str_;
  8666. std::string res_body_copy_;
  8667. detail::task_timer::identifier_type task_id_{};
  8668. bool continue_requested{};
  8669. bool need_to_call_after_handlers_{};
  8670. bool need_to_start_read_after_complete_{};
  8671. bool add_keep_alive_{};
  8672. std::tuple<Middlewares...> *middlewares_;
  8673. detail::context<Middlewares...> ctx_;
  8674. std::function<std::string()> &get_cached_date_str;
  8675. detail::task_timer &task_timer_;
  8676. size_t res_stream_threshold_;
  8677. std::atomic<unsigned int> &queue_length_;
  8678. };
  8679. } // namespace crow
  8680. #ifdef CROW_USE_BOOST
  8681. #include <boost/asio.hpp>
  8682. #ifdef CROW_ENABLE_SSL
  8683. #include <boost/asio/ssl.hpp>
  8684. #endif
  8685. #else
  8686. #ifndef ASIO_STANDALONE
  8687. #define ASIO_STANDALONE
  8688. #endif
  8689. #include <asio.hpp>
  8690. #ifdef CROW_ENABLE_SSL
  8691. #include <asio/ssl.hpp>
  8692. #endif
  8693. #endif
  8694. #include <atomic>
  8695. #include <chrono>
  8696. #include <cstdint>
  8697. #include <future>
  8698. #include <memory>
  8699. #include <thread>
  8700. #include <vector>
  8701. namespace crow // NOTE: Already documented in "crow/app.h"
  8702. {
  8703. #ifdef CROW_USE_BOOST
  8704. namespace asio = boost::asio;
  8705. using error_code = boost::system::error_code;
  8706. #else
  8707. using error_code = asio::error_code;
  8708. #endif
  8709. using tcp = asio::ip::tcp;
  8710. using stream_protocol = asio::local::stream_protocol;
  8711. template <typename Handler, typename Acceptor = TCPAcceptor,
  8712. typename Adaptor = SocketAdaptor, typename... Middlewares>
  8713. class Server {
  8714. public:
  8715. Server(Handler *handler, typename Acceptor::endpoint endpoint,
  8716. std::string server_name = std::string("Crow/") + VERSION,
  8717. std::tuple<Middlewares...> *middlewares = nullptr,
  8718. unsigned int concurrency = 1, uint8_t timeout = 5,
  8719. typename Adaptor::context *adaptor_ctx = nullptr)
  8720. : concurrency_(concurrency), task_queue_length_pool_(concurrency_ - 1),
  8721. acceptor_(io_context_), signals_(io_context_), tick_timer_(io_context_),
  8722. handler_(handler), timeout_(timeout), server_name_(server_name),
  8723. middlewares_(middlewares), adaptor_ctx_(adaptor_ctx) {
  8724. if (startup_failed_) {
  8725. CROW_LOG_ERROR << "Startup failed; not running server.";
  8726. return;
  8727. }
  8728. error_code ec;
  8729. acceptor_.raw_acceptor().open(endpoint.protocol(), ec);
  8730. if (ec) {
  8731. CROW_LOG_ERROR << "Failed to open acceptor: " << ec.message();
  8732. startup_failed_ = true;
  8733. return;
  8734. }
  8735. acceptor_.raw_acceptor().set_option(Acceptor::reuse_address_option(), ec);
  8736. if (ec) {
  8737. CROW_LOG_ERROR << "Failed to set socket option: " << ec.message();
  8738. startup_failed_ = true;
  8739. return;
  8740. }
  8741. acceptor_.raw_acceptor().bind(endpoint, ec);
  8742. if (ec) {
  8743. CROW_LOG_ERROR << "Failed to bind to " << acceptor_.address() << ":"
  8744. << acceptor_.port() << " - " << ec.message();
  8745. startup_failed_ = true;
  8746. return;
  8747. }
  8748. acceptor_.raw_acceptor().listen(tcp::acceptor::max_listen_connections, ec);
  8749. if (ec) {
  8750. CROW_LOG_ERROR << "Failed to listen on port: " << ec.message();
  8751. startup_failed_ = true;
  8752. return;
  8753. }
  8754. }
  8755. void set_tick_function(std::chrono::milliseconds d, std::function<void()> f) {
  8756. tick_interval_ = d;
  8757. tick_function_ = f;
  8758. }
  8759. void on_tick() {
  8760. tick_function_();
  8761. tick_timer_.expires_after(
  8762. std::chrono::milliseconds(tick_interval_.count()));
  8763. tick_timer_.async_wait([this](const error_code &ec) {
  8764. if (ec) return;
  8765. on_tick();
  8766. });
  8767. }
  8768. void run() {
  8769. if (startup_failed_) {
  8770. CROW_LOG_ERROR << "Server startup failed. Aborting run().";
  8771. return;
  8772. }
  8773. uint16_t worker_thread_count = concurrency_ - 1;
  8774. for (int i = 0; i < worker_thread_count; i++)
  8775. io_context_pool_.emplace_back(new asio::io_context());
  8776. get_cached_date_str_pool_.resize(worker_thread_count);
  8777. task_timer_pool_.resize(worker_thread_count);
  8778. std::vector<std::future<void>> v;
  8779. std::atomic<int> init_count(0);
  8780. for (uint16_t i = 0; i < worker_thread_count; i++)
  8781. v.push_back(std::async(std::launch::async, [this, i, &init_count] {
  8782. // thread local date string get function
  8783. auto last = std::chrono::steady_clock::now();
  8784. std::string date_str;
  8785. auto update_date_str = [&] {
  8786. auto last_time_t = time(0);
  8787. tm my_tm;
  8788. #if defined(_MSC_VER) || defined(__MINGW32__)
  8789. gmtime_s(&my_tm, &last_time_t);
  8790. #else
  8791. gmtime_r(&last_time_t, &my_tm);
  8792. #endif
  8793. date_str.resize(100);
  8794. size_t date_str_sz =
  8795. strftime(&date_str[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &my_tm);
  8796. date_str.resize(date_str_sz);
  8797. };
  8798. update_date_str();
  8799. get_cached_date_str_pool_[i] = [&]() -> std::string {
  8800. if (std::chrono::steady_clock::now() - last >=
  8801. std::chrono::seconds(1)) {
  8802. last = std::chrono::steady_clock::now();
  8803. update_date_str();
  8804. }
  8805. return date_str;
  8806. };
  8807. // initializing task timers
  8808. detail::task_timer task_timer(*io_context_pool_[i]);
  8809. task_timer.set_default_timeout(timeout_);
  8810. task_timer_pool_[i] = &task_timer;
  8811. task_queue_length_pool_[i] = 0;
  8812. init_count++;
  8813. while (1) {
  8814. try {
  8815. if (io_context_pool_[i]->run() == 0) {
  8816. // when io_service.run returns 0, there are no more works to do.
  8817. break;
  8818. }
  8819. } catch (std::exception &e) {
  8820. CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: "
  8821. << e.what();
  8822. }
  8823. }
  8824. }));
  8825. if (tick_function_ && tick_interval_.count() > 0) {
  8826. tick_timer_.expires_after(
  8827. std::chrono::milliseconds(tick_interval_.count()));
  8828. tick_timer_.async_wait([this](const error_code &ec) {
  8829. if (ec) return;
  8830. on_tick();
  8831. });
  8832. }
  8833. handler_->port(acceptor_.port());
  8834. handler_->address_is_bound();
  8835. CROW_LOG_INFO << server_name_ << " server is running at "
  8836. << acceptor_.url_display(handler_->ssl_used()) << " using "
  8837. << concurrency_ << " threads";
  8838. CROW_LOG_INFO << "Call `app.loglevel(crow::LogLevel::Warning)` to hide "
  8839. "Info level logs.";
  8840. signals_.async_wait(
  8841. [&](const error_code & /*error*/, int /*signal_number*/) { stop(); });
  8842. while (worker_thread_count != init_count)
  8843. std::this_thread::yield();
  8844. do_accept();
  8845. std::thread([this] {
  8846. notify_start();
  8847. io_context_.run();
  8848. CROW_LOG_INFO << "Exiting.";
  8849. }).join();
  8850. }
  8851. void stop() {
  8852. shutting_down_ = true; // Prevent the acceptor from taking new connections
  8853. // Explicitly close the acceptor
  8854. // else asio will throw an exception (linux only), when trying to start
  8855. // server again: what(): bind: Address already in use
  8856. if (acceptor_.raw_acceptor().is_open()) {
  8857. CROW_LOG_INFO << "Closing acceptor. " << &acceptor_;
  8858. error_code ec;
  8859. acceptor_.raw_acceptor().close(ec);
  8860. if (ec) {
  8861. CROW_LOG_WARNING << "Failed to close acceptor: " << ec.message();
  8862. }
  8863. }
  8864. for (auto &io_context : io_context_pool_) {
  8865. if (io_context != nullptr) {
  8866. CROW_LOG_INFO << "Closing IO service " << &io_context;
  8867. io_context->stop(); // Close all io_services (and HTTP connections)
  8868. }
  8869. }
  8870. CROW_LOG_INFO << "Closing main IO service (" << &io_context_ << ')';
  8871. io_context_.stop(); // Close main io_service
  8872. }
  8873. uint16_t port() const { return acceptor_.local_endpoint().port(); }
  8874. /// Wait until the server has properly started or until timeout
  8875. std::cv_status
  8876. wait_for_start(std::chrono::steady_clock::time_point wait_until) {
  8877. std::unique_lock<std::mutex> lock(start_mutex_);
  8878. std::cv_status status = std::cv_status::no_timeout;
  8879. while (!server_started_ && !startup_failed_ &&
  8880. status == std::cv_status::no_timeout)
  8881. status = cv_started_.wait_until(lock, wait_until);
  8882. return status;
  8883. }
  8884. void signal_clear() { signals_.clear(); }
  8885. void signal_add(int signal_number) { signals_.add(signal_number); }
  8886. private:
  8887. size_t pick_io_context_idx() {
  8888. size_t min_queue_idx = 0;
  8889. // TODO improve load balancing
  8890. // size_t is used here to avoid the security issue
  8891. // https://codeql.github.com/codeql-query-help/cpp/cpp-comparison-with-wider-type/
  8892. // even though the max value of this can be only uint16_t as concurrency is
  8893. // uint16_t.
  8894. for (size_t i = 1; i < task_queue_length_pool_.size() &&
  8895. task_queue_length_pool_[min_queue_idx] > 0;
  8896. i++)
  8897. // No need to check other io_services if the current one has no tasks
  8898. {
  8899. if (task_queue_length_pool_[i] < task_queue_length_pool_[min_queue_idx])
  8900. min_queue_idx = i;
  8901. }
  8902. return min_queue_idx;
  8903. }
  8904. void do_accept() {
  8905. if (!shutting_down_) {
  8906. size_t context_idx = pick_io_context_idx();
  8907. asio::io_context &ic = *io_context_pool_[context_idx];
  8908. auto p = std::make_shared<Connection<Adaptor, Handler, Middlewares...>>(
  8909. ic, handler_, server_name_, middlewares_,
  8910. get_cached_date_str_pool_[context_idx],
  8911. *task_timer_pool_[context_idx], adaptor_ctx_,
  8912. task_queue_length_pool_[context_idx]);
  8913. CROW_LOG_DEBUG << &ic << " {" << context_idx << "} queue length: "
  8914. << task_queue_length_pool_[context_idx];
  8915. acceptor_.raw_acceptor().async_accept(
  8916. p->socket(), [this, p, &ic](error_code ec) {
  8917. if (!ec) {
  8918. asio::post(ic, [p] { p->start(); });
  8919. }
  8920. do_accept();
  8921. });
  8922. }
  8923. }
  8924. /// Notify anything using `wait_for_start()` to proceed
  8925. void notify_start() {
  8926. std::unique_lock<std::mutex> lock(start_mutex_);
  8927. server_started_ = true;
  8928. cv_started_.notify_all();
  8929. }
  8930. private:
  8931. unsigned int concurrency_{2};
  8932. std::vector<std::atomic<unsigned int>> task_queue_length_pool_;
  8933. std::vector<std::unique_ptr<asio::io_context>> io_context_pool_;
  8934. asio::io_context io_context_;
  8935. std::vector<detail::task_timer *> task_timer_pool_;
  8936. std::vector<std::function<std::string()>> get_cached_date_str_pool_;
  8937. Acceptor acceptor_;
  8938. bool shutting_down_ = false;
  8939. bool server_started_{false};
  8940. bool startup_failed_ = false;
  8941. std::condition_variable cv_started_;
  8942. std::mutex start_mutex_;
  8943. asio::signal_set signals_;
  8944. asio::basic_waitable_timer<std::chrono::high_resolution_clock> tick_timer_;
  8945. Handler *handler_;
  8946. std::uint8_t timeout_;
  8947. std::string server_name_;
  8948. bool use_unix_;
  8949. std::chrono::milliseconds tick_interval_;
  8950. std::function<void()> tick_function_;
  8951. std::tuple<Middlewares...> *middlewares_;
  8952. typename Adaptor::context *adaptor_ctx_;
  8953. };
  8954. } // namespace crow
  8955. #include <array>
  8956. #include <memory>
  8957. #include <optional>
  8958. #include <string>
  8959. #include <thread>
  8960. namespace crow // NOTE: Already documented in "crow/app.h"
  8961. {
  8962. #ifdef CROW_USE_BOOST
  8963. namespace asio = boost::asio;
  8964. using error_code = boost::system::error_code;
  8965. #else
  8966. using error_code = asio::error_code;
  8967. #endif
  8968. /**
  8969. * \namespace crow::websocket
  8970. * \brief Namespace that includes the \ref Connection class
  8971. * and \ref connection struct. Useful for WebSockets connection.
  8972. *
  8973. * Used specially in crow/websocket.h, crow/app.h and crow/routing.h
  8974. */
  8975. namespace websocket {
  8976. enum class WebSocketReadState {
  8977. MiniHeader,
  8978. Len16,
  8979. Len64,
  8980. Mask,
  8981. Payload,
  8982. };
  8983. // Codes taken from https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
  8984. enum CloseStatusCode : uint16_t {
  8985. NormalClosure = 1000,
  8986. EndpointGoingAway = 1001,
  8987. ProtocolError = 1002,
  8988. UnacceptableData = 1003,
  8989. InconsistentData = 1007,
  8990. PolicyViolated = 1008,
  8991. MessageTooBig = 1009,
  8992. ExtensionsNotNegotiated = 1010,
  8993. UnexpectedCondition = 1011,
  8994. // Reserved for applications only, should not send/receive these to/from
  8995. // clients
  8996. NoStatusCodePresent = 1005,
  8997. ClosedAbnormally = 1006,
  8998. TLSHandshakeFailure = 1015,
  8999. StartStatusCodesForLibraries = 3000,
  9000. StartStatusCodesForPrivateUse = 4000,
  9001. // Status code should be between 1000 and 4999 inclusive
  9002. StartStatusCodes = NormalClosure,
  9003. EndStatusCodes = 4999,
  9004. };
  9005. /// A base class for websocket connection.
  9006. struct connection {
  9007. virtual void send_binary(std::string msg) = 0;
  9008. virtual void send_text(std::string msg) = 0;
  9009. virtual void send_ping(std::string msg) = 0;
  9010. virtual void send_pong(std::string msg) = 0;
  9011. virtual void close(std::string const &msg = "quit",
  9012. uint16_t status_code = CloseStatusCode::NormalClosure) = 0;
  9013. virtual std::string get_remote_ip() = 0;
  9014. virtual std::string get_subprotocol() const = 0;
  9015. virtual ~connection() = default;
  9016. void userdata(void *u) { userdata_ = u; }
  9017. void *userdata() { return userdata_; }
  9018. private:
  9019. void *userdata_;
  9020. };
  9021. // Modified version of the illustration in RFC6455 Section-5.2
  9022. //
  9023. //
  9024. // 0 1 2 3 -byte
  9025. // 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 -bit
  9026. // +-+-+-+-+-------+-+-------------+-------------------------------+
  9027. // |F|R|R|R| opcode|M| Payload len | Extended payload length |
  9028. // |I|S|S|S| (4) |A| (7) | (16/64) |
  9029. // |N|V|V|V| |S| | (if payload len==126/127) |
  9030. // | |1|2|3| |K| | |
  9031. // +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
  9032. // | Extended payload length continued, if payload len == 127 |
  9033. // + - - - - - - - - - - - - - - - +-------------------------------+
  9034. // | |Masking-key, if MASK set to 1 |
  9035. // +-------------------------------+-------------------------------+
  9036. // | Masking-key (continued) | Payload Data |
  9037. // +-------------------------------- - - - - - - - - - - - - - - - +
  9038. // : Payload Data continued ... :
  9039. // + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
  9040. // | Payload Data continued ... |
  9041. // +---------------------------------------------------------------+
  9042. //
  9043. /// A websocket connection.
  9044. template <typename Adaptor, typename Handler>
  9045. class Connection
  9046. : public connection,
  9047. public std::enable_shared_from_this<Connection<Adaptor, Handler>> {
  9048. public:
  9049. /// Factory for a connection.
  9050. ///
  9051. /// Requires a request with an "Upgrade: websocket" header.<br>
  9052. /// Automatically handles the handshake.
  9053. static void
  9054. create(const crow::request &req, Adaptor adaptor, Handler *handler,
  9055. uint64_t max_payload, const std::vector<std::string> &subprotocols,
  9056. std::function<void(crow::websocket::connection &)> open_handler,
  9057. std::function<void(crow::websocket::connection &, const std::string &,
  9058. bool)>
  9059. message_handler,
  9060. std::function<void(crow::websocket::connection &, const std::string &,
  9061. uint16_t)>
  9062. close_handler,
  9063. std::function<void(crow::websocket::connection &, const std::string &)>
  9064. error_handler,
  9065. std::function<void(const crow::request &,
  9066. std::optional<crow::response> &, void **)>
  9067. accept_handler,
  9068. bool mirror_protocols) {
  9069. auto conn = std::shared_ptr<Connection>(new Connection(
  9070. std::move(adaptor), handler, max_payload, std::move(open_handler),
  9071. std::move(message_handler), std::move(close_handler),
  9072. std::move(error_handler), std::move(accept_handler)));
  9073. // Perform handshake validation
  9074. if (!utility::string_equals(req.get_header_value("upgrade"), "websocket")) {
  9075. conn->adaptor_.close();
  9076. return;
  9077. }
  9078. std::string requested_subprotocols_header =
  9079. req.get_header_value("Sec-WebSocket-Protocol");
  9080. if (!subprotocols.empty() || !requested_subprotocols_header.empty()) {
  9081. auto requested_subprotocols =
  9082. utility::split(requested_subprotocols_header, ", ");
  9083. auto subprotocol = utility::find_first_of(
  9084. subprotocols.begin(), subprotocols.end(),
  9085. requested_subprotocols.begin(), requested_subprotocols.end());
  9086. if (subprotocol != subprotocols.end()) {
  9087. conn->subprotocol_ = *subprotocol;
  9088. }
  9089. }
  9090. if (mirror_protocols & !requested_subprotocols_header.empty()) {
  9091. conn->subprotocol_ = requested_subprotocols_header;
  9092. }
  9093. if (conn->accept_handler_) {
  9094. void *ud = nullptr;
  9095. std::optional<crow::response> res;
  9096. conn->accept_handler_(req, res, &ud);
  9097. if (res) {
  9098. std::vector<asio::const_buffer> buffers;
  9099. auto server_name = "";
  9100. std::string content_length_buffer;
  9101. res->write_header_into_buffer(buffers, content_length_buffer,
  9102. req.keep_alive, server_name);
  9103. buffers.emplace_back(res->body.data(), res->body.size());
  9104. error_code ec;
  9105. asio::write(conn->adaptor_.socket(), buffers, ec);
  9106. conn->adaptor_.close();
  9107. return;
  9108. }
  9109. conn->userdata(ud);
  9110. }
  9111. // Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  9112. // Sec-WebSocket-Version: 13
  9113. std::string magic = req.get_header_value("Sec-WebSocket-Key") +
  9114. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
  9115. sha1::SHA1 s;
  9116. s.processBytes(magic.data(), magic.size());
  9117. uint8_t digest[20];
  9118. s.getDigestBytes(digest);
  9119. conn->handler_->add_websocket(conn);
  9120. conn->start(crow::utility::base64encode((unsigned char *)digest, 20));
  9121. }
  9122. ~Connection() noexcept override = default;
  9123. template <typename Callable> struct WeakWrappedMessage {
  9124. Callable callable;
  9125. std::weak_ptr<void> watch;
  9126. void operator()() {
  9127. if (auto anchor = watch.lock()) { std::move(callable)(); }
  9128. }
  9129. };
  9130. /// Send data through the socket.
  9131. template <typename CompletionHandler>
  9132. void dispatch(CompletionHandler &&handler) {
  9133. asio::dispatch(
  9134. adaptor_.get_io_context(),
  9135. WeakWrappedMessage<typename std::decay<CompletionHandler>::type>{
  9136. std::forward<CompletionHandler>(handler), anchor_});
  9137. }
  9138. /// Send data through the socket and return immediately.
  9139. template <typename CompletionHandler> void post(CompletionHandler &&handler) {
  9140. asio::post(adaptor_.get_io_context(),
  9141. WeakWrappedMessage<typename std::decay<CompletionHandler>::type>{
  9142. std::forward<CompletionHandler>(handler), anchor_});
  9143. }
  9144. /// Send a "Ping" message.
  9145. ///
  9146. /// Usually invoked to check if the other point is still online.
  9147. void send_ping(std::string msg) override { send_data(0x9, std::move(msg)); }
  9148. /// Send a "Pong" message.
  9149. ///
  9150. /// Usually automatically invoked as a response to a "Ping" message.
  9151. void send_pong(std::string msg) override { send_data(0xA, std::move(msg)); }
  9152. /// Send a binary encoded message.
  9153. void send_binary(std::string msg) override { send_data(0x2, std::move(msg)); }
  9154. /// Send a plaintext message.
  9155. void send_text(std::string msg) override { send_data(0x1, std::move(msg)); }
  9156. /// Send a close signal.
  9157. ///
  9158. /// Sets a flag to destroy the object once the message is sent.
  9159. void close(std::string const &msg, uint16_t status_code) override {
  9160. dispatch(
  9161. [shared_this = this->shared_from_this(), msg, status_code]() mutable {
  9162. shared_this->has_sent_close_ = true;
  9163. if (shared_this->has_recv_close_ &&
  9164. !shared_this->is_close_handler_called_) {
  9165. shared_this->is_close_handler_called_ = true;
  9166. if (shared_this->close_handler_)
  9167. shared_this->close_handler_(*shared_this, msg, status_code);
  9168. }
  9169. auto header = shared_this->build_header(0x8, msg.size() + 2);
  9170. char status_buf[2];
  9171. *(uint16_t *)(status_buf) = htons(status_code);
  9172. shared_this->write_buffers_.emplace_back(std::move(header));
  9173. shared_this->write_buffers_.emplace_back(std::string(status_buf, 2));
  9174. shared_this->write_buffers_.emplace_back(msg);
  9175. shared_this->do_write();
  9176. });
  9177. }
  9178. std::string get_remote_ip() override { return adaptor_.address(); }
  9179. void set_max_payload_size(uint64_t payload) { max_payload_bytes_ = payload; }
  9180. /// Returns the matching client/server subprotocol, empty string if none
  9181. /// matched.
  9182. std::string get_subprotocol() const override { return subprotocol_; }
  9183. protected:
  9184. /// Generate the websocket headers using an opcode and the message size (in
  9185. /// bytes).
  9186. std::string build_header(int opcode, size_t size) {
  9187. char buf[2 + 8] = "\x80\x00";
  9188. buf[0] += opcode;
  9189. if (size < 126) {
  9190. buf[1] += static_cast<char>(size);
  9191. return {buf, buf + 2};
  9192. } else if (size < 0x10000) {
  9193. buf[1] += 126;
  9194. *(uint16_t *)(buf + 2) = htons(static_cast<uint16_t>(size));
  9195. return {buf, buf + 4};
  9196. } else {
  9197. buf[1] += 127;
  9198. *reinterpret_cast<uint64_t *>(buf + 2) =
  9199. ((1 == htonl(1))
  9200. ? static_cast<uint64_t>(size)
  9201. : (static_cast<uint64_t>(htonl((size) & 0xFFFFFFFF)) << 32) |
  9202. htonl(static_cast<uint64_t>(size) >> 32));
  9203. return {buf, buf + 10};
  9204. }
  9205. }
  9206. /// Send the HTTP upgrade response.
  9207. ///
  9208. /// Finishes the handshake process, then starts reading messages from the
  9209. /// socket.
  9210. void start(std::string &&hello) {
  9211. static const std::string header = "HTTP/1.1 101 Switching Protocols\r\n"
  9212. "Upgrade: websocket\r\n"
  9213. "Connection: Upgrade\r\n"
  9214. "Sec-WebSocket-Accept: ";
  9215. write_buffers_.emplace_back(header);
  9216. write_buffers_.emplace_back(std::move(hello));
  9217. write_buffers_.emplace_back(crlf);
  9218. if (!subprotocol_.empty()) {
  9219. write_buffers_.emplace_back("Sec-WebSocket-Protocol: ");
  9220. write_buffers_.emplace_back(subprotocol_);
  9221. write_buffers_.emplace_back(crlf);
  9222. }
  9223. write_buffers_.emplace_back(crlf);
  9224. do_write();
  9225. if (open_handler_) open_handler_(*this);
  9226. do_read();
  9227. }
  9228. /// Read a websocket message.
  9229. ///
  9230. /// Involves:<br>
  9231. /// Handling headers (opcodes, size).<br>
  9232. /// Unmasking the payload.<br>
  9233. /// Reading the actual payload.<br>
  9234. void do_read() {
  9235. if (has_sent_close_ && has_recv_close_) {
  9236. close_connection_ = true;
  9237. adaptor_.shutdown_readwrite();
  9238. adaptor_.close();
  9239. check_destroy();
  9240. return;
  9241. }
  9242. is_reading = true;
  9243. switch (state_) {
  9244. case WebSocketReadState::MiniHeader: {
  9245. mini_header_ = 0;
  9246. // asio::async_read(adaptor_.socket(), asio::buffer(&mini_header_, 1),
  9247. adaptor_.socket().async_read_some(
  9248. asio::buffer(&mini_header_, 2),
  9249. [shared_this = this->shared_from_this()](const error_code &ec,
  9250. std::size_t
  9251. #ifdef CROW_ENABLE_DEBUG
  9252. bytes_transferred
  9253. #endif
  9254. )
  9255. {
  9256. shared_this->is_reading = false;
  9257. shared_this->mini_header_ = ntohs(shared_this->mini_header_);
  9258. #ifdef CROW_ENABLE_DEBUG
  9259. if (!ec && bytes_transferred != 2) {
  9260. throw std::runtime_error(
  9261. "WebSocket:MiniHeader:async_read fail:asio bug?");
  9262. }
  9263. #endif
  9264. if (!ec) {
  9265. if ((shared_this->mini_header_ & 0x80) == 0x80)
  9266. shared_this->has_mask_ = true;
  9267. else // if the websocket specification is enforced and the message
  9268. // isn't masked, terminate the connection
  9269. {
  9270. #ifndef CROW_ENFORCE_WS_SPEC
  9271. shared_this->has_mask_ = false;
  9272. #else
  9273. shared_this->close_connection_ = true;
  9274. shared_this->adaptor_.shutdown_readwrite();
  9275. shared_this->adaptor_.close();
  9276. if (shared_this->error_handler_)
  9277. shared_this->error_handler_(*shared_this,
  9278. "Client connection not masked.");
  9279. shared_this->check_destroy(CloseStatusCode::UnacceptableData);
  9280. #endif
  9281. }
  9282. if ((shared_this->mini_header_ & 0x7f) == 127) {
  9283. shared_this->state_ = WebSocketReadState::Len64;
  9284. } else if ((shared_this->mini_header_ & 0x7f) == 126) {
  9285. shared_this->state_ = WebSocketReadState::Len16;
  9286. } else {
  9287. shared_this->remaining_length_ =
  9288. shared_this->mini_header_ & 0x7f;
  9289. shared_this->state_ = WebSocketReadState::Mask;
  9290. }
  9291. shared_this->do_read();
  9292. } else {
  9293. shared_this->close_connection_ = true;
  9294. shared_this->adaptor_.shutdown_readwrite();
  9295. shared_this->adaptor_.close();
  9296. if (shared_this->error_handler_)
  9297. shared_this->error_handler_(*shared_this, ec.message());
  9298. shared_this->check_destroy();
  9299. }
  9300. });
  9301. } break;
  9302. case WebSocketReadState::Len16: {
  9303. remaining_length_ = 0;
  9304. remaining_length16_ = 0;
  9305. asio::async_read(
  9306. adaptor_.socket(), asio::buffer(&remaining_length16_, 2),
  9307. [shared_this = this->shared_from_this()](const error_code &ec,
  9308. std::size_t
  9309. #ifdef CROW_ENABLE_DEBUG
  9310. bytes_transferred
  9311. #endif
  9312. ) {
  9313. shared_this->is_reading = false;
  9314. shared_this->remaining_length16_ =
  9315. ntohs(shared_this->remaining_length16_);
  9316. shared_this->remaining_length_ = shared_this->remaining_length16_;
  9317. #ifdef CROW_ENABLE_DEBUG
  9318. if (!ec && bytes_transferred != 2) {
  9319. throw std::runtime_error(
  9320. "WebSocket:Len16:async_read fail:asio bug?");
  9321. }
  9322. #endif
  9323. if (!ec) {
  9324. shared_this->state_ = WebSocketReadState::Mask;
  9325. shared_this->do_read();
  9326. } else {
  9327. shared_this->close_connection_ = true;
  9328. shared_this->adaptor_.shutdown_readwrite();
  9329. shared_this->adaptor_.close();
  9330. if (shared_this->error_handler_)
  9331. shared_this->error_handler_(*shared_this, ec.message());
  9332. shared_this->check_destroy();
  9333. }
  9334. });
  9335. } break;
  9336. case WebSocketReadState::Len64: {
  9337. asio::async_read(
  9338. adaptor_.socket(), asio::buffer(&remaining_length_, 8),
  9339. [shared_this = this->shared_from_this()](const error_code &ec,
  9340. std::size_t
  9341. #ifdef CROW_ENABLE_DEBUG
  9342. bytes_transferred
  9343. #endif
  9344. ) {
  9345. shared_this->is_reading = false;
  9346. shared_this->remaining_length_ =
  9347. ((1 == ntohl(1))
  9348. ? (shared_this->remaining_length_)
  9349. : (static_cast<uint64_t>(ntohl(
  9350. (shared_this->remaining_length_) & 0xFFFFFFFF))
  9351. << 32) |
  9352. ntohl((shared_this->remaining_length_) >> 32));
  9353. #ifdef CROW_ENABLE_DEBUG
  9354. if (!ec && bytes_transferred != 8) {
  9355. throw std::runtime_error(
  9356. "WebSocket:Len16:async_read fail:asio bug?");
  9357. }
  9358. #endif
  9359. if (!ec) {
  9360. shared_this->state_ = WebSocketReadState::Mask;
  9361. shared_this->do_read();
  9362. } else {
  9363. shared_this->close_connection_ = true;
  9364. shared_this->adaptor_.shutdown_readwrite();
  9365. shared_this->adaptor_.close();
  9366. if (shared_this->error_handler_)
  9367. shared_this->error_handler_(*shared_this, ec.message());
  9368. shared_this->check_destroy();
  9369. }
  9370. });
  9371. } break;
  9372. case WebSocketReadState::Mask:
  9373. if (remaining_length_ > max_payload_bytes_) {
  9374. close_connection_ = true;
  9375. adaptor_.close();
  9376. if (error_handler_)
  9377. error_handler_(*this, "Message length exceeds maximum payload.");
  9378. check_destroy(MessageTooBig);
  9379. } else if (has_mask_) {
  9380. asio::async_read(adaptor_.socket(), asio::buffer((char *)&mask_, 4),
  9381. [shared_this = this->shared_from_this()](
  9382. const error_code &ec, std::size_t
  9383. #ifdef CROW_ENABLE_DEBUG
  9384. bytes_transferred
  9385. #endif
  9386. ) {
  9387. shared_this->is_reading = false;
  9388. #ifdef CROW_ENABLE_DEBUG
  9389. if (!ec && bytes_transferred != 4) {
  9390. throw std::runtime_error(
  9391. "WebSocket:Mask:async_read fail:asio bug?");
  9392. }
  9393. #endif
  9394. if (!ec) {
  9395. shared_this->state_ = WebSocketReadState::Payload;
  9396. shared_this->do_read();
  9397. } else {
  9398. shared_this->close_connection_ = true;
  9399. if (shared_this->error_handler_)
  9400. shared_this->error_handler_(*shared_this,
  9401. ec.message());
  9402. shared_this->adaptor_.shutdown_readwrite();
  9403. shared_this->adaptor_.close();
  9404. shared_this->check_destroy();
  9405. }
  9406. });
  9407. } else {
  9408. state_ = WebSocketReadState::Payload;
  9409. do_read();
  9410. }
  9411. break;
  9412. case WebSocketReadState::Payload: {
  9413. auto to_read = static_cast<std::uint64_t>(buffer_.size());
  9414. if (remaining_length_ < to_read) to_read = remaining_length_;
  9415. adaptor_.socket().async_read_some(
  9416. asio::buffer(buffer_, static_cast<std::size_t>(to_read)),
  9417. [shared_this = this->shared_from_this()](
  9418. const error_code &ec, std::size_t bytes_transferred) {
  9419. shared_this->is_reading = false;
  9420. if (!ec) {
  9421. shared_this->fragment_.insert(
  9422. shared_this->fragment_.end(), shared_this->buffer_.begin(),
  9423. shared_this->buffer_.begin() + bytes_transferred);
  9424. shared_this->remaining_length_ -= bytes_transferred;
  9425. if (shared_this->remaining_length_ == 0) {
  9426. if (shared_this->handle_fragment()) {
  9427. shared_this->state_ = WebSocketReadState::MiniHeader;
  9428. shared_this->do_read();
  9429. }
  9430. } else
  9431. shared_this->do_read();
  9432. } else {
  9433. shared_this->close_connection_ = true;
  9434. if (shared_this->error_handler_)
  9435. shared_this->error_handler_(*shared_this, ec.message());
  9436. shared_this->adaptor_.shutdown_readwrite();
  9437. shared_this->adaptor_.close();
  9438. shared_this->check_destroy();
  9439. }
  9440. });
  9441. } break;
  9442. }
  9443. }
  9444. /// Check if the FIN bit is set.
  9445. bool is_FIN() { return mini_header_ & 0x8000; }
  9446. /// Extract the opcode from the header.
  9447. int opcode() { return (mini_header_ & 0x0f00) >> 8; }
  9448. /// Process the payload fragment.
  9449. ///
  9450. /// Unmasks the fragment, checks the opcode, merges fragments into 1 message
  9451. /// body, and calls the appropriate handler.
  9452. bool handle_fragment() {
  9453. if (has_mask_) {
  9454. for (decltype(fragment_.length()) i = 0; i < fragment_.length(); i++) {
  9455. fragment_[i] ^= ((char *)&mask_)[i % 4];
  9456. }
  9457. }
  9458. switch (opcode()) {
  9459. case 0: // Continuation
  9460. {
  9461. message_ += fragment_;
  9462. if (is_FIN()) {
  9463. if (message_handler_) message_handler_(*this, message_, is_binary_);
  9464. message_.clear();
  9465. }
  9466. } break;
  9467. case 1: // Text
  9468. {
  9469. is_binary_ = false;
  9470. message_ += fragment_;
  9471. if (is_FIN()) {
  9472. if (message_handler_) message_handler_(*this, message_, is_binary_);
  9473. message_.clear();
  9474. }
  9475. } break;
  9476. case 2: // Binary
  9477. {
  9478. is_binary_ = true;
  9479. message_ += fragment_;
  9480. if (is_FIN()) {
  9481. if (message_handler_) message_handler_(*this, message_, is_binary_);
  9482. message_.clear();
  9483. }
  9484. } break;
  9485. case 0x8: // Close
  9486. {
  9487. has_recv_close_ = true;
  9488. uint16_t status_code = NoStatusCodePresent;
  9489. std::string::size_type message_start = 2;
  9490. if (fragment_.size() >= 2) {
  9491. status_code = ntohs(((uint16_t *)fragment_.data())[0]);
  9492. } else {
  9493. // no message will crash substr
  9494. message_start = 0;
  9495. }
  9496. if (!has_sent_close_) {
  9497. close(fragment_.substr(message_start), status_code);
  9498. } else {
  9499. close_connection_ = true;
  9500. if (!is_close_handler_called_) {
  9501. if (close_handler_)
  9502. close_handler_(*this, fragment_.substr(message_start), status_code);
  9503. is_close_handler_called_ = true;
  9504. }
  9505. adaptor_.shutdown_readwrite();
  9506. adaptor_.close();
  9507. // Close handler must have been called at this point so code does not
  9508. // matter
  9509. check_destroy();
  9510. return false;
  9511. }
  9512. } break;
  9513. case 0x9: // Ping
  9514. {
  9515. send_pong(fragment_);
  9516. } break;
  9517. case 0xA: // Pong
  9518. {
  9519. pong_received_ = true;
  9520. } break;
  9521. }
  9522. fragment_.clear();
  9523. return true;
  9524. }
  9525. /// Send the buffers' data through the socket.
  9526. ///
  9527. /// Also destroys the object if the Close flag is set.
  9528. void do_write() {
  9529. if (sending_buffers_.empty()) {
  9530. if (write_buffers_.empty()) return;
  9531. sending_buffers_.swap(write_buffers_);
  9532. std::vector<asio::const_buffer> buffers;
  9533. buffers.reserve(sending_buffers_.size());
  9534. for (auto &s : sending_buffers_) {
  9535. buffers.emplace_back(asio::buffer(s));
  9536. }
  9537. auto watch = std::weak_ptr<void>{anchor_};
  9538. asio::async_write(
  9539. adaptor_.socket(), buffers,
  9540. [shared_this = this->shared_from_this(),
  9541. watch](const error_code &ec, std::size_t /*bytes_transferred*/) {
  9542. auto anchor = watch.lock();
  9543. if (anchor == nullptr) return;
  9544. if (!ec && !shared_this->close_connection_) {
  9545. shared_this->sending_buffers_.clear();
  9546. if (!shared_this->write_buffers_.empty()) shared_this->do_write();
  9547. if (shared_this->has_sent_close_)
  9548. shared_this->close_connection_ = true;
  9549. } else {
  9550. shared_this->sending_buffers_.clear();
  9551. shared_this->close_connection_ = true;
  9552. shared_this->check_destroy();
  9553. }
  9554. });
  9555. }
  9556. }
  9557. /// Destroy the Connection.
  9558. void check_destroy(
  9559. websocket::CloseStatusCode code = CloseStatusCode::ClosedAbnormally) {
  9560. // Note that if the close handler was not yet called at this point we did
  9561. // not receive a close packet (or send one) and thus we use ClosedAbnormally
  9562. // unless instructed otherwise
  9563. if (!is_close_handler_called_) {
  9564. if (close_handler_) { close_handler_(*this, "uncleanly", code); }
  9565. }
  9566. handler_->remove_websocket(this->shared_from_this());
  9567. }
  9568. struct SendMessageType {
  9569. std::string payload;
  9570. Connection *self;
  9571. int opcode;
  9572. void operator()() { self->send_data_impl(this); }
  9573. };
  9574. void send_data_impl(SendMessageType *s) {
  9575. auto header = build_header(s->opcode, s->payload.size());
  9576. write_buffers_.emplace_back(std::move(header));
  9577. write_buffers_.emplace_back(std::move(s->payload));
  9578. do_write();
  9579. }
  9580. void send_data(int opcode, std::string &&msg) {
  9581. SendMessageType event_arg{std::move(msg), this, opcode};
  9582. post(std::move(event_arg));
  9583. }
  9584. private:
  9585. Connection(
  9586. Adaptor &&adaptor, Handler *handler, uint64_t max_payload,
  9587. std::function<void(crow::websocket::connection &)> open_handler,
  9588. std::function<void(crow::websocket::connection &, const std::string &,
  9589. bool)>
  9590. message_handler,
  9591. std::function<void(crow::websocket::connection &, const std::string &,
  9592. uint16_t)>
  9593. close_handler,
  9594. std::function<void(crow::websocket::connection &, const std::string &)>
  9595. error_handler,
  9596. std::function<void(const crow::request &, std::optional<crow::response> &,
  9597. void **)>
  9598. accept_handler)
  9599. : adaptor_(std::move(adaptor)), handler_(handler),
  9600. max_payload_bytes_(max_payload), open_handler_(std::move(open_handler)),
  9601. message_handler_(std::move(message_handler)),
  9602. close_handler_(std::move(close_handler)),
  9603. error_handler_(std::move(error_handler)),
  9604. accept_handler_(std::move(accept_handler)) {}
  9605. Adaptor adaptor_;
  9606. Handler *handler_;
  9607. std::vector<std::string> sending_buffers_;
  9608. std::vector<std::string> write_buffers_;
  9609. std::array<char, 4096> buffer_;
  9610. bool is_binary_;
  9611. std::string message_;
  9612. std::string fragment_;
  9613. WebSocketReadState state_{WebSocketReadState::MiniHeader};
  9614. uint16_t remaining_length16_{0};
  9615. uint64_t remaining_length_{0};
  9616. uint64_t max_payload_bytes_{UINT64_MAX};
  9617. std::string subprotocol_;
  9618. bool close_connection_{false};
  9619. bool is_reading{false};
  9620. bool has_mask_{false};
  9621. uint32_t mask_;
  9622. uint16_t mini_header_;
  9623. bool has_sent_close_{false};
  9624. bool has_recv_close_{false};
  9625. bool error_occurred_{false};
  9626. bool pong_received_{false};
  9627. bool is_close_handler_called_{false};
  9628. std::shared_ptr<void> anchor_ =
  9629. std::make_shared<int>(); // Value is just for placeholding
  9630. std::function<void(crow::websocket::connection &)> open_handler_;
  9631. std::function<void(crow::websocket::connection &, const std::string &, bool)>
  9632. message_handler_;
  9633. std::function<void(crow::websocket::connection &, const std::string &,
  9634. uint16_t status_code)>
  9635. close_handler_;
  9636. std::function<void(crow::websocket::connection &, const std::string &)>
  9637. error_handler_;
  9638. std::function<void(const crow::request &, std::optional<crow::response> &,
  9639. void **)>
  9640. accept_handler_;
  9641. };
  9642. } // namespace websocket
  9643. } // namespace crow
  9644. #include <algorithm>
  9645. #include <cstdint>
  9646. #include <limits>
  9647. #include <memory>
  9648. #include <optional>
  9649. #include <tuple>
  9650. #include <type_traits>
  9651. #include <unordered_map>
  9652. #include <utility>
  9653. #include <vector>
  9654. namespace crow // NOTE: Already documented in "crow/app.h"
  9655. {
  9656. constexpr size_t INVALID_BP_ID{SIZE_MAX};
  9657. namespace detail {
  9658. /// Typesafe wrapper for storing lists of middleware as their indices in the App
  9659. struct middleware_indices {
  9660. template <typename App> void push() {}
  9661. template <typename App, typename MW, typename... Middlewares> void push() {
  9662. using MwContainer = typename App::mw_container_t;
  9663. static_assert(black_magic::has_type<MW, MwContainer>::value,
  9664. "Middleware must be present in app");
  9665. static_assert(std::is_base_of<crow::ILocalMiddleware, MW>::value,
  9666. "Middleware must extend ILocalMiddleware");
  9667. int idx = black_magic::tuple_index<MW, MwContainer>::value;
  9668. indices_.push_back(idx);
  9669. push<App, Middlewares...>();
  9670. }
  9671. void merge_front(const detail::middleware_indices &other) {
  9672. indices_.insert(indices_.begin(), other.indices_.cbegin(),
  9673. other.indices_.cend());
  9674. }
  9675. void merge_back(const detail::middleware_indices &other) {
  9676. indices_.insert(indices_.end(), other.indices_.cbegin(),
  9677. other.indices_.cend());
  9678. }
  9679. void pop_back(const detail::middleware_indices &other) {
  9680. indices_.resize(indices_.size() - other.indices_.size());
  9681. }
  9682. bool empty() const { return indices_.empty(); }
  9683. // Sorts indices and filters out duplicates to allow fast lookups with
  9684. // traversal
  9685. void pack() {
  9686. std::sort(indices_.begin(), indices_.end());
  9687. indices_.erase(std::unique(indices_.begin(), indices_.end()),
  9688. indices_.end());
  9689. }
  9690. const std::vector<int> &indices() { return indices_; }
  9691. private:
  9692. std::vector<int> indices_;
  9693. };
  9694. } // namespace detail
  9695. /// A base class for all rules.
  9696. ///
  9697. /// Used to provide a common interface for code dealing with different types of
  9698. /// rules.<br> A Rule provides a URL, allowed HTTP methods, and handlers.
  9699. class BaseRule {
  9700. public:
  9701. BaseRule(std::string rule) : rule_(std::move(rule)) {}
  9702. virtual ~BaseRule() = default;
  9703. virtual void validate() = 0;
  9704. void set_added() { added_ = true; }
  9705. bool is_added() { return added_; }
  9706. std::unique_ptr<BaseRule> upgrade() {
  9707. if (rule_to_upgrade_) return std::move(rule_to_upgrade_);
  9708. return {};
  9709. }
  9710. virtual void handle(request &, response &, const routing_params &) = 0;
  9711. virtual void handle_upgrade(const request &, response &res,
  9712. SocketAdaptor &&) {
  9713. res = response(404);
  9714. res.end();
  9715. }
  9716. virtual void handle_upgrade(const request &, response &res,
  9717. UnixSocketAdaptor &&) {
  9718. res = response(404);
  9719. res.end();
  9720. }
  9721. #ifdef CROW_ENABLE_SSL
  9722. virtual void handle_upgrade(const request &, response &res, SSLAdaptor &&) {
  9723. res = response(404);
  9724. res.end();
  9725. }
  9726. #endif
  9727. uint32_t get_methods() { return methods_; }
  9728. template <typename F> void foreach_method(F f) {
  9729. for (uint32_t method = 0, method_bit = 1;
  9730. method < static_cast<uint32_t>(HTTPMethod::InternalMethodCount);
  9731. method++, method_bit <<= 1) {
  9732. if (methods_ & method_bit) f(method);
  9733. }
  9734. }
  9735. std::string custom_templates_base;
  9736. const std::string &rule() { return rule_; }
  9737. protected:
  9738. uint32_t methods_{1 << static_cast<int>(HTTPMethod::Get)};
  9739. std::string rule_;
  9740. std::string name_;
  9741. bool added_{false};
  9742. std::unique_ptr<BaseRule> rule_to_upgrade_;
  9743. detail::middleware_indices mw_indices_;
  9744. friend class Router;
  9745. friend class Blueprint;
  9746. template <typename T> friend struct RuleParameterTraits;
  9747. };
  9748. namespace detail {
  9749. namespace routing_handler_call_helper {
  9750. template <typename T, int Pos> struct call_pair {
  9751. using type = T;
  9752. static const int pos = Pos;
  9753. };
  9754. template <typename H1> struct call_params {
  9755. H1 &handler;
  9756. const routing_params &params;
  9757. request &req;
  9758. response &res;
  9759. };
  9760. template <typename F, int NInt, int NUint, int NDouble, int NString,
  9761. typename S1, typename S2>
  9762. struct call {};
  9763. template <typename F, int NInt, int NUint, int NDouble, int NString,
  9764. typename... Args1, typename... Args2>
  9765. struct call<F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>,
  9766. black_magic::S<Args2...>> {
  9767. void operator()(F cparams) {
  9768. using pushed = typename black_magic::S<Args2...>::template push_back<
  9769. call_pair<int64_t, NInt>>;
  9770. call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>,
  9771. pushed>()(cparams);
  9772. }
  9773. };
  9774. template <typename F, int NInt, int NUint, int NDouble, int NString,
  9775. typename... Args1, typename... Args2>
  9776. struct call<F, NInt, NUint, NDouble, NString,
  9777. black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>> {
  9778. void operator()(F cparams) {
  9779. using pushed = typename black_magic::S<Args2...>::template push_back<
  9780. call_pair<uint64_t, NUint>>;
  9781. call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>,
  9782. pushed>()(cparams);
  9783. }
  9784. };
  9785. template <typename F, int NInt, int NUint, int NDouble, int NString,
  9786. typename... Args1, typename... Args2>
  9787. struct call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>,
  9788. black_magic::S<Args2...>> {
  9789. void operator()(F cparams) {
  9790. using pushed = typename black_magic::S<Args2...>::template push_back<
  9791. call_pair<double, NDouble>>;
  9792. call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>,
  9793. pushed>()(cparams);
  9794. }
  9795. };
  9796. template <typename F, int NInt, int NUint, int NDouble, int NString,
  9797. typename... Args1, typename... Args2>
  9798. struct call<F, NInt, NUint, NDouble, NString,
  9799. black_magic::S<std::string, Args1...>, black_magic::S<Args2...>> {
  9800. void operator()(F cparams) {
  9801. using pushed = typename black_magic::S<Args2...>::template push_back<
  9802. call_pair<std::string, NString>>;
  9803. call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>,
  9804. pushed>()(cparams);
  9805. }
  9806. };
  9807. template <typename F, int NInt, int NUint, int NDouble, int NString,
  9808. typename... Args1>
  9809. struct call<F, NInt, NUint, NDouble, NString, black_magic::S<>,
  9810. black_magic::S<Args1...>> {
  9811. void operator()(F cparams) {
  9812. cparams.handler(
  9813. cparams.req, cparams.res,
  9814. cparams.params.template get<typename Args1::type>(Args1::pos)...);
  9815. }
  9816. };
  9817. template <typename Func, typename... ArgsWrapped> struct Wrapped {
  9818. template <typename... Args>
  9819. void
  9820. set_(Func f,
  9821. typename std::enable_if<
  9822. !std::is_same<
  9823. typename std::tuple_element<0, std::tuple<Args..., void>>::type,
  9824. const request &>::value,
  9825. int>::type = 0) {
  9826. handler_ =
  9827. ([f = std::move(f)](const request &, response &res, Args... args) {
  9828. res = response(f(args...));
  9829. res.end();
  9830. });
  9831. }
  9832. template <typename Req, typename... Args> struct req_handler_wrapper {
  9833. req_handler_wrapper(Func fun) : f(std::move(fun)) {}
  9834. void operator()(const request &req, response &res, Args... args) {
  9835. res = response(f(req, args...));
  9836. res.end();
  9837. }
  9838. Func f;
  9839. };
  9840. template <typename... Args>
  9841. void
  9842. set_(Func f,
  9843. typename std::enable_if<
  9844. std::is_same<
  9845. typename std::tuple_element<0, std::tuple<Args..., void>>::type,
  9846. const request &>::value &&
  9847. !std::is_same<typename std::tuple_element<
  9848. 1, std::tuple<Args..., void, void>>::type,
  9849. response &>::value,
  9850. int>::type = 0) {
  9851. handler_ = req_handler_wrapper<Args...>(std::move(f));
  9852. /*handler_ = (
  9853. [f = std::move(f)]
  9854. (const request& req, response& res, Args... args){
  9855. res = response(f(req, args...));
  9856. res.end();
  9857. });*/
  9858. }
  9859. template <typename... Args>
  9860. void
  9861. set_(Func f,
  9862. typename std::enable_if<
  9863. std::is_same<
  9864. typename std::tuple_element<0, std::tuple<Args..., void>>::type,
  9865. const request &>::value &&
  9866. std::is_same<typename std::tuple_element<
  9867. 1, std::tuple<Args..., void, void>>::type,
  9868. response &>::value,
  9869. int>::type = 0) {
  9870. handler_ = std::move(f);
  9871. }
  9872. template <typename... Args> struct handler_type_helper {
  9873. using type =
  9874. std::function<void(const crow::request &, crow::response &, Args...)>;
  9875. using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
  9876. };
  9877. template <typename... Args>
  9878. struct handler_type_helper<const request &, Args...> {
  9879. using type =
  9880. std::function<void(const crow::request &, crow::response &, Args...)>;
  9881. using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
  9882. };
  9883. template <typename... Args>
  9884. struct handler_type_helper<const request &, response &, Args...> {
  9885. using type =
  9886. std::function<void(const crow::request &, crow::response &, Args...)>;
  9887. using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
  9888. };
  9889. typename handler_type_helper<ArgsWrapped...>::type handler_;
  9890. void operator()(request &req, response &res, const routing_params &params) {
  9891. detail::routing_handler_call_helper::call<
  9892. detail::routing_handler_call_helper::call_params<decltype(handler_)>, 0,
  9893. 0, 0, 0, typename handler_type_helper<ArgsWrapped...>::args_type,
  9894. black_magic::S<>>()(
  9895. detail::routing_handler_call_helper::call_params<decltype(handler_)>{
  9896. handler_, params, req, res});
  9897. }
  9898. };
  9899. } // namespace routing_handler_call_helper
  9900. } // namespace detail
  9901. class CatchallRule {
  9902. public:
  9903. /// @cond SKIP
  9904. CatchallRule() {}
  9905. template <typename Func>
  9906. typename std::enable_if<
  9907. black_magic::CallHelper<Func, black_magic::S<>>::value, void>::type
  9908. operator()(Func &&f) {
  9909. static_assert(!std::is_same<void, decltype(f())>::value,
  9910. "Handler function cannot have void return type; valid return "
  9911. "types: string, int, crow::response, crow::returnable");
  9912. handler_ = ([f = std::move(f)](const request &, response &res) {
  9913. res = response(f());
  9914. res.end();
  9915. });
  9916. }
  9917. template <typename Func>
  9918. typename std::enable_if<
  9919. !black_magic::CallHelper<Func, black_magic::S<>>::value &&
  9920. black_magic::CallHelper<Func, black_magic::S<crow::request>>::value,
  9921. void>::type
  9922. operator()(Func &&f) {
  9923. static_assert(
  9924. !std::is_same<void, decltype(f(std::declval<crow::request>()))>::value,
  9925. "Handler function cannot have void return type; valid return types: "
  9926. "string, int, crow::response, crow::returnable");
  9927. handler_ = ([f = std::move(f)](const request &req, response &res) {
  9928. res = response(f(req));
  9929. res.end();
  9930. });
  9931. }
  9932. template <typename Func>
  9933. typename std::enable_if<
  9934. !black_magic::CallHelper<Func, black_magic::S<>>::value &&
  9935. !black_magic::CallHelper<Func,
  9936. black_magic::S<crow::request>>::value &&
  9937. black_magic::CallHelper<Func,
  9938. black_magic::S<crow::response &>>::value,
  9939. void>::type
  9940. operator()(Func &&f) {
  9941. static_assert(
  9942. std::is_same<void,
  9943. decltype(f(std::declval<crow::response &>()))>::value,
  9944. "Handler function with response argument should have void return type");
  9945. handler_ = ([f = std::move(f)](const request &, response &res) { f(res); });
  9946. }
  9947. template <typename Func>
  9948. typename std::enable_if<
  9949. !black_magic::CallHelper<Func, black_magic::S<>>::value &&
  9950. !black_magic::CallHelper<Func,
  9951. black_magic::S<crow::request>>::value &&
  9952. !black_magic::CallHelper<Func,
  9953. black_magic::S<crow::response &>>::value,
  9954. void>::type
  9955. operator()(Func &&f) {
  9956. static_assert(
  9957. std::is_same<void,
  9958. decltype(f(std::declval<crow::request>(),
  9959. std::declval<crow::response &>()))>::value,
  9960. "Handler function with response argument should have void return type");
  9961. handler_ = std::move(f);
  9962. }
  9963. /// @endcond
  9964. bool has_handler() { return (handler_ != nullptr); }
  9965. protected:
  9966. friend class Router;
  9967. private:
  9968. std::function<void(const crow::request &, crow::response &)> handler_;
  9969. };
  9970. /// A rule dealing with websockets.
  9971. ///
  9972. /// Provides the interface for the user to put in the necessary handlers for a
  9973. /// websocket to work.
  9974. template <typename App> class WebSocketRule : public BaseRule {
  9975. using self_t = WebSocketRule;
  9976. public:
  9977. WebSocketRule(std::string rule, App *app)
  9978. : BaseRule(std::move(rule)), app_(app), max_payload_(UINT64_MAX) {}
  9979. void validate() override {}
  9980. void handle(request &, response &res, const routing_params &) override {
  9981. res = response(404);
  9982. res.end();
  9983. }
  9984. void handle_upgrade(const request &req, response &,
  9985. SocketAdaptor &&adaptor) override {
  9986. max_payload_ =
  9987. max_payload_override_ ? max_payload_ : app_->websocket_max_payload();
  9988. crow::websocket::Connection<SocketAdaptor, App>::create(
  9989. req, std::move(adaptor), app_, max_payload_, subprotocols_,
  9990. open_handler_, message_handler_, close_handler_, error_handler_,
  9991. accept_handler_, mirror_protocols_);
  9992. }
  9993. void handle_upgrade(const request &req, response &,
  9994. UnixSocketAdaptor &&adaptor) override {
  9995. max_payload_ =
  9996. max_payload_override_ ? max_payload_ : app_->websocket_max_payload();
  9997. crow::websocket::Connection<UnixSocketAdaptor, App>::create(
  9998. req, std::move(adaptor), app_, max_payload_, subprotocols_,
  9999. open_handler_, message_handler_, close_handler_, error_handler_,
  10000. accept_handler_, mirror_protocols_);
  10001. }
  10002. #ifdef CROW_ENABLE_SSL
  10003. void handle_upgrade(const request &req, response &,
  10004. SSLAdaptor &&adaptor) override {
  10005. crow::websocket::Connection<SSLAdaptor, App>::create(
  10006. req, std::move(adaptor), app_, max_payload_, subprotocols_,
  10007. open_handler_, message_handler_, close_handler_, error_handler_,
  10008. accept_handler_, mirror_protocols_);
  10009. }
  10010. #endif
  10011. /// Override the global payload limit for this single WebSocket rule
  10012. self_t &max_payload(uint64_t max_payload) {
  10013. max_payload_ = max_payload;
  10014. max_payload_override_ = true;
  10015. return *this;
  10016. }
  10017. self_t &subprotocols(const std::vector<std::string> &subprotocols) {
  10018. subprotocols_ = subprotocols;
  10019. return *this;
  10020. }
  10021. template <typename Func> self_t &onopen(Func f) {
  10022. open_handler_ = f;
  10023. return *this;
  10024. }
  10025. template <typename Func> self_t &onmessage(Func f) {
  10026. message_handler_ = f;
  10027. return *this;
  10028. }
  10029. template <typename Func> self_t &onclose(Func f) {
  10030. close_handler_ = f;
  10031. return *this;
  10032. }
  10033. template <typename Func> self_t &onerror(Func f) {
  10034. error_handler_ = f;
  10035. return *this;
  10036. }
  10037. self_t &onaccept(
  10038. std::function<void(const crow::request &, std::optional<crow::response> &,
  10039. void **)> &&callback) {
  10040. accept_handler_ = std::move(callback);
  10041. return *this;
  10042. }
  10043. self_t &
  10044. onaccept(std::function<bool(const crow::request &, void **)> &&callback) {
  10045. onaccept([callback](const crow::request &req,
  10046. std::optional<crow::response> &res, void **p) {
  10047. if (!callback(req, p)) { res = crow::response(400); }
  10048. });
  10049. return *this;
  10050. }
  10051. self_t &mirrorprotocols(bool mirror_protocols = true) {
  10052. mirror_protocols_ = mirror_protocols;
  10053. return *this;
  10054. }
  10055. protected:
  10056. App *app_;
  10057. std::function<void(crow::websocket::connection &)> open_handler_;
  10058. std::function<void(crow::websocket::connection &, const std::string &, bool)>
  10059. message_handler_;
  10060. std::function<void(crow::websocket::connection &, const std::string &,
  10061. uint16_t)>
  10062. close_handler_;
  10063. std::function<void(crow::websocket::connection &, const std::string &)>
  10064. error_handler_;
  10065. std::function<void(const crow::request &, std::optional<crow::response> &,
  10066. void **)>
  10067. accept_handler_;
  10068. bool mirror_protocols_ = false;
  10069. uint64_t max_payload_;
  10070. bool max_payload_override_ = false;
  10071. std::vector<std::string> subprotocols_;
  10072. };
  10073. /// Allows the user to assign parameters using functions.
  10074. ///
  10075. /// `rule.name("name").methods(HTTPMethod::POST)`
  10076. template <typename T> struct RuleParameterTraits {
  10077. using self_t = T;
  10078. template <typename App> WebSocketRule<App> &websocket(App *app) {
  10079. auto p = new WebSocketRule<App>(static_cast<self_t *>(this)->rule_, app);
  10080. static_cast<self_t *>(this)->rule_to_upgrade_.reset(p);
  10081. return *p;
  10082. }
  10083. self_t &name(std::string name) noexcept {
  10084. static_cast<self_t *>(this)->name_ = std::move(name);
  10085. return static_cast<self_t &>(*this);
  10086. }
  10087. self_t &methods(HTTPMethod method) {
  10088. static_cast<self_t *>(this)->methods_ = 1 << static_cast<int>(method);
  10089. return static_cast<self_t &>(*this);
  10090. }
  10091. template <typename... MethodArgs>
  10092. self_t &methods(HTTPMethod method, MethodArgs... args_method) {
  10093. methods(args_method...);
  10094. static_cast<self_t *>(this)->methods_ |= 1 << static_cast<int>(method);
  10095. return static_cast<self_t &>(*this);
  10096. }
  10097. /// Enable local middleware for this handler
  10098. template <typename App, typename... Middlewares> self_t &middlewares() {
  10099. static_cast<self_t *>(this)
  10100. ->mw_indices_.template push<App, Middlewares...>();
  10101. return static_cast<self_t &>(*this);
  10102. }
  10103. };
  10104. /// A rule that can change its parameters during runtime.
  10105. class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> {
  10106. public:
  10107. DynamicRule(std::string rule) : BaseRule(std::move(rule)) {}
  10108. void validate() override {
  10109. if (!erased_handler_) {
  10110. throw std::runtime_error(name_ + (!name_.empty() ? ": " : "") +
  10111. "no handler for url " + rule_);
  10112. }
  10113. }
  10114. void handle(request &req, response &res,
  10115. const routing_params &params) override {
  10116. if (!custom_templates_base.empty())
  10117. mustache::set_base(custom_templates_base);
  10118. else if (mustache::detail::get_template_base_directory_ref() != "templates")
  10119. mustache::set_base("templates");
  10120. erased_handler_(req, res, params);
  10121. }
  10122. template <typename Func> void operator()(Func f) {
  10123. #ifdef CROW_MSVC_WORKAROUND
  10124. using function_t = utility::function_traits<decltype(&Func::operator())>;
  10125. #else
  10126. using function_t = utility::function_traits<Func>;
  10127. #endif
  10128. erased_handler_ =
  10129. wrap(std::move(f), black_magic::gen_seq<function_t::arity>());
  10130. }
  10131. // enable_if Arg1 == request && Arg2 == response
  10132. // enable_if Arg1 == request && Arg2 != resposne
  10133. // enable_if Arg1 != request
  10134. #ifdef CROW_MSVC_WORKAROUND
  10135. template <typename Func, size_t... Indices>
  10136. #else
  10137. template <typename Func, unsigned... Indices>
  10138. #endif
  10139. std::function<void(request &, response &, const routing_params &)>
  10140. wrap(Func f, black_magic::seq<Indices...>) {
  10141. #ifdef CROW_MSVC_WORKAROUND
  10142. using function_t = utility::function_traits<decltype(&Func::operator())>;
  10143. #else
  10144. using function_t = utility::function_traits<Func>;
  10145. #endif
  10146. if (!black_magic::is_parameter_tag_compatible(
  10147. black_magic::get_parameter_tag_runtime(rule_.c_str()),
  10148. black_magic::compute_parameter_tag_from_args_list<
  10149. typename function_t::template arg<Indices>...>::value)) {
  10150. throw std::runtime_error(
  10151. "route_dynamic: Handler type is mismatched with URL parameters: " +
  10152. rule_);
  10153. }
  10154. auto ret = detail::routing_handler_call_helper::Wrapped<
  10155. Func, typename function_t::template arg<Indices>...>();
  10156. ret.template set_<typename function_t::template arg<Indices>...>(
  10157. std::move(f));
  10158. return ret;
  10159. }
  10160. template <typename Func> void operator()(std::string name, Func &&f) {
  10161. name_ = std::move(name);
  10162. (*this).template operator()<Func>(std::forward(f));
  10163. }
  10164. private:
  10165. std::function<void(request &, response &, const routing_params &)>
  10166. erased_handler_;
  10167. };
  10168. /// Default rule created when CROW_ROUTE is called.
  10169. template <typename... Args>
  10170. class TaggedRule : public BaseRule,
  10171. public RuleParameterTraits<TaggedRule<Args...>> {
  10172. public:
  10173. using self_t = TaggedRule<Args...>;
  10174. TaggedRule(std::string rule) : BaseRule(std::move(rule)) {}
  10175. void validate() override {
  10176. if (rule_.at(0) != '/')
  10177. throw std::runtime_error("Internal error: Routes must start with a '/'");
  10178. if (!handler_) {
  10179. throw std::runtime_error(name_ + (!name_.empty() ? ": " : "") +
  10180. "no handler for url " + rule_);
  10181. }
  10182. }
  10183. template <typename Func> void operator()(Func &&f) {
  10184. handler_ = ([f = std::move(f)](request &req, response &res, Args... args) {
  10185. detail::wrapped_handler_call(req, res, f, std::forward<Args>(args)...);
  10186. });
  10187. }
  10188. template <typename Func> void operator()(std::string name, Func &&f) {
  10189. name_ = std::move(name);
  10190. (*this).template operator()<Func>(std::forward(f));
  10191. }
  10192. void handle(request &req, response &res,
  10193. const routing_params &params) override {
  10194. if (!custom_templates_base.empty())
  10195. mustache::set_base(custom_templates_base);
  10196. else if (mustache::detail::get_template_base_directory_ref() !=
  10197. mustache::detail::get_global_template_base_directory_ref())
  10198. mustache::set_base(
  10199. mustache::detail::get_global_template_base_directory_ref());
  10200. detail::routing_handler_call_helper::call<
  10201. detail::routing_handler_call_helper::call_params<decltype(handler_)>, 0,
  10202. 0, 0, 0, black_magic::S<Args...>, black_magic::S<>>()(
  10203. detail::routing_handler_call_helper::call_params<decltype(handler_)>{
  10204. handler_, params, req, res});
  10205. }
  10206. private:
  10207. std::function<void(crow::request &, crow::response &, Args...)> handler_;
  10208. };
  10209. constexpr size_t RULE_SPECIAL_REDIRECT_SLASH = 1;
  10210. /// A search tree.
  10211. class Trie {
  10212. public:
  10213. struct Node {
  10214. size_t rule_index{};
  10215. // Assign the index to the maximum 32 unsigned integer value by default so
  10216. // that any other number (specifically 0) is a valid BP id.
  10217. size_t blueprint_index{INVALID_BP_ID};
  10218. std::string key;
  10219. ParamType param = ParamType::MAX; // MAX = No param.
  10220. std::vector<Node> children;
  10221. bool IsSimpleNode() const {
  10222. return !rule_index && blueprint_index == INVALID_BP_ID &&
  10223. children.size() < 2 && param == ParamType::MAX &&
  10224. std::all_of(
  10225. std::begin(children), std::end(children),
  10226. [](const Node &x) { return x.param == ParamType::MAX; });
  10227. }
  10228. Node &add_child_node() {
  10229. children.emplace_back();
  10230. return children.back();
  10231. }
  10232. };
  10233. Trie() {}
  10234. /// Check whether or not the trie is empty.
  10235. bool is_empty() { return head_.children.empty(); }
  10236. void optimize() {
  10237. for (auto &child : head_.children) {
  10238. optimizeNode(child);
  10239. }
  10240. }
  10241. private:
  10242. void optimizeNode(Node &node) {
  10243. if (node.children.empty()) return;
  10244. if (node.IsSimpleNode()) {
  10245. auto children_temp = std::move(node.children);
  10246. auto &child_temp = children_temp[0];
  10247. node.key += child_temp.key;
  10248. node.rule_index = child_temp.rule_index;
  10249. node.blueprint_index = child_temp.blueprint_index;
  10250. node.children = std::move(child_temp.children);
  10251. optimizeNode(node);
  10252. } else {
  10253. for (auto &child : node.children) {
  10254. optimizeNode(child);
  10255. }
  10256. }
  10257. }
  10258. void debug_node_print(const Node &node, size_t level) {
  10259. if (node.param != ParamType::MAX) {
  10260. switch (node.param) {
  10261. case ParamType::INT:
  10262. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ "
  10263. << "<int>";
  10264. break;
  10265. case ParamType::UINT:
  10266. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ "
  10267. << "<uint>";
  10268. break;
  10269. case ParamType::DOUBLE:
  10270. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ "
  10271. << "<double>";
  10272. break;
  10273. case ParamType::STRING:
  10274. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ "
  10275. << "<string>";
  10276. break;
  10277. case ParamType::PATH:
  10278. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ "
  10279. << "<path>";
  10280. break;
  10281. default:
  10282. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ "
  10283. << "<ERROR>";
  10284. break;
  10285. }
  10286. } else
  10287. CROW_LOG_DEBUG << std::string(3 * level, ' ') << "└➝ " << node.key;
  10288. for (const auto &child : node.children) {
  10289. debug_node_print(child, level + 1);
  10290. }
  10291. }
  10292. public:
  10293. void debug_print() {
  10294. CROW_LOG_DEBUG << "└➙ ROOT";
  10295. for (const auto &child : head_.children)
  10296. debug_node_print(child, 1);
  10297. }
  10298. void validate() {
  10299. if (!head_.IsSimpleNode())
  10300. throw std::runtime_error("Internal error: Trie header should be simple!");
  10301. optimize();
  10302. }
  10303. // Rule_index, Blueprint_index, routing_params
  10304. routing_handle_result find(const std::string &req_url, const Node &node,
  10305. size_t pos = 0, routing_params *params = nullptr,
  10306. std::vector<size_t> *blueprints = nullptr) const {
  10307. // start params as an empty struct
  10308. routing_params empty;
  10309. if (params == nullptr) params = &empty;
  10310. // same for blueprint vector
  10311. std::vector<size_t> MT;
  10312. if (blueprints == nullptr) blueprints = &MT;
  10313. size_t found{}; // The rule index to be found
  10314. std::vector<size_t> found_BP; // The Blueprint indices to be found
  10315. routing_params match_params; // supposedly the final matched parameters
  10316. auto update_found = [&found, &found_BP,
  10317. &match_params](routing_handle_result &ret) {
  10318. found_BP = std::move(ret.blueprint_indices);
  10319. if (ret.rule_index && (!found || found > ret.rule_index)) {
  10320. found = ret.rule_index;
  10321. match_params = std::move(ret.r_params);
  10322. }
  10323. };
  10324. // if the function was called on a node at the end of the string (the last
  10325. // recursion), return the nodes rule index, and whatever params were passed
  10326. // to the function
  10327. if (pos == req_url.size()) {
  10328. found_BP = std::move(*blueprints);
  10329. return routing_handle_result{node.rule_index, *blueprints, *params};
  10330. }
  10331. bool found_fragment = false;
  10332. for (const auto &child : node.children) {
  10333. if (child.param != ParamType::MAX) {
  10334. if (child.param == ParamType::INT) {
  10335. char c = req_url[pos];
  10336. if ((c >= '0' && c <= '9') || c == '+' || c == '-') {
  10337. char *eptr;
  10338. errno = 0;
  10339. long long int value = strtoll(req_url.data() + pos, &eptr, 10);
  10340. if (errno != ERANGE && eptr != req_url.data() + pos) {
  10341. found_fragment = true;
  10342. params->int_params.push_back(value);
  10343. if (child.blueprint_index != INVALID_BP_ID)
  10344. blueprints->push_back(child.blueprint_index);
  10345. auto ret = find(req_url, child, eptr - req_url.data(), params,
  10346. blueprints);
  10347. update_found(ret);
  10348. params->int_params.pop_back();
  10349. if (!blueprints->empty()) blueprints->pop_back();
  10350. }
  10351. }
  10352. }
  10353. else if (child.param == ParamType::UINT) {
  10354. char c = req_url[pos];
  10355. if ((c >= '0' && c <= '9') || c == '+') {
  10356. char *eptr;
  10357. errno = 0;
  10358. unsigned long long int value =
  10359. strtoull(req_url.data() + pos, &eptr, 10);
  10360. if (errno != ERANGE && eptr != req_url.data() + pos) {
  10361. found_fragment = true;
  10362. params->uint_params.push_back(value);
  10363. if (child.blueprint_index != INVALID_BP_ID)
  10364. blueprints->push_back(child.blueprint_index);
  10365. auto ret = find(req_url, child, eptr - req_url.data(), params,
  10366. blueprints);
  10367. update_found(ret);
  10368. params->uint_params.pop_back();
  10369. if (!blueprints->empty()) blueprints->pop_back();
  10370. }
  10371. }
  10372. }
  10373. else if (child.param == ParamType::DOUBLE) {
  10374. char c = req_url[pos];
  10375. if ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.') {
  10376. char *eptr;
  10377. errno = 0;
  10378. double value = strtod(req_url.data() + pos, &eptr);
  10379. if (errno != ERANGE && eptr != req_url.data() + pos) {
  10380. found_fragment = true;
  10381. params->double_params.push_back(value);
  10382. if (child.blueprint_index != INVALID_BP_ID)
  10383. blueprints->push_back(child.blueprint_index);
  10384. auto ret = find(req_url, child, eptr - req_url.data(), params,
  10385. blueprints);
  10386. update_found(ret);
  10387. params->double_params.pop_back();
  10388. if (!blueprints->empty()) blueprints->pop_back();
  10389. }
  10390. }
  10391. }
  10392. else if (child.param == ParamType::STRING) {
  10393. size_t epos = pos;
  10394. for (; epos < req_url.size(); epos++) {
  10395. if (req_url[epos] == '/') break;
  10396. }
  10397. if (epos != pos) {
  10398. found_fragment = true;
  10399. params->string_params.push_back(req_url.substr(pos, epos - pos));
  10400. if (child.blueprint_index != INVALID_BP_ID)
  10401. blueprints->push_back(child.blueprint_index);
  10402. auto ret = find(req_url, child, epos, params, blueprints);
  10403. update_found(ret);
  10404. params->string_params.pop_back();
  10405. if (!blueprints->empty()) blueprints->pop_back();
  10406. }
  10407. }
  10408. else if (child.param == ParamType::PATH) {
  10409. size_t epos = req_url.size();
  10410. if (epos != pos) {
  10411. found_fragment = true;
  10412. params->string_params.push_back(req_url.substr(pos, epos - pos));
  10413. if (child.blueprint_index != INVALID_BP_ID)
  10414. blueprints->push_back(child.blueprint_index);
  10415. auto ret = find(req_url, child, epos, params, blueprints);
  10416. update_found(ret);
  10417. params->string_params.pop_back();
  10418. if (!blueprints->empty()) blueprints->pop_back();
  10419. }
  10420. }
  10421. }
  10422. else {
  10423. const std::string &fragment = child.key;
  10424. if (req_url.compare(pos, fragment.size(), fragment) == 0) {
  10425. found_fragment = true;
  10426. if (child.blueprint_index != INVALID_BP_ID)
  10427. blueprints->push_back(child.blueprint_index);
  10428. auto ret =
  10429. find(req_url, child, pos + fragment.size(), params, blueprints);
  10430. update_found(ret);
  10431. if (!blueprints->empty()) blueprints->pop_back();
  10432. }
  10433. }
  10434. }
  10435. if (!found_fragment) found_BP = std::move(*blueprints);
  10436. return routing_handle_result{
  10437. found, found_BP,
  10438. match_params}; // Called after all the recursions have been done
  10439. }
  10440. routing_handle_result find(const std::string &req_url) const {
  10441. return find(req_url, head_);
  10442. }
  10443. // This functions assumes any blueprint info passed is valid
  10444. void add(const std::string &url, size_t rule_index,
  10445. unsigned bp_prefix_length = 0,
  10446. size_t blueprint_index = INVALID_BP_ID) {
  10447. auto idx = &head_;
  10448. bool has_blueprint =
  10449. bp_prefix_length != 0 && blueprint_index != INVALID_BP_ID;
  10450. for (unsigned i = 0; i < url.size(); i++) {
  10451. char c = url[i];
  10452. if (c == '<') {
  10453. static struct ParamTraits {
  10454. ParamType type;
  10455. std::string name;
  10456. } paramTraits[] = {
  10457. {ParamType::INT, "<int>"}, {ParamType::UINT, "<uint>"},
  10458. {ParamType::DOUBLE, "<float>"}, {ParamType::DOUBLE, "<double>"},
  10459. {ParamType::STRING, "<str>"}, {ParamType::STRING, "<string>"},
  10460. {ParamType::PATH, "<path>"},
  10461. };
  10462. for (const auto &x : paramTraits) {
  10463. if (url.compare(i, x.name.size(), x.name) == 0) {
  10464. bool found = false;
  10465. for (auto &child : idx->children) {
  10466. if (child.param == x.type) {
  10467. idx = &child;
  10468. i += x.name.size();
  10469. found = true;
  10470. break;
  10471. }
  10472. }
  10473. if (found) break;
  10474. auto new_node_idx = &idx->add_child_node();
  10475. new_node_idx->param = x.type;
  10476. idx = new_node_idx;
  10477. i += x.name.size();
  10478. break;
  10479. }
  10480. }
  10481. i--;
  10482. } else {
  10483. // This part assumes the tree is unoptimized (every node has a max 1
  10484. // character key)
  10485. bool piece_found = false;
  10486. for (auto &child : idx->children) {
  10487. if (child.key[0] == c) {
  10488. idx = &child;
  10489. piece_found = true;
  10490. break;
  10491. }
  10492. }
  10493. if (!piece_found) {
  10494. auto new_node_idx = &idx->add_child_node();
  10495. new_node_idx->key = c;
  10496. // The assumption here is that you'd only need to add a blueprint
  10497. // index if the tree didn't have the BP prefix.
  10498. if (has_blueprint && i == bp_prefix_length)
  10499. new_node_idx->blueprint_index = blueprint_index;
  10500. idx = new_node_idx;
  10501. }
  10502. }
  10503. }
  10504. // check if the last node already has a value (exact url already in Trie)
  10505. if (idx->rule_index)
  10506. throw std::runtime_error("handler already exists for " + url);
  10507. idx->rule_index = rule_index;
  10508. }
  10509. private:
  10510. Node head_;
  10511. };
  10512. /// A blueprint can be considered a smaller section of a Crow app, specifically
  10513. /// where the router is concerned.
  10514. ///
  10515. /// You can use blueprints to assign a common prefix to rules' prefix, set
  10516. /// custom static and template folders, and set a custom catchall route. You can
  10517. /// also assign nest blueprints for maximum Compartmentalization.
  10518. class Blueprint {
  10519. public:
  10520. Blueprint(const std::string &prefix)
  10521. : prefix_(prefix), static_dir_(prefix), templates_dir_(prefix) {}
  10522. Blueprint(const std::string &prefix, const std::string &static_dir)
  10523. : prefix_(prefix), static_dir_(static_dir) {}
  10524. Blueprint(const std::string &prefix, const std::string &static_dir,
  10525. const std::string &templates_dir)
  10526. : prefix_(prefix), static_dir_(static_dir),
  10527. templates_dir_(templates_dir) {}
  10528. /*
  10529. Blueprint(Blueprint& other)
  10530. {
  10531. prefix_ = std::move(other.prefix_);
  10532. all_rules_ = std::move(other.all_rules_);
  10533. }
  10534. Blueprint(const Blueprint& other)
  10535. {
  10536. prefix_ = other.prefix_;
  10537. all_rules_ = other.all_rules_;
  10538. }
  10539. */
  10540. Blueprint(Blueprint &&value) { *this = std::move(value); }
  10541. Blueprint &operator=(const Blueprint &value) = delete;
  10542. Blueprint &operator=(Blueprint &&value) noexcept {
  10543. prefix_ = std::move(value.prefix_);
  10544. static_dir_ = std::move(value.static_dir_);
  10545. templates_dir_ = std::move(value.templates_dir_);
  10546. all_rules_ = std::move(value.all_rules_);
  10547. catchall_rule_ = std::move(value.catchall_rule_);
  10548. blueprints_ = std::move(value.blueprints_);
  10549. mw_indices_ = std::move(value.mw_indices_);
  10550. return *this;
  10551. }
  10552. bool operator==(const Blueprint &value) { return value.prefix() == prefix_; }
  10553. bool operator!=(const Blueprint &value) { return value.prefix() != prefix_; }
  10554. std::string prefix() const { return prefix_; }
  10555. std::string static_dir() const { return static_dir_; }
  10556. void set_added() { added_ = true; }
  10557. bool is_added() { return added_; }
  10558. DynamicRule &new_rule_dynamic(const std::string &rule) {
  10559. std::string new_rule = '/' + prefix_ + rule;
  10560. auto ruleObject = new DynamicRule(std::move(new_rule));
  10561. ruleObject->custom_templates_base = templates_dir_;
  10562. all_rules_.emplace_back(ruleObject);
  10563. return *ruleObject;
  10564. }
  10565. template <uint64_t N>
  10566. typename black_magic::arguments<N>::type::template rebind<TaggedRule> &
  10567. new_rule_tagged(const std::string &rule) {
  10568. std::string new_rule = '/' + prefix_ + rule;
  10569. using RuleT =
  10570. typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
  10571. auto ruleObject = new RuleT(std::move(new_rule));
  10572. ruleObject->custom_templates_base = templates_dir_;
  10573. all_rules_.emplace_back(ruleObject);
  10574. return *ruleObject;
  10575. }
  10576. void register_blueprint(Blueprint &blueprint) {
  10577. if (blueprints_.empty() || std::find(blueprints_.begin(), blueprints_.end(),
  10578. &blueprint) == blueprints_.end()) {
  10579. apply_blueprint(blueprint);
  10580. blueprints_.emplace_back(&blueprint);
  10581. } else
  10582. throw std::runtime_error("blueprint \"" + blueprint.prefix_ +
  10583. "\" already exists in blueprint \"" + prefix_ +
  10584. '\"');
  10585. }
  10586. CatchallRule &catchall_rule() { return catchall_rule_; }
  10587. template <typename App, typename... Middlewares> void middlewares() {
  10588. mw_indices_.push<App, Middlewares...>();
  10589. }
  10590. private:
  10591. void apply_blueprint(Blueprint &blueprint) {
  10592. blueprint.prefix_ = prefix_ + '/' + blueprint.prefix_;
  10593. blueprint.static_dir_ = static_dir_ + '/' + blueprint.static_dir_;
  10594. blueprint.templates_dir_ = templates_dir_ + '/' + blueprint.templates_dir_;
  10595. for (auto &rule : blueprint.all_rules_) {
  10596. std::string new_rule = '/' + prefix_ + rule->rule_;
  10597. rule->rule_ = new_rule;
  10598. }
  10599. for (Blueprint *bp_child : blueprint.blueprints_) {
  10600. Blueprint &bp_ref = *bp_child;
  10601. apply_blueprint(bp_ref);
  10602. }
  10603. }
  10604. std::string prefix_;
  10605. std::string static_dir_;
  10606. std::string templates_dir_;
  10607. std::vector<std::unique_ptr<BaseRule>> all_rules_;
  10608. CatchallRule catchall_rule_;
  10609. std::vector<Blueprint *> blueprints_;
  10610. detail::middleware_indices mw_indices_;
  10611. bool added_{false};
  10612. friend class Router;
  10613. };
  10614. /// Handles matching requests to existing rules and upgrade requests.
  10615. class Router {
  10616. public:
  10617. bool using_ssl;
  10618. Router() : using_ssl(false) {}
  10619. DynamicRule &new_rule_dynamic(const std::string &rule) {
  10620. auto ruleObject = new DynamicRule(rule);
  10621. all_rules_.emplace_back(ruleObject);
  10622. return *ruleObject;
  10623. }
  10624. template <uint64_t N>
  10625. typename black_magic::arguments<N>::type::template rebind<TaggedRule> &
  10626. new_rule_tagged(const std::string &rule) {
  10627. using RuleT =
  10628. typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
  10629. auto ruleObject = new RuleT(rule);
  10630. all_rules_.emplace_back(ruleObject);
  10631. return *ruleObject;
  10632. }
  10633. CatchallRule &catchall_rule() { return catchall_rule_; }
  10634. void internal_add_rule_object(const std::string &rule, BaseRule *ruleObject) {
  10635. internal_add_rule_object(rule, ruleObject, INVALID_BP_ID, blueprints_);
  10636. }
  10637. void internal_add_rule_object(const std::string &rule, BaseRule *ruleObject,
  10638. const size_t &BP_index,
  10639. std::vector<Blueprint *> &blueprints) {
  10640. bool has_trailing_slash = false;
  10641. std::string rule_without_trailing_slash;
  10642. if (rule.size() > 1 && rule.back() == '/') {
  10643. has_trailing_slash = true;
  10644. rule_without_trailing_slash = rule;
  10645. rule_without_trailing_slash.pop_back();
  10646. }
  10647. ruleObject->mw_indices_.pack();
  10648. ruleObject->foreach_method([&](int method) {
  10649. per_methods_[method].rules.emplace_back(ruleObject);
  10650. per_methods_[method].trie.add(
  10651. rule, per_methods_[method].rules.size() - 1,
  10652. BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length()
  10653. : 0,
  10654. BP_index);
  10655. // directory case:
  10656. // request to '/about' url matches '/about/' rule
  10657. if (has_trailing_slash) {
  10658. per_methods_[method].trie.add(
  10659. rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH,
  10660. BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length()
  10661. : 0,
  10662. BP_index);
  10663. }
  10664. });
  10665. ruleObject->set_added();
  10666. }
  10667. void register_blueprint(Blueprint &blueprint) {
  10668. if (std::find(blueprints_.begin(), blueprints_.end(), &blueprint) ==
  10669. blueprints_.end()) {
  10670. blueprints_.emplace_back(&blueprint);
  10671. } else
  10672. throw std::runtime_error("blueprint \"" + blueprint.prefix_ +
  10673. "\" already exists in router");
  10674. }
  10675. void get_recursive_child_methods(Blueprint *blueprint,
  10676. std::vector<HTTPMethod> &methods) {
  10677. // we only need to deal with children if the blueprint has absolutely no
  10678. // methods (meaning its index won't be added to the trie)
  10679. if (blueprint->static_dir_.empty() && blueprint->all_rules_.empty()) {
  10680. for (Blueprint *bp : blueprint->blueprints_) {
  10681. get_recursive_child_methods(bp, methods);
  10682. }
  10683. } else if (!blueprint->static_dir_.empty())
  10684. methods.emplace_back(HTTPMethod::Get);
  10685. for (auto &rule : blueprint->all_rules_) {
  10686. rule->foreach_method([&methods](unsigned method) {
  10687. HTTPMethod method_final = static_cast<HTTPMethod>(method);
  10688. if (std::find(methods.begin(), methods.end(), method_final) ==
  10689. methods.end())
  10690. methods.emplace_back(method_final);
  10691. });
  10692. }
  10693. }
  10694. void validate_bp() {
  10695. // Take all the routes from the registered blueprints and add them to
  10696. // `all_rules_` to be processed.
  10697. detail::middleware_indices blueprint_mw;
  10698. validate_bp(blueprints_, blueprint_mw);
  10699. }
  10700. void validate_bp(std::vector<Blueprint *> blueprints,
  10701. detail::middleware_indices &current_mw) {
  10702. for (unsigned i = 0; i < blueprints.size(); i++) {
  10703. Blueprint *blueprint = blueprints[i];
  10704. if (blueprint->is_added()) continue;
  10705. if (blueprint->static_dir_ == "" && blueprint->all_rules_.empty()) {
  10706. std::vector<HTTPMethod> methods;
  10707. get_recursive_child_methods(blueprint, methods);
  10708. for (HTTPMethod x : methods) {
  10709. int method_index = static_cast<int>(x);
  10710. per_methods_[method_index].trie.add(blueprint->prefix(), 0,
  10711. blueprint->prefix().length(),
  10712. method_index);
  10713. }
  10714. }
  10715. current_mw.merge_back(blueprint->mw_indices_);
  10716. for (auto &rule : blueprint->all_rules_) {
  10717. if (rule && !rule->is_added()) {
  10718. auto upgraded = rule->upgrade();
  10719. if (upgraded) rule = std::move(upgraded);
  10720. rule->validate();
  10721. rule->mw_indices_.merge_front(current_mw);
  10722. internal_add_rule_object(rule->rule(), rule.get(), i, blueprints);
  10723. }
  10724. }
  10725. validate_bp(blueprint->blueprints_, current_mw);
  10726. current_mw.pop_back(blueprint->mw_indices_);
  10727. blueprint->set_added();
  10728. }
  10729. }
  10730. void validate() {
  10731. for (auto &rule : all_rules_) {
  10732. if (rule && !rule->is_added()) {
  10733. auto upgraded = rule->upgrade();
  10734. if (upgraded) rule = std::move(upgraded);
  10735. rule->validate();
  10736. internal_add_rule_object(rule->rule(), rule.get());
  10737. }
  10738. }
  10739. for (auto &per_method : per_methods_) {
  10740. per_method.trie.validate();
  10741. }
  10742. }
  10743. // TODO maybe add actual_method
  10744. template <typename Adaptor>
  10745. void handle_upgrade(const request &req, response &res, Adaptor &&adaptor) {
  10746. if (req.method >= HTTPMethod::InternalMethodCount) return;
  10747. auto &per_method = per_methods_[static_cast<int>(req.method)];
  10748. auto &rules = per_method.rules;
  10749. size_t rule_index = per_method.trie.find(req.url).rule_index;
  10750. if (!rule_index) {
  10751. for (auto &method : per_methods_) {
  10752. if (method.trie.find(req.url).rule_index) {
  10753. CROW_LOG_DEBUG << "Cannot match method " << req.url << " "
  10754. << method_name(req.method);
  10755. res = response(405);
  10756. res.end();
  10757. return;
  10758. }
  10759. }
  10760. CROW_LOG_INFO << "Cannot match rules " << req.url;
  10761. res = response(404);
  10762. res.end();
  10763. return;
  10764. }
  10765. if (rule_index >= rules.size())
  10766. throw std::runtime_error("Trie internal structure corrupted!");
  10767. if (rule_index == RULE_SPECIAL_REDIRECT_SLASH) {
  10768. CROW_LOG_INFO << "Redirecting to a url with trailing slash: " << req.url;
  10769. res = response(301);
  10770. res.add_header("Location", req.url + "/");
  10771. res.end();
  10772. return;
  10773. }
  10774. CROW_LOG_DEBUG << "Matched rule (upgrade) '" << rules[rule_index]->rule_
  10775. << "' " << static_cast<uint32_t>(req.method) << " / "
  10776. << rules[rule_index]->get_methods();
  10777. try {
  10778. rules[rule_index]->handle_upgrade(req, res, std::move(adaptor));
  10779. } catch (...) {
  10780. exception_handler_(res);
  10781. res.end();
  10782. return;
  10783. }
  10784. }
  10785. void get_found_bp(const std::vector<size_t> &bp_i,
  10786. const std::vector<Blueprint *> &blueprints,
  10787. std::vector<Blueprint *> &found_bps, size_t index = 0) {
  10788. // This statement makes 3 assertions:
  10789. // 1. The index is above 0.
  10790. // 2. The index does not lie outside the given blueprint list.
  10791. // 3. The next blueprint we're adding has a prefix that starts the same as
  10792. // the already added blueprint + a slash (the rest is irrelevant).
  10793. //
  10794. // This is done to prevent a blueprint that has a prefix of "bp_prefix2" to
  10795. // be assumed as a child of one that has "bp_prefix".
  10796. //
  10797. // If any of the assertions is untrue, we delete the last item added, and
  10798. // continue using the blueprint list of the blueprint found before, the
  10799. // topmost being the router's list
  10800. auto verify_prefix = [&bp_i, &index, &blueprints, &found_bps]() {
  10801. return index > 0 && bp_i[index] < blueprints.size() &&
  10802. blueprints[bp_i[index]]
  10803. ->prefix()
  10804. .substr(0, found_bps[index - 1]->prefix().length() + 1)
  10805. .compare(std::string(found_bps[index - 1]->prefix() +
  10806. '/')) == 0;
  10807. };
  10808. if (index < bp_i.size()) {
  10809. if (verify_prefix()) {
  10810. found_bps.push_back(blueprints[bp_i[index]]);
  10811. get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
  10812. } else {
  10813. if (found_bps.size() < 2) {
  10814. found_bps.clear();
  10815. found_bps.push_back(blueprints_[bp_i[index]]);
  10816. } else {
  10817. found_bps.pop_back();
  10818. Blueprint *last_element = found_bps.back();
  10819. found_bps.push_back(last_element->blueprints_[bp_i[index]]);
  10820. }
  10821. get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
  10822. }
  10823. }
  10824. }
  10825. CatchallRule &get_catch_all(const routing_handle_result &found) {
  10826. std::vector<Blueprint *> bps_found;
  10827. get_found_bp(found.blueprint_indices, blueprints_, bps_found);
  10828. if (!bps_found.empty()) {
  10829. for (size_t i = bps_found.size() - 1; i > 0; i--) {
  10830. if (bps_found[i]->catchall_rule().has_handler()) {
  10831. return bps_found[i]->catchall_rule();
  10832. }
  10833. }
  10834. }
  10835. return catchall_rule_;
  10836. }
  10837. std::string get_error(const routing_handle_result &found) {
  10838. const std::string EMPTY;
  10839. std::vector<Blueprint *> bps_found;
  10840. get_found_bp(found.blueprint_indices, blueprints_, bps_found);
  10841. if (!bps_found.empty()) {
  10842. for (size_t i = bps_found.size() - 1; i > 0; i--) {
  10843. if (bps_found[i]->catchall_rule().has_handler()) {
  10844. #ifdef CROW_ENABLE_DEBUG
  10845. return std::string("Redirected to Blueprint \"" +
  10846. bps_found[i]->prefix() + "\" Catchall rule");
  10847. #else
  10848. return EMPTY;
  10849. #endif
  10850. }
  10851. }
  10852. } else if (catchall_rule_.has_handler()) {
  10853. #ifdef CROW_ENABLE_DEBUG
  10854. return std::string("Redirected to global Catchall rule");
  10855. #else
  10856. return EMPTY;
  10857. #endif
  10858. }
  10859. return EMPTY;
  10860. }
  10861. std::unique_ptr<routing_handle_result> handle_initial(request &req,
  10862. response &res) {
  10863. HTTPMethod method_actual = req.method;
  10864. std::unique_ptr<routing_handle_result> found{new routing_handle_result(
  10865. 0, std::vector<size_t>(), routing_params(),
  10866. HTTPMethod::InternalMethodCount)}; // This is always returned to avoid a
  10867. // null pointer dereference.
  10868. // NOTE(EDev): This most likely will never run since the parser should
  10869. // handle this situation and close the connection before it gets here.
  10870. if (CROW_UNLIKELY(req.method >= HTTPMethod::InternalMethodCount))
  10871. return found;
  10872. else if (req.method == HTTPMethod::Head) {
  10873. *found = per_methods_[static_cast<int>(method_actual)].trie.find(req.url);
  10874. // support HEAD requests using GET if not defined as method for the
  10875. // requested URL
  10876. if (!found->rule_index) {
  10877. method_actual = HTTPMethod::Get;
  10878. *found =
  10879. per_methods_[static_cast<int>(method_actual)].trie.find(req.url);
  10880. if (!found->rule_index) // If a route is still not found, return a 404
  10881. // without executing the rest of the HEAD
  10882. // specific code.
  10883. {
  10884. CROW_LOG_DEBUG << "Cannot match rules " << req.url;
  10885. res = response(404); // TODO(EDev): Should this redirect to catchall?
  10886. res.end();
  10887. return found;
  10888. }
  10889. }
  10890. res.skip_body = true;
  10891. found->method = method_actual;
  10892. return found;
  10893. } else if (req.method == HTTPMethod::Options) {
  10894. std::string allow = "OPTIONS, HEAD";
  10895. if (req.url == "/*") {
  10896. for (int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount);
  10897. i++) {
  10898. if (static_cast<int>(HTTPMethod::Head) == i)
  10899. continue; // HEAD is always allowed
  10900. if (!per_methods_[i].trie.is_empty()) {
  10901. allow.append(", ");
  10902. allow.append(method_name(static_cast<HTTPMethod>(i)));
  10903. }
  10904. }
  10905. #ifdef CROW_RETURNS_OK_ON_HTTP_OPTIONS_REQUEST
  10906. res = response(crow::status::OK);
  10907. #else
  10908. res = response(crow::status::NO_CONTENT);
  10909. #endif
  10910. res.set_header("Allow", allow);
  10911. res.end();
  10912. found->method = method_actual;
  10913. return found;
  10914. } else {
  10915. bool rules_matched = false;
  10916. for (int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount);
  10917. i++) {
  10918. if (per_methods_[i].trie.find(req.url).rule_index) {
  10919. rules_matched = true;
  10920. if (static_cast<int>(HTTPMethod::Head) == i)
  10921. continue; // HEAD is always allowed
  10922. allow.append(", ");
  10923. allow.append(method_name(static_cast<HTTPMethod>(i)));
  10924. }
  10925. }
  10926. if (rules_matched) {
  10927. #ifdef CROW_RETURNS_OK_ON_HTTP_OPTIONS_REQUEST
  10928. res = response(crow::status::OK);
  10929. #else
  10930. res = response(crow::status::NO_CONTENT);
  10931. #endif
  10932. res.set_header("Allow", allow);
  10933. res.end();
  10934. found->method = method_actual;
  10935. return found;
  10936. } else {
  10937. CROW_LOG_DEBUG << "Cannot match rules " << req.url;
  10938. res = response(404); // TODO(EDev): Should this redirect to catchall?
  10939. res.end();
  10940. return found;
  10941. }
  10942. }
  10943. } else // Every request that isn't a HEAD or OPTIONS request
  10944. {
  10945. *found = per_methods_[static_cast<int>(method_actual)].trie.find(req.url);
  10946. // TODO(EDev): maybe ending the else here would allow the requests coming
  10947. // from above (after removing the return statement) to be checked on
  10948. // whether they actually point to a route
  10949. if (!found->rule_index) {
  10950. for (auto &per_method : per_methods_) {
  10951. if (per_method.trie.find(req.url)
  10952. .rule_index) // Route found, but in another method
  10953. {
  10954. res.code = 405;
  10955. found->catch_all = true;
  10956. CROW_LOG_DEBUG << "Cannot match method " << req.url << " "
  10957. << method_name(method_actual) << ". "
  10958. << get_error(*found);
  10959. return found;
  10960. }
  10961. }
  10962. // Route does not exist anywhere
  10963. res.code = 404;
  10964. found->catch_all = true;
  10965. CROW_LOG_DEBUG << "Cannot match rules " << req.url << ". "
  10966. << get_error(*found);
  10967. return found;
  10968. }
  10969. found->method = method_actual;
  10970. return found;
  10971. }
  10972. }
  10973. template <typename App>
  10974. void handle(request &req, response &res, routing_handle_result found) {
  10975. if (found.catch_all) {
  10976. auto catch_all = get_catch_all(found);
  10977. if (catch_all.has_handler()) {
  10978. try {
  10979. catch_all.handler_(req, res);
  10980. } catch (...) { exception_handler_(res); }
  10981. }
  10982. res.end();
  10983. } else {
  10984. HTTPMethod method_actual = found.method;
  10985. const auto &rules = per_methods_[static_cast<int>(method_actual)].rules;
  10986. const size_t rule_index = found.rule_index;
  10987. if (rule_index >= rules.size())
  10988. throw std::runtime_error("Trie internal structure corrupted!");
  10989. if (rule_index == RULE_SPECIAL_REDIRECT_SLASH) {
  10990. CROW_LOG_INFO << "Redirecting to a url with trailing slash: "
  10991. << req.url;
  10992. res = response(301);
  10993. res.add_header("Location", req.url + "/");
  10994. res.end();
  10995. } else {
  10996. CROW_LOG_DEBUG << "Matched rule '" << rules[rule_index]->rule_ << "' "
  10997. << static_cast<uint32_t>(req.method) << " / "
  10998. << rules[rule_index]->get_methods();
  10999. try {
  11000. BaseRule &rule = *rules[rule_index];
  11001. handle_rule<App>(rule, req, res, found.r_params);
  11002. } catch (...) {
  11003. exception_handler_(res);
  11004. res.end();
  11005. }
  11006. }
  11007. }
  11008. }
  11009. template <typename App>
  11010. typename std::enable_if<
  11011. std::tuple_size<typename App::mw_container_t>::value != 0, void>::type
  11012. handle_rule(BaseRule &rule, crow::request &req, crow::response &res,
  11013. const crow::routing_params &rp) {
  11014. if (!rule.mw_indices_.empty()) {
  11015. auto &ctx =
  11016. *reinterpret_cast<typename App::context_t *>(req.middleware_context);
  11017. auto &container = *reinterpret_cast<typename App::mw_container_t *>(
  11018. req.middleware_container);
  11019. detail::middleware_call_criteria_dynamic<false> crit_fwd(
  11020. rule.mw_indices_.indices());
  11021. auto glob_completion_handler = std::move(res.complete_request_handler_);
  11022. res.complete_request_handler_ = [] {};
  11023. detail::middleware_call_helper<decltype(crit_fwd), 0,
  11024. typename App::context_t,
  11025. typename App::mw_container_t>(
  11026. crit_fwd, container, req, res, ctx);
  11027. if (res.completed_) {
  11028. glob_completion_handler();
  11029. return;
  11030. }
  11031. res.complete_request_handler_ = [&rule, &ctx, &container, &req, &res,
  11032. glob_completion_handler] {
  11033. detail::middleware_call_criteria_dynamic<true> crit_bwd(
  11034. rule.mw_indices_.indices());
  11035. detail::after_handlers_call_helper<
  11036. decltype(crit_bwd),
  11037. std::tuple_size<typename App::mw_container_t>::value - 1,
  11038. typename App::context_t, typename App::mw_container_t>(
  11039. crit_bwd, container, ctx, req, res);
  11040. glob_completion_handler();
  11041. };
  11042. }
  11043. rule.handle(req, res, rp);
  11044. }
  11045. template <typename App>
  11046. typename std::enable_if<
  11047. std::tuple_size<typename App::mw_container_t>::value == 0, void>::type
  11048. handle_rule(BaseRule &rule, crow::request &req, crow::response &res,
  11049. const crow::routing_params &rp) {
  11050. rule.handle(req, res, rp);
  11051. }
  11052. void debug_print() {
  11053. for (int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount);
  11054. i++) {
  11055. Trie &trie_ = per_methods_[i].trie;
  11056. if (!trie_.is_empty()) {
  11057. CROW_LOG_DEBUG << method_name(static_cast<HTTPMethod>(i));
  11058. trie_.debug_print();
  11059. }
  11060. }
  11061. }
  11062. std::vector<Blueprint *> &blueprints() { return blueprints_; }
  11063. std::function<void(crow::response &)> &exception_handler() {
  11064. return exception_handler_;
  11065. }
  11066. static void default_exception_handler(response &res) {
  11067. // any uncaught exceptions become 500s
  11068. res = response(500);
  11069. try {
  11070. throw;
  11071. } catch (const bad_request &e) {
  11072. res = response(400);
  11073. res.body = e.what();
  11074. } catch (const std::exception &e) {
  11075. CROW_LOG_ERROR << "An uncaught exception occurred: " << e.what();
  11076. } catch (...) {
  11077. CROW_LOG_ERROR << "An uncaught exception occurred. The type was unknown "
  11078. "so no information was available.";
  11079. }
  11080. }
  11081. private:
  11082. CatchallRule catchall_rule_;
  11083. struct PerMethod {
  11084. std::vector<BaseRule *> rules;
  11085. Trie trie;
  11086. // rule index 0, 1 has special meaning; preallocate it to avoid duplication.
  11087. PerMethod() : rules(2) {}
  11088. };
  11089. std::array<PerMethod, static_cast<int>(HTTPMethod::InternalMethodCount)>
  11090. per_methods_;
  11091. std::vector<std::unique_ptr<BaseRule>> all_rules_;
  11092. std::vector<Blueprint *> blueprints_;
  11093. std::function<void(crow::response &)> exception_handler_ =
  11094. &default_exception_handler;
  11095. };
  11096. } // namespace crow
  11097. namespace crow {
  11098. struct CORSHandler;
  11099. /// Used for tuning CORS policies
  11100. struct CORSRules {
  11101. friend struct crow::CORSHandler;
  11102. /// Set Access-Control-Allow-Origin. Default is "*"
  11103. CORSRules &origin(const std::string &origin) {
  11104. origin_ = origin;
  11105. return *this;
  11106. }
  11107. /// Set Access-Control-Allow-Methods. Default is "*"
  11108. CORSRules &methods(crow::HTTPMethod method) {
  11109. add_list_item(methods_, crow::method_name(method));
  11110. return *this;
  11111. }
  11112. /// Set Access-Control-Allow-Methods. Default is "*"
  11113. template <typename... Methods>
  11114. CORSRules &methods(crow::HTTPMethod method, Methods... method_list) {
  11115. add_list_item(methods_, crow::method_name(method));
  11116. methods(method_list...);
  11117. return *this;
  11118. }
  11119. /// Set Access-Control-Allow-Headers. Default is "*"
  11120. CORSRules &headers(const std::string &header) {
  11121. add_list_item(headers_, header);
  11122. return *this;
  11123. }
  11124. /// Set Access-Control-Allow-Headers. Default is "*"
  11125. template <typename... Headers>
  11126. CORSRules &headers(const std::string &header, Headers... header_list) {
  11127. add_list_item(headers_, header);
  11128. headers(header_list...);
  11129. return *this;
  11130. }
  11131. /// Set Access-Control-Expose-Headers. Default is none
  11132. CORSRules &expose(const std::string &header) {
  11133. add_list_item(exposed_headers_, header);
  11134. return *this;
  11135. }
  11136. /// Set Access-Control-Expose-Headers. Default is none
  11137. template <typename... Headers>
  11138. CORSRules &expose(const std::string &header, Headers... header_list) {
  11139. add_list_item(exposed_headers_, header);
  11140. expose(header_list...);
  11141. return *this;
  11142. }
  11143. /// Set Access-Control-Max-Age. Default is none
  11144. CORSRules &max_age(int max_age) {
  11145. max_age_ = std::to_string(max_age);
  11146. return *this;
  11147. }
  11148. /// Enable Access-Control-Allow-Credentials
  11149. CORSRules &allow_credentials() {
  11150. allow_credentials_ = true;
  11151. return *this;
  11152. }
  11153. /// Ignore CORS and don't send any headers
  11154. void ignore() { ignore_ = true; }
  11155. /// Handle CORS on specific prefix path
  11156. CORSRules &prefix(const std::string &prefix);
  11157. /// Handle CORS for specific blueprint
  11158. CORSRules &blueprint(const Blueprint &bp);
  11159. /// Global CORS policy
  11160. CORSRules &global();
  11161. private:
  11162. CORSRules() = delete;
  11163. CORSRules(CORSHandler *handler) : handler_(handler) {}
  11164. /// build comma separated list
  11165. void add_list_item(std::string &list, const std::string &val) {
  11166. if (list == "*") list = "";
  11167. if (list.size() > 0) list += ", ";
  11168. list += val;
  11169. }
  11170. /// Set header `key` to `value` if it is not set
  11171. void set_header_no_override(const std::string &key, const std::string &value,
  11172. crow::response &res) {
  11173. if (value.size() == 0) return;
  11174. if (!get_header_value(res.headers, key).empty()) return;
  11175. res.add_header(key, value);
  11176. }
  11177. /// Set response headers
  11178. void apply(const request &req, response &res) {
  11179. if (ignore_) return;
  11180. set_header_no_override("Access-Control-Allow-Methods", methods_, res);
  11181. set_header_no_override("Access-Control-Allow-Headers", headers_, res);
  11182. set_header_no_override("Access-Control-Expose-Headers", exposed_headers_,
  11183. res);
  11184. set_header_no_override("Access-Control-Max-Age", max_age_, res);
  11185. bool origin_set = false;
  11186. if (req.method != HTTPMethod::Options) {
  11187. if (allow_credentials_) {
  11188. set_header_no_override("Access-Control-Allow-Credentials", "true", res);
  11189. if (origin_ == "*") {
  11190. set_header_no_override("Access-Control-Allow-Origin",
  11191. req.get_header_value("Origin"), res);
  11192. origin_set = true;
  11193. }
  11194. }
  11195. }
  11196. if (!origin_set) {
  11197. set_header_no_override("Access-Control-Allow-Origin", origin_, res);
  11198. }
  11199. }
  11200. bool ignore_ = false;
  11201. // TODO: support multiple origins that are dynamically selected
  11202. std::string origin_ = "*";
  11203. std::string methods_ = "*";
  11204. std::string headers_ = "*";
  11205. std::string exposed_headers_;
  11206. std::string max_age_;
  11207. bool allow_credentials_ = false;
  11208. CORSHandler *handler_;
  11209. };
  11210. /// CORSHandler is a global middleware for setting CORS headers.
  11211. ///
  11212. /// By default, it sets Access-Control-Allow-Origin/Methods/Headers to "*".
  11213. /// The default behaviour can be changed with the `global()` cors rule.
  11214. /// Additional rules for prexies can be added with `prefix()`.
  11215. struct CORSHandler {
  11216. struct context {};
  11217. void before_handle(crow::request & /*req*/, crow::response & /*res*/,
  11218. context & /*ctx*/) {}
  11219. void after_handle(crow::request &req, crow::response &res,
  11220. context & /*ctx*/) {
  11221. auto &rule = find_rule(req.url);
  11222. rule.apply(req, res);
  11223. }
  11224. /// Handle CORS on a specific prefix path
  11225. CORSRules &prefix(const std::string &prefix) {
  11226. rules.emplace_back(prefix, CORSRules(this));
  11227. return rules.back().second;
  11228. }
  11229. /// Handle CORS for a specific blueprint
  11230. CORSRules &blueprint(const Blueprint &bp) {
  11231. rules.emplace_back(bp.prefix(), CORSRules(this));
  11232. return rules.back().second;
  11233. }
  11234. /// Get the global CORS policy
  11235. CORSRules &global() { return default_; }
  11236. private:
  11237. CORSRules &find_rule(const std::string &path) {
  11238. // TODO: use a trie in case of many rules
  11239. for (auto &rule : rules) {
  11240. // Check if path starts with a rules prefix
  11241. if (path.rfind(rule.first, 0) == 0) { return rule.second; }
  11242. }
  11243. return default_;
  11244. }
  11245. std::vector<std::pair<std::string, CORSRules>> rules;
  11246. CORSRules default_ = CORSRules(this);
  11247. };
  11248. inline CORSRules &CORSRules::prefix(const std::string &prefix) {
  11249. return handler_->prefix(prefix);
  11250. }
  11251. inline CORSRules &CORSRules::blueprint(const Blueprint &bp) {
  11252. return handler_->blueprint(bp);
  11253. }
  11254. inline CORSRules &CORSRules::global() { return handler_->global(); }
  11255. } // namespace crow
  11256. /**
  11257. * \file crow/app.h
  11258. * \brief This file includes the definition of the crow::Crow class,
  11259. * the crow::App and crow::SimpleApp aliases, and some macros.
  11260. *
  11261. * In this file are defined:
  11262. * - crow::Crow
  11263. * - crow::App
  11264. * - crow::SimpleApp
  11265. * - \ref CROW_ROUTE
  11266. * - \ref CROW_BP_ROUTE
  11267. * - \ref CROW_WEBSOCKET_ROUTE
  11268. * - \ref CROW_MIDDLEWARES
  11269. * - \ref CROW_CATCHALL_ROUTE
  11270. * - \ref CROW_BP_CATCHALL_ROUTE
  11271. */
  11272. #include <chrono>
  11273. #include <condition_variable>
  11274. #include <cstdint>
  11275. #include <functional>
  11276. #include <future>
  11277. #include <memory>
  11278. #include <string>
  11279. #include <thread>
  11280. #include <type_traits>
  11281. #ifdef CROW_ENABLE_COMPRESSION
  11282. #endif // #ifdef CROW_ENABLE_COMPRESSION
  11283. #ifdef CROW_MSVC_WORKAROUND
  11284. #define CROW_ROUTE(app, url) \
  11285. app.route_dynamic(url) // See the documentation in the comment below.
  11286. #define CROW_BP_ROUTE(blueprint, url) \
  11287. blueprint.new_rule_dynamic(url) // See the documentation in the comment below.
  11288. #else // #ifdef CROW_MSVC_WORKAROUND
  11289. /**
  11290. * \def CROW_ROUTE(app, url)
  11291. * \brief Creates a route for app using a rule.
  11292. *
  11293. * It use crow::Crow::route_dynamic or crow::Crow::route to define
  11294. * a rule for your application. It's usage is like this:
  11295. *
  11296. * ```cpp
  11297. * auto app = crow::SimpleApp(); // or crow::App()
  11298. * CROW_ROUTE(app, "/")
  11299. * ([](){
  11300. * return "<h1>Hello, world!</h1>";
  11301. * });
  11302. * ```
  11303. *
  11304. * This is the recommended way to define routes in a crow application.
  11305. * \see [Page of guide "Routes"](https://crowcpp.org/master/guides/routes/).
  11306. */
  11307. #define CROW_ROUTE(app, url) \
  11308. app.template route<crow::black_magic::get_parameter_tag(url)>(url)
  11309. /**
  11310. * \def CROW_BP_ROUTE(blueprint, url)
  11311. * \brief Creates a route for a blueprint using a rule.
  11312. *
  11313. * It may use crow::Blueprint::new_rule_dynamic or
  11314. * crow::Blueprint::new_rule_tagged to define a new rule for
  11315. * an given blueprint. It's usage is similar
  11316. * to CROW_ROUTE macro:
  11317. *
  11318. * ```cpp
  11319. * crow::Blueprint my_bp();
  11320. * CROW_BP_ROUTE(my_bp, "/")
  11321. * ([](){
  11322. * return "<h1>Hello, world!</h1>";
  11323. * });
  11324. * ```
  11325. *
  11326. * This is the recommended way to define routes in a crow blueprint
  11327. * because of its compile-time capabilities.
  11328. *
  11329. * \see [Page of the guide
  11330. * "Blueprints"](https://crowcpp.org/master/guides/blueprints/).
  11331. */
  11332. #define CROW_BP_ROUTE(blueprint, url) \
  11333. blueprint.new_rule_tagged<crow::black_magic::get_parameter_tag(url)>(url)
  11334. /**
  11335. * \def CROW_WEBSOCKET_ROUTE(app, url)
  11336. * \brief Defines WebSocket route for app.
  11337. *
  11338. * It binds a WebSocket route to app. Easy solution to implement
  11339. * WebSockets in your app. The usage syntax of this macro is
  11340. * like this:
  11341. *
  11342. * ```cpp
  11343. * auto app = crow::SimpleApp(); // or crow::App()
  11344. * CROW_WEBSOCKET_ROUTE(app, "/ws")
  11345. * .onopen([&](crow::websocket::connection& conn){
  11346. * do_something();
  11347. * })
  11348. * .onclose([&](crow::websocket::connection& conn, const std::string&
  11349. * reason, uint16_t){ do_something();
  11350. * })
  11351. * .onmessage([&](crow::websocket::connection&, const std::string& data,
  11352. * bool is_binary){ if (is_binary) do_something(data); else
  11353. * do_something_else(data);
  11354. * });
  11355. * ```
  11356. *
  11357. * \see [Page of the guide
  11358. * "WebSockets"](https://crowcpp.org/master/guides/websockets/).
  11359. */
  11360. #define CROW_WEBSOCKET_ROUTE(app, url) \
  11361. app.route<crow::black_magic::get_parameter_tag(url)>(url) \
  11362. .websocket<std::remove_reference<decltype(app)>::type>(&app)
  11363. /**
  11364. * \def CROW_MIDDLEWARES(app, ...)
  11365. * \brief Enable a Middleware for an specific route in app
  11366. * or blueprint.
  11367. *
  11368. * It defines the usage of a Middleware in one route. And it
  11369. * can be used in both crow::SimpleApp (and crow::App) instances and
  11370. * crow::Blueprint. Its usage syntax is like this:
  11371. *
  11372. * ```cpp
  11373. * auto app = crow::SimpleApp(); // or crow::App()
  11374. * CROW_ROUTE(app, "/with_middleware")
  11375. * .CROW_MIDDLEWARES(app, LocalMiddleware) // Can be used more than one
  11376. * ([]() { // middleware.
  11377. * return "Hello world!";
  11378. * });
  11379. * ```
  11380. *
  11381. * \see [Page of the guide
  11382. * "Middlewares"](https://crowcpp.org/master/guides/middleware/).
  11383. */
  11384. #define CROW_MIDDLEWARES(app, ...) \
  11385. template middlewares<typename std::remove_reference<decltype(app)>::type, \
  11386. __VA_ARGS__>()
  11387. #endif // #ifdef CROW_MSVC_WORKAROUND
  11388. /**
  11389. * \def CROW_CATCHALL_ROUTE(app)
  11390. * \brief Defines a custom catchall route for app using a
  11391. * custom rule.
  11392. *
  11393. * It defines a handler when the client make a request for an
  11394. * undefined route. Instead of just reply with a `404` status
  11395. * code (default behavior), you can define a custom handler
  11396. * using this macro.
  11397. *
  11398. * \see [Page of the guide "Routes" (Catchall
  11399. * routes)](https://crowcpp.org/master/guides/routes/#catchall-routes).
  11400. */
  11401. #define CROW_CATCHALL_ROUTE(app) app.catchall_route()
  11402. /**
  11403. * \def CROW_BP_CATCHALL_ROUTE(blueprint)
  11404. * \brief Defines a custom catchall route for blueprint
  11405. * using a custom rule.
  11406. *
  11407. * It defines a handler when the client make a request for an
  11408. * undefined route in the blueprint.
  11409. *
  11410. * \see [Page of the guide "Blueprint" (Define a custom Catchall
  11411. * route)](https://crowcpp.org/master/guides/blueprints/#define-a-custom-catchall-route).
  11412. */
  11413. #define CROW_BP_CATCHALL_ROUTE(blueprint) blueprint.catchall_rule()
  11414. /**
  11415. * \namespace crow
  11416. * \brief The main namespace of the library. In this namespace
  11417. * is defined the most important classes and functions of the
  11418. * library.
  11419. *
  11420. * Within this namespace, the Crow class, Router class, Connection
  11421. * class, and other are defined.
  11422. */
  11423. namespace crow {
  11424. #ifdef CROW_ENABLE_SSL
  11425. using ssl_context_t = asio::ssl::context;
  11426. #endif
  11427. /**
  11428. * \class Crow
  11429. * \brief The main server application class.
  11430. *
  11431. * Use crow::SimpleApp or crow::App<Middleware1, Middleware2, etc...> instead of
  11432. * directly instantiate this class.
  11433. */
  11434. template <typename... Middlewares> class Crow {
  11435. public:
  11436. /// \brief This is the crow application
  11437. using self_t = Crow;
  11438. /// \brief The HTTP server
  11439. using server_t = Server<Crow, TCPAcceptor, SocketAdaptor, Middlewares...>;
  11440. /// \brief An HTTP server that runs on unix domain socket
  11441. using unix_server_t =
  11442. Server<Crow, UnixSocketAcceptor, UnixSocketAdaptor, Middlewares...>;
  11443. #ifdef CROW_ENABLE_SSL
  11444. /// \brief An HTTP server that runs on SSL with an SSLAdaptor
  11445. using ssl_server_t = Server<Crow, TCPAcceptor, SSLAdaptor, Middlewares...>;
  11446. #endif
  11447. Crow() {}
  11448. /// \brief Construct Crow with a subset of middleware
  11449. template <typename... Ts>
  11450. Crow(Ts &&...ts)
  11451. : middlewares_(make_middleware_tuple(std::forward<Ts>(ts)...)) {}
  11452. /// \brief Process an Upgrade request
  11453. ///
  11454. /// Currently used to upgrade an HTTP connection to a WebSocket connection
  11455. template <typename Adaptor>
  11456. void handle_upgrade(const request &req, response &res, Adaptor &&adaptor) {
  11457. router_.handle_upgrade(req, res, adaptor);
  11458. }
  11459. /// \brief Process only the method and URL of a request and provide a route
  11460. /// (or an error response)
  11461. std::unique_ptr<routing_handle_result> handle_initial(request &req,
  11462. response &res) {
  11463. return router_.handle_initial(req, res);
  11464. }
  11465. /// \brief Process the fully parsed request and generate a response for it
  11466. void handle(request &req, response &res,
  11467. std::unique_ptr<routing_handle_result> &found) {
  11468. router_.handle<self_t>(req, res, *found);
  11469. }
  11470. /// \brief Process a fully parsed request from start to finish (primarily used
  11471. /// for debugging)
  11472. void handle_full(request &req, response &res) {
  11473. auto found = handle_initial(req, res);
  11474. if (found->rule_index || found->catch_all) handle(req, res, found);
  11475. }
  11476. /// \brief Create a dynamic route using a rule (**Use CROW_ROUTE instead**)
  11477. DynamicRule &route_dynamic(const std::string &rule) {
  11478. return router_.new_rule_dynamic(rule);
  11479. }
  11480. /// \brief Create a route using a rule (**Use CROW_ROUTE instead**)
  11481. template <uint64_t Tag>
  11482. auto route(const std::string &rule) ->
  11483. typename std::invoke_result<decltype(&Router::new_rule_tagged<Tag>),
  11484. Router, const std::string &>::type {
  11485. return router_.new_rule_tagged<Tag>(rule);
  11486. }
  11487. /// \brief Create a route for any requests without a proper route (**Use
  11488. /// CROW_CATCHALL_ROUTE instead**)
  11489. CatchallRule &catchall_route() { return router_.catchall_rule(); }
  11490. /// \brief Set the default max payload size for websockets
  11491. self_t &websocket_max_payload(uint64_t max_payload) {
  11492. max_payload_ = max_payload;
  11493. return *this;
  11494. }
  11495. /// \brief Get the default max payload size for websockets
  11496. uint64_t websocket_max_payload() { return max_payload_; }
  11497. self_t &signal_clear() {
  11498. signals_.clear();
  11499. return *this;
  11500. }
  11501. self_t &signal_add(int signal_number) {
  11502. signals_.push_back(signal_number);
  11503. return *this;
  11504. }
  11505. std::vector<int> signals() { return signals_; }
  11506. /// \brief Set the port that Crow will handle requests on
  11507. self_t &port(std::uint16_t port) {
  11508. port_ = port;
  11509. return *this;
  11510. }
  11511. /// \brief Get the port that Crow will handle requests on
  11512. std::uint16_t port() const {
  11513. if (!server_started_) { return port_; }
  11514. #ifdef CROW_ENABLE_SSL
  11515. if (ssl_used_) {
  11516. return ssl_server_->port();
  11517. } else
  11518. #endif
  11519. {
  11520. return server_->port();
  11521. }
  11522. }
  11523. /// \brief Set status variable to note that the address that Crow will handle
  11524. /// requests on is bound
  11525. void address_is_bound() { is_bound_ = true; }
  11526. /// \brief Get whether address that Crow will handle requests on is bound
  11527. bool is_bound() const { return is_bound_; }
  11528. /// \brief Set the connection timeout in seconds (default is 5)
  11529. self_t &timeout(std::uint8_t timeout) {
  11530. timeout_ = timeout;
  11531. return *this;
  11532. }
  11533. /// \brief Set the server name included in the 'Server' HTTP response header.
  11534. /// If set to an empty string, the header will be omitted by default.
  11535. self_t &server_name(std::string server_name) {
  11536. server_name_ = server_name;
  11537. return *this;
  11538. }
  11539. /// \brief The IP address that Crow will handle requests on (default is
  11540. /// 0.0.0.0)
  11541. self_t &bindaddr(std::string bindaddr) {
  11542. bindaddr_ = bindaddr;
  11543. return *this;
  11544. }
  11545. /// \brief Get the address that Crow will handle requests on
  11546. std::string bindaddr() { return bindaddr_; }
  11547. /// \brief Disable tcp/ip and use unix domain socket instead
  11548. self_t &local_socket_path(std::string path) {
  11549. bindaddr_ = path;
  11550. use_unix_ = true;
  11551. return *this;
  11552. }
  11553. /// \brief Get the unix domain socket path
  11554. std::string local_socket_path() { return bindaddr_; }
  11555. /// \brief Run the server on multiple threads using all available threads
  11556. self_t &multithreaded() {
  11557. return concurrency(std::thread::hardware_concurrency());
  11558. }
  11559. /// \brief Run the server on multiple threads using a specific number
  11560. self_t &concurrency(unsigned int concurrency) {
  11561. if (concurrency < 2) // Crow can have a minimum of 2 threads running
  11562. concurrency = 2;
  11563. concurrency_ = concurrency;
  11564. return *this;
  11565. }
  11566. /// \brief Get the number of threads that server is using
  11567. std::uint16_t concurrency() const { return concurrency_; }
  11568. /// \brief Set the server's log level
  11569. ///
  11570. /// Possible values are:
  11571. /// - crow::LogLevel::Debug (0)
  11572. /// - crow::LogLevel::Info (1)
  11573. /// - crow::LogLevel::Warning (2)
  11574. /// - crow::LogLevel::Error (3)
  11575. /// - crow::LogLevel::Critical (4)
  11576. self_t &loglevel(LogLevel level) {
  11577. crow::logger::setLogLevel(level);
  11578. return *this;
  11579. }
  11580. /// \brief Set the response body size (in bytes) beyond which Crow
  11581. /// automatically streams responses (Default is 1MiB)
  11582. ///
  11583. /// Any streamed response is unaffected by Crow's timer, and therefore won't
  11584. /// timeout before a response is fully sent.
  11585. self_t &stream_threshold(size_t threshold) {
  11586. res_stream_threshold_ = threshold;
  11587. return *this;
  11588. }
  11589. /// \brief Get the response body size (in bytes) beyond which Crow
  11590. /// automatically streams responses
  11591. size_t &stream_threshold() { return res_stream_threshold_; }
  11592. self_t &register_blueprint(Blueprint &blueprint) {
  11593. router_.register_blueprint(blueprint);
  11594. return *this;
  11595. }
  11596. /// \brief Set the function to call to handle uncaught exceptions generated in
  11597. /// routes (Default generates error 500).
  11598. ///
  11599. /// The function must have the following signature: void(crow::response&).
  11600. /// It must set the response passed in argument to the function, which will be
  11601. /// sent back to the client. See Router::default_exception_handler() for the
  11602. /// default implementation.
  11603. template <typename Func> self_t &exception_handler(Func &&f) {
  11604. router_.exception_handler() = std::forward<Func>(f);
  11605. return *this;
  11606. }
  11607. std::function<void(crow::response &)> &exception_handler() {
  11608. return router_.exception_handler();
  11609. }
  11610. /// \brief Set a custom duration and function to run on every tick
  11611. template <typename Duration, typename Func> self_t &tick(Duration d, Func f) {
  11612. tick_interval_ = std::chrono::duration_cast<std::chrono::milliseconds>(d);
  11613. tick_function_ = f;
  11614. return *this;
  11615. }
  11616. #ifdef CROW_ENABLE_COMPRESSION
  11617. self_t &use_compression(compression::algorithm algorithm) {
  11618. comp_algorithm_ = algorithm;
  11619. compression_used_ = true;
  11620. return *this;
  11621. }
  11622. compression::algorithm compression_algorithm() { return comp_algorithm_; }
  11623. bool compression_used() const { return compression_used_; }
  11624. #endif
  11625. /// \brief Apply blueprints
  11626. void add_blueprint() {
  11627. #if defined(__APPLE__) || defined(__MACH__)
  11628. if (router_.blueprints().empty()) return;
  11629. #endif
  11630. for (Blueprint *bp : router_.blueprints()) {
  11631. if (bp->static_dir().empty()) {
  11632. CROW_LOG_ERROR
  11633. << "Blueprint " << bp->prefix()
  11634. << " and its sub-blueprints ignored due to empty static directory.";
  11635. continue;
  11636. }
  11637. auto static_dir_ = crow::utility::normalize_path(bp->static_dir());
  11638. bp->new_rule_tagged<crow::black_magic::get_parameter_tag(
  11639. CROW_STATIC_ENDPOINT)>(CROW_STATIC_ENDPOINT)(
  11640. [static_dir_](crow::response &res, std::string file_path_partial) {
  11641. utility::sanitize_filename(file_path_partial);
  11642. res.set_static_file_info_unsafe(static_dir_ + file_path_partial);
  11643. res.end();
  11644. });
  11645. }
  11646. router_.validate_bp();
  11647. }
  11648. /// \brief Go through the rules, upgrade them if possible, and add them to the
  11649. /// list of rules
  11650. void add_static_dir() {
  11651. if (are_static_routes_added()) return;
  11652. auto static_dir_ = crow::utility::normalize_path(CROW_STATIC_DIRECTORY);
  11653. route<crow::black_magic::get_parameter_tag(CROW_STATIC_ENDPOINT)>(
  11654. CROW_STATIC_ENDPOINT)(
  11655. [static_dir_](crow::response &res, std::string file_path_partial) {
  11656. utility::sanitize_filename(file_path_partial);
  11657. res.set_static_file_info_unsafe(static_dir_ + file_path_partial);
  11658. res.end();
  11659. });
  11660. set_static_routes_added();
  11661. }
  11662. /// \brief A wrapper for `validate()` in the router
  11663. void validate() { router_.validate(); }
  11664. /// \brief Run the server
  11665. void run() {
  11666. #ifndef CROW_DISABLE_STATIC_DIR
  11667. add_blueprint();
  11668. add_static_dir();
  11669. #endif
  11670. validate();
  11671. #ifdef CROW_ENABLE_SSL
  11672. if (ssl_used_) {
  11673. error_code ec;
  11674. asio::ip::address addr = asio::ip::make_address(bindaddr_, ec);
  11675. if (ec) {
  11676. CROW_LOG_ERROR << ec.message()
  11677. << " - Can not create valid ip address from string: \""
  11678. << bindaddr_ << "\"";
  11679. return;
  11680. }
  11681. tcp::endpoint endpoint(addr, port_);
  11682. router_.using_ssl = true;
  11683. ssl_server_ = std::move(std::unique_ptr<ssl_server_t>(
  11684. new ssl_server_t(this, endpoint, server_name_, &middlewares_,
  11685. concurrency_, timeout_, &ssl_context_)));
  11686. ssl_server_->set_tick_function(tick_interval_, tick_function_);
  11687. ssl_server_->signal_clear();
  11688. for (auto snum : signals_) {
  11689. ssl_server_->signal_add(snum);
  11690. }
  11691. notify_server_start();
  11692. ssl_server_->run();
  11693. } else
  11694. #endif
  11695. {
  11696. if (use_unix_) {
  11697. UnixSocketAcceptor::endpoint endpoint(bindaddr_);
  11698. unix_server_ = std::move(std::unique_ptr<unix_server_t>(
  11699. new unix_server_t(this, endpoint, server_name_, &middlewares_,
  11700. concurrency_, timeout_, nullptr)));
  11701. unix_server_->set_tick_function(tick_interval_, tick_function_);
  11702. for (auto snum : signals_) {
  11703. unix_server_->signal_add(snum);
  11704. }
  11705. notify_server_start();
  11706. unix_server_->run();
  11707. } else {
  11708. error_code ec;
  11709. asio::ip::address addr = asio::ip::make_address(bindaddr_, ec);
  11710. if (ec) {
  11711. CROW_LOG_ERROR << ec.message()
  11712. << " - Can not create valid ip address from string: \""
  11713. << bindaddr_ << "\"";
  11714. return;
  11715. }
  11716. TCPAcceptor::endpoint endpoint(addr, port_);
  11717. server_ = std::move(std::unique_ptr<server_t>(
  11718. new server_t(this, endpoint, server_name_, &middlewares_,
  11719. concurrency_, timeout_, nullptr)));
  11720. server_->set_tick_function(tick_interval_, tick_function_);
  11721. for (auto snum : signals_) {
  11722. server_->signal_add(snum);
  11723. }
  11724. notify_server_start();
  11725. server_->run();
  11726. }
  11727. }
  11728. }
  11729. /// \brief Non-blocking version of \ref run()
  11730. ///
  11731. /// The output from this method needs to be saved into a variable!
  11732. /// Otherwise the call will be made on the same thread.
  11733. std::future<void> run_async() {
  11734. return std::async(std::launch::async, [&] { this->run(); });
  11735. }
  11736. /// \brief Stop the server
  11737. void stop() {
  11738. #ifdef CROW_ENABLE_SSL
  11739. if (ssl_used_) {
  11740. if (ssl_server_) { ssl_server_->stop(); }
  11741. } else
  11742. #endif
  11743. {
  11744. close_websockets();
  11745. if (server_) { server_->stop(); }
  11746. if (unix_server_) { unix_server_->stop(); }
  11747. }
  11748. }
  11749. void close_websockets() {
  11750. std::lock_guard<std::mutex> lock{websockets_mutex_};
  11751. for (auto websocket : websockets_) {
  11752. CROW_LOG_INFO << "Quitting Websocket: " << websocket;
  11753. websocket->close("Websocket Closed");
  11754. }
  11755. }
  11756. void add_websocket(std::shared_ptr<websocket::connection> conn) {
  11757. std::lock_guard<std::mutex> lock{websockets_mutex_};
  11758. websockets_.push_back(conn);
  11759. }
  11760. void remove_websocket(std::shared_ptr<websocket::connection> conn) {
  11761. std::lock_guard<std::mutex> lock{websockets_mutex_};
  11762. websockets_.erase(std::remove(websockets_.begin(), websockets_.end(), conn),
  11763. websockets_.end());
  11764. }
  11765. /// \brief Print the routing paths defined for each HTTP method
  11766. void debug_print() {
  11767. CROW_LOG_DEBUG << "Routing:";
  11768. router_.debug_print();
  11769. }
  11770. #ifdef CROW_ENABLE_SSL
  11771. /// \brief Use certificate and key files for SSL
  11772. self_t &ssl_file(const std::string &crt_filename,
  11773. const std::string &key_filename) {
  11774. ssl_used_ = true;
  11775. ssl_context_.set_verify_mode(asio::ssl::verify_peer);
  11776. ssl_context_.set_verify_mode(asio::ssl::verify_client_once);
  11777. ssl_context_.use_certificate_file(crt_filename, ssl_context_t::pem);
  11778. ssl_context_.use_private_key_file(key_filename, ssl_context_t::pem);
  11779. ssl_context_.set_options(asio::ssl::context::default_workarounds |
  11780. asio::ssl::context::no_sslv2 |
  11781. asio::ssl::context::no_sslv3);
  11782. return *this;
  11783. }
  11784. /// \brief Use `.pem` file for SSL
  11785. self_t &ssl_file(const std::string &pem_filename) {
  11786. ssl_used_ = true;
  11787. ssl_context_.set_verify_mode(asio::ssl::verify_peer);
  11788. ssl_context_.set_verify_mode(asio::ssl::verify_client_once);
  11789. ssl_context_.load_verify_file(pem_filename);
  11790. ssl_context_.set_options(asio::ssl::context::default_workarounds |
  11791. asio::ssl::context::no_sslv2 |
  11792. asio::ssl::context::no_sslv3);
  11793. return *this;
  11794. }
  11795. /// \brief Use certificate chain and key files for SSL
  11796. self_t &ssl_chainfile(const std::string &crt_filename,
  11797. const std::string &key_filename) {
  11798. ssl_used_ = true;
  11799. ssl_context_.set_verify_mode(asio::ssl::verify_peer);
  11800. ssl_context_.set_verify_mode(asio::ssl::verify_client_once);
  11801. ssl_context_.use_certificate_chain_file(crt_filename);
  11802. ssl_context_.use_private_key_file(key_filename, ssl_context_t::pem);
  11803. ssl_context_.set_options(asio::ssl::context::default_workarounds |
  11804. asio::ssl::context::no_sslv2 |
  11805. asio::ssl::context::no_sslv3);
  11806. return *this;
  11807. }
  11808. self_t &ssl(asio::ssl::context &&ctx) {
  11809. ssl_used_ = true;
  11810. ssl_context_ = std::move(ctx);
  11811. return *this;
  11812. }
  11813. bool ssl_used() const { return ssl_used_; }
  11814. #else
  11815. template <typename T, typename... Remain>
  11816. self_t &ssl_file(T &&, Remain &&...) {
  11817. // We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
  11818. static_assert(
  11819. // make static_assert dependent to T; always false
  11820. std::is_base_of<T, void>::value,
  11821. "Define CROW_ENABLE_SSL to enable ssl support.");
  11822. return *this;
  11823. }
  11824. template <typename T, typename... Remain>
  11825. self_t &ssl_chainfile(T &&, Remain &&...) {
  11826. // We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
  11827. static_assert(
  11828. // make static_assert dependent to T; always false
  11829. std::is_base_of<T, void>::value,
  11830. "Define CROW_ENABLE_SSL to enable ssl support.");
  11831. return *this;
  11832. }
  11833. template <typename T> self_t &ssl(T &&) {
  11834. // We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
  11835. static_assert(
  11836. // make static_assert dependent to T; always false
  11837. std::is_base_of<T, void>::value,
  11838. "Define CROW_ENABLE_SSL to enable ssl support.");
  11839. return *this;
  11840. }
  11841. bool ssl_used() const { return false; }
  11842. #endif
  11843. // middleware
  11844. using context_t = detail::context<Middlewares...>;
  11845. using mw_container_t = std::tuple<Middlewares...>;
  11846. template <typename T> typename T::context &get_context(const request &req) {
  11847. static_assert(black_magic::contains<T, Middlewares...>::value,
  11848. "App doesn't have the specified middleware type.");
  11849. auto &ctx = *reinterpret_cast<context_t *>(req.middleware_context);
  11850. return ctx.template get<T>();
  11851. }
  11852. template <typename T> T &get_middleware() {
  11853. return utility::get_element_by_type<T, Middlewares...>(middlewares_);
  11854. }
  11855. /// \brief Wait until the server has properly started
  11856. std::cv_status wait_for_server_start(std::chrono::milliseconds wait_timeout =
  11857. std::chrono::milliseconds(3000)) {
  11858. std::cv_status status = std::cv_status::no_timeout;
  11859. auto wait_until = std::chrono::steady_clock::now() + wait_timeout;
  11860. {
  11861. std::unique_lock<std::mutex> lock(start_mutex_);
  11862. while (!server_started_ && (status == std::cv_status::no_timeout)) {
  11863. status = cv_started_.wait_until(lock, wait_until);
  11864. }
  11865. }
  11866. if (status == std::cv_status::no_timeout) {
  11867. if (server_) {
  11868. status = server_->wait_for_start(wait_until);
  11869. } else if (unix_server_) {
  11870. status = unix_server_->wait_for_start(wait_until);
  11871. }
  11872. #ifdef CROW_ENABLE_SSL
  11873. else if (ssl_server_) {
  11874. status = ssl_server_->wait_for_start(wait_until);
  11875. }
  11876. #endif
  11877. }
  11878. return status;
  11879. }
  11880. private:
  11881. template <typename... Ts>
  11882. std::tuple<Middlewares...> make_middleware_tuple(Ts &&...ts) {
  11883. auto fwd = std::forward_as_tuple((ts)...);
  11884. return std::make_tuple(std::forward<Middlewares>(
  11885. black_magic::tuple_extract<Middlewares, decltype(fwd)>(fwd))...);
  11886. }
  11887. /// \brief Notify anything using \ref wait_for_server_start() to proceed
  11888. void notify_server_start() {
  11889. std::unique_lock<std::mutex> lock(start_mutex_);
  11890. server_started_ = true;
  11891. cv_started_.notify_all();
  11892. }
  11893. void set_static_routes_added() { static_routes_added_ = true; }
  11894. bool are_static_routes_added() { return static_routes_added_; }
  11895. private:
  11896. std::uint8_t timeout_{5};
  11897. uint16_t port_ = 80;
  11898. unsigned int concurrency_ = 2;
  11899. std::atomic_bool is_bound_ = false;
  11900. uint64_t max_payload_{UINT64_MAX};
  11901. std::string server_name_ = std::string("Crow/") + VERSION;
  11902. std::string bindaddr_ = "0.0.0.0";
  11903. bool use_unix_ = false;
  11904. size_t res_stream_threshold_ = 1048576;
  11905. Router router_;
  11906. bool static_routes_added_{false};
  11907. #ifdef CROW_ENABLE_COMPRESSION
  11908. compression::algorithm comp_algorithm_;
  11909. bool compression_used_{false};
  11910. #endif
  11911. std::chrono::milliseconds tick_interval_;
  11912. std::function<void()> tick_function_;
  11913. std::tuple<Middlewares...> middlewares_;
  11914. #ifdef CROW_ENABLE_SSL
  11915. std::unique_ptr<ssl_server_t> ssl_server_;
  11916. bool ssl_used_{false};
  11917. ssl_context_t ssl_context_{asio::ssl::context::sslv23};
  11918. #endif
  11919. std::unique_ptr<server_t> server_;
  11920. std::unique_ptr<unix_server_t> unix_server_;
  11921. std::vector<int> signals_{SIGINT, SIGTERM};
  11922. bool server_started_{false};
  11923. std::condition_variable cv_started_;
  11924. std::mutex start_mutex_;
  11925. std::mutex websockets_mutex_; ///< \brief mutex to protect websockets_
  11926. std::vector<std::shared_ptr<websocket::connection>> websockets_;
  11927. };
  11928. /// \brief Alias of Crow<Middlewares...>. Useful if you want
  11929. /// a instance of an Crow application that require Middlewares
  11930. template <typename... Middlewares> using App = Crow<Middlewares...>;
  11931. /// \brief Alias of Crow<>. Useful if you want a instance of
  11932. /// an Crow application that doesn't require of Middlewares
  11933. using SimpleApp = Crow<>;
  11934. } // namespace crow