assumpta-0.1.0.0: src/Network/Mail/Assumpta/Internal/Net.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{- |
Network operations using
the <https://hackage.haskell.org/package/connection connection>
package.
-}
module Network.Mail.Assumpta.Internal.Net
where
import Control.Monad.Catch (MonadMask)
import Control.Monad.IO.Class
import Data.Default (def)
import qualified Network.Connection as NC
import Network.Mail.Assumpta.Connection as C
-- --
-- Network types and ops
type Port = Int
type HostName = String
-- | Network handle, containing enough
-- information to both communicate a connection,
-- and upgrade to TLS.
data Handle = Handle {
hConn :: !NC.Connection
, hContext :: !NC.ConnectionContext
}
-- Implementation of 'Connection' using
-- the <https://hackage.haskell.org/package/connection connection>
-- package.
instance Connection Handle where
type Cstrt Handle = MonadIO
type Params Handle = NC.ConnectionParams
open params = do ctx <- liftIO NC.initConnectionContext
conn <- liftIO $ NC.connectTo ctx params
return $ Handle conn ctx
close = liftIO . NC.connectionClose . hConn
send h bs = liftIO $ NC.connectionPut (hConn h) bs
recv h = liftIO $ NC.connectionGet (hConn h) 2048
upgrade h = let conn = hConn h
ctx = hContext h
tls = defaultTLSSettings
in liftIO $ NC.connectionSetSecure ctx conn tls
-- | default TLS settings
defaultTLSSettings :: NC.TLSSettings
defaultTLSSettings = def
mkParams ::
HostName -> Int -> NC.ConnectionParams
mkParams hostname port =
NC.ConnectionParams {
NC.connectionHostname = hostname
, NC.connectionPort = fromIntegral port
, NC.connectionUseSecure = Nothing
, NC.connectionUseSocks = Nothing
}
-- | Open a network 'Handle' with the specified 'NC.ConnectionParams'
openParams ::
MonadIO m => NC.ConnectionParams -> m Handle
openParams =
C.open
-- | Open a network 'Handle' to the specified hostname and port
open :: MonadIO m => HostName -> Port -> m Handle
open host port =
let p = mkParams host port
in openParams p
-- | Open a secure network 'Handle' to the specified hostname and port
-- using the default TLS settings ('defaultTLSSettings')
openTls :: MonadIO m => HostName -> Port -> m Handle
openTls host port =
let p = (mkParams host port) { NC.connectionUseSecure = Just defaultTLSSettings }
in openParams p
-- | Close a network 'Handle'
close :: MonadIO m => Handle -> m ()
close =
C.close
-- | @withHandleParams p a@
--
-- Given some parameters @p@ (hostname, port etc) for opening a 'Handle':
-- open a handle, run some action @a@ with it, then
-- close.
withHandleParams ::
(MonadMask m, MonadIO m) => NC.ConnectionParams -> (Handle -> m b) -> m b
withHandleParams =
C.withConnection
-- | @withHandle hostname port a@
--
-- Open a 'Handle' to the specified @hostname@ and @port@,
-- run some action @a@ with it, then
-- close.
withHandle ::
(MonadMask m, MonadIO m) => HostName -> Port -> (Handle -> m b) -> m b
withHandle host port =
let p = mkParams host port
in withHandleParams p
-- | @withSecureHandle hostname port a@
--
-- Open a secure 'Handle' to the specified @hostname@ and @port@,
-- run some action @a@ with it, then
-- close.
withSecureHandle ::
(MonadMask m, MonadIO m) => HostName -> Port -> (Handle -> m b) -> m b
withSecureHandle host port =
let p = (mkParams host port) {
NC.connectionUseSecure = Just defaultTLSSettings
}
in withHandleParams p