lookupSessionBS/setSessionBS (#235)
This commit is contained in:
parent
61efa0e1af
commit
fec0d42827
@ -70,8 +70,10 @@ module Yesod.Handler
|
|||||||
-- * Session
|
-- * Session
|
||||||
, SessionMap
|
, SessionMap
|
||||||
, lookupSession
|
, lookupSession
|
||||||
|
, lookupSessionBS
|
||||||
, getSession
|
, getSession
|
||||||
, setSession
|
, setSession
|
||||||
|
, setSessionBS
|
||||||
, deleteSession
|
, deleteSession
|
||||||
-- ** Ultimate destination
|
-- ** Ultimate destination
|
||||||
, setUltDest
|
, setUltDest
|
||||||
@ -272,7 +274,7 @@ data GHState = GHState
|
|||||||
, ghsHeaders :: Endo [Header]
|
, ghsHeaders :: Endo [Header]
|
||||||
}
|
}
|
||||||
|
|
||||||
type SessionMap = Map.Map Text Text
|
type SessionMap = Map.Map Text S.ByteString
|
||||||
|
|
||||||
-- | An extension of the basic WAI 'W.Application' datatype to provide extra
|
-- | An extension of the basic WAI 'W.Application' datatype to provide extra
|
||||||
-- features needed by Yesod. Users should never need to use this directly, as
|
-- features needed by Yesod. Users should never need to use this directly, as
|
||||||
@ -678,7 +680,13 @@ expiresAt = setHeader "Expires" . formatRFC1123
|
|||||||
setSession :: Text -- ^ key
|
setSession :: Text -- ^ key
|
||||||
-> Text -- ^ value
|
-> Text -- ^ value
|
||||||
-> GHandler sub master ()
|
-> GHandler sub master ()
|
||||||
setSession k = modify . modSession . Map.insert k
|
setSession k = setSessionBS k . encodeUtf8
|
||||||
|
|
||||||
|
-- | Same as 'setSession', but uses binary data for the value.
|
||||||
|
setSessionBS :: Text
|
||||||
|
-> S.ByteString
|
||||||
|
-> GHandler sub master ()
|
||||||
|
setSessionBS k = modify . modSession . Map.insert k
|
||||||
|
|
||||||
-- | Unsets a session variable. See 'setSession'.
|
-- | Unsets a session variable. See 'setSession'.
|
||||||
deleteSession :: Text -> GHandler sub master ()
|
deleteSession :: Text -> GHandler sub master ()
|
||||||
@ -725,7 +733,11 @@ localNoCurrent =
|
|||||||
|
|
||||||
-- | Lookup for session data.
|
-- | Lookup for session data.
|
||||||
lookupSession :: Text -> GHandler s m (Maybe Text)
|
lookupSession :: Text -> GHandler s m (Maybe Text)
|
||||||
lookupSession n = do
|
lookupSession = (fmap . fmap) (decodeUtf8With lenientDecode) . lookupSessionBS
|
||||||
|
|
||||||
|
-- | Lookup for session data in binary format.
|
||||||
|
lookupSessionBS :: Text -> GHandler s m (Maybe S.ByteString)
|
||||||
|
lookupSessionBS n = do
|
||||||
m <- liftM ghsSession get
|
m <- liftM ghsSession get
|
||||||
return $ Map.lookup n m
|
return $ Map.lookup n m
|
||||||
|
|
||||||
|
|||||||
@ -402,7 +402,7 @@ defaultYesodRunner handler master sub murl toMasterRoute mkey req = do
|
|||||||
(Just key, Just nonce)
|
(Just key, Just nonce)
|
||||||
-> encodeSession key iv exp' host
|
-> encodeSession key iv exp' host
|
||||||
$ Map.toList
|
$ Map.toList
|
||||||
$ Map.insert nonceKey nonce sm
|
$ Map.insert nonceKey (TE.encodeUtf8 nonce) sm
|
||||||
_ -> mempty
|
_ -> mempty
|
||||||
hs' =
|
hs' =
|
||||||
case mkey of
|
case mkey of
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import Yesod.Internal
|
|||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
import System.Random (RandomGen, newStdGen, randomRs)
|
import System.Random (RandomGen, newStdGen, randomRs)
|
||||||
import Web.Cookie (parseCookiesText)
|
import Web.Cookie (parseCookiesText)
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import Data.Text (Text, pack)
|
import Data.Text (Text, pack)
|
||||||
import Network.HTTP.Types (queryToQueryText)
|
import Network.HTTP.Types (queryToQueryText)
|
||||||
@ -25,6 +26,8 @@ import Data.Maybe (fromMaybe, catMaybes)
|
|||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import Data.Text.Encoding (decodeUtf8With)
|
||||||
|
import Data.Text.Encoding.Error (lenientDecode)
|
||||||
|
|
||||||
-- | The parsed request information.
|
-- | The parsed request information.
|
||||||
data Request = Request
|
data Request = Request
|
||||||
@ -38,14 +41,14 @@ data Request = Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseWaiRequest :: W.Request
|
parseWaiRequest :: W.Request
|
||||||
-> [(Text, Text)] -- ^ session
|
-> [(Text, ByteString)] -- ^ session
|
||||||
-> Maybe a
|
-> Maybe a
|
||||||
-> IO Request
|
-> IO Request
|
||||||
parseWaiRequest env session' key' = parseWaiRequest' env session' key' <$> newStdGen
|
parseWaiRequest env session' key' = parseWaiRequest' env session' key' <$> newStdGen
|
||||||
|
|
||||||
parseWaiRequest' :: RandomGen g
|
parseWaiRequest' :: RandomGen g
|
||||||
=> W.Request
|
=> W.Request
|
||||||
-> [(Text, Text)] -- ^ session
|
-> [(Text, ByteString)] -- ^ session
|
||||||
-> Maybe a
|
-> Maybe a
|
||||||
-> g
|
-> g
|
||||||
-> Request
|
-> Request
|
||||||
@ -57,10 +60,13 @@ parseWaiRequest' env session' key' gen = Request gets'' cookies' env langs'' non
|
|||||||
cookies' = maybe [] parseCookiesText reqCookie
|
cookies' = maybe [] parseCookiesText reqCookie
|
||||||
acceptLang = lookup "Accept-Language" $ W.requestHeaders env
|
acceptLang = lookup "Accept-Language" $ W.requestHeaders env
|
||||||
langs = map (pack . S8.unpack) $ maybe [] NWP.parseHttpAccept acceptLang
|
langs = map (pack . S8.unpack) $ maybe [] NWP.parseHttpAccept acceptLang
|
||||||
|
|
||||||
|
lookupText k = fmap (decodeUtf8With lenientDecode) . lookup k
|
||||||
|
|
||||||
-- The language preferences are prioritized as follows:
|
-- The language preferences are prioritized as follows:
|
||||||
langs' = catMaybes [ join $ lookup langKey gets' -- Query _LANG
|
langs' = catMaybes [ join $ lookup langKey gets' -- Query _LANG
|
||||||
, lookup langKey cookies' -- Cookie _LANG
|
, lookup langKey cookies' -- Cookie _LANG
|
||||||
, lookup langKey session' -- Session _LANG
|
, lookupText langKey session' -- Session _LANG
|
||||||
] ++ langs -- Accept-Language(s)
|
] ++ langs -- Accept-Language(s)
|
||||||
|
|
||||||
-- Github issue #195. We want to add an extra two-letter version of any
|
-- Github issue #195. We want to add an extra two-letter version of any
|
||||||
@ -73,7 +79,7 @@ parseWaiRequest' env session' key' gen = Request gets'' cookies' env langs'' non
|
|||||||
-- generated.
|
-- generated.
|
||||||
nonce = case (key', lookup nonceKey session') of
|
nonce = case (key', lookup nonceKey session') of
|
||||||
(Nothing, _) -> Nothing
|
(Nothing, _) -> Nothing
|
||||||
(_, Just x) -> Just x
|
(_, Just x) -> Just $ decodeUtf8With lenientDecode x
|
||||||
_ -> Just $ pack $ randomString 10 gen
|
_ -> Just $ pack $ randomString 10 gen
|
||||||
|
|
||||||
addTwoLetters :: ([Text] -> [Text], Set.Set Text) -> [Text] -> [Text]
|
addTwoLetters :: ([Text] -> [Text], Set.Set Text) -> [Text] -> [Text]
|
||||||
|
|||||||
@ -9,13 +9,14 @@ import Data.Time
|
|||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Control.Monad (guard)
|
import Control.Monad (guard)
|
||||||
import Data.Text (Text, pack, unpack)
|
import Data.Text (Text, pack, unpack)
|
||||||
import Control.Arrow ((***))
|
import Control.Arrow (first)
|
||||||
|
import Control.Applicative ((<$>))
|
||||||
|
|
||||||
encodeSession :: CS.Key
|
encodeSession :: CS.Key
|
||||||
-> CS.IV
|
-> CS.IV
|
||||||
-> UTCTime -- ^ expire time
|
-> UTCTime -- ^ expire time
|
||||||
-> ByteString -- ^ remote host
|
-> ByteString -- ^ remote host
|
||||||
-> [(Text, Text)] -- ^ session
|
-> [(Text, ByteString)] -- ^ session
|
||||||
-> ByteString -- ^ cookie value
|
-> ByteString -- ^ cookie value
|
||||||
encodeSession key iv expire rhost session' =
|
encodeSession key iv expire rhost session' =
|
||||||
CS.encrypt key iv $ encode $ SessionCookie expire rhost session'
|
CS.encrypt key iv $ encode $ SessionCookie expire rhost session'
|
||||||
@ -24,7 +25,7 @@ decodeSession :: CS.Key
|
|||||||
-> UTCTime -- ^ current time
|
-> UTCTime -- ^ current time
|
||||||
-> ByteString -- ^ remote host field
|
-> ByteString -- ^ remote host field
|
||||||
-> ByteString -- ^ cookie value
|
-> ByteString -- ^ cookie value
|
||||||
-> Maybe [(Text, Text)]
|
-> Maybe [(Text, ByteString)]
|
||||||
decodeSession key now rhost encrypted = do
|
decodeSession key now rhost encrypted = do
|
||||||
decrypted <- CS.decrypt key encrypted
|
decrypted <- CS.decrypt key encrypted
|
||||||
SessionCookie expire rhost' session' <-
|
SessionCookie expire rhost' session' <-
|
||||||
@ -33,14 +34,14 @@ decodeSession key now rhost encrypted = do
|
|||||||
guard $ rhost' == rhost
|
guard $ rhost' == rhost
|
||||||
return session'
|
return session'
|
||||||
|
|
||||||
data SessionCookie = SessionCookie UTCTime ByteString [(Text, Text)]
|
data SessionCookie = SessionCookie UTCTime ByteString [(Text, ByteString)]
|
||||||
deriving (Show, Read)
|
deriving (Show, Read)
|
||||||
instance Serialize SessionCookie where
|
instance Serialize SessionCookie where
|
||||||
put (SessionCookie a b c) = putTime a >> put b >> put (map (unpack *** unpack) c)
|
put (SessionCookie a b c) = putTime a >> put b >> put (map (first unpack) c)
|
||||||
get = do
|
get = do
|
||||||
a <- getTime
|
a <- getTime
|
||||||
b <- get
|
b <- get
|
||||||
c <- map (pack *** pack) `fmap` get
|
c <- map (first pack) <$> get
|
||||||
return $ SessionCookie a b c
|
return $ SessionCookie a b c
|
||||||
|
|
||||||
putTime :: Putter UTCTime
|
putTime :: Putter UTCTime
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user