From 40639bfcf937d17f18b87d5b4ae508544188ab16 Mon Sep 17 00:00:00 2001 From: Philipp Balzarek Date: Fri, 16 Aug 2013 17:22:38 +0200 Subject: [PATCH] add generic connection method --- source/Network/Xmpp/Stream.hs | 56 +++++++++++++++++++++++++---------- source/Network/Xmpp/Types.hs | 1 + 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/source/Network/Xmpp/Stream.hs b/source/Network/Xmpp/Stream.hs index 9a418a0..ffee9e2 100644 --- a/source/Network/Xmpp/Stream.hs +++ b/source/Network/Xmpp/Stream.hs @@ -21,7 +21,6 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC8 import Data.Char (isSpace) import Data.Conduit -import Data.Conduit.Binary as CB import qualified Data.Conduit.Internal as DCI import qualified Data.Conduit.List as CL import Data.IP @@ -237,11 +236,15 @@ flattenAttrs attrs = Prelude.map (\(name, cont) -> restartStream :: StateT StreamState IO (Either XmppFailure ()) restartStream = do liftIO $ debugM "Pontarius.Xmpp" "Restarting stream..." - raw <- gets (streamReceive . streamHandle) - let newSource =loopRead raw $= XP.parseBytes def + raw <- gets streamHandle + let newSource = sourceStreamHandle raw $= XP.parseBytes def buffered <- liftIO . bufferSrc $ newSource modify (\s -> s{streamEventSource = buffered }) startStream + + +sourceStreamHandle :: MonadIO m => StreamHandle -> ConduitM i ByteString m () +sourceStreamHandle s = loopRead $ streamReceive s where loopRead rd = do bs <- liftIO (rd 4096) @@ -508,22 +511,23 @@ zeroSource = liftIO $ do debugM "Pontarius.Xmpp" "zeroSource" ExL.throwIO XmppOtherFailure +handleToStreamHandle :: Handle -> StreamHandle +handleToStreamHandle h = StreamHandle { streamSend = \d -> catchPush $ BS.hPut h d + , streamReceive = \n -> BS.hGetSome h n + , streamFlush = hFlush h + , streamClose = hClose h + } + createStream :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO (Stream) createStream realm config = do result <- connect realm config case result of - Just h -> ErrorT $ do + Just hand -> ErrorT $ do debugM "Pontarius.Xmpp" "Acquired handle." debugM "Pontarius.Xmpp" "Setting NoBuffering mode on handle." - hSetBuffering h NoBuffering eSource <- liftIO . bufferSrc $ - (sourceHandle h $= logConduit) $= XP.parseBytes def - - let hand = StreamHandle { streamSend = \d -> catchPush $ BS.hPut h d - , streamReceive = \n -> BS.hGetSome h n - , streamFlush = hFlush h - , streamClose = hClose h - } + (sourceStreamHandle hand $= logConduit) + $= XP.parseBytes def let stream = StreamState { streamConnectionState = Plain , streamHandle = hand @@ -553,14 +557,34 @@ createStream realm config = do -- case that address is used instead). If an A(AAA) record results are -- encountered, all IP addresses will be tried until a successful connection -- attempt has been made. Will return the Handle acquired, if any. -connect :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO (Maybe Handle) +connect :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO + (Maybe StreamHandle) connect realm config = do case connectionDetails config of UseHost host port -> lift $ do debugM "Pontarius.Xmpp" "Connecting to configured address." - connectTcp $ [(host, port)] - UseSrv host -> connectSrv host - UseRealm -> connectSrv realm + h <- connectTcp $ [(host, port)] + case h of + Nothing -> return Nothing + Just h' -> do + liftIO $ hSetBuffering h' NoBuffering + return . Just $ handleToStreamHandle h' + UseSrv host -> do + h <- connectSrv host + case h of + Nothing -> return Nothing + Just h' -> do + liftIO $ hSetBuffering h' NoBuffering + return . Just $ handleToStreamHandle h' + UseRealm -> do + h <- connectSrv realm + case h of + Nothing -> return Nothing + Just h' -> do + liftIO $ hSetBuffering h' NoBuffering + return . Just $ handleToStreamHandle h' + UseConnection mkC -> Just <$> liftIO mkC + where connectSrv host = do case checkHostName (Text.pack host) of diff --git a/source/Network/Xmpp/Types.hs b/source/Network/Xmpp/Types.hs index 9036a7a..7f5b545 100644 --- a/source/Network/Xmpp/Types.hs +++ b/source/Network/Xmpp/Types.hs @@ -1007,6 +1007,7 @@ instance Exception InvalidXmppXml data ConnectionDetails = UseRealm -- ^ Use realm to resolv host | UseSrv HostName -- ^ Use this hostname for a SRV lookup | UseHost HostName PortID -- ^ Use specified host + | UseConnection (IO StreamHandle) -- | Configuration settings related to the stream. data StreamConfiguration =