package Ġorg . fe up . c mov . acme client . di Ċ Ċ import Ġcom . google . gson . Gson Builder Ċ import Ġdagger . Module Ċ import Ġdagger . Provides Ċ import Ġdagger . h ilt . Install In Ċ import Ġdagger . h ilt . android . components . Application Component Ċ import Ġkotlinx . coroutines . flow . first Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġok io . Buffer Ċ import Ġorg . fe up . c mov . acme client . data . WebService Ċ import Ġorg . fe up . c mov . acme client . data . api . details . ApiResponse Adapter Factory Ċ import Ġorg . fe up . c mov . acme client . utils . Cache Ċ import Ġorg . fe up . c mov . acme client . utils . Crypto Ċ import Ġorg . fe up . c mov . acme client . utils . WEB _ SERVICE _ URL Ċ import Ġretrofit 2 . Invocation Ċ import Ġretrofit 2 . Ret rofit Ċ import Ġretrofit 2 . converter . gson . Gson Converter Factory Ċ import Ġjava . time . Zone Offset Ċ import Ġjava . time . Z onedDateTime Ċ import Ġjava . time . format . DateTime Formatter Ċ import Ġjava . util .* Ċ import Ġjavax . inject . Singleton Ċ Ċ @ Module Ċ @ Install In ( Application Component :: class ) Ċ object ĠWeb Service Module Ġ{ ĊĊĠĠĠ Ġ@ Singleton ĊĠĠĠ Ġ@ Provides ĊĠĠĠ Ġfun Ġprovide WebService (): ĠWeb Service Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠhttpClient Ġ= ĠOk HttpClient . Builder () ĊĠĠĠĠĠĠĠ ĠhttpClient . add Interceptor Ġ{ Ġchain Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= Ġchain . request () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġauthenticated Request Ġ= Ġrequest . tag ( Invocation :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . method () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . getAnnotation ( WebService . Companion . Authenticated Request :: class . java ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( authenticated Request Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Request Ġ= Ġrequest . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠBuffer () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCached Ġuser ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcached User Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCache . cached User . first () !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFull Ġpath ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġrequest . url (). url () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfull Path Ġ= Ġurl . path Ġ+ Ġif Ġ( url . query Ġ!= Ġnull ) Ġ(" ?" Ġ+ Ġurl . query ) Ġelse Ġ"" ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTimestamp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtimestamp Ġ= ĠDateTime Formatter ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. of Pattern (" EEE , Ġdd ĠM MM Ġy yyy ĠHH : mm : ss ĠO ", ĠLocale . EN GL ISH ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. format ( Z onedDateTime . now ( Zone Offset . UTC )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġdata Ġto Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer . write ( cached User . userId . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. write ( fullPath . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. write ( timestamp . toByteArray ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . body ()?. writeTo ( buffer ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsignature Ġ= ĠCrypto . sign ( cached User . username , Ġbuffer ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer . close () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Request . add Header (" Date ", Ġtimestamp ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Request . add Header (" User - Signature ", Ġ"${ cached User . userId }: $ signature ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ add Interceptor Ġchain . proceed ( new Request . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain . proceed ( request ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠRet rofit . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. baseUrl ( WEB _ SERVICE _ URL ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Converter Factory ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGson Converter Factory . create ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGson Builder (). exclude Fields Without Expose Annotation (). create () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Call Adapter Factory ( ApiResponse Adapter Factory ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. client ( httpClient . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. create ( WebService :: class . java ) ĊĠĠĠ Ġ} Ċ }