{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.HTTP.Client.Core
( withResponse
, httpLbs
, httpNoBody
, httpRaw
, httpRaw'
, getModifiedRequestManager
, responseOpen
, responseClose
, httpRedirect
, httpRedirect'
, withConnection
, handleClosedRead
) where
import Network.HTTP.Types
import Network.HTTP.Client.Manager
import Network.HTTP.Client.Types
import Network.HTTP.Client.Headers
import Network.HTTP.Client.Body
import Network.HTTP.Client.Request
import Network.HTTP.Client.Response
import Network.HTTP.Client.Cookies
import Data.Maybe (fromMaybe, isJust)
import Data.Time
import Control.Exception
import qualified Data.ByteString.Lazy as L
import Data.Monoid
import Control.Monad (void)
import System.Timeout (timeout)
import Data.KeyedPool
import GHC.IO.Exception (IOException(..), IOErrorType(..))
withResponse :: Request
-> Manager
-> (Response BodyReader -> IO a)
-> IO a
withResponse :: Request -> Manager -> (Response BodyReader -> IO a) -> IO a
withResponse Request
req Manager
man Response BodyReader -> IO a
f = IO (Response BodyReader)
-> (Response BodyReader -> IO ())
-> (Response BodyReader -> IO a)
-> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Request -> Manager -> IO (Response BodyReader)
responseOpen Request
req Manager
man) Response BodyReader -> IO ()
forall a. Response a -> IO ()
responseClose Response BodyReader -> IO a
f
httpLbs :: Request -> Manager -> IO (Response L.ByteString)
httpLbs :: Request -> Manager -> IO (Response ByteString)
httpLbs Request
req Manager
man = Request
-> Manager
-> (Response BodyReader -> IO (Response ByteString))
-> IO (Response ByteString)
forall a.
Request -> Manager -> (Response BodyReader -> IO a) -> IO a
withResponse Request
req Manager
man ((Response BodyReader -> IO (Response ByteString))
-> IO (Response ByteString))
-> (Response BodyReader -> IO (Response ByteString))
-> IO (Response ByteString)
forall a b. (a -> b) -> a -> b
$ \Response BodyReader
res -> do
[ByteString]
bss <- BodyReader -> IO [ByteString]
brConsume (BodyReader -> IO [ByteString]) -> BodyReader -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$ Response BodyReader -> BodyReader
forall body. Response body -> body
responseBody Response BodyReader
res
Response ByteString -> IO (Response ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return Response BodyReader
res { responseBody :: ByteString
responseBody = [ByteString] -> ByteString
L.fromChunks [ByteString]
bss }
httpNoBody :: Request -> Manager -> IO (Response ())
httpNoBody :: Request -> Manager -> IO (Response ())
httpNoBody Request
req Manager
man = Request
-> Manager
-> (Response BodyReader -> IO (Response ()))
-> IO (Response ())
forall a.
Request -> Manager -> (Response BodyReader -> IO a) -> IO a
withResponse Request
req Manager
man ((Response BodyReader -> IO (Response ())) -> IO (Response ()))
-> (Response BodyReader -> IO (Response ())) -> IO (Response ())
forall a b. (a -> b) -> a -> b
$ Response () -> IO (Response ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Response () -> IO (Response ()))
-> (Response BodyReader -> Response ())
-> Response BodyReader
-> IO (Response ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response BodyReader -> Response ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void
httpRaw
:: Request
-> Manager
-> IO (Response BodyReader)
httpRaw :: Request -> Manager -> IO (Response BodyReader)
httpRaw = (IO (Request, Response BodyReader) -> IO (Response BodyReader))
-> (Manager -> IO (Request, Response BodyReader))
-> Manager
-> IO (Response BodyReader)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Request, Response BodyReader) -> Response BodyReader)
-> IO (Request, Response BodyReader) -> IO (Response BodyReader)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Request, Response BodyReader) -> Response BodyReader
forall a b. (a, b) -> b
snd) ((Manager -> IO (Request, Response BodyReader))
-> Manager -> IO (Response BodyReader))
-> (Request -> Manager -> IO (Request, Response BodyReader))
-> Request
-> Manager
-> IO (Response BodyReader)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> Manager -> IO (Request, Response BodyReader)
httpRaw'
httpRaw'
:: Request
-> Manager
-> IO (Request, Response BodyReader)
httpRaw' :: Request -> Manager -> IO (Request, Response BodyReader)
httpRaw' Request
req0 Manager
m = do
let req' :: Request
req' = Manager -> Request -> Request
mSetProxy Manager
m Request
req0
(Request
req, CookieJar
cookie_jar') <- case Request -> Maybe CookieJar
cookieJar Request
req' of
Just CookieJar
cj -> do
UTCTime
now <- IO UTCTime
getCurrentTime
(Request, CookieJar) -> IO (Request, CookieJar)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Request, CookieJar) -> IO (Request, CookieJar))
-> (Request, CookieJar) -> IO (Request, CookieJar)
forall a b. (a -> b) -> a -> b
$ Request -> CookieJar -> UTCTime -> (Request, CookieJar)
insertCookiesIntoRequest Request
req' (CookieJar -> UTCTime -> CookieJar
evictExpiredCookies CookieJar
cj UTCTime
now) UTCTime
now
Maybe CookieJar
Nothing -> (Request, CookieJar) -> IO (Request, CookieJar)
forall (m :: * -> *) a. Monad m => a -> m a
return (Request
req', CookieJar
forall a. Monoid a => a
Data.Monoid.mempty)
(Maybe Int
timeout', Managed Connection
mconn) <- Maybe Int
-> IO (Managed Connection) -> IO (Maybe Int, Managed Connection)
forall a resource.
Integral a =>
Maybe Int
-> IO (Managed resource) -> IO (Maybe a, Managed resource)
getConnectionWrapper
(Request -> Maybe Int
responseTimeout' Request
req)
(Request -> Manager -> IO (Managed Connection)
getConn Request
req Manager
m)
Either SomeException (Response BodyReader)
ex <- IO (Response BodyReader)
-> IO (Either SomeException (Response BodyReader))
forall e a. Exception e => IO a -> IO (Either e a)
try (IO (Response BodyReader)
-> IO (Either SomeException (Response BodyReader)))
-> IO (Response BodyReader)
-> IO (Either SomeException (Response BodyReader))
forall a b. (a -> b) -> a -> b
$ do
Maybe (IO ())
cont <- Request -> Connection -> IO (Maybe (IO ()))
requestBuilder (Request -> Request
dropProxyAuthSecure Request
req) (Managed Connection -> Connection
forall resource. Managed resource -> resource
managedResource Managed Connection
mconn)
Maybe Int
-> Request
-> Managed Connection
-> Maybe (IO ())
-> IO (Response BodyReader)
getResponse Maybe Int
timeout' Request
req Managed Connection
mconn Maybe (IO ())
cont
case Either SomeException (Response BodyReader)
ex of
Left SomeException
e | Managed Connection -> Bool
forall resource. Managed resource -> Bool
managedReused Managed Connection
mconn Bool -> Bool -> Bool
&& Manager -> SomeException -> Bool
mRetryableException Manager
m SomeException
e -> do
Managed Connection -> Reuse -> IO ()
forall resource. Managed resource -> Reuse -> IO ()
managedRelease Managed Connection
mconn Reuse
DontReuse
Request -> Manager -> IO (Request, Response BodyReader)
httpRaw' Request
req Manager
m
Left SomeException
e -> do
Managed Connection -> Reuse -> IO ()
forall resource. Managed resource -> Reuse -> IO ()
managedRelease Managed Connection
mconn Reuse
DontReuse
SomeException -> IO (Request, Response BodyReader)
forall e a. Exception e => e -> IO a
throwIO SomeException
e
Right Response BodyReader
res -> case Request -> Maybe CookieJar
cookieJar Request
req' of
Just CookieJar
_ -> do
UTCTime
now' <- IO UTCTime
getCurrentTime
let (CookieJar
cookie_jar, Response BodyReader
_) = Response BodyReader
-> Request
-> UTCTime
-> CookieJar
-> (CookieJar, Response BodyReader)
forall a.
Response a
-> Request -> UTCTime -> CookieJar -> (CookieJar, Response a)
updateCookieJar Response BodyReader
res Request
req UTCTime
now' CookieJar
cookie_jar'
(Request, Response BodyReader) -> IO (Request, Response BodyReader)
forall (m :: * -> *) a. Monad m => a -> m a
return (Request
req, Response BodyReader
res {responseCookieJar :: CookieJar
responseCookieJar = CookieJar
cookie_jar})
Maybe CookieJar
Nothing -> (Request, Response BodyReader) -> IO (Request, Response BodyReader)
forall (m :: * -> *) a. Monad m => a -> m a
return (Request
req, Response BodyReader
res)
where
getConnectionWrapper :: Maybe Int
-> IO (Managed resource) -> IO (Maybe a, Managed resource)
getConnectionWrapper Maybe Int
mtimeout IO (Managed resource)
f =
case Maybe Int
mtimeout of
Maybe Int
Nothing -> (Managed resource -> (Maybe a, Managed resource))
-> IO (Managed resource) -> IO (Maybe a, Managed resource)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) Maybe a
forall a. Maybe a
Nothing) IO (Managed resource)
f
Just Int
timeout' -> do
UTCTime
before <- IO UTCTime
getCurrentTime
Maybe (Managed resource)
mres <- Int -> IO (Managed resource) -> IO (Maybe (Managed resource))
forall a. Int -> IO a -> IO (Maybe a)
timeout Int
timeout' IO (Managed resource)
f
case Maybe (Managed resource)
mres of
Maybe (Managed resource)
Nothing -> HttpExceptionContent -> IO (Maybe a, Managed resource)
forall a. HttpExceptionContent -> IO a
throwHttp HttpExceptionContent
ConnectionTimeout
Just Managed resource
mConn -> do
UTCTime
now <- IO UTCTime
getCurrentTime
let timeSpentMicro :: NominalDiffTime
timeSpentMicro = UTCTime -> UTCTime -> NominalDiffTime
diffUTCTime UTCTime
now UTCTime
before NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Num a => a -> a -> a
* NominalDiffTime
1000000
remainingTime :: a
remainingTime = NominalDiffTime -> a
forall a b. (RealFrac a, Integral b) => a -> b
round (NominalDiffTime -> a) -> NominalDiffTime -> a
forall a b. (a -> b) -> a -> b
$ Int -> NominalDiffTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
timeout' NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Num a => a -> a -> a
- NominalDiffTime
timeSpentMicro
if a
remainingTime a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0
then do
Managed resource -> Reuse -> IO ()
forall resource. Managed resource -> Reuse -> IO ()
managedRelease Managed resource
mConn Reuse
DontReuse
HttpExceptionContent -> IO (Maybe a, Managed resource)
forall a. HttpExceptionContent -> IO a
throwHttp HttpExceptionContent
ConnectionTimeout
else (Maybe a, Managed resource) -> IO (Maybe a, Managed resource)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe a
forall a. a -> Maybe a
Just a
remainingTime, Managed resource
mConn)
responseTimeout' :: Request -> Maybe Int
responseTimeout' Request
req =
case Request -> ResponseTimeout
responseTimeout Request
req of
ResponseTimeout
ResponseTimeoutDefault ->
case Manager -> ResponseTimeout
mResponseTimeout Manager
m of
ResponseTimeout
ResponseTimeoutDefault -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
30000000
ResponseTimeout
ResponseTimeoutNone -> Maybe Int
forall a. Maybe a
Nothing
ResponseTimeoutMicro Int
u -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
u
ResponseTimeout
ResponseTimeoutNone -> Maybe Int
forall a. Maybe a
Nothing
ResponseTimeoutMicro Int
u -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
u
getModifiedRequestManager :: Manager -> Request -> IO (Manager, Request)
getModifiedRequestManager :: Manager -> Request -> IO (Manager, Request)
getModifiedRequestManager Manager
manager0 Request
req0 = do
let manager :: Manager
manager = Manager -> Maybe Manager -> Manager
forall a. a -> Maybe a -> a
fromMaybe Manager
manager0 (Request -> Maybe Manager
requestManagerOverride Request
req0)
Request
req <- Manager -> Request -> IO Request
mModifyRequest Manager
manager Request
req0
(Manager, Request) -> IO (Manager, Request)
forall (m :: * -> *) a. Monad m => a -> m a
return (Manager
manager, Request
req)
responseOpen :: Request -> Manager -> IO (Response BodyReader)
responseOpen :: Request -> Manager -> IO (Response BodyReader)
responseOpen Request
inputReq Manager
manager' = do
case RequestHeaders -> HeadersValidationResult
validateHeaders (Request -> RequestHeaders
requestHeaders Request
inputReq) of
HeadersValidationResult
GoodHeaders -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
BadHeaders ByteString
reason -> HttpExceptionContent -> IO ()
forall a. HttpExceptionContent -> IO a
throwHttp (HttpExceptionContent -> IO ()) -> HttpExceptionContent -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> HttpExceptionContent
InvalidRequestHeader ByteString
reason
(Manager
manager, Request
req0) <- Manager -> Request -> IO (Manager, Request)
getModifiedRequestManager Manager
manager' Request
inputReq
Request -> IO (Response BodyReader) -> IO (Response BodyReader)
forall a. Request -> IO a -> IO a
wrapExc Request
req0 (IO (Response BodyReader) -> IO (Response BodyReader))
-> IO (Response BodyReader) -> IO (Response BodyReader)
forall a b. (a -> b) -> a -> b
$ Manager
-> Request -> IO (Response BodyReader) -> IO (Response BodyReader)
Manager -> forall a. Request -> IO a -> IO a
mWrapException Manager
manager Request
req0 (IO (Response BodyReader) -> IO (Response BodyReader))
-> IO (Response BodyReader) -> IO (Response BodyReader)
forall a b. (a -> b) -> a -> b
$ do
(Request
req, Response BodyReader
res) <- Manager -> Int -> Request -> IO (Request, Response BodyReader)
go Manager
manager (Request -> Int
redirectCount Request
req0) Request
req0
Request -> Request -> Response BodyReader -> IO ()
checkResponse Request
req Request
req Response BodyReader
res
Manager -> Response BodyReader -> IO (Response BodyReader)
mModifyResponse Manager
manager Response BodyReader
res
{ responseBody :: BodyReader
responseBody = Request -> BodyReader -> BodyReader
forall a. Request -> IO a -> IO a
wrapExc Request
req0 (Response BodyReader -> BodyReader
forall body. Response body -> body
responseBody Response BodyReader
res)
}
where
wrapExc :: Request -> IO a -> IO a
wrapExc :: Request -> IO a -> IO a
wrapExc Request
req0 = (HttpExceptionContentWrapper -> IO a) -> IO a -> IO a
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle ((HttpExceptionContentWrapper -> IO a) -> IO a -> IO a)
-> (HttpExceptionContentWrapper -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ HttpException -> IO a
forall e a. Exception e => e -> IO a
throwIO (HttpException -> IO a)
-> (HttpExceptionContentWrapper -> HttpException)
-> HttpExceptionContentWrapper
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> HttpExceptionContentWrapper -> HttpException
toHttpException Request
req0
go :: Manager -> Int -> Request -> IO (Request, Response BodyReader)
go Manager
manager0 Int
count Request
req' = Int
-> (Request -> IO (Response BodyReader, Request, Bool))
-> Request
-> IO (Request, Response BodyReader)
httpRedirect'
Int
count
(\Request
req -> do
(Manager
manager, Request
modReq) <- Manager -> Request -> IO (Manager, Request)
getModifiedRequestManager Manager
manager0 Request
req
(Request
req'', Response BodyReader
res) <- Request -> Manager -> IO (Request, Response BodyReader)
httpRaw' Request
modReq Manager
manager
let mreq :: Maybe Request
mreq = if Request -> Int
redirectCount Request
modReq Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then Maybe Request
forall a. Maybe a
Nothing
else Request -> RequestHeaders -> CookieJar -> Int -> Maybe Request
getRedirectedRequest Request
req'' (Response BodyReader -> RequestHeaders
forall body. Response body -> RequestHeaders
responseHeaders Response BodyReader
res) (Response BodyReader -> CookieJar
forall body. Response body -> CookieJar
responseCookieJar Response BodyReader
res) (Status -> Int
statusCode (Response BodyReader -> Status
forall body. Response body -> Status
responseStatus Response BodyReader
res))
(Response BodyReader, Request, Bool)
-> IO (Response BodyReader, Request, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (Response BodyReader
res, Request -> Maybe Request -> Request
forall a. a -> Maybe a -> a
fromMaybe Request
req'' Maybe Request
mreq, Maybe Request -> Bool
forall a. Maybe a -> Bool
isJust Maybe Request
mreq))
Request
req'
httpRedirect
:: Int
-> (Request -> IO (Response BodyReader, Maybe Request))
-> Request
-> IO (Response BodyReader)
httpRedirect :: Int
-> (Request -> IO (Response BodyReader, Maybe Request))
-> Request
-> IO (Response BodyReader)
httpRedirect Int
count0 Request -> IO (Response BodyReader, Maybe Request)
http0 Request
req0 = ((Request, Response BodyReader) -> Response BodyReader)
-> IO (Request, Response BodyReader) -> IO (Response BodyReader)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Request, Response BodyReader) -> Response BodyReader
forall a b. (a, b) -> b
snd (IO (Request, Response BodyReader) -> IO (Response BodyReader))
-> IO (Request, Response BodyReader) -> IO (Response BodyReader)
forall a b. (a -> b) -> a -> b
$ Int
-> (Request -> IO (Response BodyReader, Request, Bool))
-> Request
-> IO (Request, Response BodyReader)
httpRedirect' Int
count0 Request -> IO (Response BodyReader, Request, Bool)
http' Request
req0
where
http' :: Request -> IO (Response BodyReader, Request, Bool)
http' Request
req' = do
(Response BodyReader
res, Maybe Request
mbReq) <- Request -> IO (Response BodyReader, Maybe Request)
http0 Request
req'
(Response BodyReader, Request, Bool)
-> IO (Response BodyReader, Request, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (Response BodyReader
res, Request -> Maybe Request -> Request
forall a. a -> Maybe a -> a
fromMaybe Request
req0 Maybe Request
mbReq, Maybe Request -> Bool
forall a. Maybe a -> Bool
isJust Maybe Request
mbReq)
handleClosedRead :: SomeException -> IO L.ByteString
handleClosedRead :: SomeException -> IO ByteString
handleClosedRead SomeException
se
| Just HttpExceptionContent
ConnectionClosed <- (HttpExceptionContentWrapper -> HttpExceptionContent)
-> Maybe HttpExceptionContentWrapper -> Maybe HttpExceptionContent
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HttpExceptionContentWrapper -> HttpExceptionContent
unHttpExceptionContentWrapper (SomeException -> Maybe HttpExceptionContentWrapper
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
se)
= ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
L.empty
| Just (HttpExceptionRequest Request
_ HttpExceptionContent
ConnectionClosed) <- SomeException -> Maybe HttpException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
se
= ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
L.empty
| Just (IOError Maybe Handle
_ IOErrorType
ResourceVanished String
_ String
_ Maybe CInt
_ Maybe String
_) <- SomeException -> Maybe IOException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
se
= ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
L.empty
| Bool
otherwise
= SomeException -> IO ByteString
forall e a. Exception e => e -> IO a
throwIO SomeException
se
httpRedirect'
:: Int
-> (Request -> IO (Response BodyReader, Request, Bool))
-> Request
-> IO (Request, Response BodyReader)
httpRedirect' :: Int
-> (Request -> IO (Response BodyReader, Request, Bool))
-> Request
-> IO (Request, Response BodyReader)
httpRedirect' Int
count0 Request -> IO (Response BodyReader, Request, Bool)
http' Request
req0 = Int
-> Request
-> [Response ByteString]
-> IO (Request, Response BodyReader)
forall t.
(Ord t, Num t) =>
t
-> Request
-> [Response ByteString]
-> IO (Request, Response BodyReader)
go Int
count0 Request
req0 []
where
go :: t
-> Request
-> [Response ByteString]
-> IO (Request, Response BodyReader)
go t
count Request
_ [Response ByteString]
ress | t
count t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
0 = HttpExceptionContent -> IO (Request, Response BodyReader)
forall a. HttpExceptionContent -> IO a
throwHttp (HttpExceptionContent -> IO (Request, Response BodyReader))
-> HttpExceptionContent -> IO (Request, Response BodyReader)
forall a b. (a -> b) -> a -> b
$ [Response ByteString] -> HttpExceptionContent
TooManyRedirects [Response ByteString]
ress
go t
count Request
req' [Response ByteString]
ress = do
(Response BodyReader
res, Request
req, Bool
isRedirect) <- Request -> IO (Response BodyReader, Request, Bool)
http' Request
req'
if Bool
isRedirect then do
let maxFlush :: Int
maxFlush = Int
1024
ByteString
lbs <- BodyReader -> Int -> IO ByteString
brReadSome (Response BodyReader -> BodyReader
forall body. Response body -> body
responseBody Response BodyReader
res) Int
maxFlush
IO ByteString -> (SomeException -> IO ByteString) -> IO ByteString
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`Control.Exception.catch` SomeException -> IO ByteString
handleClosedRead
Response BodyReader -> IO ()
forall a. Response a -> IO ()
responseClose Response BodyReader
res
t
-> Request
-> [Response ByteString]
-> IO (Request, Response BodyReader)
go (t
count t -> t -> t
forall a. Num a => a -> a -> a
- t
1) Request
req (Response BodyReader
res { responseBody :: ByteString
responseBody = ByteString
lbs }Response ByteString
-> [Response ByteString] -> [Response ByteString]
forall a. a -> [a] -> [a]
:[Response ByteString]
ress)
else
(Request, Response BodyReader) -> IO (Request, Response BodyReader)
forall (m :: * -> *) a. Monad m => a -> m a
return (Request
req, Response BodyReader
res)
responseClose :: Response a -> IO ()
responseClose :: Response a -> IO ()
responseClose = ResponseClose -> IO ()
runResponseClose (ResponseClose -> IO ())
-> (Response a -> ResponseClose) -> Response a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response a -> ResponseClose
forall body. Response body -> ResponseClose
responseClose'
withConnection :: Request -> Manager -> (Connection -> IO a) -> IO a
withConnection :: Request -> Manager -> (Connection -> IO a) -> IO a
withConnection Request
origReq Manager
man Connection -> IO a
action = do
Managed Connection
mHttpConn <- Request -> Manager -> IO (Managed Connection)
getConn (Manager -> Request -> Request
mSetProxy Manager
man Request
origReq) Manager
man
Connection -> IO a
action (Managed Connection -> Connection
forall resource. Managed resource -> resource
managedResource Managed Connection
mHttpConn) IO a -> IO () -> IO a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Managed Connection -> IO ()
forall resource. Managed resource -> IO ()
keepAlive Managed Connection
mHttpConn
IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO a
`finally` Managed Connection -> Reuse -> IO ()
forall resource. Managed resource -> Reuse -> IO ()
managedRelease Managed Connection
mHttpConn Reuse
DontReuse