Browse Source

unlifted connection handling

exported withConnection
master
Philipp Balzarek 14 years ago
parent
commit
fc63b62bab
  1. 21
      src/Network/XMPP.hs
  2. 9
      src/Network/XMPP/Bind.hs
  3. 13
      src/Network/XMPP/Monad.hs
  4. 13
      src/Network/XMPP/Session.hs
  5. 5
      src/Network/XMPP/TLS.hs
  6. 1
      src/Tests.hs

21
src/Network/XMPP.hs

@ -37,6 +37,7 @@ module Network.XMPP
withNewSession withNewSession
, withSession , withSession
, newSession , newSession
, withConnection
, connect , connect
, startTLS , startTLS
, auth , auth
@ -161,14 +162,8 @@ import Network.XMPP.Types
import Control.Monad.Error import Control.Monad.Error
-- | Connect to host with given address. -- | Connect to host with given address.
xmppConnect :: HostName -> Text -> XMPPConMonad (Either StreamError ()) connect :: HostName -> Text -> XMPPConMonad (Either StreamError ())
xmppConnect address hostname = xmppRawConnect address hostname >> xmppStartStream connect address hostname = xmppRawConnect address hostname >> xmppStartStream
-- | Attempts to secure the connection using TLS. Will return
-- 'TLSNoServerSupport' when the server does not offer TLS or does not
-- expect it at this time.
startTLS :: TLS.TLSParams -> XMPP (Either XMPPTLSError ())
startTLS = withConnection . xmppStartTLS
-- | Authenticate to the server with the given username and password -- | Authenticate to the server with the given username and password
-- and bind a resource -- and bind a resource
@ -176,13 +171,9 @@ auth :: Text.Text -- ^ The username
-> Text.Text -- ^ The password -> Text.Text -- ^ The password
-> Maybe Text -- ^ The desired resource or 'Nothing' to let the server -> Maybe Text -- ^ The desired resource or 'Nothing' to let the server
-- assign one -- assign one
-> XMPP (Either AuthError Text.Text) -> XMPPConMonad (Either AuthError Text.Text)
auth username passwd resource = runErrorT $ do auth username passwd resource = runErrorT $ do
ErrorT . withConnection $ xmppSASL username passwd ErrorT $ xmppSASL username passwd
res <- lift $ xmppBind resource res <- lift $ xmppBind resource
lift $ startSession lift $ xmppStartSession
return res return res
-- | Connect to an xmpp server
connect :: HostName -> Text -> XMPP (Either StreamError ())
connect address hostname = withConnection $ xmppConnect address hostname

9
src/Network/XMPP/Bind.hs

@ -11,7 +11,7 @@ import Data.XML.Types
import Network.XMPP.Types import Network.XMPP.Types
import Network.XMPP.Pickle import Network.XMPP.Pickle
import Network.XMPP.Concurrent import Network.XMPP.Monad
-- A `bind' element. -- A `bind' element.
@ -29,7 +29,6 @@ bindBody rsrc = (pickleElem
rsrc rsrc
) )
-- Extracts the character data in the `jid' element. -- Extracts the character data in the `jid' element.
jidP :: PU [Node] JID jidP :: PU [Node] JID
@ -39,10 +38,10 @@ jidP = bindP $ xpElemNodes "jid" (xpContent xpPrim)
-- Sends a (synchronous) IQ set request for a (`Just') given or -- Sends a (synchronous) IQ set request for a (`Just') given or
-- server-generated resource and extract the JID from the non-error -- server-generated resource and extract the JID from the non-error
-- response. -- response.
xmppBind :: Maybe Text -> XMPPConMonad Text
xmppBind :: Maybe Text -> XMPP Text
xmppBind rsrc = do xmppBind rsrc = do
answer <- sendIQ' Nothing Set Nothing (bindBody rsrc) answer <- xmppSendIQ' "bind" Nothing Set Nothing (bindBody rsrc)
let (Right IQResult{iqResultPayload = Just b}) = answer -- TODO: Error handling let (Right IQResult{iqResultPayload = Just b}) = answer -- TODO: Error handling
let Right (JID _n _d (Just r)) = unpickleElem jidP b let Right (JID _n _d (Just r)) = unpickleElem jidP b
return r return r

13
src/Network/XMPP/Monad.hs

@ -137,3 +137,16 @@ xmppKillConnection = do
cc <- gets sCloseConnection cc <- gets sCloseConnection
liftIO cc liftIO cc
put xmppZeroConState put xmppZeroConState
xmppSendIQ' iqID to tp lang body = do
push . IQRequestS $ IQRequest iqID Nothing to lang tp body
res <- pullPickle $ xpEither xpIQError xpIQResult
case res of
Left e -> return $ Left e
Right iq' -> do
unless (iqID == iqResultID iq') . liftIO . Ex.throwIO $
StreamXMLError
("In xmppSendIQ' IDs don't match: " ++ show iqID ++
" /= " ++ show (iqResultID iq') ++ " .")
return $ Right iq'

13
src/Network/XMPP/Session.hs

@ -25,12 +25,13 @@ sessionIQ = IQRequestS $ IQRequest { iqRequestID = "sess"
, iqRequestPayload = sessionXML , iqRequestPayload = sessionXML
} }
xmppSession :: XMPPConMonad () xmppStartSession :: XMPPConMonad ()
xmppSession = do xmppStartSession = do
push $ sessionIQ answer <- xmppSendIQ' "session" Nothing Set Nothing sessionXML
answer <- pullStanza case answer of
let IQResultS (IQResult "sess" Nothing Nothing _lang _body) = answer Left e -> error $ show e
return () Right _ -> return ()
startSession :: XMPP () startSession :: XMPP ()
startSession = do startSession = do

5
src/Network/XMPP/TLS.hs

@ -45,9 +45,8 @@ data XMPPTLSError = TLSError TLSError
instance Error XMPPTLSError where instance Error XMPPTLSError where
noMsg = TLSNoConnection -- TODO: What should we choose here? noMsg = TLSNoConnection -- TODO: What should we choose here?
startTLS :: TLS.TLSParams -> XMPPConMonad (Either XMPPTLSError ())
xmppStartTLS :: TLS.TLSParams -> XMPPConMonad (Either XMPPTLSError ()) startTLS params = Ex.handle (return . Left . TLSError)
xmppStartTLS params = Ex.handle (return . Left . TLSError)
. runErrorT $ do . runErrorT $ do
features <- lift $ gets sFeatures features <- lift $ gets sFeatures
handle' <- lift $ gets sConHandle handle' <- lift $ gets sConHandle

1
src/Tests.hs

@ -95,6 +95,7 @@ runMain debug number = do
withNewSession $ do withNewSession $ do
setSessionEndHandler (liftIO . atomically $ putTMVar wait ()) setSessionEndHandler (liftIO . atomically $ putTMVar wait ())
debug' "running" debug' "running"
withConnection $ do
connect "localhost" "species64739.dyndns.org" connect "localhost" "species64739.dyndns.org"
startTLS exampleParams startTLS exampleParams
saslResponse <- auth (fromJust $ localpart we) "pwd" (resourcepart we) saslResponse <- auth (fromJust $ localpart we) "pwd" (resourcepart we)

Loading…
Cancel
Save