websockets-0.8.1.1: tests/haskell/Network/WebSockets/Handshake/Tests.hs
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
module Network.WebSockets.Handshake.Tests
( tests
) where
--------------------------------------------------------------------------------
import Control.Concurrent (forkIO)
import Control.Exception (handle)
import Data.ByteString.Char8 ()
import Data.IORef (newIORef, readIORef,
writeIORef)
import Data.Maybe (fromJust)
import qualified System.IO.Streams.Attoparsec as Streams
import qualified System.IO.Streams.Builder as Streams
import Test.Framework (Test, testGroup)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit (Assertion, (@?=), assert)
--------------------------------------------------------------------------------
import Network.WebSockets
import Network.WebSockets.Connection
import Network.WebSockets.Http
import Network.WebSockets.Tests.Util
--------------------------------------------------------------------------------
tests :: Test
tests = testGroup "Network.WebSockets.Handshake.Test"
[ testCase "handshake Hybi13" testHandshakeHybi13
, testCase "handshake reject" testHandshakeReject
, testCase "handshake Hybi9000" testHandshakeHybi9000
]
--------------------------------------------------------------------------------
testHandshake :: RequestHead -> (PendingConnection -> IO a) -> IO ResponseHead
testHandshake rq app = do
(is, os) <- makeChanPipe
os' <- Streams.builderStream os
_ <- forkIO $ do
_ <- app (PendingConnection defaultConnectionOptions rq nullify is os')
return ()
Streams.parseFromStream decodeResponseHead is
where
nullify _ = return ()
--------------------------------------------------------------------------------
(!) :: Eq a => [(a, b)] -> a -> b
assoc ! key = fromJust (lookup key assoc)
--------------------------------------------------------------------------------
rq13 :: RequestHead
rq13 = RequestHead "/mychat"
[ ("Host", "server.example.com")
, ("Upgrade", "websocket")
, ("Connection", "Upgrade")
, ("Sec-WebSocket-Key", "x3JJHMbDL1EzLkh9GBhXDw==")
, ("Sec-WebSocket-Protocol", "chat")
, ("Sec-WebSocket-Version", "13")
, ("Origin", "http://example.com")
]
False
--------------------------------------------------------------------------------
testHandshakeHybi13 :: Assertion
testHandshakeHybi13 = do
onAcceptFired <- newIORef False
ResponseHead code message headers <- testHandshake rq13 $ \pc ->
acceptRequest pc {pendingOnAccept = \_ -> writeIORef onAcceptFired True}
readIORef onAcceptFired >>= assert
code @?= 101
message @?= "WebSocket Protocol Handshake"
headers ! "Sec-WebSocket-Accept" @?= "HSmrc0sMlYUkAGmm5OPpG2HaGWk="
headers ! "Connection" @?= "Upgrade"
--------------------------------------------------------------------------------
testHandshakeReject :: Assertion
testHandshakeReject = do
ResponseHead code _ _ <- testHandshake rq13 $ \pc ->
rejectRequest pc "YOU SHALL NOT PASS"
code @?= 400
--------------------------------------------------------------------------------
-- I don't believe this one is supported yet
rq9000 :: RequestHead
rq9000 = RequestHead "/chat"
[ ("Host", "server.example.com")
, ("Upgrade", "websocket")
, ("Connection", "Upgrade")
, ("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==")
, ("Sec-WebSocket-Origin", "http://example.com")
, ("Sec-WebSocket-Protocol", "chat, superchat")
, ("Sec-WebSocket-Version", "9000")
]
False
--------------------------------------------------------------------------------
testHandshakeHybi9000 :: Assertion
testHandshakeHybi9000 = do
ResponseHead code _ headers <- testHandshake rq9000 $ \pc ->
flip handle (acceptRequest pc) $ \e -> case e of
NotSupported -> return undefined
_ -> error $ "Unexpected Exception: " ++ show e
code @?= 400
headers ! "Sec-WebSocket-Version" @?= "13"