{-# LANGUAGE RecordWildCards #-} -- | Basic abstraction module Network.AMQP.Connection ( Connection , SSL.SSLContext , ConnectionParams(..) , connectionClose , connectTo , connectionGet , connectionPut ) where import Network.Socket (PortNumber) import qualified OpenSSL.Session as SSL import qualified OpenSSL as SSL import qualified System.IO.Streams as Streams import qualified System.IO.Streams.SSL as Streams hiding (connect) import System.IO.Streams (InputStream, OutputStream) import qualified Network.Socket as N import Network.AMQP.Prelude data Connection = Connection { connClose :: IO () , connOS :: OutputStream ByteString , connIS :: InputStream ByteString } data ConnectionParams = ConnectionParams { connectionHostname :: String , connectionPort :: PortNumber , connectionSecure :: Maybe SSL.SSLContext } connectionClose :: Connection -> IO () connectionClose = connClose connectionPut :: Connection -> ByteString -> IO () connectionPut Connection{..} bs = do Streams.write (Just bs) connOS Streams.write (Just mempty) connOS connectionGet :: Connection -> Int -> IO ByteString connectionGet Connection{..} n = Streams.readExactly n connIS connectTo :: ConnectionParams -> IO Connection connectTo ConnectionParams{..} = do ais <- N.getAddrInfo (Just N.defaultHints { N.addrFlags = [N.AI_ADDRCONFIG, N.AI_NUMERICSERV], N.addrSocketType = N.Stream }) (Just connectionHostname) (Just $ show connectionPort) let addr = head ais s <- N.socket (N.addrFamily addr) N.Stream N.defaultProtocol N.connect s (N.addrAddress addr) case connectionSecure of Nothing -> do (connIS,connOS) <- Streams.socketToStreams s let connClose = N.close s pure Connection {..} Just ctx -> SSL.withOpenSSL $ do ssl <- SSL.connection ctx s SSL.setTlsextHostName ssl connectionHostname SSL.connect ssl (connIS,connOS) <- Streams.sslToStreams ssl let connClose = do SSL.shutdown ssl SSL.Unidirectional N.close s pure Connection {..}