{-# LANGUAGE CPP, DeriveDataTypeable #-}
module Happstack.Server.Internal.Cookie
( Cookie(..)
, CookieLife(..)
, SameSite(..)
, calcLife
, mkCookie
, mkCookieHeader
, getCookies
, getCookie
, getCookies'
, getCookie'
, parseCookies
, cookiesParser
)
where
import Control.Monad
import Control.Monad.Fail (MonadFail)
import qualified Data.ByteString.Char8 as C
import Data.Char (chr, toLower)
import Data.Data (Data, Typeable)
import Data.List ((\\), intersperse)
import Data.Time.Clock (UTCTime, addUTCTime, diffUTCTime)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
import Happstack.Server.Internal.Clock (getApproximateUTCTime)
import Network.URI (escapeURIString)
import Text.ParserCombinators.Parsec hiding (token)
#if MIN_VERSION_time(1,5,0)
import Data.Time.Format (formatTime, defaultTimeLocale)
#else
import Data.Time.Format (formatTime)
import System.Locale (defaultTimeLocale)
#endif
data Cookie = Cookie
{ Cookie -> [Char]
cookieVersion :: String
, Cookie -> [Char]
cookiePath :: String
, Cookie -> [Char]
cookieDomain :: String
, Cookie -> [Char]
cookieName :: String
, Cookie -> [Char]
cookieValue :: String
, Cookie -> Bool
secure :: Bool
, Cookie -> Bool
httpOnly :: Bool
, Cookie -> SameSite
sameSite :: SameSite
, Cookie -> Bool
partitioned :: Bool
} deriving(Int -> Cookie -> ShowS
[Cookie] -> ShowS
Cookie -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Cookie] -> ShowS
$cshowList :: [Cookie] -> ShowS
show :: Cookie -> [Char]
$cshow :: Cookie -> [Char]
showsPrec :: Int -> Cookie -> ShowS
$cshowsPrec :: Int -> Cookie -> ShowS
Show,Cookie -> Cookie -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Cookie -> Cookie -> Bool
$c/= :: Cookie -> Cookie -> Bool
== :: Cookie -> Cookie -> Bool
$c== :: Cookie -> Cookie -> Bool
Eq,ReadPrec [Cookie]
ReadPrec Cookie
Int -> ReadS Cookie
ReadS [Cookie]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Cookie]
$creadListPrec :: ReadPrec [Cookie]
readPrec :: ReadPrec Cookie
$creadPrec :: ReadPrec Cookie
readList :: ReadS [Cookie]
$creadList :: ReadS [Cookie]
readsPrec :: Int -> ReadS Cookie
$creadsPrec :: Int -> ReadS Cookie
Read,Typeable,Typeable Cookie
Cookie -> DataType
Cookie -> Constr
(forall b. Data b => b -> b) -> Cookie -> Cookie
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Cookie -> u
forall u. (forall d. Data d => d -> u) -> Cookie -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Cookie -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Cookie -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Cookie
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Cookie -> c Cookie
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Cookie)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Cookie)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Cookie -> m Cookie
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Cookie -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Cookie -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Cookie -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Cookie -> [u]
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Cookie -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Cookie -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Cookie -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Cookie -> r
gmapT :: (forall b. Data b => b -> b) -> Cookie -> Cookie
$cgmapT :: (forall b. Data b => b -> b) -> Cookie -> Cookie
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Cookie)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Cookie)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Cookie)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Cookie)
dataTypeOf :: Cookie -> DataType
$cdataTypeOf :: Cookie -> DataType
toConstr :: Cookie -> Constr
$ctoConstr :: Cookie -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Cookie
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Cookie
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Cookie -> c Cookie
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Cookie -> c Cookie
Data)
data CookieLife
= Session
| MaxAge Int
| Expires UTCTime
| Expired
deriving (CookieLife -> CookieLife -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CookieLife -> CookieLife -> Bool
$c/= :: CookieLife -> CookieLife -> Bool
== :: CookieLife -> CookieLife -> Bool
$c== :: CookieLife -> CookieLife -> Bool
Eq, Eq CookieLife
CookieLife -> CookieLife -> Bool
CookieLife -> CookieLife -> Ordering
CookieLife -> CookieLife -> CookieLife
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CookieLife -> CookieLife -> CookieLife
$cmin :: CookieLife -> CookieLife -> CookieLife
max :: CookieLife -> CookieLife -> CookieLife
$cmax :: CookieLife -> CookieLife -> CookieLife
>= :: CookieLife -> CookieLife -> Bool
$c>= :: CookieLife -> CookieLife -> Bool
> :: CookieLife -> CookieLife -> Bool
$c> :: CookieLife -> CookieLife -> Bool
<= :: CookieLife -> CookieLife -> Bool
$c<= :: CookieLife -> CookieLife -> Bool
< :: CookieLife -> CookieLife -> Bool
$c< :: CookieLife -> CookieLife -> Bool
compare :: CookieLife -> CookieLife -> Ordering
$ccompare :: CookieLife -> CookieLife -> Ordering
Ord, ReadPrec [CookieLife]
ReadPrec CookieLife
Int -> ReadS CookieLife
ReadS [CookieLife]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CookieLife]
$creadListPrec :: ReadPrec [CookieLife]
readPrec :: ReadPrec CookieLife
$creadPrec :: ReadPrec CookieLife
readList :: ReadS [CookieLife]
$creadList :: ReadS [CookieLife]
readsPrec :: Int -> ReadS CookieLife
$creadsPrec :: Int -> ReadS CookieLife
Read, Int -> CookieLife -> ShowS
[CookieLife] -> ShowS
CookieLife -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [CookieLife] -> ShowS
$cshowList :: [CookieLife] -> ShowS
show :: CookieLife -> [Char]
$cshow :: CookieLife -> [Char]
showsPrec :: Int -> CookieLife -> ShowS
$cshowsPrec :: Int -> CookieLife -> ShowS
Show, Typeable)
data SameSite
= SameSiteLax
| SameSiteStrict
| SameSiteNone
| SameSiteNoValue
deriving (SameSite -> SameSite -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SameSite -> SameSite -> Bool
$c/= :: SameSite -> SameSite -> Bool
== :: SameSite -> SameSite -> Bool
$c== :: SameSite -> SameSite -> Bool
Eq, Eq SameSite
SameSite -> SameSite -> Bool
SameSite -> SameSite -> Ordering
SameSite -> SameSite -> SameSite
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SameSite -> SameSite -> SameSite
$cmin :: SameSite -> SameSite -> SameSite
max :: SameSite -> SameSite -> SameSite
$cmax :: SameSite -> SameSite -> SameSite
>= :: SameSite -> SameSite -> Bool
$c>= :: SameSite -> SameSite -> Bool
> :: SameSite -> SameSite -> Bool
$c> :: SameSite -> SameSite -> Bool
<= :: SameSite -> SameSite -> Bool
$c<= :: SameSite -> SameSite -> Bool
< :: SameSite -> SameSite -> Bool
$c< :: SameSite -> SameSite -> Bool
compare :: SameSite -> SameSite -> Ordering
$ccompare :: SameSite -> SameSite -> Ordering
Ord, Typeable, Typeable SameSite
SameSite -> DataType
SameSite -> Constr
(forall b. Data b => b -> b) -> SameSite -> SameSite
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SameSite -> u
forall u. (forall d. Data d => d -> u) -> SameSite -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SameSite -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SameSite -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SameSite
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SameSite -> c SameSite
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SameSite)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SameSite)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SameSite -> m SameSite
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SameSite -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SameSite -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> SameSite -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SameSite -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SameSite -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SameSite -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SameSite -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SameSite -> r
gmapT :: (forall b. Data b => b -> b) -> SameSite -> SameSite
$cgmapT :: (forall b. Data b => b -> b) -> SameSite -> SameSite
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SameSite)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SameSite)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SameSite)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SameSite)
dataTypeOf :: SameSite -> DataType
$cdataTypeOf :: SameSite -> DataType
toConstr :: SameSite -> Constr
$ctoConstr :: SameSite -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SameSite
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SameSite
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SameSite -> c SameSite
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SameSite -> c SameSite
Data, Int -> SameSite -> ShowS
[SameSite] -> ShowS
SameSite -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [SameSite] -> ShowS
$cshowList :: [SameSite] -> ShowS
show :: SameSite -> [Char]
$cshow :: SameSite -> [Char]
showsPrec :: Int -> SameSite -> ShowS
$cshowsPrec :: Int -> SameSite -> ShowS
Show, ReadPrec [SameSite]
ReadPrec SameSite
Int -> ReadS SameSite
ReadS [SameSite]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SameSite]
$creadListPrec :: ReadPrec [SameSite]
readPrec :: ReadPrec SameSite
$creadPrec :: ReadPrec SameSite
readList :: ReadS [SameSite]
$creadList :: ReadS [SameSite]
readsPrec :: Int -> ReadS SameSite
$creadsPrec :: Int -> ReadS SameSite
Read)
displaySameSite :: SameSite -> String
displaySameSite :: SameSite -> [Char]
displaySameSite SameSite
ss =
case SameSite
ss of
SameSite
SameSiteLax -> [Char]
"SameSite=Lax"
SameSite
SameSiteStrict -> [Char]
"SameSite=Strict"
SameSite
SameSiteNone -> [Char]
"SameSite=None"
SameSite
SameSiteNoValue -> [Char]
""
calcLife :: CookieLife -> IO (Maybe (Int, UTCTime))
calcLife :: CookieLife -> IO (Maybe (Int, UTCTime))
calcLife CookieLife
Session = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
calcLife (MaxAge Int
s) =
do UTCTime
now <- IO UTCTime
getApproximateUTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (Int
s, NominalDiffTime -> UTCTime -> UTCTime
addUTCTime (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s) UTCTime
now))
calcLife (Expires UTCTime
expirationDate) =
do UTCTime
now <- IO UTCTime
getApproximateUTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall a b. (RealFrac a, Integral b) => a -> b
round forall a b. (a -> b) -> a -> b
$ UTCTime
expirationDate UTCTime -> UTCTime -> NominalDiffTime
`diffUTCTime` UTCTime
now, UTCTime
expirationDate)
calcLife CookieLife
Expired =
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Int
0, NominalDiffTime -> UTCTime
posixSecondsToUTCTime NominalDiffTime
0)
mkCookie :: String
-> String
-> Cookie
mkCookie :: [Char] -> [Char] -> Cookie
mkCookie [Char]
key [Char]
val = [Char]
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> Bool
-> Bool
-> SameSite
-> Bool
-> Cookie
Cookie [Char]
"1" [Char]
"/" [Char]
"" [Char]
key [Char]
val Bool
False Bool
False SameSite
SameSiteNoValue Bool
False
mkCookieHeader :: Maybe (Int, UTCTime) -> Cookie -> String
Maybe (Int, UTCTime)
mLife Cookie
cookie =
let
l :: [([Char], [Char])]
l =
[ (,) [Char]
"Domain=" (Cookie -> [Char]
cookieDomain Cookie
cookie)
, (,) [Char]
"Max-Age=" (forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"" (forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => a -> a -> a
max Int
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) Maybe (Int, UTCTime)
mLife)
, (,) [Char]
"expires=" (forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"" (UTCTime -> [Char]
formatTime' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) Maybe (Int, UTCTime)
mLife)
, (,) [Char]
"Path=" (Cookie -> [Char]
cookiePath Cookie
cookie)
, (,) [Char]
"Version=" ((Cookie -> [Char]) -> [Char]
s Cookie -> [Char]
cookieVersion)
]
formatTime' :: UTCTime -> [Char]
formatTime' =
forall t. FormatTime t => TimeLocale -> [Char] -> t -> [Char]
formatTime TimeLocale
defaultTimeLocale [Char]
"%a, %d-%b-%Y %X GMT"
encode :: ShowS
encode =
(Char -> Bool) -> ShowS
escapeURIString
(\Char
c -> Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char
'A'..Char
'Z'] forall a. [a] -> [a] -> [a]
++ [Char
'a'..Char
'z'] forall a. [a] -> [a] -> [a]
++ [Char
'0'..Char
'9'] forall a. [a] -> [a] -> [a]
++ [Char]
"-_.~"))
s :: (Cookie -> [Char]) -> [Char]
s Cookie -> [Char]
f | Cookie -> [Char]
f Cookie
cookie forall a. Eq a => a -> a -> Bool
== [Char]
"" = [Char]
""
| Bool
otherwise = Char
'\"' forall a. a -> [a] -> [a]
: (ShowS
encode forall a b. (a -> b) -> a -> b
$ Cookie -> [Char]
f Cookie
cookie) forall a. [a] -> [a] -> [a]
++ [Char]
"\""
in
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a. a -> [a] -> [a]
intersperse [Char]
";" forall a b. (a -> b) -> a -> b
$
(Cookie -> [Char]
cookieName Cookie
cookieforall a. [a] -> [a] -> [a]
++[Char]
"="forall a. [a] -> [a] -> [a]
++(Cookie -> [Char]) -> [Char]
s Cookie -> [Char]
cookieValue)forall a. a -> [a] -> [a]
:[ ([Char]
kforall a. [a] -> [a] -> [a]
++[Char]
v) | ([Char]
k,[Char]
v) <- [([Char], [Char])]
l, [Char]
"" forall a. Eq a => a -> a -> Bool
/= [Char]
v ]
forall a. [a] -> [a] -> [a]
++ (if Cookie -> Bool
secure Cookie
cookie then [[Char]
"Secure"] else [])
forall a. [a] -> [a] -> [a]
++ (if Cookie -> Bool
httpOnly Cookie
cookie then [[Char]
"HttpOnly"] else [])
forall a. [a] -> [a] -> [a]
++ (if Cookie -> SameSite
sameSite Cookie
cookie forall a. Eq a => a -> a -> Bool
/= SameSite
SameSiteNoValue
then [SameSite -> [Char]
displaySameSite forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cookie -> SameSite
sameSite forall a b. (a -> b) -> a -> b
$ Cookie
cookie] else [])
forall a. [a] -> [a] -> [a]
++ (if Cookie -> Bool
partitioned Cookie
cookie then [[Char]
"Partitioned"] else [])
parseCookies :: String -> Either String [Cookie]
parseCookies :: [Char] -> Either [Char] [Cookie]
parseCookies [Char]
str = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show) forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall s t a.
Stream s Identity t =>
Parsec s () a -> [Char] -> s -> Either ParseError a
parse forall st. GenParser Char st [Cookie]
cookiesParser [Char]
str [Char]
str
cookiesParser :: GenParser Char st [Cookie]
cookiesParser :: forall st. GenParser Char st [Cookie]
cookiesParser = forall st. GenParser Char st [Cookie]
cookies
where
cookies :: ParsecT [Char] u Identity [Cookie]
cookies = do
forall {u}. ParsecT [Char] u Identity ()
ws
[Char]
ver<-forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Char]
"" forall a b. (a -> b) -> a -> b
$ forall tok st a. GenParser tok st a -> GenParser tok st a
try (forall {u}. ParsecT [Char] u Identity [Char]
cookie_version forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\[Char]
x -> forall {u}. ParsecT [Char] u Identity ()
cookieSep forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
x))
[Cookie]
cookieList<-(forall {u}. [Char] -> ParsecT [Char] u Identity Cookie
cookie_value [Char]
ver) forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy1` forall tok st a. GenParser tok st a -> GenParser tok st a
try forall {u}. ParsecT [Char] u Identity ()
cookieSep
forall {u}. ParsecT [Char] u Identity ()
ws
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
forall (m :: * -> *) a. Monad m => a -> m a
return [Cookie]
cookieList
cookie_value :: [Char] -> ParsecT [Char] u Identity Cookie
cookie_value [Char]
ver = do
[Char]
name<-forall {u}. ParsecT [Char] u Identity [Char]
name_parser
forall {u}. ParsecT [Char] u Identity ()
cookieEq
[Char]
val<-forall {u}. ParsecT [Char] u Identity [Char]
value
[Char]
path<-forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Char]
"" forall a b. (a -> b) -> a -> b
$ forall tok st a. GenParser tok st a -> GenParser tok st a
try (forall {u}. ParsecT [Char] u Identity ()
cookieSep forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {u}. ParsecT [Char] u Identity [Char]
cookie_path)
[Char]
domain<-forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Char]
"" forall a b. (a -> b) -> a -> b
$ forall tok st a. GenParser tok st a -> GenParser tok st a
try (forall {u}. ParsecT [Char] u Identity ()
cookieSep forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {u}. ParsecT [Char] u Identity [Char]
cookie_domain)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Char]
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> Bool
-> Bool
-> SameSite
-> Bool
-> Cookie
Cookie [Char]
ver [Char]
path [Char]
domain (ShowS
low [Char]
name) [Char]
val Bool
False Bool
False SameSite
SameSiteNoValue Bool
False
cookie_version :: ParsecT [Char] u Identity [Char]
cookie_version = forall {u}. [Char] -> ParsecT [Char] u Identity [Char]
cookie_special [Char]
"$Version"
cookie_path :: ParsecT [Char] u Identity [Char]
cookie_path = forall {u}. [Char] -> ParsecT [Char] u Identity [Char]
cookie_special [Char]
"$Path"
cookie_domain :: ParsecT [Char] u Identity [Char]
cookie_domain = forall {u}. [Char] -> ParsecT [Char] u Identity [Char]
cookie_special [Char]
"$Domain"
cookie_special :: [Char] -> ParsecT [Char] u Identity [Char]
cookie_special [Char]
s = do
forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
s
forall {u}. ParsecT [Char] u Identity ()
cookieEq
forall {u}. ParsecT [Char] u Identity [Char]
value
cookieSep :: ParsecT [Char] u Identity ()
cookieSep = forall {u}. ParsecT [Char] u Identity ()
ws forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
",;" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {u}. ParsecT [Char] u Identity ()
ws
cookieEq :: ParsecT [Char] u Identity ()
cookieEq = forall {u}. ParsecT [Char] u Identity ()
ws forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'=' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {u}. ParsecT [Char] u Identity ()
ws
ws :: ParsecT [Char] u Identity ()
ws = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
value :: ParsecT [Char] u Identity [Char]
value = forall {u}. ParsecT [Char] u Identity [Char]
word
word :: ParsecT [Char] u Identity [Char]
word = forall tok st a. GenParser tok st a -> GenParser tok st a
try forall {u}. ParsecT [Char] u Identity [Char]
quoted_string forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall tok st a. GenParser tok st a -> GenParser tok st a
try forall {u}. ParsecT [Char] u Identity [Char]
incomp_token forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
""
quoted_string :: ParsecT [Char] u Identity [Char]
quoted_string = do
forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
[Char]
r <-forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ((forall tok st a. GenParser tok st a -> GenParser tok st a
try forall {u}. ParsecT [Char] u Identity Char
quotedPair) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
qdtext))
forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
r
incomp_token :: ParsecT [Char] u Identity [Char]
incomp_token = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf (([Char]
chars forall a. Eq a => [a] -> [a] -> [a]
\\ [Char]
ctl) forall a. Eq a => [a] -> [a] -> [a]
\\ [Char]
" \t\";")
name_parser :: ParsecT [Char] u Identity [Char]
name_parser = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf (([Char]
chars forall a. Eq a => [a] -> [a] -> [a]
\\ [Char]
ctl) forall a. Eq a => [a] -> [a] -> [a]
\\ [Char]
"= ;,")
ctl :: [Char]
ctl = forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
chr (Int
127forall a. a -> [a] -> [a]
:[Int
0..Int
31])
chars :: [Char]
chars = forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
chr [Int
0..Int
127]
octet :: [Char]
octet = forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
chr [Int
0..Int
255]
text :: [Char]
text = [Char]
octet forall a. Eq a => [a] -> [a] -> [a]
\\ [Char]
ctl
qdtext :: [Char]
qdtext = [Char]
text forall a. Eq a => [a] -> [a] -> [a]
\\ [Char]
"\""
quotedPair :: ParsecT [Char] u Identity Char
quotedPair = forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
getCookies :: MonadFail m => C.ByteString -> m [Cookie]
getCookies :: forall (m :: * -> *). MonadFail m => ByteString -> m [Cookie]
getCookies ByteString
h = forall (m :: * -> *).
Monad m =>
ByteString -> m (Either [Char] [Cookie])
getCookies' ByteString
h forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. MonadFail m => [Char] -> m a
failforall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char]
"Cookie parsing failed!"forall a. [a] -> [a] -> [a]
++)) forall (m :: * -> *) a. Monad m => a -> m a
return
getCookie :: MonadFail m => String -> C.ByteString -> m Cookie
getCookie :: forall (m :: * -> *).
MonadFail m =>
[Char] -> ByteString -> m Cookie
getCookie [Char]
s ByteString
h = forall (m :: * -> *).
Monad m =>
[Char] -> ByteString -> m (Either [Char] Cookie)
getCookie' [Char]
s ByteString
h forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char]
"getCookie: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show [Char]
s)) forall (m :: * -> *) a. Monad m => a -> m a
return
getCookies' :: Monad m => C.ByteString -> m (Either String [Cookie])
getCookies' :: forall (m :: * -> *).
Monad m =>
ByteString -> m (Either [Char] [Cookie])
getCookies' ByteString
header | ByteString -> Bool
C.null ByteString
header = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right []
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Char] -> Either [Char] [Cookie]
parseCookies (ByteString -> [Char]
C.unpack ByteString
header)
getCookie' :: Monad m => String -> C.ByteString -> m (Either String Cookie)
getCookie' :: forall (m :: * -> *).
Monad m =>
[Char] -> ByteString -> m (Either [Char] Cookie)
getCookie' [Char]
s ByteString
h = do
Either [Char] [Cookie]
cs <- forall (m :: * -> *).
Monad m =>
ByteString -> m (Either [Char] [Cookie])
getCookies' ByteString
h
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ do
[Cookie]
cooks <- Either [Char] [Cookie]
cs
case forall a. (a -> Bool) -> [a] -> [a]
filter (\Cookie
x->forall a. Eq a => a -> a -> Bool
(==) (ShowS
low [Char]
s) (Cookie -> [Char]
cookieName Cookie
x) ) [Cookie]
cooks of
[] -> forall a b. a -> Either a b
Left [Char]
"No cookie found"
[Cookie]
f -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [Cookie]
f
low :: String -> String
low :: ShowS
low = forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower