@@ -10,15 +10,17 @@ import Control.Monad.IO.Class
1010import Data.ByteString (ByteString)
1111import Data.Kind
1212import Data.Proxy
13−import Network.Wai
13+import qualified Data.Sequence as Seq
14+import qualified Network.Wai as Wai
1415import Servant.API
16+import Servant.Client.Core
1517import Servant.Server
1618import Servant.Server.Internal
1719
1820-- | Types to use in you API description
1921data RequestTracking
2022
21−type family TrackingData :: Type -> Type
23+type family TrackingData a
2224
2325-- | Same as above, except no argument is passed to a handler.
2426data RequestTracking_
@@ -38,12 +40,22 @@ instance forall (api :: Type) context.
3840 hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt . s
3941
4042 route _ context subserver = route (Proxy :: Proxy api) context (subserver `addHeaderCheck` withRequest trackingCheck)
41− where trackingCheck :: Request -> DelayedIO (TrackingData RequestTracking)
43+ where trackingCheck :: Wai.Request -> DelayedIO (TrackingData RequestTracking)
4244 trackingCheck = either delayedFailFatal return <=< liftIO . runHandler . trackingHandler
43− trackingHandler :: Request -> Handler (TrackingData RequestTracking)
45+ trackingHandler :: Wai.Request -> Handler (TrackingData RequestTracking)
4446 trackingHandler = let ReqtrackingHandler h = getContextEntry context
4547 in h . parseTrackingHeaders
4648
49+instance HasClient m api => HasClient m (RequestTracking :> api) where
50+ type Client m (RequestTracking :> api) = Maybe ReqtrackInfo -> Client m api
51+
52+ clientWithRoute pm Proxy req mrti = clientWithRoute pm (Proxy :: Proxy api) req'
53+ where req' | Just rti <- mrti = req { requestHeaders = Seq.fromList (mkTrackingHeaders rti) <> requestHeaders req }
54+ | otherwise = req
55+
56+ hoistClientMonad pm Proxy f cl = \rti -> hoistClientMonad pm (Proxy :: Proxy api) f (cl rti)
57+
58+
4759instance forall (api :: Type) context.
4860 ( HasServer api context
4961 , HasContextEntry context (ReqtrackingHandler (Maybe ReqtrackInfo) ())
@@ -53,12 +65,18 @@ instance forall (api :: Type) context.
5365 hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt s
5466
5567 route _ context subserver = route (Proxy :: Proxy api) context (fmap const subserver `addHeaderCheck` withRequest trackingCheck)
56− where trackingCheck :: Request -> DelayedIO ()
68+ where trackingCheck :: Wai.Request -> DelayedIO ()
5769 trackingCheck = either delayedFailFatal (const $ return ()) <=< liftIO . runHandler . trackingHandler
58− trackingHandler :: Request -> Handler ()
70+ trackingHandler :: Wai.Request -> Handler ()
5971 trackingHandler = let ReqtrackingHandler h = getContextEntry context
6072 in h . parseTrackingHeaders
6173
74+instance HasClient m api => HasClient m (RequestTracking_ :> api) where
75+ type Client m (RequestTracking_ :> api) = Client m api
76+
77+ clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy api)
78+ hoistClientMonad pm Proxy f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl
79+
6280
6381type ReqtrackHeaders = '[ Header RequestIdHdr ByteString
6482 , Header RequestLevelHdr Word