on master help sign in
Update wai-websockets to use conduit
commit5598b8d31a2bdec35cd7d26ae8f9a13bcab8353d authorJasper Van der Jeugt <m@jaspervdj.be> dateWed 11 Jan 2012, 17:26 (15 years ago) parent342421b
2 files changed+40−17
wai-websockets/Network/Wai/Handler/WebSockets.hs+35−15 wai-websockets/wai-websockets.cabal+5−2
wai-websockets/Network/Wai/Handler/WebSockets.hs+35−15
@@ -3,24 +3,44 @@ module Network.Wai.Handler.WebSockets
33 ( intercept
44 ) where
55
6−import Network.Wai (Request, requestHeaders, rawPathInfo, requestHeaders)
7−import Network.Socket (Socket)
8−import Data.Char (toLower)
9−import Data.Enumerator (Iteratee)
6+import Control.Monad.IO.Class (liftIO)
107import Data.ByteString (ByteString)
8+import Data.Char (toLower)
9+import Network.Socket (Socket)
10+import Network.Wai (Request, requestHeaders, rawPathInfo, requestHeaders)
1111import qualified Data.ByteString.Char8 as S
12−import Network.WebSockets (WebSockets, runWebSockets, RequestHttpPart(RequestHttpPart), Protocol)
12+import qualified Data.Conduit as C
13+import qualified Data.Enumerator as E
1314import qualified Network.WebSockets as WS
14−import Network.Socket.Enumerator (iterSocket)
15+import qualified Network.WebSockets.Internal as WS
1516
16−intercept :: Protocol p
17− => (WS.Request -> WebSockets p ())
17+-- | For use with 'settingsIntercept' from the Warp web server.
18+intercept :: WS.Protocol p
19+ => (WS.Request -> WS.WebSockets p ())
1820 -> Request
19− -> Maybe (Socket -> Iteratee ByteString IO ())
20−intercept app req =
21− case lookup "upgrade" $ requestHeaders req of
22− Just s | S.map toLower s=="websocket" -> Just $ \socket -> do
23− runWebSockets req' app (iterSocket socket)
24− _ -> Nothing
21+ -> Maybe (C.BufferedSource IO ByteString -> Socket -> C.ResourceT IO ())
22+intercept app req = case lookup "upgrade" $ requestHeaders req of
23+ Just s
24+ | S.map toLower s == "websocket" -> Just $ runWebSockets req' app
25+ | otherwise -> Nothing
26+ _ -> Nothing
27+ where
28+ req' = WS.RequestHttpPart (rawPathInfo req) (requestHeaders req)
29+
30+-- | Internal function to run the WebSocket iteratee using the conduit library
31+runWebSockets :: WS.Protocol p
32+ => WS.RequestHttpPart
33+ -> (WS.Request -> WS.WebSockets p ())
34+ -> C.BufferedSource IO ByteString
35+ -> Socket
36+ -> C.ResourceT IO ()
37+runWebSockets req app source sock = do
38+ step <- liftIO $ E.runIteratee $ WS.runWebSockets req app send
39+ source C.$$ C.sinkState (E.returnI step) push close
2540 where
26− req' = RequestHttpPart (rawPathInfo req) (requestHeaders req)
41+ send = WS.iterSocket sock
42+ close = const $ return ()
43+
44+ push iter bs = do
45+ step <- liftIO $ E.runIteratee $ E.enumList 1 [bs] E.$$ iter
46+ return (E.returnI step, C.Processing)
wai-websockets/wai-websockets.cabal+5−2
@@ -1,5 +1,5 @@
11Name: wai-websockets
2−Version: 1.0.0
2+Version: 1.1.0
33Synopsis: Provide a bridge betweeen WAI and the websockets package.
44License: BSD3
55License-file: LICENSE
@@ -19,13 +19,15 @@ flag example
1919Library
2020 Build-Depends: base >= 3 && < 5
2121 , bytestring >= 0.9.1.4 && < 0.10
22+ , conduit >= 0.0 && < 0.1
2223 , wai >= 1.0 && < 1.1
2324 , enumerator >= 0.4.8 && < 0.5
2425 , network-enumerator >= 0.1.2 && < 0.2
2526 , blaze-builder >= 0.2.1.4 && < 0.4
2627 , case-insensitive >= 0.2
2728 , network >= 2.2.1.5 && < 2.4
28− , websockets >= 0.4 && < 0.5
29+ , transformers >= 0.2 && < 0.3
30+ , websockets >= 0.5.1 && < 0.6
2931 Exposed-modules: Network.Wai.Handler.WebSockets
3032 ghc-options: -Wall
3133
@@ -35,6 +37,7 @@ Executable wai-websockets-example
3537 else
3638 buildable: False
3739 Build-Depends: base >=3 && < 5,
40+ conduit,
3841 wai-websockets,
3942 websockets,
4043 network-enumerator,