{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.HTTP.Conduit
(
simpleHttp
, httpLbs
, http
, Proxy (..)
, RequestBody (..)
, Request
, method
, secure
, host
, port
, path
, queryString
, requestHeaders
, requestBody
, proxy
, hostAddress
, rawBody
, decompress
, redirectCount
#if MIN_VERSION_http_client(0,6,2)
, shouldStripHeaderOnRedirect
#endif
, checkResponse
, responseTimeout
, cookieJar
, requestVersion
, HCC.setQueryString
, requestBodySource
, requestBodySourceChunked
, requestBodySourceIO
, requestBodySourceChunkedIO
, Response
, responseStatus
, responseVersion
, responseHeaders
, responseBody
, responseCookieJar
, Manager
, newManager
, closeManager
, ManagerSettings
, tlsManagerSettings
, mkManagerSettings
, managerConnCount
, managerResponseTimeout
, managerTlsConnection
, HC.ResponseTimeout
, HC.responseTimeoutMicro
, HC.responseTimeoutNone
, HC.responseTimeoutDefault
, Cookie(..)
, CookieJar
, createCookieJar
, destroyCookieJar
, parseUrl
, parseUrlThrow
, parseRequest
, parseRequest_
, defaultRequest
, applyBasicAuth
, addProxy
, lbsResponse
, getRedirectedRequest
, alwaysDecompress
, browserDecompress
, urlEncodedBody
, HttpException (..)
, HCC.HttpExceptionContent (..)
) where
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.Conduit
import qualified Data.Conduit.List as CL
import Data.IORef (readIORef, writeIORef, newIORef)
import Data.Int (Int64)
import Control.Applicative as A ((<$>))
import Control.Monad.IO.Unlift (MonadIO (liftIO))
import Control.Monad.Trans.Resource
import qualified Network.HTTP.Client as Client (httpLbs, responseOpen, responseClose)
import qualified Network.HTTP.Client as HC
import qualified Network.HTTP.Client.Conduit as HCC
import Network.HTTP.Client.Internal (createCookieJar,
destroyCookieJar)
import Network.HTTP.Client.Internal (Manager, ManagerSettings,
closeManager, managerConnCount,
managerResponseTimeout,
managerTlsConnection, newManager)
import Network.HTTP.Client (parseUrl, parseUrlThrow, urlEncodedBody, applyBasicAuth,
defaultRequest, parseRequest, parseRequest_)
import Network.HTTP.Client.Internal (addProxy, alwaysDecompress,
browserDecompress)
import Network.HTTP.Client.Internal (getRedirectedRequest)
import Network.HTTP.Client.TLS (mkManagerSettings,
tlsManagerSettings)
import Network.HTTP.Client.Internal (Cookie (..), CookieJar (..),
HttpException (..), Proxy (..),
Request (..), RequestBody (..),
Response (..))
httpLbs :: MonadIO m => Request -> Manager -> m (Response L.ByteString)
httpLbs :: forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs Request
r Manager
m = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Request -> Manager -> IO (Response ByteString)
Client.httpLbs Request
r Manager
m
simpleHttp :: MonadIO m => String -> m L.ByteString
simpleHttp :: forall (m :: * -> *). MonadIO m => String -> m ByteString
simpleHttp String
url = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
Manager
man <- ManagerSettings -> IO Manager
newManager ManagerSettings
tlsManagerSettings
Request
req <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadThrow m => String -> m Request
parseUrlThrow String
url
forall body. Response body -> body
responseBody forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
A.<$> forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs (Request -> Request
setConnectionClose Request
req) Manager
man
setConnectionClose :: Request -> Request
setConnectionClose :: Request -> Request
setConnectionClose Request
req = Request
req{requestHeaders :: RequestHeaders
requestHeaders = (HeaderName
"Connection", ByteString
"close") forall a. a -> [a] -> [a]
: Request -> RequestHeaders
requestHeaders Request
req}
lbsResponse :: Monad m
=> Response (ConduitM () S.ByteString m ())
-> m (Response L.ByteString)
lbsResponse :: forall (m :: * -> *).
Monad m =>
Response (ConduitM () ByteString m ()) -> m (Response ByteString)
lbsResponse Response (ConduitM () ByteString m ())
res = do
[ByteString]
bss <- forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit forall a b. (a -> b) -> a -> b
$ forall body. Response body -> body
responseBody Response (ConduitM () ByteString m ())
res forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
CL.consume
forall (m :: * -> *) a. Monad m => a -> m a
return Response (ConduitM () ByteString m ())
res
{ responseBody :: ByteString
responseBody = [ByteString] -> ByteString
L.fromChunks [ByteString]
bss
}
http :: MonadResource m
=> Request
-> Manager
-> m (Response (ConduitM i S.ByteString m ()))
http :: forall (m :: * -> *) i.
MonadResource m =>
Request -> Manager -> m (Response (ConduitM i ByteString m ()))
http Request
req Manager
man = do
(ReleaseKey
key, Response BodyReader
res) <- forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate (Request -> Manager -> IO (Response BodyReader)
Client.responseOpen Request
req Manager
man) forall a. Response a -> IO ()
Client.responseClose
forall (m :: * -> *) a. Monad m => a -> m a
return Response BodyReader
res { responseBody :: ConduitM i ByteString m ()
responseBody = do
forall (m :: * -> *) i.
MonadIO m =>
BodyReader -> ConduitM i ByteString m ()
HCC.bodyReaderSource forall a b. (a -> b) -> a -> b
$ forall body. Response body -> body
responseBody Response BodyReader
res
forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
key
}
requestBodySource :: Int64 -> ConduitM () S.ByteString (ResourceT IO) () -> RequestBody
requestBodySource :: Int64 -> ConduitM () ByteString (ResourceT IO) () -> RequestBody
requestBodySource Int64
size = Int64 -> GivesPopper () -> RequestBody
RequestBodyStream Int64
size forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConduitM () ByteString (ResourceT IO) () -> GivesPopper ()
srcToPopper
requestBodySourceChunked :: ConduitM () S.ByteString (ResourceT IO) () -> RequestBody
requestBodySourceChunked :: ConduitM () ByteString (ResourceT IO) () -> RequestBody
requestBodySourceChunked = GivesPopper () -> RequestBody
RequestBodyStreamChunked forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConduitM () ByteString (ResourceT IO) () -> GivesPopper ()
srcToPopper
srcToPopper :: ConduitM () S.ByteString (ResourceT IO) () -> HCC.GivesPopper ()
srcToPopper :: ConduitM () ByteString (ResourceT IO) () -> GivesPopper ()
srcToPopper ConduitM () ByteString (ResourceT IO) ()
src NeedsPopper ()
f = forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT forall a b. (a -> b) -> a -> b
$ do
(SealedConduitT () ByteString (ResourceT IO) ()
rsrc0, ()) <- ConduitM () ByteString (ResourceT IO) ()
src forall (m :: * -> *) a b.
Monad m =>
ConduitT () a m ()
-> ConduitT a Void m b -> m (SealedConduitT () a m (), b)
$$+ forall (m :: * -> *) a. Monad m => a -> m a
return ()
IORef (SealedConduitT () ByteString (ResourceT IO) ())
irsrc <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef SealedConduitT () ByteString (ResourceT IO) ()
rsrc0
InternalState
is <- forall (m :: * -> *). Monad m => ResourceT m InternalState
getInternalState
let popper :: IO S.ByteString
popper :: BodyReader
popper = do
SealedConduitT () ByteString (ResourceT IO) ()
rsrc <- forall a. IORef a -> IO a
readIORef IORef (SealedConduitT () ByteString (ResourceT IO) ())
irsrc
(SealedConduitT () ByteString (ResourceT IO) ()
rsrc', Maybe ByteString
mres) <- forall (m :: * -> *) a. ResourceT m a -> InternalState -> m a
runInternalState (SealedConduitT () ByteString (ResourceT IO) ()
rsrc forall (m :: * -> *) a b.
Monad m =>
SealedConduitT () a m ()
-> ConduitT a Void m b -> m (SealedConduitT () a m (), b)
$$++ forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await) InternalState
is
forall a. IORef a -> a -> IO ()
writeIORef IORef (SealedConduitT () ByteString (ResourceT IO) ())
irsrc SealedConduitT () ByteString (ResourceT IO) ()
rsrc'
case Maybe ByteString
mres of
Maybe ByteString
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
S.empty
Just ByteString
bs
| ByteString -> Bool
S.null ByteString
bs -> BodyReader
popper
| Bool
otherwise -> forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
bs
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ NeedsPopper ()
f BodyReader
popper
requestBodySourceIO :: Int64 -> ConduitM () S.ByteString IO () -> RequestBody
requestBodySourceIO :: Int64 -> ConduitM () ByteString IO () -> RequestBody
requestBodySourceIO = Int64 -> ConduitM () ByteString IO () -> RequestBody
HCC.requestBodySource
requestBodySourceChunkedIO :: ConduitM () S.ByteString IO () -> RequestBody
requestBodySourceChunkedIO :: ConduitM () ByteString IO () -> RequestBody
requestBodySourceChunkedIO = ConduitM () ByteString IO () -> RequestBody
HCC.requestBodySourceChunked