{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.Mattermost.Types.Internal where
import Control.Monad (when)
import Data.Pool (Pool)
import qualified Network.Connection as C
import Control.Exception (finally)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Network.HTTP.Headers (Header, HeaderName(..), mkHeader)
import qualified Network.HTTP.Stream as HTTP
import qualified Data.ByteString.Char8 as B
import Network.Mattermost.Types.Base
data Token = Token String
deriving (Read, Show, Eq, Ord)
getTokenString :: Token -> String
getTokenString (Token s) = s
data AutoClose = No | Yes
deriving (Read, Show, Eq, Ord)
autoCloseToHeader :: AutoClose -> [Header]
autoCloseToHeader No = []
autoCloseToHeader Yes = [mkHeader HdrConnection "Close"]
data MMConn = MMConn { fromMMConn :: C.Connection
, connConnected :: IORef Bool
}
closeMMConn :: MMConn -> IO ()
closeMMConn c = do
conn <- readIORef $ connConnected c
when conn $
C.connectionClose (fromMMConn c)
`finally` (writeIORef (connConnected c) False)
newMMConn :: C.Connection -> IO MMConn
newMMConn c = do
v <- newIORef True
return $ MMConn c v
isConnected :: MMConn -> IO Bool
isConnected = readIORef . connConnected
maxLineLength :: Int
maxLineLength = 2^(16::Int)
dropTrailingChar :: B.ByteString -> B.ByteString
dropTrailingChar bs | not (B.null bs) = B.init bs
dropTrailingChar _ = ""
instance HTTP.Stream MMConn where
readLine con = Right . B.unpack . dropTrailingChar <$> C.connectionGetLine maxLineLength (fromMMConn con)
readBlock con n = Right . B.unpack <$> C.connectionGetExact (fromMMConn con) n
writeBlock con block = Right <$> C.connectionPut (fromMMConn con) (B.pack block)
close con = C.connectionClose (fromMMConn con)
closeOnEnd _ _ = return ()
data ConnectionData
= ConnectionData
{ cdHostname :: Hostname
, cdPort :: Port
, cdAutoClose :: AutoClose
, cdConnectionPool :: Pool MMConn
, cdConnectionCtx :: C.ConnectionContext
, cdToken :: Maybe Token
, cdLogger :: Maybe Logger
, cdUseTLS :: Bool
}