websockets-0.4.0.0: src/Network/WebSockets/Mask.hs
-- | Masking of fragmes using a simple XOR algorithm
{-# LANGUAGE BangPatterns #-}
module Network.WebSockets.Mask
( Mask
, maskPayload
, randomMask
) where
import Control.Applicative ((<$>))
import Control.Monad (replicateM)
import Data.Bits (xor)
import System.Random (randomRIO)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
-- | ByteString should be exactly 4 bytes long
type Mask = Maybe B.ByteString
-- | Apply mask
maskPayload :: Mask -> BL.ByteString -> BL.ByteString
maskPayload Nothing = id
maskPayload (Just mask) = snd . BL.mapAccumL f 0
where
len = B.length mask
f !i !c = let i' = (i + 1) `mod` len
m = mask `B.index` i
in (i', m `xor` c)
-- | Create a random mask
randomMask :: IO Mask
randomMask = Just . B.pack <$> replicateM 4 randomByte
where
randomByte = fromIntegral <$> randomRIO (0x00 :: Int, 0xff)