{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE CPP #-}
module Network.HTTP.Client
(
withResponse
, httpLbs
, httpNoBody
, responseOpen
, responseClose
, withResponseHistory
, responseOpenHistory
, HistoriedResponse
, hrRedirects
, hrFinalRequest
, hrFinalResponse
, Manager
, newManager
, closeManager
, withManager
, HasHttpManager(..)
, ManagerSettings
, defaultManagerSettings
, managerConnCount
, managerRawConnection
, managerTlsConnection
, managerResponseTimeout
, managerRetryableException
, managerWrapException
, managerIdleConnectionCount
, managerModifyRequest
, managerModifyResponse
, managerSetProxy
, managerSetInsecureProxy
, managerSetSecureProxy
, ProxyOverride
, proxyFromRequest
, noProxy
, useProxy
, useProxySecureWithoutConnect
, proxyEnvironment
, proxyEnvironmentNamed
, defaultProxy
, ResponseTimeout
, responseTimeoutMicro
, responseTimeoutNone
, responseTimeoutDefault
, rawConnectionModifySocket
, rawConnectionModifySocketSize
, parseUrl
, parseUrlThrow
, parseRequest
, parseRequest_
, requestFromURI
, requestFromURI_
, defaultRequest
, applyBasicAuth
, applyBearerAuth
, urlEncodedBody
, getUri
, setRequestIgnoreStatus
, setRequestCheckStatus
, setQueryString
#if MIN_VERSION_http_types(0,12,1)
, setQueryStringPartialEscape
#endif
, Request
, method
, secure
, host
, port
, path
, queryString
, requestHeaders
, requestBody
, proxy
, applyBasicProxyAuth
, decompress
, redirectCount
, shouldStripHeaderOnRedirect
, shouldStripHeaderOnRedirectIfOnDifferentHostOnly
, checkResponse
, responseTimeout
, cookieJar
, requestVersion
, redactHeaders
, RequestBody (..)
, Popper
, NeedsPopper
, GivesPopper
, streamFile
, observedStreamFile
, StreamFileStatus (..)
, Response
, responseStatus
, responseVersion
, responseHeaders
, responseBody
, responseCookieJar
, getOriginalRequest
, throwErrorStatusCodes
, BodyReader
, brRead
, brReadSome
, brConsume
, makeConnection
, socketConnection
, HttpException (..)
, HttpExceptionContent (..)
, Cookie (..)
, equalCookie
, equivCookie
, compareCookies
, CookieJar
, equalCookieJar
, equivCookieJar
, Proxy (..)
, withConnection
, strippedHostName
, module Network.HTTP.Client.Cookies
) where
import Network.HTTP.Client.Body
import Network.HTTP.Client.Connection (makeConnection, socketConnection, strippedHostName)
import Network.HTTP.Client.Cookies
import Network.HTTP.Client.Core
import Network.HTTP.Client.Manager
import Network.HTTP.Client.Request
import Network.HTTP.Client.Response
import Network.HTTP.Client.Types
import Data.IORef (newIORef, writeIORef, readIORef, modifyIORef)
import qualified Data.ByteString.Lazy as L
import Data.Foldable (Foldable)
import Data.Traversable (Traversable)
import Network.HTTP.Types (statusCode)
import GHC.Generics (Generic)
import Data.Typeable (Typeable)
import Control.Exception (bracket, catch, handle, throwIO)
data HistoriedResponse body = HistoriedResponse
{ forall body.
HistoriedResponse body -> [(Request, Response ByteString)]
hrRedirects :: [(Request, Response L.ByteString)]
, forall body. HistoriedResponse body -> Request
hrFinalRequest :: Request
, forall body. HistoriedResponse body -> Response body
hrFinalResponse :: Response body
}
deriving (forall a b. a -> HistoriedResponse b -> HistoriedResponse a
forall a b. (a -> b) -> HistoriedResponse a -> HistoriedResponse b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> HistoriedResponse b -> HistoriedResponse a
$c<$ :: forall a b. a -> HistoriedResponse b -> HistoriedResponse a
fmap :: forall a b. (a -> b) -> HistoriedResponse a -> HistoriedResponse b
$cfmap :: forall a b. (a -> b) -> HistoriedResponse a -> HistoriedResponse b
Functor, Functor HistoriedResponse
Foldable HistoriedResponse
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
HistoriedResponse (m a) -> m (HistoriedResponse a)
forall (f :: * -> *) a.
Applicative f =>
HistoriedResponse (f a) -> f (HistoriedResponse a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HistoriedResponse a -> m (HistoriedResponse b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HistoriedResponse a -> f (HistoriedResponse b)
sequence :: forall (m :: * -> *) a.
Monad m =>
HistoriedResponse (m a) -> m (HistoriedResponse a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
HistoriedResponse (m a) -> m (HistoriedResponse a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HistoriedResponse a -> m (HistoriedResponse b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HistoriedResponse a -> m (HistoriedResponse b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
HistoriedResponse (f a) -> f (HistoriedResponse a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
HistoriedResponse (f a) -> f (HistoriedResponse a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HistoriedResponse a -> f (HistoriedResponse b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HistoriedResponse a -> f (HistoriedResponse b)
Data.Traversable.Traversable, forall a. Eq a => a -> HistoriedResponse a -> Bool
forall a. Num a => HistoriedResponse a -> a
forall a. Ord a => HistoriedResponse a -> a
forall m. Monoid m => HistoriedResponse m -> m
forall a. HistoriedResponse a -> Bool
forall a. HistoriedResponse a -> Int
forall a. HistoriedResponse a -> [a]
forall a. (a -> a -> a) -> HistoriedResponse a -> a
forall m a. Monoid m => (a -> m) -> HistoriedResponse a -> m
forall b a. (b -> a -> b) -> b -> HistoriedResponse a -> b
forall a b. (a -> b -> b) -> b -> HistoriedResponse a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => HistoriedResponse a -> a
$cproduct :: forall a. Num a => HistoriedResponse a -> a
sum :: forall a. Num a => HistoriedResponse a -> a
$csum :: forall a. Num a => HistoriedResponse a -> a
minimum :: forall a. Ord a => HistoriedResponse a -> a
$cminimum :: forall a. Ord a => HistoriedResponse a -> a
maximum :: forall a. Ord a => HistoriedResponse a -> a
$cmaximum :: forall a. Ord a => HistoriedResponse a -> a
elem :: forall a. Eq a => a -> HistoriedResponse a -> Bool
$celem :: forall a. Eq a => a -> HistoriedResponse a -> Bool
length :: forall a. HistoriedResponse a -> Int
$clength :: forall a. HistoriedResponse a -> Int
null :: forall a. HistoriedResponse a -> Bool
$cnull :: forall a. HistoriedResponse a -> Bool
toList :: forall a. HistoriedResponse a -> [a]
$ctoList :: forall a. HistoriedResponse a -> [a]
foldl1 :: forall a. (a -> a -> a) -> HistoriedResponse a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> HistoriedResponse a -> a
foldr1 :: forall a. (a -> a -> a) -> HistoriedResponse a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> HistoriedResponse a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> HistoriedResponse a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> HistoriedResponse a -> b
foldl :: forall b a. (b -> a -> b) -> b -> HistoriedResponse a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> HistoriedResponse a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> HistoriedResponse a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> HistoriedResponse a -> b
foldr :: forall a b. (a -> b -> b) -> b -> HistoriedResponse a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> HistoriedResponse a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> HistoriedResponse a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> HistoriedResponse a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> HistoriedResponse a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> HistoriedResponse a -> m
fold :: forall m. Monoid m => HistoriedResponse m -> m
$cfold :: forall m. Monoid m => HistoriedResponse m -> m
Data.Foldable.Foldable, Int -> HistoriedResponse body -> ShowS
forall body. Show body => Int -> HistoriedResponse body -> ShowS
forall body. Show body => [HistoriedResponse body] -> ShowS
forall body. Show body => HistoriedResponse body -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HistoriedResponse body] -> ShowS
$cshowList :: forall body. Show body => [HistoriedResponse body] -> ShowS
show :: HistoriedResponse body -> String
$cshow :: forall body. Show body => HistoriedResponse body -> String
showsPrec :: Int -> HistoriedResponse body -> ShowS
$cshowsPrec :: forall body. Show body => Int -> HistoriedResponse body -> ShowS
Show, Typeable, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall body x.
Rep (HistoriedResponse body) x -> HistoriedResponse body
forall body x.
HistoriedResponse body -> Rep (HistoriedResponse body) x
$cto :: forall body x.
Rep (HistoriedResponse body) x -> HistoriedResponse body
$cfrom :: forall body x.
HistoriedResponse body -> Rep (HistoriedResponse body) x
Generic)
responseOpenHistory :: Request -> Manager -> IO (HistoriedResponse BodyReader)
responseOpenHistory :: Request -> Manager -> IO (HistoriedResponse BodyReader)
responseOpenHistory Request
reqOrig Manager
man0 = forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle (forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> HttpExceptionContentWrapper -> HttpException
toHttpException Request
reqOrig) forall a b. (a -> b) -> a -> b
$ do
IORef Request
reqRef <- forall a. a -> IO (IORef a)
newIORef Request
reqOrig
IORef
([(Request, Response ByteString)]
-> [(Request, Response ByteString)])
historyRef <- forall a. a -> IO (IORef a)
newIORef forall a. a -> a
id
let go :: Request -> IO (Response BodyReader, Request, Bool)
go Request
req0 = do
(Manager
man, Request
req) <- Manager -> Request -> IO (Manager, Request)
getModifiedRequestManager Manager
man0 Request
req0
(Request
req', Response BodyReader
res') <- Request -> Manager -> IO (Request, Response BodyReader)
httpRaw' Request
req Manager
man
let res :: Response BodyReader
res = Response BodyReader
res'
{ responseBody :: BodyReader
responseBody = forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle (forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> HttpExceptionContentWrapper -> HttpException
toHttpException Request
req0)
(forall body. Response body -> body
responseBody Response BodyReader
res')
}
case Request
-> Request -> ResponseHeaders -> CookieJar -> Int -> Maybe Request
getRedirectedRequest
Request
req
Request
req'
(forall body. Response body -> ResponseHeaders
responseHeaders Response BodyReader
res)
(forall body. Response body -> CookieJar
responseCookieJar Response BodyReader
res)
(Status -> Int
statusCode forall a b. (a -> b) -> a -> b
$ forall body. Response body -> Status
responseStatus Response BodyReader
res) of
Maybe Request
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return (Response BodyReader
res, Request
req', Bool
False)
Just Request
req'' -> do
forall a. IORef a -> a -> IO ()
writeIORef IORef Request
reqRef Request
req''
ByteString
body <- BodyReader -> Int -> IO ByteString
brReadSome (forall body. Response body -> body
responseBody Response BodyReader
res) Int
1024
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` SomeException -> IO ByteString
handleClosedRead
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef
([(Request, Response ByteString)]
-> [(Request, Response ByteString)])
historyRef (forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Request
req, Response BodyReader
res { responseBody :: ByteString
responseBody = ByteString
body })forall a. a -> [a] -> [a]
:))
forall (m :: * -> *) a. Monad m => a -> m a
return (Response BodyReader
res, Request
req'', Bool
True)
(Request
_, Response BodyReader
res) <- Int
-> (Request -> IO (Response BodyReader, Request, Bool))
-> Request
-> IO (Request, Response BodyReader)
httpRedirect' (Request -> Int
redirectCount Request
reqOrig) Request -> IO (Response BodyReader, Request, Bool)
go Request
reqOrig
Request
reqFinal <- forall a. IORef a -> IO a
readIORef IORef Request
reqRef
[(Request, Response ByteString)]
-> [(Request, Response ByteString)]
history <- forall a. IORef a -> IO a
readIORef IORef
([(Request, Response ByteString)]
-> [(Request, Response ByteString)])
historyRef
forall (m :: * -> *) a. Monad m => a -> m a
return HistoriedResponse
{ hrRedirects :: [(Request, Response ByteString)]
hrRedirects = [(Request, Response ByteString)]
-> [(Request, Response ByteString)]
history []
, hrFinalRequest :: Request
hrFinalRequest = Request
reqFinal
, hrFinalResponse :: Response BodyReader
hrFinalResponse = Response BodyReader
res
}
withResponseHistory :: Request
-> Manager
-> (HistoriedResponse BodyReader -> IO a)
-> IO a
withResponseHistory :: forall a.
Request
-> Manager -> (HistoriedResponse BodyReader -> IO a) -> IO a
withResponseHistory Request
req Manager
man = forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(Request -> Manager -> IO (HistoriedResponse BodyReader)
responseOpenHistory Request
req Manager
man)
(forall a. Response a -> IO ()
responseClose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall body. HistoriedResponse body -> Response body
hrFinalResponse)
managerSetInsecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetInsecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetInsecureProxy ProxyOverride
po ManagerSettings
m = ManagerSettings
m { managerProxyInsecure :: ProxyOverride
managerProxyInsecure = ProxyOverride
po }
managerSetSecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetSecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetSecureProxy ProxyOverride
po ManagerSettings
m = ManagerSettings
m { managerProxySecure :: ProxyOverride
managerProxySecure = ProxyOverride
po }
managerSetProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetProxy ProxyOverride
po = ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetInsecureProxy ProxyOverride
po forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProxyOverride -> ManagerSettings -> ManagerSettings
managerSetSecureProxy ProxyOverride
po
responseTimeoutMicro :: Int -> ResponseTimeout
responseTimeoutMicro :: Int -> ResponseTimeout
responseTimeoutMicro = Int -> ResponseTimeout
ResponseTimeoutMicro
responseTimeoutNone :: ResponseTimeout
responseTimeoutNone :: ResponseTimeout
responseTimeoutNone = ResponseTimeout
ResponseTimeoutNone
responseTimeoutDefault :: ResponseTimeout
responseTimeoutDefault :: ResponseTimeout
responseTimeoutDefault = ResponseTimeout
ResponseTimeoutDefault