wai-websockets 0.5.0.1 → 1.0.0
raw patch · 2 files changed
+58/−19 lines, 2 filesdep +conduitdep ~transformersdep ~waidep ~websockets
Dependencies added: conduit
Dependency ranges changed: transformers, wai, websockets
Files
- Network/Wai/Handler/WebSockets.hs +45/−15
- wai-websockets.cabal +13/−4
Network/Wai/Handler/WebSockets.hs view
@@ -1,26 +1,56 @@ {-# LANGUAGE OverloadedStrings #-} module Network.Wai.Handler.WebSockets ( intercept+ , interceptWith ) where -import Network.Wai (Request, requestHeaders, rawPathInfo, requestHeaders)-import Network.Socket (Socket)-import Data.Char (toLower)-import Data.Enumerator (Iteratee)+import Control.Monad.IO.Class (liftIO) import Data.ByteString (ByteString)+import Data.Char (toLower)+import Network.Socket (Socket)+import Network.Wai (Request, requestHeaders, rawPathInfo, requestHeaders) import qualified Data.ByteString.Char8 as S-import Network.WebSockets (WebSockets, runWebSockets, RequestHttpPart(RequestHttpPart), Protocol)+import qualified Data.Conduit as C+import qualified Data.Enumerator as E import qualified Network.WebSockets as WS-import Network.Socket.Enumerator (iterSocket)+import qualified Network.WebSockets.Internal as WS -intercept :: Protocol p- => (WS.Request -> WebSockets p ())+-- | For use with 'settingsIntercept' from the Warp web server.+intercept :: WS.Protocol p+ => (WS.Request -> WS.WebSockets p ()) -> Request- -> Maybe (Socket -> Iteratee ByteString IO ())-intercept app req =- case lookup "upgrade" $ requestHeaders req of- Just s | S.map toLower s=="websocket" -> Just $ \socket -> do- runWebSockets req' app (iterSocket socket)- _ -> Nothing+ -> Maybe (C.BufferedSource IO ByteString -> Socket -> C.ResourceT IO ())+intercept = interceptWith WS.defaultWebSocketsOptions++-- | Variation of 'intercept' which allows custom options.+interceptWith :: WS.Protocol p+ => WS.WebSocketsOptions+ -> (WS.Request -> WS.WebSockets p ())+ -> Request+ -> Maybe (C.BufferedSource IO ByteString -> Socket -> C.ResourceT IO ())+interceptWith opts app req = case lookup "upgrade" $ requestHeaders req of+ Just s+ | S.map toLower s == "websocket" -> Just $ runWebSockets opts req' app+ | otherwise -> Nothing+ _ -> Nothing where- req' = RequestHttpPart (rawPathInfo req) (requestHeaders req)+ req' = WS.RequestHttpPart (rawPathInfo req) (requestHeaders req)++-- | Internal function to run the WebSocket iteratee using the conduit library+runWebSockets :: WS.Protocol p+ => WS.WebSocketsOptions+ -> WS.RequestHttpPart+ -> (WS.Request -> WS.WebSockets p ())+ -> C.BufferedSource IO ByteString+ -> Socket+ -> C.ResourceT IO ()+runWebSockets opts req app source sock = do+ step <- liftIO $ E.runIteratee $ WS.runWebSocketsWith opts req app send+ source C.$$ C.sinkState (E.returnI step) push close+ where+ send = WS.iterSocket sock+ close = const $ return ()++ push iter bs = do+ step <- liftIO $ E.runIteratee $ E.enumList 1 [bs] E.$$ iter+ return (E.returnI step, C.Processing)
wai-websockets.cabal view
@@ -1,9 +1,9 @@ Name: wai-websockets-Version: 0.5.0.1+Version: 1.0.0 Synopsis: Provide a bridge betweeen WAI and the websockets package. License: BSD3 License-file: LICENSE-Author: Michael Snoyman+Author: Michael Snoyman, Jasper Van der Jeugt Maintainer: michael@snoyman.com Homepage: http://github.com/yesodweb/wai Category: Web, Yesod@@ -14,21 +14,30 @@ extra-source-files: static/client.js, static/client.html, static/screen.css +flag example+ Library Build-Depends: base >= 3 && < 5 , bytestring >= 0.9.1.4 && < 0.10- , wai >= 0.4 && < 0.5+ , conduit+ , wai >= 1.0 && < 1.1 , enumerator >= 0.4.8 && < 0.5 , network-enumerator >= 0.1.2 && < 0.2 , blaze-builder >= 0.2.1.4 && < 0.4 , case-insensitive >= 0.2 , network >= 2.2.1.5 && < 2.4- , websockets >= 0.4 && < 0.5+ , transformers >= 0.2 && < 0.3+ , websockets >= 0.5.1 && < 0.6 Exposed-modules: Network.Wai.Handler.WebSockets ghc-options: -Wall Executable wai-websockets-example+ if flag(example)+ buildable: True+ else+ buildable: False Build-Depends: base >=3 && < 5,+ conduit, wai-websockets, websockets, network-enumerator,