wai-session 0.3.2 → 0.3.3
raw patch · 4 files changed
+28/−21 lines, 4 filesdep +bytestring-builderdep +entropy
Dependencies added: bytestring-builder, entropy
Files
- Network/Wai/Session.hs +14/−9
- Network/Wai/Session/Map.hs +1/−1
- README +10/−10
- wai-session.cabal +3/−1
Network/Wai/Session.hs view
@@ -1,9 +1,7 @@ {-# LANGUAGE CPP #-} module Network.Wai.Session (Session, SessionStore, withSession, genSessionId) where -import Data.Unique (newUnique, hashUnique)-import Data.Ratio (numerator, denominator)-import Data.Time.Clock.POSIX (getPOSIXTime)+import Data.Monoid (mconcat) import Data.String (fromString) import Control.Monad.IO.Class (liftIO) import Network.HTTP.Types (ResponseHeaders)@@ -22,9 +20,13 @@ import Data.Vault (Key) import qualified Data.Vault as Vault #endif-import Data.ByteString (ByteString)+import Data.ByteString (ByteString, foldr')+import Data.ByteString.Lazy (toStrict)+import Data.ByteString.Builder (word8Hex, toLazyByteString) import qualified Blaze.ByteString.Builder as Builder +import System.Entropy (getEntropy)+ -- | Type representing a single session (a lookup, insert pair) type Session m k v = ((k -> m (Maybe v)), (k -> v -> m ())) @@ -67,14 +69,17 @@ setCookie = fromString "Set-Cookie" ciCookie = fromString "Cookie" --- | Simple session ID generator based on time and 'Data.Unique'+-- | Simple session ID generator using cryptographically strong random IDs -- -- Useful for session stores that use session IDs. genSessionId :: IO ByteString genSessionId = do- u <- fmap (toInteger . hashUnique) newUnique- time <- fmap toRational getPOSIXTime- return $ fromString $ show (numerator time * denominator time * u)+ randBytes <- getEntropy 32+ return $ prettyPrint randBytes+ where+ prettyPrint :: ByteString -> ByteString+ prettyPrint = toStrict . toLazyByteString . mconcat . Data.ByteString.foldr'+ ( \ byte acc -> word8Hex byte:acc ) [] -- | Run a function over the headers in a 'Response' mapHeader :: (ResponseHeaders -> ResponseHeaders) -> Response -> Response@@ -82,7 +87,7 @@ mapHeader f (ResponseBuilder s h b) = ResponseBuilder s (f h) b #if MIN_VERSION_wai(3,0,0) mapHeader f (ResponseStream s h b) = ResponseStream s (f h) b-mapHeader _ (ResponseRaw _ _) = error "Cannot mapHeader of Wai.Interal.ResponseRaw when trying to add session cookie header"+mapHeader f (ResponseRaw io resp) = ResponseRaw io (mapHeader f resp) #else mapHeader f (ResponseSource s h b) = ResponseSource s (f h) b #endif
Network/Wai/Session/Map.hs view
@@ -30,7 +30,7 @@ case Map.lookup k m of Just sv -> return (sessionFromMapStateVar sv, return k) -- Could not find key, so it's as if we were not sent one- Nothing -> mapStore' (return k) ssv Nothing+ Nothing -> mapStore' gen ssv Nothing mapStore' genNewKey ssv Nothing = do newKey <- genNewKey sv <- newThreadSafeStateVar Map.empty
README view
@@ -1,10 +1,10 @@-Provides a generic, cookie-based middleware for sessions that is-parameterised over the session store, the cookie name, and the-cookie parameters (such as path, expiry, etc). Passes a pair of-functions (lookup key, set key) for the current session through the-'Vault' in the 'Request'.--Also provides a simple example session store based on threadsafe-'IORef's and 'Data.Map'.--See example/Main.hs in git for example usage.+ Provides a generic, cookie-based middleware for sessions that is+ parameterised over the session store, the cookie name, and the+ cookie parameters (such as path, expiry, etc). Passes a pair of+ functions (lookup key, set key) for the current session through the+ 'Vault' in the 'Request'.+ .+ Also provides a simple example session store based on threadsafe+ 'IORef's and 'Data.Map'.+ .+ See example/Main.hs in git for example usage.
wai-session.cabal view
@@ -1,5 +1,5 @@ name: wai-session-version: 0.3.2+version: 0.3.3 cabal-version: >= 1.8 license: OtherLicense license-file: COPYING@@ -37,6 +37,8 @@ base == 4.*, containers, bytestring,+ bytestring-builder,+ entropy, transformers, time, StateVar,