wai-thrift (empty) → 0.0.1.0
raw patch · 4 files changed
+200/−0 lines, 4 filesdep +basedep +blaze-builderdep +bytestringsetup-changed
Dependencies added: base, blaze-builder, bytestring, http-types, stm, thrift, wai
Files
- LICENSE +22/−0
- Setup.hs +2/−0
- src/Thrift/Transport/Wai.hs +142/−0
- wai-thrift.cabal +34/−0
+ LICENSE view
@@ -0,0 +1,22 @@+The MIT License (MIT)++Copyright (c) 2015 Yogesh Sajanikar++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
+ src/Thrift/Transport/Wai.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE FlexibleInstances #-}++{-|+Module : Thrift.Transport.Wai+Description : Wai support for thrift transport+License : MIT+Maintainer : Yogesh Sajanikar <yogesh_sajanikar@yahoo.com>+Stability : experimental+Portability : POSIX, WINDOWS++Support thrift transport for Wai Request and Response.++-}+module Thrift.Transport.Wai (+ RequestTransport,+ StreamTransport,+ fromRequest,+ toStreamTransport,+ thriftWaiApp,+ thriftMiddleware+ ) where++import Thrift.Transport+import Thrift.Protocol+import Thrift.Transport.IOBuffer+import Network.Wai as Wai+import Network.Wai.Internal+import Data.IORef+import Blaze.ByteString.Builder+import Data.Monoid+import Network.HTTP.Types (status200)+import Network.HTTP.Types.Method++data RequestTransport = RequestTransport Request ReadBuffer++-- | Creates RequestTransport from WAI request+fromRequest :: Request -> IO RequestTransport+fromRequest req = RequestTransport+ <$> return req+ <*> (Wai.lazyRequestBody req >>= newIORef)++instance Transport RequestTransport where++ tIsOpen = const $ return True++ tClose = const $ return ()++ tRead (RequestTransport _ b) n = readBuf b (fromIntegral n)++ tPeek (RequestTransport _ b) = peekBuf b++ tWrite _ _ = fail "RequestTransport does not support write"++ tFlush _ = fail "RequestTransport does not support flush"+++type WriteBuilder = IORef Builder++newtype ResponseTransport = ResponseTransport WriteBuilder++newResponseTransport :: IO ResponseTransport+newResponseTransport = ResponseTransport <$> (newIORef mempty)++instance Transport ResponseTransport where++ tIsOpen = const $ return False++ tClose = const $ return ()++ tRead _ _ = fail "Read operation is not supported for response"++ tPeek _ = fail "Peek is not allowed for response buffers"++ tWrite (ResponseTransport b) bs = modifyIORef b (<> fromLazyByteString bs)++ tFlush (ResponseTransport b) = modifyIORef b (<> flush)+ +++data StreamTransport = StreamTransport { writer :: Builder -> IO ()+ , flusher :: IO ()+ }++toStreamTransport :: (Builder -> IO () ) -> IO () -> StreamTransport+toStreamTransport w f = StreamTransport w f+++instance Transport StreamTransport where++ tIsOpen = const $ return True++ tClose = const $ return ()++ tRead _ _ = fail "Read operation is not supported for response"++ tPeek _ = fail "Peek is not allowed for response buffers"++ tWrite st bs = writer st $ fromLazyByteString bs++ tFlush st = flusher st++++thriftWaiApp ::+ (Protocol ip, Protocol op)+ => h+ -> (RequestTransport -> ip RequestTransport)+ -> (StreamTransport -> op StreamTransport)+ -> (h -> (ip RequestTransport, op StreamTransport) -> IO Bool)+ -> Application +thriftWaiApp h isp osp proc_ req responder = do+ inp <- isp <$> fromRequest req+ responder $ Wai.responseStream status200 [] $ \write flushstream -> do+ let out = osp (StreamTransport write flushstream)+ _ <- proc_ h (inp, out)+ return ()+ + +-- | Creates Wai middleware for the given handler+thriftMiddleware :: (Protocol ip, Protocol op)+ => h+ -> (RequestTransport -> ip RequestTransport)+ -> (StreamTransport -> op StreamTransport)+ -> (h -> (ip RequestTransport, op StreamTransport) -> IO Bool)+ -> Application+ -> Application+thriftMiddleware h isp osp proc_ app req responder = app req $ \res ->+ case res of+ ResponseStream {} -> + if methodPost == requestMethod req then+ do+ inp <- isp <$> fromRequest req+ responder $ Wai.responseStream status200 (responseHeaders res) $ \write flushstream -> do+ let out = osp (StreamTransport write flushstream)+ _ <- proc_ h (inp, out)+ return ()+ else+ responder res++ _ -> responder res+ +
+ wai-thrift.cabal view
@@ -0,0 +1,34 @@+-- Initial wai-thrift.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: wai-thrift+version: 0.0.1.0+synopsis: Thrift transport layer for Wai+description: Implements a read-only transport layer for Wai+ Request, and write-only transport layer for Wai+ streaming body.+license: MIT+license-file: LICENSE+author: Yogesh Sajanikar+maintainer: yogesh.sajanikar@yahoo.com+-- copyright: +category: Web+build-type: Simple+-- extra-source-files: +cabal-version: >=1.10++library+ exposed-modules: Thrift.Transport.Wai+ -- other-modules: + -- other-extensions: + build-depends: base >=4.8 && <4.9+ , thrift+ , wai+ , bytestring+ , stm+ , blaze-builder+ , http-types+ hs-source-dirs: src+ default-language: Haskell2010++