engine-io-growler (empty) → 0.1.0.0
raw patch · 5 files changed
+131/−0 lines, 5 filesdep +basedep +bytestringdep +engine-iosetup-changed
Dependencies added: base, bytestring, engine-io, growler, http-types, mtl, pipes, pipes-attoparsec, pipes-wai, socket-io, text, transformers, unordered-containers, wai, wai-websockets, websockets
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- engine-io-growler.cabal +42/−0
- src/Network/EngineIO/Growler.hs +54/−0
- src/Network/SocketIO/Growler.hs +13/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Ian Duncan++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ engine-io-growler.cabal view
@@ -0,0 +1,42 @@+-- Initial growler-socket-io.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: engine-io-growler+version: 0.1.0.0+-- synopsis: +description: This package provides an @engine-io@ @ServerAPI@ that is compatible with+ <http://http://hackage.haskell.org/package/growler Growler>. It also provides a few helper utilities for setting up @socket-io@+homepage: http://github.com/iand675/growler+license: MIT+license-file: LICENSE+author: Ian Duncan+maintainer: ian@iankduncan.com+-- copyright: +category: Web+build-type: Simple+-- extra-source-files: +cabal-version: >=1.10++library+ exposed-modules: Network.EngineIO.Growler,+ Network.SocketIO.Growler+ -- other-modules: + -- other-extensions: + build-depends: base >=4.6 && <5,+ growler == 0.6.*,+ wai >=3.0 && < 4,+ engine-io == 1.2.*,+ socket-io == 1.3.*,+ websockets == 0.9.*,+ wai-websockets == 3.*,+ text,+ bytestring,+ unordered-containers,+ mtl,+ pipes == 4.*,+ pipes-attoparsec == 0.5.*,+ pipes-wai == 3.*,+ transformers,+ http-types == 0.8.*+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Network/EngineIO/Growler.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE OverloadedStrings #-}+module Network.EngineIO.Growler where+import Control.Applicative ((<$>))+import Control.Arrow (second)+import Control.Monad.Reader+import Control.Monad.Trans.State.Strict (evalStateT)+import qualified Data.ByteString.Builder as B+import qualified Data.HashMap.Strict as H+import Data.Maybe (maybeToList)+import Network.EngineIO hiding (Socket, initialize)+import qualified Network.HTTP.Types.Status as S+import Network.Wai (queryString, requestMethod, responseLBS)+import qualified Network.Wai.Handler.WebSockets as WaiWS+import qualified Network.WebSockets as WS+import Web.Growler (HandlerT, bytestring, request, raw, setHeader, status, abort, currentResponse)+import Pipes.Attoparsec (parse)+import Pipes.Wai (producerRequestBody)++growlerAPI :: MonadIO m => ServerAPI (HandlerT m)+growlerAPI = ServerAPI+ { srvTerminateWithResponse = \code ct b -> do+ let aStatus = filter ((==) code . S.statusCode) [S.status100..S.status511]+ case aStatus of+ [] -> error "not a valid status code"+ (st:_) -> do+ status st+ setHeader "Content-Type" ct+ bytestring $ B.toLazyByteString b+ currentResponse >>= abort+ undefined++ , srvGetQueryParams = makeParams <$> request++ , srvParseRequestBody = \p -> do+ r <- request+ eps <- evalStateT (parse p) $ producerRequestBody r+ return $ case eps of+ Nothing -> Left "Exhausted request body"+ Just ps -> case ps of+ Left err -> Left $ show err+ Right res -> Right res++ , srvGetRequestMethod = requestMethod <$> request++ , srvRunWebSocket = \app -> do+ r <- request+ unless (WaiWS.isWebSocketsReq r) undefined+ let socketRunner src sink = liftIO $ WaiWS.runWebSockets WS.defaultConnectionOptions+ (WaiWS.getRequestHead r) app src sink+ raw socketRunner $ responseLBS S.status404 [] ""+ }+ where+ makeParams = H.fromListWith (++) . map (second maybeToList) . queryString+
+ src/Network/SocketIO/Growler.hs view
@@ -0,0 +1,13 @@+module Network.SocketIO.Growler where+import Control.Monad.Trans (MonadIO)+import Control.Monad.Trans.Reader (ReaderT)+import Control.Monad.Trans.State.Strict (StateT)+import Network.SocketIO (initialize, RoutingTable, Socket)+import Web.Growler (GrowlerT, HandlerT, matchAny, literal)+import Network.EngineIO.Growler (growlerAPI)++initializeSocketIO :: MonadIO m => StateT RoutingTable (ReaderT Socket (HandlerT m)) a -> IO (HandlerT m ())+initializeSocketIO = initialize growlerAPI++socketIOHandler :: MonadIO m => HandlerT m () -> GrowlerT m ()+socketIOHandler = matchAny (literal "/socket.io")