@@ -72,16 +72,27 @@ import qualified Network.HTTP.Client as Client
7272import qualified Servant.Types.SourceT as S
7373
7474-- | The environment in which a request is run.
75+-- The 'baseUrl' and 'makeClientRequest' function are used to create a @http-client@ request.
76+-- Cookies are then added to that request if a 'CookieJar' is set on the environment.
77+-- Finally the request is executed with the 'manager'.
78+-- The 'makeClientRequest' function can be used to modify the request to execute and set values which
79+-- are not specified on a @servant@ 'Request' like 'responseTimeout' or 'redirectCount'
7580data ClientEnv
7681 = ClientEnv
7782 { manager :: Client.Manager
7883 , baseUrl :: BaseUrl
7984 , cookieJar :: Maybe (TVar Client.CookieJar)
85+ , makeClientRequest :: BaseUrl -> Request -> Client.Request
86+ -- ^ this function can be used to customize the creation of @http-client@ requests from @servant@ requests. Default value: 'defaultMakeClientRequest'
87+ -- Note that:
88+ -- 1. 'makeClientRequest' exists to allow overriding operational semantics e.g. 'responseTimeout' per request,
89+ -- If you need global modifications, you should use 'managerModifyRequest'
90+ -- 2. the 'cookieJar', if defined, is being applied after 'makeClientRequest' is called.
8091 }
8192
8293-- | 'ClientEnv' smart constructor.
8394mkClientEnv :: Client.Manager -> BaseUrl -> ClientEnv
84−mkClientEnv mgr burl = ClientEnv mgr burl Nothing
95+mkClientEnv mgr burl = ClientEnv mgr burl Nothing defaultMakeClientRequest
8596
8697-- | Generates a set of client functions for an API.
8798--
@@ -152,8 +163,8 @@ runClientM cm env = runExceptT $ flip runReaderT env $ unClientM cm
152163
153164performRequest :: Request -> ClientM Response
154165performRequest req = do
155− ClientEnv m burl cookieJar' <- ask
156− let clientRequest = requestToClientRequest burl req
166+ ClientEnv m burl cookieJar' createClientRequest <- ask
167+ let clientRequest = createClientRequest burl req
157168 request <- case cookieJar' of
158169 Nothing -> pure clientRequest
159170 Just cj -> liftIO $ do
@@ -162,7 +173,7 @@ performRequest req = do
162173 oldCookieJar <- readTVar cj
163174 let (newRequest, newCookieJar) =
164175 Client.insertCookiesIntoRequest
165− (requestToClientRequest burl req)
176+ clientRequest
166177 oldCookieJar
167178 now
168179 writeTVar cj newCookieJar
@@ -215,8 +226,11 @@ clientResponseToResponse f r = Response
215226 , responseHttpVersion = Client.responseVersion r
216227 }
217228
218−requestToClientRequest :: BaseUrl -> Request -> Client.Request
219−requestToClientRequest burl r = Client.defaultRequest
229+-- | Create a @http-client@ 'Client.Request' from a @servant@ 'Request'
230+-- The 'Client.host', 'Client.path' and 'Client.port' fields are extracted from the 'BaseUrl'
231+-- otherwise the body, headers and query string are derived from the @servant@ 'Request'
232+defaultMakeClientRequest :: BaseUrl -> Request -> Client.Request
233+defaultMakeClientRequest burl r = Client.defaultRequest
220234 { Client.method = requestMethod r
221235 , Client.host = fromString $ baseUrlHost burl
222236 , Client.port = baseUrlPort burl