packages feed

web-cookiejar 0.1.0.0 → 0.1.1.0

raw patch · 4 files changed

+94/−6 lines, 4 filesdep +directorydep ~QuickCheck

Dependencies added: directory

Dependency ranges changed: QuickCheck

Files

ChangeLog.md view
@@ -2,6 +2,12 @@  `web-cookiejar` uses [PVP Versioning][1]. +## 0.1.1.0 -- 2025-06-23++* Relax the upper bound of the QuickCheck test dependency+* Add combinators that simplify common usage with http-client++ ## 0.1.0.0 -- 2025-04-07  * Initial version.
src/Web/Cookie/Jar.hs view
@@ -11,12 +11,19 @@ in the Netscape/Mozilla cookie jar; see `cookieBuilder`. -} module Web.Cookie.Jar-  ( -- * read/write Cookie Jar files+  ( -- * read and write files     writeJar   , writeJar'   , writeNetscapeJar   , readJar+  , readJarX+  , BadJarFile +    -- * update HTTP messages+  , addCookiesFromFile+  , saveCookies+  , usingCookiesFromFile+     -- * Cookie jar format      -- ** parsing@@ -36,6 +43,7 @@ where  import Control.Applicative ((<|>))+import Control.Exception (Exception, throwIO) import Control.Monad (void) import Data.Attoparsec.ByteString.Char8   ( Parser@@ -51,7 +59,7 @@   , try   ) import Data.ByteString (ByteString)-import qualified Data.ByteString as B+import qualified Data.ByteString as BS import Data.ByteString.Builder   ( Builder   , byteString@@ -61,6 +69,7 @@   ) import qualified Data.ByteString.Lazy as L import Data.Char (ord)+import Data.Time (getCurrentTime) import Data.Time.Clock.POSIX   ( posixSecondsToUTCTime   , utcTimeToPOSIXSeconds@@ -68,11 +77,74 @@ import Network.HTTP.Client   ( Cookie (..)   , CookieJar+  , Request+  , Response   , createCookieJar   , destroyCookieJar+  , insertCookiesIntoRequest+  , updateCookieJar   )+import System.Directory (doesFileExist)  +-- | Perform a HTTP request first loading then saving any matching cookies from a cookie file+usingCookiesFromFile :: FilePath -> Request -> (Request -> IO (Response b)) -> IO (Response b)+usingCookiesFromFile jarPath req doReq = do+  req' <- addCookiesFromFile jarPath req+  resp <- doReq req'+  saveCookies jarPath resp req'+++{- | Add any appropriate Cookies from a cookie file to a @Request@++ - if the file is absent, no update occurs+ - throws @BadJarFile@ if the file can't be parsed+-}+addCookiesFromFile+  :: FilePath+  -- ^ path to the cookie file+  -> Request+  -> IO Request+addCookiesFromFile dataPath req = do+  pathExists <- doesFileExist dataPath+  if not pathExists+    then pure req+    else do+      now <- getCurrentTime+      readJarX dataPath >>= \jar -> do+        let (req', _jar') = insertCookiesIntoRequest req jar now+        pure req'+++{- | Update the cookie file with any cookies in the response++When the file does not exist, it's created as long as the parent directory+exists and permits the file to be written++The output is saved to the cookie file using 'writeJar'++throws an exception if:+  - cannot write due to permissions or parent directory not existing+  - the file exists, but cannot be parsed into Cookies+-}+saveCookies :: FilePath -> Response a -> Request -> IO (Response a)+saveCookies dataPath resp req = do+  pathExists <- doesFileExist dataPath+  old <- if pathExists then readJarX dataPath else pure (createCookieJar [])+  now <- getCurrentTime+  let (updated, resp_) = updateCookieJar resp req now old+  writeJar dataPath updated+  pure resp_+++-- | Reasons a jar file could not be loaded+data BadJarFile = InvalidJar+  deriving (Eq, Show)+++instance Exception BadJarFile++ -- | Parse a @ByteString@ containing a cookie jar in the Netscape/Mozilla format parseCookieJar :: ByteString -> Either String CookieJar parseCookieJar = parseOnly cookieJarParser@@ -185,7 +257,14 @@  -- | Read a Cookie Jar from a file. readJar :: FilePath -> IO (Either String CookieJar)-readJar = fmap parseCookieJar . B.readFile+readJar = fmap parseCookieJar . BS.readFile+++-- | Like 'readJar', but throws @BadJarFile@ in @IO@ if the read fails+readJarX :: FilePath -> IO CookieJar+readJarX p =+  let handleErr = either (const $ throwIO InvalidJar) pure+   in readJar p >>= handleErr   {- | Builder for one cookie; generates a single line in the Cookie Jar file format
test/Cookie/JarSpec.hs view
@@ -91,7 +91,9 @@   cookieJarWithX-  :: (CookieJar -> Builder) -> CookieJar -> (CookieJar, ByteString, Either String CookieJar)+  :: (CookieJar -> Builder)+  -> CookieJar+  -> (CookieJar, ByteString, Either String CookieJar) cookieJarWithX toBuilder j =   let txt = asByteString $ toBuilder j    in (j, txt, parseCookieJar txt)
web-cookiejar.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               web-cookiejar-version:            0.1.0.0+version:            0.1.1.0 synopsis:           Parsing/printing of persistent web cookies description:   A library that provides parsing and printing functions that read and write web@@ -34,6 +34,7 @@     , attoparsec           >=0.14.4 && <0.15     , base                 >=4.10 && <5     , bytestring           >=0.10.8 && <0.11 || >=0.11.3 && <0.13+    , directory            >=1.3 && <1.4     , http-client          >=0.5 && <0.8     , time                 >=1.8 && <1.15 @@ -52,7 +53,7 @@     , bytestring     , hspec                >=2.7.0 && <2.12.0     , http-client-    , QuickCheck           >= 2.13 && < 2.16+    , QuickCheck           >= 2.13 && < 2.18     , temporary            >= 1.2 && < 1.4     , time     , web-cookiejar