/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 ĠNet E ase , ĠInc . Ġ ĠAll Ġrights Ġreserved . Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġa ĠMIT Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ġ*/ Ċ Ċ package Ġcom . net ease . yun xin . app . wis dom . edu . logic . net . service Ċ Ċ import Ġcom . google . gson . Gson Ċ import Ġcom . net ease . nim lib . sdk . pas sthrough . model . Pas sthrough Proxy Data Ċ import Ġcom . net ease . yun xin . app . wis dom . base . network . Ret rofit Manager Ċ import Ġokhttp 3 . internal . and Ċ import Ġok io . Buffer Ċ import Ġretrofit 2 . http .* Ċ import Ġjava . lang . reflect . Method Ċ import Ġjava . lang . reflect . Type Ċ import Ġjava . util . regex . Pattern Ċ Ċ /** Ċ Ġ* ĠCreated Ġby Ġh z sun yj Ġon Ġ 2 0 2 1 / 5 / 2 7 . Ċ Ġ*/ Ċ class ĠPas sthrough Data Factory Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPARAM Ġ= Ġ"[ a - zA - Z ][ a - zA - Z 0 - 9 _- ]* " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPATH _ SEGMENT _ ALWAYS _ ENCODE _ SET Ġ= Ġ" Ġ\" <> ^ ` {} | \\ ? #" ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠPARAM _ URL _ REGEX Ġ= ĠPattern . compile ("\\ { (${ Companion . PARAM }) \\ }") ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠPATH _ TRA VERSAL Ġ= ĠPattern . compile (" (. */ )? (\\ .| % 2 e |% 2 E ){ 1 , 2 } (/ .* )? ") ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠHEX _ DIG ITS Ġ= Ġchar ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ' 0 ', Ġ' 1 ', Ġ' 2 ', Ġ' 3 ', Ġ' 4 ', Ġ' 5 ', Ġ' 6 ', Ġ' 7 ', Ġ' 8 ', Ġ' 9 ', Ġ' A ', Ġ' B ', Ġ' C ', Ġ' D ', Ġ' E ', Ġ' F ' ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġgson : ĠGson Ġ= ĠGson () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġlateinit Ġvar Ġmethod : ĠMethod ĊĠĠĠ Ġlateinit Ġvar Ġargs : ĠArray < out ĠAny > ĊĠĠĠ Ġlateinit Ġvar Ġmethod Annotations : ĠArray < Annotation > ĊĠĠĠ Ġlateinit Ġvar Ġparameter Annotations Array : ĠArray < Array < Annotation >> ĊĠĠĠ Ġlateinit Ġvar Ġparameter Types : ĠArray < Type > ĊĠĠĠ Ġprivate Ġvar Ġhttp Method : ĠInt Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġhas Body : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġrelative Url : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġbody : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġbuilder ( method : ĠMethod , Ġargs : ĠArray < out ĠAny >): ĠPas sthrough Proxy Data Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . method Ġ= Ġmethod ĊĠĠĠĠĠĠĠ Ġthis . args Ġ= Ġargs ĊĠĠĠĠĠĠĠ Ġthis . method Annotations Ġ= Ġmethod . annotations ĊĠĠĠĠĠĠĠ Ġthis . parameter Types Ġ= Ġmethod . generic Parameter Types ĊĠĠĠĠĠĠĠ Ġthis . parameter Annotations Array Ġ= Ġmethod . parameter Annotations ĊĠĠĠĠĠĠĠ Ġmethod Annotations . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparse Method Annotation ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġparse Parameter () ĊĠĠĠĠĠĠĠ Ġreturn ĠPas sthrough Proxy Data ( relative Url , Ġhttp Method , Ġget Header (), Ġbody ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Header (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġgson . toJson ( Ret rofit Manager . instance (). getHeader ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Parameter () Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcount Ġ= Ġparameter Annotations Array . size ĊĠĠĠĠĠĠĠ Ġfor Ġ( index Ġin Ġ 0 Ġuntil Ġcount ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Annotations Array [ index ]. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse Parameter Annotation ( index , Ġparameter Types [ index ], Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Parameter Annotation ( index : ĠInt , Ġtype : ĠType , Ġannotation : ĠAnnotation ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( annotation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPath Ġ-> Ġadd Path Param ( annotation . value , Ġargs [ index ]. toString (), Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBody Ġ-> Ġparse Body ( args [ index ]) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Body ( arg : ĠAny ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbody Ġ= Ġgson . toJson ( arg ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Method Annotation ( annotation : ĠAnnotation ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( annotation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDELETE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse HttpMethod And Path ( Pas sthrough Proxy Data . Method . DELETE , Ġannotation . value , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠGET Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse HttpMethod And Path ( Pas sthrough Proxy Data . Method . GET , Ġannotation . value , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPOST Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse HttpMethod And Path ( Pas sthrough Proxy Data . Method . POST , Ġannotation . value , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPUT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse HttpMethod And Path ( Pas sthrough Proxy Data . Method . PUT , Ġannotation . value , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Path Param ( name : ĠString , Ġvalue : ĠString , Ġencoded : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( relative Url Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġrelative ĠURL Ġis Ġcleared Ġwhen Ġthe Ġfirst Ġquery Ġparameter Ġis Ġset . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAssertionError () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġreplacement Ġ= Ġcanonical ize For Path ( value , Ġencoded ) ĊĠĠĠĠĠĠĠ Ġval Ġnew Relative Url Ġ= Ġrelative Url !!. replace (" {$ name }", Ġreplacement ) ĊĠĠĠĠĠĠĠ Ġrequire (! PATH _ TRA VERSAL . matcher ( new Relative Url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. matches ()) Ġ{ Ġ"@ Path Ġparameters Ġshouldn 't Ġperform Ġpath Ġtraversal Ġ( '. ' Ġor Ġ'.. '): Ġ$ value " Ġ} ĊĠĠĠĠĠĠĠ Ġrelative Url Ġ= Ġnew Relative Url ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcanonical ize For Path ( input : ĠString , Ġalready Encoded : ĠBoolean ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcode Point : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġlimit Ġ= Ġinput . length ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġlimit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcode Point Ġ= Ġinput . code Point At ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( code Point Ġ< Ġ 0 x 2 0 Ġ|| Ġcode Point Ġ>= Ġ 0 x 7 f Ġ|| ĠComp anion . PATH _ SEGMENT _ ALWAYS _ ENCODE _ SET . indexOf ( code Point . to Char ()) Ġ!= Ġ- 1 Ġ|| Ġ! already Encoded Ġ&& Ġ( code Point Ġ== Ġ'/ '. toInt () Ġ|| Ġcode Point Ġ== Ġ'% '. toInt ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠS low Ġpath : Ġthe Ġcharacter Ġat Ġi Ġrequires Ġencoding ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠBuffer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . write Utf 8 ( input , Ġ 0 , Ġi ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanonical ize For Path ( out , Ġinput , Ġi , Ġlimit , Ġalready Encoded ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġout . read Utf 8 () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi Ġ+= ĠCharacter . char Count ( code Point ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠFast Ġpath : Ġno Ġcharacters Ġrequired Ġencoding . ĊĠĠĠĠĠĠĠ Ġreturn Ġinput ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcanonical ize For Path ( out : ĠBuffer , Ġinput : ĠString , Ġpos : ĠInt , Ġlimit : ĠInt , Ġalready Encoded : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġutf 8 Buffer : ĠBuffer ? Ġ= Ġnull Ġ// ĠL az ily Ġallocated . ĊĠĠĠĠĠĠĠ Ġvar Ġcode Point : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġpos ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġlimit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcode Point Ġ= Ġinput . code Point At ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( already Encoded Ġ&& Ġ( code Point Ġ== Ġ'\ t '. toInt () Ġ|| Ġcode Point Ġ== Ġ'\ n '. toInt () Ġ|| Ġcode Point Ġ== Ġ'\ r '. toInt ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSkip Ġthis Ġcharacter . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( code Point Ġ< Ġ 0 x 2 0 Ġ|| Ġcode Point Ġ>= Ġ 0 x 7 f Ġ|| ĠComp anion . PATH _ SEGMENT _ ALWAYS _ ENCODE _ SET . indexOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Point . to Char ()) Ġ!= Ġ- 1 Ġ|| Ġ! already Encoded Ġ&& Ġ( code Point Ġ== Ġ'/ '. toInt () Ġ|| Ġcode Point Ġ== Ġ'% '. toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPercent Ġencode Ġthis Ġcharacter . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( utf 8 Buffer Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġutf 8 Buffer Ġ= ĠBuffer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġutf 8 Buffer . write Utf 8 Code Point ( code Point ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ(! utf 8 Buffer . ex hausted ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġb : ĠInt Ġ= Ġutf 8 Buffer . read Byte () Ġand Ġ 0 xff ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . write Byte ('% '. toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . write Byte ( HEX _ DIG ITS [ b Ġshr Ġ 4 Ġand Ġ 0 xf ]. toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . write Byte ( HEX _ DIG ITS [ b Ġand Ġ 0 xf ]. toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġcharacter Ġdoesn 't Ġneed Ġencoding . ĠJust Ġcopy Ġit Ġover . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . write Utf 8 Code Point ( code Point ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi Ġ+= ĠCharacter . char Count ( code Point ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġparse HttpMethod And Path ( http Method : ĠInt , Ġvalue : ĠString , Ġhas Body : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( this . http Method Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Only Ġone ĠHTTP Ġmethod Ġis Ġallowed " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . http Method Ġ= Ġhttp Method ĊĠĠĠĠĠĠĠ Ġthis . has Body Ġ= Ġhas Body ĊĠĠĠĠĠĠĠ Ġif Ġ( value . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġrelative ĠURL Ġpath Ġand Ġexisting Ġquery Ġstring , Ġif Ġpresent . ĊĠĠĠĠĠĠĠ Ġval Ġquestion Ġ= Ġvalue . indexOf (' ?') ĊĠĠĠĠĠĠĠ Ġif Ġ( question Ġ!= Ġ- 1 Ġ&& Ġquestion Ġ< Ġvalue . length Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthe Ġquery Ġstring Ġdoes Ġnot Ġhave Ġany Ġnamed Ġparameters . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠqueryParams Ġ= Ġvalue . substring ( question Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġquery Param Matcher Ġ= ĠPARAM _ URL _ REGEX . matcher ( queryParams ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( query Param Matcher . find ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( false ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" URL Ġquery Ġstring Ġ\"% s \" Ġmust Ġnot Ġhave Ġreplace Ġblock . ĠFor Ġdynamic Ġquery Ġparameters Ġuse Ġ@ Query ." ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . relative Url Ġ= Ġvalue ĊĠĠĠ Ġ} Ċ } Ċ