packages feed

ismtp 2.0.3 → 3.0.1

raw patch · 11 files changed

+116/−126 lines, 11 filesdep −unixdep ~netlinessetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies removed: unix

Dependency ranges changed: netlines

API changes (from Hackage documentation)

- Network.Smtp.Connect: ignoreSigPipe :: IO ()
- Network.Smtp.Connect: withIgnoredSigPipe :: IO a -> IO a
- Network.Smtp.Monad: runMailT_ :: (Applicative m, MonadIO m) => Handle -> StringMailT (Either SomeException a) m a -> m a
- Network.Smtp.Tools: netLine :: Monad m => Int -> Iteratee ByteString m (Maybe ByteString)
- Network.Smtp.Tools: netLines :: Monad m => Int -> Enumeratee ByteString ByteString m b
- Network.Smtp.Tools: responseLines :: Monad m => Int -> Int -> Iteratee SmtpResponse m b -> Iteratee ByteString m b
- Network.Smtp.Types: type StringMailT r m = Iteratee ByteString (StateT r MailConfig m)
+ Network.Smtp.Monad: mailSetWriteTimeout :: Int -> MailT r m ()
+ Network.Smtp.Session: verify :: MonadIO m => ByteString -> MailT r m Bool
+ Network.Smtp.Simple: mailTimeoutIO :: SendMail -> Int
+ Network.Smtp.Types: SmtpVerifyCmd :: ByteString -> SmtpCommand
+ Network.Smtp.Types: mailWriteTimeout :: MailConfig -> Int
- Network.Smtp.Connect: withMxConn :: (Applicative m, DnsMonad m, MonadPeelIO m) => Domain -> Bool -> MailT (Either SomeException a) m a -> m a
+ Network.Smtp.Connect: withMxConn :: (Applicative m, DnsMonad m, MonadPeelIO m) => Domain -> Bool -> MailT a m a -> m a
- Network.Smtp.Connect: withSmtpConn :: (Applicative m, MonadPeelIO m) => HostName -> PortID -> MailT (Either SomeException a) m a -> m a
+ Network.Smtp.Connect: withSmtpConn :: (Applicative m, MonadPeelIO m) => HostName -> PortID -> MailT a m a -> m a
- Network.Smtp.Monad: runMailT :: (Applicative m, Monad m) => Handle -> StringMailT (Either SomeException a) m a -> m (Either SomeException a)
+ Network.Smtp.Monad: runMailT :: (Applicative m, Monad m) => Int -> Int -> Handle -> MailT a m a -> Iteratee ByteString m a
- Network.Smtp.Simple: SendMail :: Int -> Handle -> Int -> Int -> Handle -> Int -> SendMail
+ Network.Smtp.Simple: SendMail :: Int -> Handle -> Int -> Int -> Handle -> Int -> Int -> SendMail
- Network.Smtp.Simple: sendMail :: (Applicative m, MonadIO m) => SendMail -> MailT (Either SomeException a) m a -> m (Either SomeException a)
+ Network.Smtp.Simple: sendMail :: (Applicative m, MonadIO m) => SendMail -> MailT a m a -> m (Either SomeException a)
- Network.Smtp.Simple: sendMail_ :: (Applicative m, MonadIO m) => SendMail -> MailT (Either SomeException a) m a -> m a
+ Network.Smtp.Simple: sendMail_ :: (Applicative m, MonadIO m) => SendMail -> MailT a m a -> m a
- Network.Smtp.Types: MailConfig :: Set Extension -> Handle -> MailConfig
+ Network.Smtp.Types: MailConfig :: Set Extension -> Handle -> Int -> MailConfig
- Network.Smtp.Types: type Mail r a = MailT r IO a
+ Network.Smtp.Types: type Mail r = MailT r IO
- Network.Smtp.Types: type MailT r m = Iteratee SmtpResponse (StateT r MailConfig m)
+ Network.Smtp.Types: type MailT r m = StateT r MailConfig (Iteratee SmtpResponse m)

Files

LICENSE view
@@ -1,5 +1,5 @@ ismtp license-Copyright (c) 2010, Ertugrul Soeylemez+Copyright (c) 2011, Ertugrul Soeylemez  All rights reserved. 
Network/Smtp.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.SMTP--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- This package provides a monad transformer for fast, incremental ESMTP -- sessions, with which you can, among other things, send emails.  Here@@ -22,6 +21,12 @@ -- >     mailDataStr content -- >     quit --+-- The @r@ type parameter is related to contstuff's 'StateT' monad+-- transformer, which is used internally.  If you don't know what to do,+-- just leave it fully polymorphic like in the example above.  You only+-- need to care about @r@, if you want to make use of the CPS features+-- of 'StateT'.+-- -- The simplest interfaces to running SMTP sessions are 'withSmtpConn' -- and 'withMxConn'.  The latter does a DNS lookup for the given domain -- to discover the MX server and connect to it.  The former simply@@ -34,11 +39,11 @@ -- and other purposes. -- -- Finally you can use the low level interface for running sessions.--- See the 'runMailT' function along with 'enumHandleTimeout' and--- 'responseLines'.  This way you get the full power of iteratees.  For--- example you can run the session through a custom enumeratee, which--- enables you to wrap the session in another protocol (e.g. proxy--- servers or SSL).+-- See the 'runMailT' function along with 'enumHandleTimeout'.  This way+-- you get the full power of iteratees.  For example you can run the+-- session through a custom enumeratee, which enables you to wrap the+-- session in another protocol (e.g. proxy servers or SSL).  This is not+-- possible with the higher level functions.  module Network.Smtp     ( -- * Reexports
Network/Smtp/Connect.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Connect--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- High level interfaces for networking. @@ -15,11 +14,7 @@       withSmtpConn,        -- * Initialization-      withIsmtp,--      -- * Utility functions-      ignoreSigPipe,-      withIgnoredSigPipe+      withIsmtp     )     where @@ -31,32 +26,14 @@ import Network.Smtp.Simple import Network.Smtp.Types import System.IO-import System.Posix.Signals  --- | Disable the /SIGPIPE/ signal, so our program doesn't die on broken--- pipes.--ignoreSigPipe :: IO ()-ignoreSigPipe = () <$ installHandler sigPIPE Ignore Nothing----- | Run the given computation with the /SIGPIPE/ signal disabled, so--- our program doesn't die on broken pipes.--withIgnoredSigPipe :: IO a -> IO a-withIgnoredSigPipe =-    Ex.bracket (installHandler sigPIPE Ignore Nothing)-               (\old -> installHandler sigPIPE old Nothing)-    . const-- -- | Perform some useful (but not necessarily needed) initialization -- like disabling SIGPIPE and initializing sockets, run the given -- computation and then clean up.  withIsmtp :: IO a -> IO a-withIsmtp = withSocketsDo . withIgnoredSigPipe+withIsmtp = withSocketsDo   -- | Interface to 'withSmtpConn', which connects to the first mail@@ -66,7 +43,7 @@  withMxConn ::     (Applicative m, DnsMonad m, MonadPeelIO m) =>-    Domain -> Bool -> MailT (Either SomeException a) m a -> m a+    Domain -> Bool -> MailT a m a -> m a withMxConn domain fallback c = do     mMx <- resolveMX domain     hostname <-@@ -81,8 +58,9 @@ -- Note that there is also 'withMxConn', which resolves the MX server of -- the given domain. -withSmtpConn :: forall a m. (Applicative m, MonadPeelIO m) =>-                HostName -> PortID -> MailT (Either SomeException a) m a -> m a+withSmtpConn ::+    forall a m. (Applicative m, MonadPeelIO m) =>+    HostName -> PortID -> MailT a m a -> m a withSmtpConn host port c =     Ex.bracket connect (liftIO . hClose) $ \h -> do         sendMail_ (defSendMail h h) c
Network/Smtp/Ext/Auth.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Ext.Auth--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- This module implements the authentication extension to SMTP as -- defined in RFC 2554.
Network/Smtp/Monad.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Monad--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- This module implements a monad for SMTP sessions. @@ -12,8 +11,10 @@ module Network.Smtp.Monad     ( -- * Running sessions       runMailT,-      runMailT_, +      -- * Manipulating sessions+      mailSetWriteTimeout,+       -- * Utility functions       mailError,       mailPut,@@ -24,12 +25,13 @@  import qualified Data.Set as S import Control.ContStuff-import Control.Exception.Peel as Ex+--import Control.Exception.Peel as Ex import Data.ByteString (ByteString) import Data.ByteString.Char8 () import Data.Enumerator as E-import Data.Enumerator.Binary as EB+--import Data.Enumerator.Binary as EB import Data.Enumerator.List as EL+import Data.Enumerator.NetLines import Data.Vector (Vector) import Network.Smtp.Tools import Network.Smtp.Types@@ -43,15 +45,17 @@     Monad m =>     SmtpCommand -> String -> Integer -> Vector ByteString -> MailT r m a mailError cmd errMsg code msgs =-    throwError $ SmtpException errMsg cmd code (formatMsgs msgs)+    lift . throwError $ SmtpException errMsg cmd code (formatMsgs msgs)   -- | Send a stream of 'ByteString's to the SMTP server.  mailPut :: MonadIO m => Enumerator ByteString (MailT r m) () -> MailT r m () mailPut enum = do-    h <- lift $ getField mailHandle-    run (enum $$ EB.iterHandle h) >>= either throwError return+    h <- getField mailHandle+    timeout <- getField mailWriteTimeout+    run (enum $$ iterHandleTimeout timeout h) >>=+        either (lift . throwError) return   -- | Send a list of 'ByteString's followed an SMTP line terminator to@@ -61,30 +65,38 @@ mailPutLn strs = mailPut $ concatEnums [enumList 16 strs, enumList 1 ["\r\n"]]  +-- | Set the write timeout for the current mail session in milliseconds.++mailSetWriteTimeout :: Int -> MailT r m ()+mailSetWriteTimeout timeout =+    modify (\cfg -> cfg { mailWriteTimeout = timeout })++ -- | Retrieve the next SMTP response.  Throw an 'Error', if there is no -- next response.  nextResponse :: Monad m => MailT r m SmtpResponse-nextResponse = do-    let smtpError = throwError $ userError "Connection closed prematurely"-    EL.head >>= maybe smtpError return+nextResponse =+    lift $ do+        let smtpError = throwError $ userError "Connection closed prematurely"+        EL.head >>= maybe smtpError return  --- | Run a mail session computation with the given output handle.  The--- input is supplied by an 'Enumerator' such as 'enumHandleTimeout'.+-- | Run a mail session computation with the given protocol line length+-- limit (first argument), response lines limit (second argument) and+-- output handle.  The input is supplied by an 'Enumerator' such as+-- 'enumHandleTimeout'.+--+-- The inner iteratee uses 'SmtpResponse' as its input type and hence+-- expects the 'netLines' and 'smtpResponses' enumeratees to be applied.+-- This is done by 'runMailT' for you, so the resulting iteratee takes a+-- raw 'ByteString' stream as input.  runMailT :: (Applicative m, Monad m) =>-            Handle -> StringMailT (Either SomeException a) m a ->-            m (Either SomeException a)-runMailT h c =+            Int -> Int -> Handle -> MailT a m a ->+            Iteratee ByteString m a+runMailT maxLine maxMsgs h c =     let cfg = MailConfig { mailExtensions = S.empty,-                           mailHandle = h }-    in evalStateT cfg . run $ c----- | Run a mail session computation using 'runMailT' and throw an--- exception on error.--runMailT_ :: (Applicative m, MonadIO m) =>-             Handle -> StringMailT (Either SomeException a) m a -> m a-runMailT_ h = runMailT h >=> either Ex.throwIO return+                           mailHandle = h,+                           mailWriteTimeout = 15000 }+    in netLines maxLine =$ smtpResponses maxMsgs =$ evalStateT cfg c
Network/Smtp/Session.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Session--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- SMTP session computations. @@ -18,6 +17,7 @@       quit,       rcptTo,       reset,+      verify,       waitForWelcome     )     where@@ -44,7 +44,7 @@                L.drop 1 . V.toList $ msgs      case code of-      250 -> lift $ modify (\cfg -> cfg { mailExtensions = exts })+      250 -> modify (\cfg -> cfg { mailExtensions = exts })       500 -> tryHelo       502 -> tryHelo       554 -> tryHelo@@ -94,7 +94,8 @@       _   -> mailError (SmtpMailFromCmd from) "MAIL FROM rejected" code msgs  --- | Send /QUIT/ command.+-- | Send /QUIT/ command.  Please note:  This iteratee violates the+-- standard by recognizing a 250 result code as success.  quit :: MonadIO m => MailT r m () quit = do@@ -102,6 +103,7 @@     SmtpResponse code msgs <- nextResponse     case code of       221 -> return ()+      250 -> return ()       _   -> mailError SmtpQuitCmd "Quit rejected" code msgs  @@ -125,6 +127,24 @@     case code of       250 -> return ()       _   -> mailError SmtpResetCmd "RSET rejected" code msgs+++-- | Send the /VRFY/ command to find out, whether the mail exchangers+-- knows the given user.  Nowadays most mail exchangers disable this+-- command for security reasons.+--+-- Please note that many SMTP servers will give you false positives or+-- false negatives to prevent spamming attempts.  It is not recommended+-- to use this command.++verify :: MonadIO m => ByteString -> MailT r m Bool+verify checkUser = do+    mailPutLn ["VRFY ", checkUser]+    SmtpResponse code msgs <- nextResponse+    case code of+      250 -> return True+      550 -> return False+      _   -> mailError (SmtpVerifyCmd checkUser) "VRFY rejected" code msgs   -- | Wait for the welcome greeting from the SMTP server.
Network/Smtp/Simple.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Simple--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- Higher level interface to ismtp. @@ -34,7 +33,8 @@       mailMaxLine      :: Int,     -- ^ Maximum line length (flood protection).       mailMaxMessages  :: Int,     -- ^ Maximum number of messages (flood protection).       mailOutputHandle :: Handle,  -- ^ Output handle (e.g. sending socket).-      mailTimeout      :: Int      -- ^ Receive timeout in milliseconds.+      mailTimeout      :: Int,     -- ^ Session timeout in milliseconds.+      mailTimeoutIO    :: Int      -- ^ Read/write timeout in milliseconds.     }  @@ -48,30 +48,29 @@                mailMaxLine = 512,                mailMaxMessages = 128,                mailOutputHandle = outH,-               mailTimeout = 60000 }+               mailTimeout = 60000,+               mailTimeoutIO = 15000 }   -- | Execute the given mail session using the supplied configuration.--- Please note that both handles must be set to binary mode and the--- input handle should be unbuffered ('NoBuffering').+-- Please note that both handles must be set to binary mode and be+-- unbuffered.  See 'hSetBuffering' and 'hSetBinaryMode'.  sendMail :: (Applicative m, MonadIO m) =>-            SendMail -> MailT (Either SomeException a) m a ->-            m (Either SomeException a)-sendMail cfg c =+            SendMail -> MailT a m a -> m (Either SomeException a)+sendMail cfg c = do     let SendMail { mailBufferSize = bufSize,                    mailInputHandle = inH,                    mailMaxLine = maxLine,                    mailMaxMessages = maxMsgs,                    mailOutputHandle = outH,-                   mailTimeout = timeout } = cfg-    in runMailT outH (enumHandleTimeout bufSize timeout inH $$-                      responseLines maxLine maxMsgs c)+                   mailTimeout = timeout,+                   mailTimeoutIO = ioTimeout } = cfg+    run $ enumHandleTimeout bufSize timeout inH $$+          runMailT maxLine maxMsgs outH (mailSetWriteTimeout ioTimeout >> c)   -- | Like 'sendMail', but throws an exception on error. -sendMail_ :: (Applicative m, MonadIO m) =>-             SendMail -> MailT (Either SomeException a) m a ->-             m a+sendMail_ :: (Applicative m, MonadIO m) => SendMail -> MailT a m a -> m a sendMail_ cfg = sendMail cfg >=> either throwIO return
Network/Smtp/Tools.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Tools--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- Helper functions and types. @@ -12,9 +11,6 @@ module Network.Smtp.Tools     ( enumHandleTimeout,       formatMsgs,-      netLine,-      netLines,-      responseLines,       smtpResponseLine,       smtpResponse,       smtpResponses,@@ -63,19 +59,6 @@       45 -> return True       32 -> return False       _  -> empty----- | Composition of all 'Enumeratee's, which are needed to convert a raw--- 'ByteString' stream to an 'SmtpResponse' stream.  This function takes--- the maximum line length and the response line limit as its first two--- parameters.--responseLines :: Monad m =>-                 Int -> Int -> Iteratee SmtpResponse m b -> Iteratee ByteString m b-responseLines maxLine maxMsgs c =-    joinI $ netLines maxLine $$-    joinI $ smtpResponses maxMsgs $$-    c   -- | Read the next SMTP response line from the given 'ByteString' lines
Network/Smtp/Types.hs view
@@ -1,9 +1,8 @@ -- | -- Module:     Network.Smtp.Types--- Copyright:  (c) 2010 Ertugrul Soeylemez+-- Copyright:  (c) 2011 Ertugrul Soeylemez -- License:    BSD3 -- Maintainer: Ertugrul Soeylemez <es@ertes.de>--- Stability:  experimental -- -- Types used by ismtp. @@ -13,7 +12,6 @@     ( -- * Mail monad       Mail,       MailT,-      StringMailT,        -- * SMTP service extensions       Extension(..),@@ -54,39 +52,35 @@  -- | The 'MailT' monad transformer encapsulates an SMTP session. -type MailT r m = Iteratee SmtpResponse (StateT r MailConfig m)----- | Convenient type alias for raw streams.  Needed by--- 'Network.Smtp.Monad.runMailT'.--type StringMailT r m = Iteratee ByteString (StateT r MailConfig m)+type MailT r m = StateT r MailConfig (Iteratee SmtpResponse m)   -- | The 'Mail' monad is 'MailT' over 'IO'. -type Mail r a = MailT r IO a+type Mail r = MailT r IO   -- | Mail session configuration.  data MailConfig =     MailConfig {-      mailExtensions :: Set Extension,  -- ^ Supported extensions.-      mailHandle     :: Handle          -- ^ Connection handle.+      mailExtensions   :: Set Extension,  -- ^ Supported extensions.+      mailHandle       :: Handle,         -- ^ Connection handle.+      mailWriteTimeout :: Int             -- ^ Write timeout in milliseconds.     }   -- | Failed SMTP command (used by 'SmtpException').  data SmtpCommand-    = SmtpWelcomeCmd              -- ^ Waiting for welcome message.+    = SmtpDataCmd                 -- ^ DATA.     | SmtpHelloCmd ByteString     -- ^ EHLO or HELO with domain.     | SmtpMailFromCmd ByteString  -- ^ MAIL FROM with address.+    | SmtpQuitCmd                 -- ^ QUIT.     | SmtpRcptToCmd ByteString    -- ^ RCPT TO with address.-    | SmtpDataCmd                 -- ^ DATA.     | SmtpResetCmd                -- ^ RSET.-    | SmtpQuitCmd                 -- ^ QUIT.+    | SmtpVerifyCmd ByteString    -- ^ VRFY with the given user name.+    | SmtpWelcomeCmd              -- ^ Waiting for welcome message.   -- | SMTP exception.
Setup.lhs view
@@ -1,5 +1,5 @@ ismtp setup script-Copyright (C) 2010, Ertugrul Soeylemez+Copyright (C) 2011, Ertugrul Soeylemez  Please see the LICENSE file for terms and conditions of use, modification and distribution of this package, including this file.
ismtp.cabal view
@@ -1,14 +1,14 @@ Name:          ismtp-Version:       2.0.3+Version:       3.0.1 Category:      Network Synopsis:      Advanced ESMTP library Maintainer:    Ertugrul Söylemez <es@ertes.de> Author:        Ertugrul Söylemez <es@ertes.de>-Copyright:     (c) 2010 Ertugrul Söylemez+Copyright:     (c) 2011 Ertugrul Söylemez License:       BSD3 License-file:  LICENSE Build-type:    Simple-Stability:     experimental+Stability:     beta Cabal-version: >= 1.6 Description: @@ -24,9 +24,8 @@         dnscache >= 1.0.1,         enumerator >= 0.4.7,         monad-peel >= 0.1,-        netlines >= 0.3.0,+        netlines >= 0.4.3,         network >= 2.2.1.7,-        unix >= 2.4.0.2,         vector >= 0.7.0.1     GHC-Options: -W     Exposed-modules:@@ -39,8 +38,9 @@         Network.Smtp.Tools         Network.Smtp.Types --- Executable test+-- Executable ismtp-test --     Build-depends:---         base >= 4 && <= 5+--         base >= 4 && <= 5,+--         unix --     GHC-Options: -W -threaded --     Main-is: Test.hs