packages feed

engine-io-wai (empty) → 1.0.0

raw patch · 4 files changed

+143/−0 lines, 4 filesdep +attoparsecdep +basedep +bytestringsetup-changed

Dependencies added: attoparsec, base, bytestring, engine-io, http-types, mtl, text, transformers, unordered-containers, wai, wai-websockets, websockets

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, Brandon Martin++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Tim Baumann nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ engine-io-wai.cabal view
@@ -0,0 +1,35 @@+name: engine-io-wai+version: 1.0.0+license: BSD3+license-file: LICENSE+author: Brandon Martin+maintainer: brandon@codedmart.com+category: Network+build-type: Simple+-- extra-source-files:+cabal-version: >=1.10+description:+    This package provides an @engine-io@ @ServerAPI@ that is compatible with+    <https://hackage.haskell.org/package/wai/ Wai>.++library+    exposed-modules:+        Network.EngineIO.Wai++    build-depends:+        base >=4.6 && <4.9,+        engine-io >= 1.2 && < 1.3,+        http-types >= 0.8 && < 0.9,+        unordered-containers >= 0.2 && < 0.3,+        wai >= 3.0 && < 3.1,+        text >= 1.1 && < 1.3,+        bytestring >= 0.9 && <0.11,+        websockets >= 0.8 && < 0.10,+        wai-websockets >= 3 && < 3.1,+        mtl >= 2 && < 2.3,+        transformers >= 0.4 && < 0.5,+        attoparsec >= 0.13 && < 0.14++    hs-source-dirs: src+    default-language: Haskell2010+    ghc-options: -Wall -O2
+ src/Network/EngineIO/Wai.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+++module Network.EngineIO.Wai (+    WaiMonad,+    toWaiApplication,+    waiAPI+    ) where+++import Network.Wai+import Control.Monad.Except+import Control.Monad.Reader+import Control.Monad.Trans.Except+import Control.Arrow (second)+import Data.Maybe (maybeToList)+import Data.ByteString.Lazy (toStrict)+import Data.Text.Lazy.Encoding (encodeUtf8)+import Data.Text.Lazy (fromStrict)+import Data.Attoparsec.ByteString (parseOnly)+import Network.HTTP.Types.Header (hContentType)+++import Network.HTTP.Types.Status as ST+import Network.HTTP.Types.URI as URI+import qualified Data.ByteString as BS+import qualified Network.EngineIO as EIO+import qualified Data.HashMap.Strict as HashMap+import qualified Network.Wai as WAI+import qualified Network.Wai.Handler.WebSockets as WaiWS+import qualified Network.WebSockets as WS+++newtype WaiMonad a = WaiMonad {+    runWaiMonad :: ExceptT Response (ReaderT Request IO) a+    } deriving (Monad, Functor, Applicative, MonadReader Request, MonadError Response, MonadIO)+++toWaiApplication :: WaiMonad a -> Application+toWaiApplication sHandler req respond = do+    socket <- runReaderT (runExceptT (runWaiMonad sHandler)) req+    case socket of+        Left response -> respond response+        Right _ -> respond $ responseLBS status200 [("Content-Type", "text/html")] $ encodeUtf8 $ fromStrict ""+++--------------------------------------------------------------------------------+-- | A drop in 'EIO.ServerAPI' that works with Wai.+waiAPI :: EIO.ServerAPI WaiMonad+waiAPI = EIO.ServerAPI+    { EIO.srvTerminateWithResponse = \code ct builder -> do+        let status = filter ((==) code . ST.statusCode) [ST.status100..ST.status511]+        case status of+            [] -> error "not a valid status code"+            (st:_) -> throwError (responseBuilder st [(hContentType, ct)] builder)++    , EIO.srvGetQueryParams = fmap (queryToHashMap . WAI.queryString) ask++    , EIO.srvParseRequestBody = \p -> do+        req <- ask+        b <- liftIO $ WAI.lazyRequestBody req+        return (parseOnly p $ toStrict b)++    , EIO.srvGetRequestMethod = fmap (WAI.requestMethod) ask++    , EIO.srvRunWebSocket = \app -> do+        req <- ask+        maybe (return ()) throwError (WaiWS.websocketsApp WS.defaultConnectionOptions app req)+    }+++queryToHashMap :: URI.Query -> HashMap.HashMap BS.ByteString [BS.ByteString]+queryToHashMap = HashMap.fromListWith (++) . map (second maybeToList)+