From 5adbe2784a636e7069cfc64b8ccfc3cdc2d431df Mon Sep 17 00:00:00 2001 From: Philipp Balzarek Date: Mon, 26 Aug 2013 13:02:49 +0200 Subject: [PATCH] close stream after failed connection attempt (including exceptions) --- source/Network/Xmpp/Concurrent.hs | 65 ++++++++++++++++++------------- tests/Tests.hs | 4 +- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/source/Network/Xmpp/Concurrent.hs b/source/Network/Xmpp/Concurrent.hs index 73fb733..76abc16 100644 --- a/source/Network/Xmpp/Concurrent.hs +++ b/source/Network/Xmpp/Concurrent.hs @@ -170,6 +170,39 @@ newSession stream config realm mbSasl = runErrorT $ do onConnectionClosed config sess } return sess +connectStream :: HostName + -> SessionConfiguration + -> Maybe (ConnectionState -> [SaslHandler], Maybe Text) + -> IO (Either XmppFailure Stream) +connectStream realm config mbSasl = do + Ex.bracketOnError (openStream realm (sessionStreamConfiguration config)) + (\s -> case s of + Left _ -> return () + Right stream -> closeStreams stream) + + (\stream' -> case stream' of + Left e -> return $ Left e + Right stream -> do + res <- runErrorT $ do + ErrorT $ tls stream + cs <- liftIO $ withStream (gets streamConnectionState) + stream + mbAuthError <- case mbSasl of + Nothing -> return Nothing + Just (handlers, resource) -> ErrorT $ auth (handlers cs) + resource stream + case mbAuthError of + Nothing -> return () + Just e -> throwError $ XmppAuthFailure e + return stream + case res of + Left e -> do + debugM "Pontarius.Xmpp" "Closing stream after error" + closeStreams stream + return (Left e) + Right r -> return $ Right r + ) + -- | Creates a 'Session' object by setting up a connection with an XMPP server. -- -- Will connect to the specified host with the provided configuration. If the @@ -182,15 +215,7 @@ session :: HostName -- ^ The hostname / realm -> SessionConfiguration -- ^ configuration details -> IO (Either XmppFailure Session) session realm mbSasl config = runErrorT $ do - stream <- ErrorT $ openStream realm (sessionStreamConfiguration config) - ErrorT $ tls stream - cs <- liftIO $ withStream (gets streamConnectionState) stream - mbAuthError <- case mbSasl of - Nothing -> return Nothing - Just (handlers, resource) -> ErrorT $ auth (handlers cs) resource stream - case mbAuthError of - Nothing -> return () - Just e -> throwError $ XmppAuthFailure e + stream <- ErrorT $ connectStream realm config mbSasl ses <- ErrorT $ newSession stream config realm mbSasl liftIO $ when (enableRoster config) $ initRoster ses return ses @@ -202,24 +227,10 @@ reconnectNow :: Session -- ^ session to reconnect reconnectNow sess@Session{conf = config, reconnectWait = rw} = do debugM "Pontarius.Xmpp" "reconnecting" res <- flip withConnection sess $ \oldStream -> do - s <- runErrorT $ do - liftIO $ debugM "Pontarius.Xmpp" "reconnect: closing stream" - _ <- liftIO $ closeStreams oldStream - liftIO $ debugM "Pontarius.Xmpp" "reconnect: opening stream" - stream <- ErrorT $ openStream (sRealm sess) - (sessionStreamConfiguration config) - liftIO $ debugM "Pontarius.Xmpp" "reconnect: tls" - ErrorT $ tls stream - liftIO $ debugM "Pontarius.Xmpp" "reconnect: auth" - cs <- liftIO $ withStream (gets streamConnectionState) stream - mbAuthError <- case sSaslCredentials sess of - Nothing -> return Nothing - Just (handlers, resource) -> ErrorT $ auth (handlers cs) - resource stream - case mbAuthError of - Nothing -> return () - Just e -> throwError $ XmppAuthFailure e - return stream + debugM "Pontarius.Xmpp" "reconnect: closing stream" + closeStreams oldStream + debugM "Pontarius.Xmpp" "reconnect: opening stream" + s <- connectStream (sRealm sess) config (sSaslCredentials sess) case s of Left e -> do errorM "Pontarius.Xmpp" $ "reconnect failed" ++ show e diff --git a/tests/Tests.hs b/tests/Tests.hs index 4ef2e2f..57cc759 100644 --- a/tests/Tests.hs +++ b/tests/Tests.hs @@ -218,8 +218,8 @@ connectionClosedTest = do } sendPresence presenceOnline context forkIO $ do - threadDelay 1000000 - endSession context + threadDelay 5000000 + closeConnection context debug' "done" forever $ threadDelay 1000000 return ()