Prepare for http
This commit is contained in:
37
FeedMonad/src/Control/Monad/HTTP.hs
Normal file
37
FeedMonad/src/Control/Monad/HTTP.hs
Normal file
@ -0,0 +1,37 @@
|
||||
{-# LANGUAGE DeriveFunctor #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
module Control.Monad.HTTP where
|
||||
import Data.ByteString.Lazy (ByteString)
|
||||
import Data.URL (URL (URL))
|
||||
import Control.Monad.Free.Church (F, liftF, foldF)
|
||||
import Network.HTTP.Client (Manager, httpLbs, parseRequest, responseBody)
|
||||
import System.IO.Unsafe (unsafeInterleaveIO)
|
||||
|
||||
data OpsF f = Fetch URL (ByteString -> f)
|
||||
deriving Functor
|
||||
|
||||
-- | A restricted HTTP monad
|
||||
--
|
||||
-- While the "regular" code could access http whenever and it would be
|
||||
-- fine, the middleware functions shouldn't probably have full IO
|
||||
-- access. So restricting the access and providing manager and user
|
||||
-- agents should prove useful
|
||||
type FetchM = F OpsF
|
||||
|
||||
-- | Execute a http request and return the bytestring
|
||||
--
|
||||
-- Possible HTTP exceptions are thrown (how?)
|
||||
fetch :: URL -> FetchM ByteString
|
||||
fetch u = liftF (Fetch u id)
|
||||
|
||||
-- Run the http monad
|
||||
--
|
||||
-- The requests are executed lazily, both as an atomic request and as
|
||||
-- a lazy bytestring. Be careful.
|
||||
execute :: Manager -> FetchM a -> IO a
|
||||
execute manager = foldF $ \case
|
||||
Fetch (URL u) k -> k <$> unsafeInterleaveIO (fetchR u)
|
||||
where
|
||||
fetchR u = do
|
||||
req <- parseRequest u
|
||||
responseBody <$> httpLbs req manager
|
Reference in New Issue
Block a user