Browse Source

Simplify API

Drops the Connection newtype, and shows TMVar Connection instead.

Hides Connection from Network.Xmpp, as the vast majority of users will
not need to work with Connection directly. The related functions are
now instead available from Network.Xmpp.Basic.

Renames `simpleConnect' to `session', and makes it flexible in terms
of authentication and whether or not to use TLS.

Adds some minor documentation changes.

We will need to export some session related information (such as the
acquired resource, stream properties, etc.). We will also need to
expose any failures encountered, probably by making `session' an
ErrorT calculation.

Also removed the Errors module from the Cabal file.
master
Jon Kristensen 13 years ago
parent
commit
2fa9b0decb
  1. 1
      pontarius-xmpp.cabal
  2. 14
      source/Network/Xmpp.hs
  3. 8
      source/Network/Xmpp/Basic.hs
  4. 4
      source/Network/Xmpp/Bind.hs
  5. 2
      source/Network/Xmpp/Concurrent/Channels.hs
  6. 3
      source/Network/Xmpp/Concurrent/Channels/Types.hs
  7. 12
      source/Network/Xmpp/Concurrent/Threads.hs
  8. 2
      source/Network/Xmpp/Concurrent/Types.hs
  9. 41
      source/Network/Xmpp/Connection.hs
  10. 4
      source/Network/Xmpp/Sasl.hs
  11. 2
      source/Network/Xmpp/Sasl/Types.hs
  12. 64
      source/Network/Xmpp/Session.hs
  13. 7
      source/Network/Xmpp/Stream.hs
  14. 4
      source/Network/Xmpp/Tls.hs
  15. 17
      source/Network/Xmpp/Types.hs
  16. 6
      source/Network/Xmpp/Xep/InbandRegistration.hs
  17. 3
      source/Network/Xmpp/Xep/ServiceDiscovery.hs

1
pontarius-xmpp.cabal

@ -69,7 +69,6 @@ Library @@ -69,7 +69,6 @@ Library
, Network.Xmpp.Concurrent.Threads
, Network.Xmpp.Concurrent.Monad
, Network.Xmpp.Connection
, Network.Xmpp.Errors
, Network.Xmpp.IM.Message
, Network.Xmpp.IM.Presence
, Network.Xmpp.Jid

14
source/Network/Xmpp.hs

@ -25,19 +25,7 @@ @@ -25,19 +25,7 @@
module Network.Xmpp
( -- * Session management
Session
, simpleConnect
, connectTcp
, newSession
, withConnection
, startTls
, simpleAuth
, auth
, scramSha1
, digestMd5
, plain
, closeConnection
, endContext
, setConnectionClosedHandler
, session
-- * JID
-- | A JID (historically: Jabber ID) is XMPPs native format
-- for addressing entities in the network. It is somewhat similar to an e-mail

8
source/Network/Xmpp/Basic.hs

@ -2,15 +2,20 @@ module Network.Xmpp.Basic @@ -2,15 +2,20 @@ module Network.Xmpp.Basic
( Connection(..)
, ConnectionState(..)
, connectTcp
, simpleConnect
, newSession
, withConnection
, startTls
, simpleAuth
, auth
, scramSha1
, digestMd5
, plain
, closeConnection
, pushStanza
, pullStanza
, closeConnection
, endContext
, setConnectionClosedHandler
)
where
@ -21,3 +26,4 @@ import Network.Xmpp.Session @@ -21,3 +26,4 @@ import Network.Xmpp.Session
import Network.Xmpp.Stream
import Network.Xmpp.Tls
import Network.Xmpp.Types
import Network.Xmpp.Concurrent

4
source/Network/Xmpp/Bind.hs

@ -17,6 +17,8 @@ import Network.Xmpp.Types @@ -17,6 +17,8 @@ import Network.Xmpp.Types
import Control.Monad.State(modify)
import Control.Concurrent.STM.TMVar
-- Produces a `bind' element, optionally wrapping a resource.
bindBody :: Maybe Text -> Element
bindBody = pickleElem $
@ -28,7 +30,7 @@ bindBody = pickleElem $ @@ -28,7 +30,7 @@ bindBody = pickleElem $
-- Sends a (synchronous) IQ set request for a (`Just') given or server-generated
-- resource and extract the JID from the non-error response.
xmppBind :: Maybe Text -> Connection -> IO Jid
xmppBind :: Maybe Text -> TMVar Connection -> IO Jid
xmppBind rsrc c = do
answer <- pushIQ' "bind" Nothing Set Nothing (bindBody rsrc) c
jid <- case () of () | Right IQResult{iqResultPayload = Just b} <- answer

2
source/Network/Xmpp/Concurrent/Channels.hs

@ -71,7 +71,7 @@ toChans stanzaC iqHands sta = atomically $ do @@ -71,7 +71,7 @@ toChans stanzaC iqHands sta = atomically $ do
-- | Creates and initializes a new Xmpp context.
newSession :: Connection -> IO Session
newSession :: TMVar Connection -> IO Session
newSession con = do
outC <- newTChanIO
stanzaChan <- newTChanIO

3
source/Network/Xmpp/Concurrent/Channels/Types.hs

@ -8,7 +8,8 @@ import Data.Text (Text) @@ -8,7 +8,8 @@ import Data.Text (Text)
import Network.Xmpp.Concurrent.Types
import Network.Xmpp.Types
-- | An XMPP session context
-- | The @Session@ object holds the current state of the XMPP connection, and is
-- thus necessary for any interaction with it.
data Session = Session
{ context :: Context
, stanzaCh :: TChan Stanza -- All stanzas

12
source/Network/Xmpp/Concurrent/Threads.hs

@ -18,13 +18,15 @@ import qualified Data.ByteString as BS @@ -18,13 +18,15 @@ import qualified Data.ByteString as BS
import Network.Xmpp.Concurrent.Types
import Network.Xmpp.Connection
import Control.Concurrent.STM.TMVar
import GHC.IO (unsafeUnmask)
-- Worker to read stanzas from the stream and concurrently distribute them to
-- all listener threads.
readWorker :: (Stanza -> IO ())
-> (StreamFailure -> IO ())
-> TMVar Connection
-> TMVar (TMVar Connection)
-> IO a
readWorker onStanza onConnectionClosed stateRef =
Ex.mask_ . forever $ do
@ -32,8 +34,8 @@ readWorker onStanza onConnectionClosed stateRef = @@ -32,8 +34,8 @@ readWorker onStanza onConnectionClosed stateRef =
-- we don't know whether pull will
-- necessarily be interruptible
s <- atomically $ do
con@(Connection con_) <- readTMVar stateRef
state <- sConnectionState <$> readTMVar con_
con <- readTMVar stateRef
state <- sConnectionState <$> readTMVar con
when (state == ConnectionClosed)
retry
return con
@ -72,11 +74,11 @@ readWorker onStanza onConnectionClosed stateRef = @@ -72,11 +74,11 @@ readWorker onStanza onConnectionClosed stateRef =
-- connection.
startThreadsWith :: (Stanza -> IO ())
-> TVar EventHandlers
-> Connection
-> TMVar Connection
-> IO
(IO (),
TMVar (BS.ByteString -> IO Bool),
TMVar Connection,
TMVar (TMVar Connection),
ThreadId)
startThreadsWith stanzaHandler eh con = do
read <- withConnection' (gets $ cSend. cHand) con

2
source/Network/Xmpp/Concurrent/Types.hs

@ -25,7 +25,7 @@ data Context = Context @@ -25,7 +25,7 @@ data Context = Context
, idGenerator :: IO StanzaId
-- | Lock (used by withConnection) to make sure that a maximum of one
-- XmppConMonad action is executed at any given time.
, conRef :: TMVar Connection
, conRef :: TMVar (TMVar Connection)
, eventHandlers :: TVar EventHandlers
, stopThreads :: IO ()
}

41
source/Network/Xmpp/Connection.hs

@ -40,45 +40,48 @@ import Text.XML.Unresolved(InvalidEventStream(..)) @@ -40,45 +40,48 @@ import Text.XML.Unresolved(InvalidEventStream(..))
import System.Log.Logger
import Data.ByteString.Base64
import Control.Concurrent.STM.TMVar
-- Enable/disable debug output
-- This will dump all incoming and outgoing network taffic to the console,
-- prefixed with "in: " and "out: " respectively
debug :: Bool
debug = False
pushElement :: Element -> StateT Connection_ IO Bool
pushElement :: Element -> StateT Connection IO Bool
pushElement x = do
send <- gets (cSend . cHand)
liftIO . send $ renderElement x
-- | Encode and send stanza
pushStanza :: Stanza -> Connection -> IO Bool
pushStanza :: Stanza -> TMVar Connection -> IO Bool
pushStanza s = withConnection' . pushElement $ pickleElem xpStanza s
-- XML documents and XMPP streams SHOULD be preceeded by an XML declaration.
-- UTF-8 is the only supported XMPP encoding. The standalone document
-- declaration (matching "SDDecl" in the XML standard) MUST NOT be included in
-- XMPP streams. RFC 6120 defines XMPP only in terms of XML 1.0.
pushXmlDecl :: StateT Connection_ IO Bool
pushXmlDecl :: StateT Connection IO Bool
pushXmlDecl = do
con <- gets cHand
liftIO $ (cSend con) "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
pushOpenElement :: Element -> StateT Connection_ IO Bool
pushOpenElement :: Element -> StateT Connection IO Bool
pushOpenElement e = do
sink <- gets (cSend . cHand )
liftIO . sink $ renderOpenElement e
-- `Connect-and-resumes' the given sink to the connection source, and pulls a
-- `b' value.
runEventsSink :: Sink Event IO b -> StateT Connection_ IO b
runEventsSink :: Sink Event IO b -> StateT Connection IO b
runEventsSink snk = do
source <- gets cEventSource
(src', r) <- lift $ source $$++ snk
modify (\s -> s{cEventSource = src'})
return r
pullElement :: StateT Connection_ IO Element
pullElement :: StateT Connection IO Element
pullElement = do
Ex.catches (do
e <- runEventsSink (elements =$ await)
@ -94,7 +97,7 @@ pullElement = do @@ -94,7 +97,7 @@ pullElement = do
]
-- Pulls an element and unpickles it.
pullUnpickle :: PU [Node] a -> StateT Connection_ IO a
pullUnpickle :: PU [Node] a -> StateT Connection IO a
pullUnpickle p = do
res <- unpickleElem p <$> pullElement
case res of
@ -103,7 +106,7 @@ pullUnpickle p = do @@ -103,7 +106,7 @@ pullUnpickle p = do
-- | Pulls a stanza (or stream error) from the stream. Throws an error on a stream
-- error.
pullStanza :: Connection -> IO Stanza
pullStanza :: TMVar Connection -> IO Stanza
pullStanza = withConnection' $ do
res <- pullUnpickle xpStreamStanza
case res of
@ -121,9 +124,9 @@ catchPush p = Ex.catch @@ -121,9 +124,9 @@ catchPush p = Ex.catch
_ -> Ex.throwIO e
)
-- -- Connection_ state used when there is no connection.
xmppNoConnection :: Connection_
xmppNoConnection = Connection_
-- -- Connection state used when there is no connection.
xmppNoConnection :: Connection
xmppNoConnection = Connection
{ cHand = Hand { cSend = \_ -> return False
, cRecv = \_ -> Ex.throwIO
$ StreamOtherFailure
@ -147,8 +150,8 @@ xmppNoConnection = Connection_ @@ -147,8 +150,8 @@ xmppNoConnection = Connection_
zeroSource = liftIO . Ex.throwIO $ StreamOtherFailure
-- Connects to the given hostname on port 5222 (TODO: Make this dynamic) and
-- updates the XmppConMonad Connection_ state.
connectTcpRaw :: HostName -> PortID -> Text -> IO Connection
-- updates the XmppConMonad Connection state.
connectTcpRaw :: HostName -> PortID -> Text -> IO (TMVar Connection)
connectTcpRaw host port hostname = do
let PortNumber portNumber = port
debugM "Pontarius.Xmpp" $ "Connecting to " ++ host ++ " on port " ++
@ -172,7 +175,7 @@ connectTcpRaw host port hostname = do @@ -172,7 +175,7 @@ connectTcpRaw host port hostname = do
, cFlush = hFlush h
, cClose = hClose h
}
let con = Connection_
let con = Connection
{ cHand = hand
, cEventSource = eSource
, sFeatures = (SF Nothing [] [])
@ -196,8 +199,8 @@ connectTcpRaw host port hostname = do @@ -196,8 +199,8 @@ connectTcpRaw host port hostname = do
return d
-- Closes the connection and updates the XmppConMonad Connection_ state.
killConnection :: Connection -> IO (Either Ex.SomeException ())
-- Closes the connection and updates the XmppConMonad Connection state.
killConnection :: TMVar Connection -> IO (Either Ex.SomeException ())
killConnection = withConnection $ do
cc <- gets (cClose . cHand)
err <- liftIO $ (Ex.try cc :: IO (Either Ex.SomeException ()))
@ -211,7 +214,7 @@ pushIQ' :: StanzaId @@ -211,7 +214,7 @@ pushIQ' :: StanzaId
-> IQRequestType
-> Maybe LangTag
-> Element
-> Connection
-> TMVar Connection
-> IO (Either IQError IQResult)
pushIQ' iqID to tp lang body con = do
pushStanza (IQRequestS $ IQRequest iqID Nothing to lang tp body) con
@ -231,7 +234,7 @@ pushIQ' iqID to tp lang body con = do @@ -231,7 +234,7 @@ pushIQ' iqID to tp lang body con = do
-- | Send "</stream:stream>" and wait for the server to finish processing and to
-- close the connection. Any remaining elements from the server and whether or
-- not we received a </stream:stream> element from the server is returned.
closeStreams :: Connection -> IO ([Element], Bool)
closeStreams :: TMVar Connection -> IO ([Element], Bool)
closeStreams = withConnection $ do
send <- gets (cSend . cHand)
cc <- gets (cClose . cHand)
@ -244,7 +247,7 @@ closeStreams = withConnection $ do @@ -244,7 +247,7 @@ closeStreams = withConnection $ do
where
-- Pulls elements from the stream until the stream ends, or an error is
-- raised.
collectElems :: [Element] -> StateT Connection_ IO ([Element], Bool)
collectElems :: [Element] -> StateT Connection IO ([Element], Bool)
collectElems es = do
result <- Ex.try pullElement
case result of

4
source/Network/Xmpp/Sasl.hs

@ -38,12 +38,14 @@ import qualified System.Random as Random @@ -38,12 +38,14 @@ import qualified System.Random as Random
import Network.Xmpp.Sasl.Types
import Network.Xmpp.Sasl.Mechanisms
import Control.Concurrent.STM.TMVar
-- | Uses the first supported mechanism to authenticate, if any. Updates the
-- state with non-password credentials and restarts the stream upon
-- success.
xmppSasl :: [SaslHandler] -- ^ Acceptable authentication mechanisms and their
-- corresponding handlers
-> Connection
-> TMVar Connection
-> IO (Either AuthError ())
xmppSasl handlers = withConnection $ do
-- Chooses the first mechanism that is acceptable by both the client and the

2
source/Network/Xmpp/Sasl/Types.hs

@ -29,7 +29,7 @@ data SaslElement = SaslSuccess (Maybe Text.Text) @@ -29,7 +29,7 @@ data SaslElement = SaslSuccess (Maybe Text.Text)
-- | SASL mechanism XmppConnection computation, with the possibility of throwing
-- an authentication error.
type SaslM a = ErrorT AuthError (StateT Connection_ IO) a
type SaslM a = ErrorT AuthError (StateT Connection IO) a
type Pairs = [(ByteString, ByteString)]

64
source/Network/Xmpp/Session.hs

@ -21,47 +21,35 @@ import Network.Xmpp.Sasl.Types @@ -21,47 +21,35 @@ import Network.Xmpp.Sasl.Types
import Network.Xmpp.Stream
import Network.Xmpp.Tls
import Network.Xmpp.Types
import Control.Concurrent.STM.TMVar
import Data.Maybe
-- | The quick and easy way to set up a connection to an XMPP server
-- | Creates a 'Session' object by setting up a connection with an XMPP server.
--
-- This will
--
-- * connect to the host
--
-- * secure the connection with TLS
--
-- * authenticate to the server using either SCRAM-SHA1 (preferred) or
-- Digest-MD5
--
-- * bind a resource
--
-- * return the full JID you have been assigned
--
-- Note that the server might assign a different resource even when we send
-- a preference.
simpleConnect :: HostName -- ^ Host to connect to
-> PortID -- ^ Port to connec to
-> Text -- ^ Hostname of the server (to distinguish the XMPP
-- service)
-> Text -- ^ User name (authcid)
-> Text -- ^ Password
-> Maybe Text -- ^ Desired resource (or Nothing to let the server
-- decide)
-> IO Session
simpleConnect host port hostname username password resource = do
con' <- connectTcp host port hostname
-- Will connect to the specified host, optionally secure the connection with
-- TLS, as well as optionally authenticate and acquire an XMPP resource.
session :: HostName -- ^ Host to connect to
-> Text -- ^ The realm host name (to
-- distinguish the XMPP service)
-> PortID -- ^ Port to connect to
-> Maybe TLS.TLSParams -- ^ TLS settings, if securing the
-- connection to the server is
-- desired
-> Maybe ([SaslHandler], Maybe Text) -- ^ SASL handlers and the desired
-- JID resource (or Nothing to let
-- the server decide)
-> IO Session -- TODO: ErrorT
session hostname realm port tls sasl = do
con' <- connectTcp hostname port realm
con <- case con' of
Left e -> Ex.throwIO e
Right r -> return r
startTls exampleParams con
saslResponse <- simpleAuth username password resource con
case saslResponse of
Right jid -> newSession con
Left e -> error $ show e
Right c -> return c
if isJust tls then startTls (fromJust tls) con >> return () else return () -- TODO: Eats TlsFailure
saslResponse <- if isJust sasl then auth (fst $ fromJust sasl) (snd $ fromJust sasl) con >> return () else return () -- TODO: Eats AuthError
newSession con
-- | Connect to host with given address.
connectTcp :: HostName -> PortID -> Text -> IO (Either StreamFailure Connection)
connectTcp :: HostName -> PortID -> Text -> IO (Either StreamFailure (TMVar Connection))
connectTcp address port hostname = do
con <- connectTcpRaw address port hostname
result <- withConnection startStream con
@ -104,7 +92,7 @@ sessionIQ = IQRequestS $ IQRequest { iqRequestID = "sess" @@ -104,7 +92,7 @@ sessionIQ = IQRequestS $ IQRequest { iqRequestID = "sess"
-- Sends the session IQ set element and waits for an answer. Throws an error if
-- if an IQ error stanza is returned from the server.
startSession :: Connection -> IO ()
startSession :: TMVar Connection -> IO ()
startSession con = do
answer <- pushIQ' "session" Nothing Set Nothing sessionXml con
case answer of
@ -115,7 +103,7 @@ startSession con = do @@ -115,7 +103,7 @@ startSession con = do
-- resource.
auth :: [SaslHandler]
-> Maybe Text
-> Connection
-> TMVar Connection
-> IO (Either AuthError Jid)
auth mechanisms resource con = runErrorT $ do
ErrorT $ xmppSasl mechanisms con
@ -131,7 +119,7 @@ simpleAuth :: Text.Text -- ^ The username @@ -131,7 +119,7 @@ simpleAuth :: Text.Text -- ^ The username
-> Text.Text -- ^ The password
-> Maybe Text -- ^ The desired resource or 'Nothing' to let the
-- server assign one
-> Connection
-> TMVar Connection
-> IO (Either AuthError Jid)
simpleAuth username passwd resource = flip auth resource $
[ -- TODO: scramSha1Plus

7
source/Network/Xmpp/Stream.hs

@ -21,7 +21,6 @@ import Data.XML.Pickle @@ -21,7 +21,6 @@ import Data.XML.Pickle
import Data.XML.Types
import Network.Xmpp.Connection
import Network.Xmpp.Errors
import Network.Xmpp.Pickle
import Network.Xmpp.Types
import Network.Xmpp.Marshal
@ -66,7 +65,7 @@ openElementFromEvents = do @@ -66,7 +65,7 @@ openElementFromEvents = do
-- server responds in a way that is invalid, an appropriate stream error will be
-- generated, the connection to the server will be closed, and a StreamFilure
-- will be produced.
startStream :: StateT Connection_ IO (Either StreamFailure ())
startStream :: StateT Connection IO (Either StreamFailure ())
startStream = runErrorT $ do
state <- lift $ get
con <- liftIO $ mkConnection state
@ -117,7 +116,7 @@ startStream = runErrorT $ do @@ -117,7 +116,7 @@ startStream = runErrorT $ do
closeStreamWithError con StreamBadNamespacePrefix Nothing
| otherwise -> ErrorT $ checkchildren con (flattenAttrs attrs)
where
-- closeStreamWithError :: MonadIO m => Connection -> StreamErrorCondition ->
-- closeStreamWithError :: MonadIO m => TMVar Connection -> StreamErrorCondition ->
-- Maybe Element -> ErrorT StreamFailure m ()
closeStreamWithError con sec el = do
liftIO $ do
@ -157,7 +156,7 @@ flattenAttrs attrs = Prelude.map (\(name, content) -> @@ -157,7 +156,7 @@ flattenAttrs attrs = Prelude.map (\(name, content) ->
-- Sets a new Event source using the raw source (of bytes)
-- and calls xmppStartStream.
restartStream :: StateT Connection_ IO (Either StreamFailure ())
restartStream :: StateT Connection IO (Either StreamFailure ())
restartStream = do
raw <- gets (cRecv . cHand)
let newSource = DCI.ResumableSource (loopRead raw $= XP.parseBytes def)

4
source/Network/Xmpp/Tls.hs

@ -22,6 +22,8 @@ import Network.Xmpp.Pickle(ppElement) @@ -22,6 +22,8 @@ import Network.Xmpp.Pickle(ppElement)
import Network.Xmpp.Stream
import Network.Xmpp.Types
import Control.Concurrent.STM.TMVar
mkBackend con = Backend { backendSend = \bs -> void (cSend con bs)
, backendRecv = cRecv con
, backendFlush = cFlush con
@ -74,7 +76,7 @@ exampleParams = TLS.defaultParamsClient @@ -74,7 +76,7 @@ exampleParams = TLS.defaultParamsClient
-- Pushes "<starttls/>, waits for "<proceed/>", performs the TLS handshake, and
-- restarts the stream.
startTls :: TLS.TLSParams -> Connection -> IO (Either TlsFailure ())
startTls :: TLS.TLSParams -> TMVar Connection -> IO (Either TlsFailure ())
startTls params con = Ex.handle (return . Left . TlsError)
. flip withConnection con
. runErrorT $ do

17
source/Network/Xmpp/Types.hs

@ -33,7 +33,6 @@ module Network.Xmpp.Types @@ -33,7 +33,6 @@ module Network.Xmpp.Types
, Version(..)
, HandleLike(..)
, Connection(..)
, Connection_(..)
, withConnection
, withConnection'
, mkConnection
@ -755,7 +754,7 @@ data HandleLike = Hand { cSend :: BS.ByteString -> IO Bool @@ -755,7 +754,7 @@ data HandleLike = Hand { cSend :: BS.ByteString -> IO Bool
, cClose :: IO ()
}
data Connection_ = Connection_
data Connection = Connection
{ sConnectionState :: !ConnectionState -- ^ State of
-- connection
, cHand :: HandleLike
@ -789,10 +788,8 @@ data Connection_ = Connection_ @@ -789,10 +788,8 @@ data Connection_ = Connection_
}
newtype Connection = Connection {unConnection :: TMVar Connection_}
withConnection :: StateT Connection_ IO c -> Connection -> IO c
withConnection action (Connection con) = bracketOnError
withConnection :: StateT Connection IO c -> TMVar Connection -> IO c
withConnection action con = bracketOnError
(atomically $ takeTMVar con)
(atomically . putTMVar con )
(\c -> do
@ -802,15 +799,15 @@ withConnection action (Connection con) = bracketOnError @@ -802,15 +799,15 @@ withConnection action (Connection con) = bracketOnError
)
-- nonblocking version. Changes to the connection are ignored!
withConnection' :: StateT Connection_ IO b -> Connection -> IO b
withConnection' action (Connection con) = do
withConnection' :: StateT Connection IO b -> TMVar Connection -> IO b
withConnection' action con = do
con_ <- atomically $ readTMVar con
(r, _) <- runStateT action con_
return r
mkConnection :: Connection_ -> IO Connection
mkConnection con = Connection `fmap` (atomically $ newTMVar con)
mkConnection :: Connection -> IO (TMVar Connection)
mkConnection con = {- Connection `fmap` -} (atomically $ newTMVar con)
-- | Failure conditions that may arise during TLS negotiation.

6
source/Network/Xmpp/Xep/InbandRegistration.hs

@ -71,7 +71,7 @@ emptyQuery = Query Nothing False False [] @@ -71,7 +71,7 @@ emptyQuery = Query Nothing False False []
-- if r then return True else g
query :: IQRequestType -> Query -> Connection -> IO (Either IbrError Query)
query :: IQRequestType -> Query -> TMVar Connection -> IO (Either IbrError Query)
query queryType x con = do
answer <- pushIQ' "ibr" Nothing queryType Nothing (pickleElem xpQuery x) con
case answer of
@ -97,7 +97,7 @@ mapError f = mapErrorT (liftM $ left f) @@ -97,7 +97,7 @@ mapError f = mapErrorT (liftM $ left f)
-- | Retrieve the necessary fields and fill them in to register an account with
-- the server
registerWith :: [(Field, Text.Text)]
-> Connection
-> TMVar Connection
-> IO (Either RegisterError Query)
registerWith givenFields con = runErrorT $ do
fs <- mapError IbrError . ErrorT $ requestFields con
@ -114,7 +114,7 @@ registerWith givenFields con = runErrorT $ do @@ -114,7 +114,7 @@ registerWith givenFields con = runErrorT $ do
-- | Terminate your account on the server. You have to be logged in for this to
-- work. You connection will most likely be terminated after unregistering.
unregister :: Connection -> IO (Either IbrError Query)
unregister :: TMVar Connection -> IO (Either IbrError Query)
unregister = query Set $ emptyQuery {remove = True}
requestFields con = runErrorT $ do

3
source/Network/Xmpp/Xep/ServiceDiscovery.hs

@ -31,6 +31,7 @@ import Network.Xmpp.Concurrent.Types @@ -31,6 +31,7 @@ import Network.Xmpp.Concurrent.Types
import Network.Xmpp.Connection
import Network.Xmpp.Pickle
import Network.Xmpp.Types
import Control.Concurrent.STM.TMVar
data DiscoError = DiscoNoQueryElement
| DiscoIQError IQError
@ -105,7 +106,7 @@ queryInfo to node context = do @@ -105,7 +106,7 @@ queryInfo to node context = do
xmppQueryInfo :: Maybe Jid
-> Maybe Text.Text
-> Connection
-> TMVar Connection
-> IO (Either DiscoError QueryInfoResult)
xmppQueryInfo to node con = do
res <- pushIQ' "info" to Get Nothing queryBody con

Loading…
Cancel
Save