module Network.TLS.Backend
( HasBackend(..)
, Backend(..)
) where
import Control.Monad
import Network.Socket (Socket, sClose)
import qualified Network.Socket.ByteString as Socket
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import System.IO (Handle, hSetBuffering, BufferMode(..), hFlush, hClose)
data Backend = Backend
{ backendFlush :: IO ()
, backendClose :: IO ()
, backendSend :: ByteString -> IO ()
, backendRecv :: Int -> IO ByteString
}
class HasBackend a where
initializeBackend :: a -> IO ()
getBackend :: a -> Backend
instance HasBackend Backend where
initializeBackend _ = return ()
getBackend = id
instance HasBackend Socket where
initializeBackend _ = return ()
getBackend sock = Backend (return ()) (sClose sock) (Socket.sendAll sock) recvAll
where recvAll n = B.concat `fmap` loop n
where loop 0 = return []
loop left = do
r <- Socket.recv sock left
if B.null r
then return []
else liftM (r:) (loop (left B.length r))
instance HasBackend Handle where
initializeBackend handle = hSetBuffering handle NoBuffering
getBackend handle = Backend (hFlush handle) (hClose handle) (B.hPut handle) (B.hGet handle)