package Ġws . os iris . local server Ċ Ċ import Ġcom . be ust . j command er . Parameter Ċ import Ġorg . eclipse . jetty . server . Handler Ċ import Ġorg . eclipse . jetty . server . Server Ċ import Ġorg . eclipse . jetty . server . handler . Context Handler Ċ import Ġorg . eclipse . jetty . server . handler . Handler List Ċ import Ġorg . eclipse . jetty . server . handler . Resource Handler Ċ import Ġorg . eclipse . jetty . servlet . ServletContext Handler Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġws . os iris . core . Api Ċ import Ġws . os iris . core . Components Provider Ċ import Ġws . os iris . core . ContentType Ċ import Ġws . os iris . core . Headers Ċ import Ġws . os iris . core . HttpHeaders Ċ import Ġws . os iris . core . HttpMethod Ċ import Ġws . os iris . core . Params Ċ import Ġws . os iris . core . Request Ċ import Ġws . os iris . core . RequestContext Factory Ċ import Ġws . os iris . core . Route Node Ċ import Ġws . os iris . core . Static Route Ċ import Ġws . os iris . core . match Ċ import Ġjava . io . BufferedReader Ċ import Ġjava . io . InputStream Reader Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . util . stream . Collectors . join ing Ċ import Ġjavax . servlet . Servlet Config Ċ import Ġjavax . servlet . http . HttpServlet Ċ import Ġjavax . servlet . http . HttpServletRequest Ċ import Ġjavax . servlet . http . HttpServletResponse Ċ Ċ private Ġval Ġlog Ġ= ĠLoggerFactory . getLogger (" ws . os iris . local server ") Ċ Ċ class ĠOs iris Servlet < T Ġ: ĠComponents Provider > Ġ: ĠHttpServlet () Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġroute Tree : ĠRoute Node < T > ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcomponents : ĠT ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġrequest Context Factory : ĠRequest Context Factory ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġbinary Mime Types : ĠSet < String > ĊĊĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠ Ġoverride Ġfun Ġinit ( config : ĠServlet Config ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprovided Api Ġ= Ġconfig . servlet Context . getAttribute ( API _ ATTRIBUTE ) Ġas ĠApi < T >? Ġ?: ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" The ĠApi Ġinstance Ġmust Ġbe Ġa Ġservlet Ġcontext Ġattribute Ġkey ed Ġwith Ġ$ API _ ATTRIBUTE ") ĊĠĠĠĠĠĠĠ Ġval Ġprovided Components Ġ= Ġconfig . servlet Context . getAttribute ( COMPONENTS _ ATTRIBUTE ) ĊĠĠĠĠĠĠĠ Ġval Ġcontext Factory Ġ= Ġconfig . servlet Context . getAttribute ( REQUEST _ CONTEXT _ FACTORY _ ATTRIBUTE ) ĊĠĠĠĠĠĠĠ Ġroute Tree Ġ= ĠRoute Node . create ( provided Api ) ĊĠĠĠĠĠĠĠ Ġcomponents Ġ= Ġprovided Components Ġas ĠT ĊĠĠĠĠĠĠĠ Ġrequest Context Factory Ġ= Ġcontext Factory Ġas ĠRequest Context Factory ĊĠĠĠĠĠĠĠ Ġbinary Mime Types Ġ= Ġprovided Api . binary Mime Types ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġservice ( req : ĠHttpServletRequest , Ġresp : ĠHttpServletResponse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmethod Ġ= ĠHttpMethod . valueOf ( req . method ) ĊĠĠĠĠĠĠĠ Ġval Ġpath Ġ= Ġreq . path Info ĊĠĠĠĠĠĠĠ Ġval ĠqueryParams Ġ= ĠParams . from QueryString ( req . queryString ) ĊĠĠĠĠĠĠĠ Ġval Ġmatch Ġ= Ġroute Tree . match ( method , Ġpath ) ĊĠĠĠĠĠĠĠ Ġif Ġ( match Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresp . write ( 4 0 4 , ĠHeaders (), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġheader Map Ġ= Ġreq . header Names . iterator (). as Sequence (). associate With Ġ{ Ġreq . getHeader ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġheaders Ġ= ĠParams ( header Map ) ĊĠĠĠĠĠĠĠ Ġval ĠpathParams Ġ= ĠParams ( match . vars ) ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġrequest Body ( header Map , Ġreq ) ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= Ġrequest Context Factory . create Context ( method , Ġpath , Ġheaders , ĠqueryParams , ĠpathParams , Ġbody ) ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest ( method , Ġpath , Ġheaders , ĠqueryParams , ĠpathParams , Ġcontext , Ġbody ) ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġmatch . handler . invoke ( components , Ġrequest ) ĊĠĠĠĠĠĠĠ Ġresp . write ( response . status , Ġresponse . headers , Ġresponse . body ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrequest Body ( headers : ĠMap < String , ĠString >, Ġreq : ĠHttpServletRequest ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠcontentType Ġ= Ġheaders [ HttpHeaders . CONTENT _ TYPE ] Ġ?: Ġreturn Ġreq . body AsString () ĊĠĠĠĠĠĠĠ Ġval Ġ( mime Type , Ġ_) Ġ= ĠContentType . parse ( contentType ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( binary Mime Types . contains ( mime Type )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreq . inputStream . use Ġ{ Ġit . read Bytes () Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreq . body AsString () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠServlet Config . init Param ( name : ĠString ): ĠString Ġ= ĊĠĠĠĠĠĠĠ Ġget Init Parameter ( name ) Ġ?: Ġthrow ĠIllegalArgumentException (" Missing Ġinit Ġparam Ġ$ name ") ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ/** ĠThe Ġattribute Ġname Ġused Ġfor Ġstoring Ġthe Ġ[ Api ] Ġinstance Ġin Ġthe Ġ` ServletContext `. Ġ*/ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠAPI _ ATTRIBUTE Ġ= Ġ" api " ĊĊĠĠĠĠĠĠĠ Ġ/** ĠThe Ġattribute Ġname Ġused Ġfor Ġstoring Ġthe Ġ[ Components Provider ] Ġinstance Ġin Ġthe Ġ` ServletContext `. Ġ*/ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠCOMPONENT S _ ATTRIBUTE Ġ= Ġ" components " ĊĊĠĠĠĠĠĠĠ Ġ/** ĠThe Ġattribute Ġname Ġused Ġfor Ġstoring Ġthe Ġ[ RequestContext Factory ] Ġinstance Ġin Ġthe Ġ` ServletContext `. Ġ*/ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠREQUEST _ CONTEXT _ FACTORY _ ATTRIBUTE Ġ= Ġ" request Context Factory " ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠHttpServletRequest . body AsString (): ĠString Ġ= ĊĠĠĠ ĠBufferedReader ( InputStream Reader ( inputStream , Ġcharacter Encoding Ġ?: Ġ" UTF - 8 ")). lines (). collect ( join ing ("\ n ")) Ċ Ċ private Ġfun ĠHttpServletResponse . write ( http Status : ĠInt , Ġheaders : ĠHeaders , Ġbody : ĠAny ?) Ġ{ ĊĠĠĠ Ġstatus Ġ= Ġhttp Status ĊĠĠĠ Ġheaders . header Map . forEach Ġ{ Ġ( name , Ġvalue ) Ġ-> Ġadd Header ( name , Ġvalue ) Ġ} ĊĠĠĠ Ġwhen Ġ( body ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠString Ġ-> ĠoutputStream . writer (). use Ġ{ Ġit . write ( body ) Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠByteArray Ġ-> ĠoutputStream . use Ġ{ Ġit . write ( body ) Ġ} ĊĠĠĠĠĠĠĠ Ġnull Ġ-> Ġreturn ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Unexpected Ġbody Ġtype Ġ${ body . java Class . name }, Ġneed ĠString Ġor ĠByteArray ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRuns Ġa Ġvery Ġbasic ĠJet ty Ġserver Ġrunning Ġon Ġthe Ġspecified Ġport Ġthat Ġserves Ġ[ Os iris Servlet ] Ġfrom Ġthe Ġroot . Ċ Ġ* Ċ Ġ* ĠThis Ġis Ġa Ġconvenience Ġmethod Ġfor Ġrunning Ġa Ġlocal Ġserver Ġfrom Ġa Ġ` main ` Ġmethod . ĠThe Ġimplementation Ċ Ġ* Ġruns Ġand Ġjoins Ġthe Ġserver , Ġso Ġthe Ġmethod Ġnever Ġreturns Ġand Ġthe Ġserver Ġcan Ġonly Ġbe Ġstopped Ġby Ġk illing Ċ Ġ* Ġthe Ġprocess . Ċ Ġ* Ċ Ġ* ĠThe Ġ` context Root ` Ġargument Ġcontrols Ġthe ĠURL Ġon Ġwhich Ġthe ĠAPI Ġis Ġavailable . ĠBy Ġdefault Ġthe ĠAPI Ġis Ċ Ġ* Ġavailable Ġat : Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// localhost : 8 0 8 0 / Ċ Ġ* Ċ Ġ* ĠIf Ġ` context Root ` Ġis Ġ`/ foo ` Ġthen Ġthe ĠAPI Ġwould Ġbe Ġavailable Ġat : Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// localhost : 8 0 8 0 / foo / Ċ Ġ*/ Ċ fun Ġ< T Ġ: ĠComponents Provider > Ġrun Local Server ( ĊĠĠĠ Ġapi : ĠApi < T >, ĊĠĠĠ Ġcomponents : ĠT , ĊĠĠĠ Ġport : ĠInt Ġ= Ġ 8 0 8 0 , ĊĠĠĠ Ġcontext Root : ĠString Ġ= Ġ"", ĊĠĠĠ Ġstatic Files Dir : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġrequest Context Factory : ĠRequest Context Factory Ġ= ĠRequest Context Factory . empty () Ċ ) Ġ{ ĊĊĠĠĠ Ġval Ġserver Ġ= Ġcreate Local Server ( api , Ġcomponents , Ġport , Ġcontext Root , Ġstatic Files Dir , Ġrequest Context Factory ) ĊĠĠĠ Ġserver . start () ĊĠĠĠ Ġlog . info (" Server Ġstarted Ġat Ġhttp :// localhost :{} {} /", Ġport , Ġcontext Root ) ĊĠĠĠ Ġserver . join () Ċ } Ċ Ċ internal Ġfun Ġ< T Ġ: ĠComponents Provider > Ġcreate Local Server ( ĊĠĠĠ Ġapi : ĠApi < T >, ĊĠĠĠ Ġcomponents : ĠT , ĊĠĠĠ Ġport : ĠInt Ġ= Ġ 8 0 8 0 , ĊĠĠĠ Ġcontext Root : ĠString Ġ= Ġ"", ĊĠĠĠ Ġstatic Files Dir : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġrequest Context Factory : ĠRequest Context Factory Ġ= ĠRequest Context Factory . empty () Ċ ): ĠServer Ġ{ ĊĊĠĠĠ Ġval Ġserver Ġ= ĠServer ( port ) ĊĠĠĠ Ġval Ġservlet Context Handler Ġ= ĠServlet Context Handler () ĊĠĠĠ Ġservlet Context Handler . context Path Ġ= Ġ"/" ĊĠĠĠ Ġservlet Context Handler . add Servlet ( Os iris Servlet :: class . java , Ġ"$ context Root /* ") ĊĠĠĠ Ġservlet Context Handler . setAttribute ( Os iris Servlet . API _ ATTRIBUTE , Ġapi ) ĊĠĠĠ Ġservlet Context Handler . setAttribute ( Os iris Servlet . COMPONENTS _ ATTRIBUTE , Ġcomponents ) ĊĠĠĠ Ġservlet Context Handler . setAttribute ( Os iris Servlet . REQUEST _ CONTEXT _ FACTORY _ ATTRIBUTE , Ġrequest Context Factory ) ĊĠĠĠ Ġserver . handler Ġ= Ġconfigure Static Files ( api , Ġservlet Context Handler , Ġcontext Root , Ġstatic Files Dir ) ĊĠĠĠ Ġreturn Ġserver Ċ } Ċ Ċ //---------------------------------------------------------------- -------------------------------- -- Ċ Ċ private Ġfun Ġconfigure Static Files ( ĊĠĠĠ Ġapi : ĠApi <* >, ĊĠĠĠ Ġservlet Handler : ĠServlet Context Handler , ĊĠĠĠ Ġcontext Root : ĠString , ĊĠĠĠ Ġstatic Files Dir : ĠString ? Ċ ): ĠHandler Ġ{ ĊĊĠĠĠ Ġval Ġstatic Routes Ġ= Ġapi . routes . filter Is Instance ( Static Route :: class . java ) ĊĠĠĠ Ġ// ĠTODO Ġlift Ġthis Ġrestriction ĊĠĠĠ Ġif Ġ( static Routes . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Only Ġone Ġstatic Ġfile Ġpath Ġis Ġsupported ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġif Ġ( api . static Files ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( static Files Dir Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" No Ġstatic Ġfile Ġlocation Ġspecified ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ĠDon 't Ġuse ĠResource Handler ĊĠĠĠĠĠĠĠ Ġ// Ġhttps :// github . com / per wen del / spark / issues / 3 1 6 ĊĠĠĠĠĠĠĠ Ġval Ġresource Handler Ġ= ĠResource Handler () ĊĠĠĠĠĠĠĠ Ġval Ġstatic Route Ġ= Ġstatic Routes [ 0 ] ĊĠĠĠĠĠĠĠ Ġstatic Route . index File ?. let Ġ{ Ġresource Handler . welcome Files Ġ= ĠarrayOf ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġresource Handler . resource Base Ġ= Ġstatic Files Dir ĊĠĠĠĠĠĠĠ Ġval Ġcontext Handler Ġ= ĠContext Handler ( context Root Ġ+ Ġstatic Route . path ) ĊĠĠĠĠĠĠĠ Ġcontext Handler . handler Ġ= Ġresource Handler ĊĠĠĠĠĠĠĠ Ġlog . info (" Ser ving Ġstatic Ġfiles Ġfrom Ġ{}", ĠPaths . get ( static Files Dir ). normalize (). to AbsolutePath ()) ĊĠĠĠĠĠĠĠ ĠHandler List ( context Handler , Ġservlet Handler ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . debug (" API Ġdoes Ġnot Ġcontain Ġstatic Ġfiles , Ġskipping Ġstatic Ġfiles Ġconfiguration ") ĊĠĠĠĠĠĠĠ Ġservlet Handler ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠThe Ġarguments Ġneeded Ġto Ġrun Ġa Ġlocal Ġserver ; Ġpopulated Ġby ĠJ Command er Ġfrom Ġthe Ġcommand - line . Ċ Ġ*/ Ċ class ĠServer Args Ġ{ ĊĊĠĠĠ Ġ@ Parameter ( names Ġ= Ġ[" - p ", Ġ"-- port "]) ĊĠĠĠ Ġvar Ġport Ġ= Ġ 8 0 8 0 ĊĊĠĠĠ Ġ@ Parameter ( names Ġ= Ġ[" - r ", Ġ"-- root "]) ĊĠĠĠ Ġvar Ġroot Ġ= Ġ"" Ċ } Ċ