{-| Conduit sources/sinks for Netscape/Mozilla cookie jar format. |-} module Data.CURL.CookieJar.Conduit ( -- * Parsing cookie jars parseCookiesC , parseCookiesEitherC , sinkCookieJar , sinkCookieJarEither , sourceCookieJarCookies -- * Pretty-printing cookie jars , prettyCookieC , prettyCookiesC , prettyCookieJarC -- * Handle and file IO , readCookieJarFileC , readCookieJarHandleC , sourceCookiesFile , sourceCookiesHandle , sinkCookiesFile , sinkCookiesHandle , writeCookieJarFileC , writeCookieJarHandleC ) where import Data.ByteString (ByteString) import Conduit ( MonadThrow , PrimMonad , MonadIO , MonadResource , mapC , ConduitT , (.|) , yield , sourceFile , sourceHandle , sinkFile , sinkHandle ) import System.IO (Handle) import Data.Conduit.List (sourceList, consume) import Data.Conduit.ByteString.Builder (builderToByteString) import Data.Conduit.Attoparsec ( ParseError, conduitParser, conduitParserEither, sinkParser, sinkParserEither) import Data.CURL.CookieJar.Parser (cookieParser, cookieJarParser) import Data.CURL.CookieJar.PrettyPrinter (CookieJarHeader, prettyCookie, prettyCookieJarHeader) import Network.HTTP.Client (Cookie, CookieJar, createCookieJar, destroyCookieJar) -- | Parse cookies from a cookie jar -- -- Note that this does not skip the header parseCookiesC :: MonadThrow m => ConduitT ByteString Cookie m () parseCookiesC = conduitParser cookieParser .| mapC snd -- | Parse cookies from a cookie jar, returning errors as values parseCookiesEitherC :: Monad m => ConduitT ByteString (Either ParseError Cookie) m () parseCookiesEitherC = conduitParserEither cookieParser .| mapC (fmap snd) -- | Parse cookies into a cookie jar, and return the value sinkCookieJar :: MonadThrow m => ConduitT ByteString o m CookieJar sinkCookieJar = sinkParser cookieJarParser -- | Parse cookies into a cookie jar, and return the value, or a parse error sinkCookieJarEither :: Monad m => ConduitT ByteString o m (Either ParseError CookieJar) sinkCookieJarEither = sinkParserEither cookieJarParser -- | Pretty print a single cookie and stream out a chunked ByteString prettyCookieC :: PrimMonad m => Cookie -> ConduitT i ByteString m () prettyCookieC cookie = (yield $ prettyCookie cookie) .| builderToByteString -- | Stream in cookies to pretty-print, along with a header prettyCookiesC :: PrimMonad m => CookieJarHeader -> ConduitT Cookie ByteString m () prettyCookiesC header = cookiesAndHeader .| builderToByteString where cookiesAndHeader = do yield $ prettyCookieJarHeader header mapC prettyCookie -- | Pretty-print a cookie jar prettyCookieJarC :: PrimMonad m => CookieJarHeader -> CookieJar -> ConduitT i ByteString m () prettyCookieJarC header jar = sourceCookieJarCookies jar .| prettyCookiesC header -- | Read a cookie jar from a file readCookieJarFileC :: MonadThrow m => MonadResource m => FilePath -> ConduitT i o m CookieJar readCookieJarFileC path = sourceCookiesFile path .| sinkCookieJarCookies -- | Read a cookie jar from a handle readCookieJarHandleC :: MonadIO m => MonadThrow m => Handle -> ConduitT i o m CookieJar readCookieJarHandleC handle = sourceCookiesHandle handle .| sinkCookieJarCookies -- | Source cookies from a cookie jar sourceCookieJarCookies :: Monad m => CookieJar -> ConduitT i Cookie m () sourceCookieJarCookies = sourceList . destroyCookieJar -- | Make a cookie jar from a finite stream of cookies sinkCookieJarCookies :: Monad m => ConduitT Cookie o m CookieJar sinkCookieJarCookies = createCookieJar <$> consume -- | Source cookies from a cookie jar file sourceCookiesFile :: MonadThrow m => MonadResource m => FilePath -> ConduitT i Cookie m () sourceCookiesFile path = sourceFile path .| parseCookiesC -- | Source cookies from a handle sourceCookiesHandle :: MonadThrow m => MonadIO m => Handle -> ConduitT i Cookie m () sourceCookiesHandle handle = sourceHandle handle .| parseCookiesC -- | Write cookies to a file sinkCookiesFile :: MonadResource m => PrimMonad m => CookieJarHeader -> FilePath -> ConduitT Cookie o m () sinkCookiesFile header path = prettyCookiesC header .| sinkFile path -- | Write cookies to a handle sinkCookiesHandle :: MonadIO m => PrimMonad m => CookieJarHeader -> Handle -> ConduitT Cookie o m () sinkCookiesHandle header handle = prettyCookiesC header .| sinkHandle handle -- | Write a cookie jar to a file writeCookieJarFileC :: MonadResource m => PrimMonad m => CookieJarHeader -> CookieJar -> FilePath -> ConduitT i o m () writeCookieJarFileC header jar path = sourceCookieJarCookies jar .| sinkCookiesFile header path writeCookieJarHandleC :: MonadIO m => PrimMonad m => CookieJarHeader -> CookieJar -> Handle -> ConduitT i o m () writeCookieJarHandleC header jar handle = sourceCookieJarCookies jar .| sinkCookiesHandle header handle