Browse Source

check for roster versioning stream feature and disable roster versioning unless present

master
Philipp Balzarek 13 years ago
parent
commit
92746237a9
  1. 6
      source/Network/Xmpp/Concurrent/Basic.hs
  2. 18
      source/Network/Xmpp/IM/Roster.hs
  3. 7
      source/Network/Xmpp/Marshal.hs
  4. 4
      source/Network/Xmpp/Stream.hs
  5. 1
      source/Network/Xmpp/Types.hs

6
source/Network/Xmpp/Concurrent/Basic.hs

@ -30,3 +30,9 @@ getJid :: Session -> IO (Maybe Jid)
getJid Session{streamRef = st} = do getJid Session{streamRef = st} = do
s <- atomically $ readTMVar st s <- atomically $ readTMVar st
withStream' (gets streamJid) s withStream' (gets streamJid) s
-- | Return the JID assigned to us by the server
getFeatures :: Session -> IO StreamFeatures
getFeatures Session{streamRef = st} = do
s <- atomically $ readTMVar st
withStream' (gets streamFeatures) s

18
source/Network/Xmpp/IM/Roster.hs

@ -4,6 +4,7 @@
module Network.Xmpp.IM.Roster where module Network.Xmpp.IM.Roster where
import Control.Applicative ((<$>))
import Control.Concurrent.STM import Control.Concurrent.STM
import Control.Monad import Control.Monad
import Data.List (nub) import Data.List (nub)
@ -14,11 +15,12 @@ import Data.XML.Pickle
import Data.XML.Types import Data.XML.Types
import System.Log.Logger import System.Log.Logger
import Network.Xmpp.Concurrent.Basic
import Network.Xmpp.Concurrent.IQ
import Network.Xmpp.Concurrent.Types
import Network.Xmpp.IM.Roster.Types import Network.Xmpp.IM.Roster.Types
import Network.Xmpp.Marshal import Network.Xmpp.Marshal
import Network.Xmpp.Concurrent.Types
import Network.Xmpp.Types import Network.Xmpp.Types
import Network.Xmpp.Concurrent.IQ
-- | Push a roster item to the server. The values for approved and ask are -- | Push a roster item to the server. The values for approved and ask are
-- ignored and all values for subsciption except "remove" are ignored -- ignored and all values for subsciption except "remove" are ignored
@ -107,9 +109,15 @@ handleRoster ref outC sta = case sta of
IQResultS $ IQResult iqid Nothing from lang Nothing IQResultS $ IQResult iqid Nothing from lang Nothing
retrieveRoster :: Maybe Roster -> Session -> IO (Maybe Roster) retrieveRoster :: Maybe Roster -> Session -> IO (Maybe Roster)
retrieveRoster oldRoster sess = do retrieveRoster mbOldRoster sess = do
useVersioning <- rosterVer <$> getFeatures sess
let version = if useVersioning
then case mbOldRoster of
Nothing -> Just ""
Just oldRoster -> ver oldRoster
else Nothing
res <- sendIQ' Nothing Get Nothing res <- sendIQ' Nothing Get Nothing
(pickleElem xpQuery (Query (ver =<< oldRoster) [])) (pickleElem xpQuery (Query version []))
sess sess
case res of case res of
IQResponseResult (IQResult{iqResultPayload = Just ros}) IQResponseResult (IQResult{iqResultPayload = Just ros})
@ -119,7 +127,7 @@ retrieveRoster oldRoster sess = do
return Nothing return Nothing
Right ros' -> return . Just $ toRoster ros' Right ros' -> return . Just $ toRoster ros'
IQResponseResult (IQResult{iqResultPayload = Nothing}) -> do IQResponseResult (IQResult{iqResultPayload = Nothing}) -> do
return oldRoster return mbOldRoster
-- sever indicated that no roster updates are necessary -- sever indicated that no roster updates are necessary
IQResponseTimeout -> do IQResponseTimeout -> do
errorM "Pontarius.Xmpp.Roster" "getRoster: request timed out" errorM "Pontarius.Xmpp.Roster" "getRoster: request timed out"

7
source/Network/Xmpp/Marshal.hs

@ -250,17 +250,18 @@ xpStream = xpElemAttrs
-- Pickler/Unpickler for the stream features - TLS, SASL, and the rest. -- Pickler/Unpickler for the stream features - TLS, SASL, and the rest.
xpStreamFeatures :: PU [Node] StreamFeatures xpStreamFeatures :: PU [Node] StreamFeatures
xpStreamFeatures = ("xpStreamFeatures","") <?> xpWrap xpStreamFeatures = ("xpStreamFeatures","") <?> xpWrap
(\(tls, sasl, rest) -> StreamFeatures tls (mbl sasl) rest) (\(tls, sasl, ver, rest) -> StreamFeatures tls (mbl sasl) ver rest)
(\(StreamFeatures tls sasl rest) -> (tls, lmb sasl, rest)) (\(StreamFeatures tls sasl ver rest) -> (tls, lmb sasl, ver, rest))
(xpElemNodes (xpElemNodes
(Name (Name
"features" "features"
(Just "http://etherx.jabber.org/streams") (Just "http://etherx.jabber.org/streams")
(Just "stream") (Just "stream")
) )
(xpTriple (xp4Tuple
(xpOption pickleTlsFeature) (xpOption pickleTlsFeature)
(xpOption pickleSaslFeature) (xpOption pickleSaslFeature)
(xpElemExists "{urn:xmpp:features:rosterver}ver")
(xpAll xpElemVerbatim) (xpAll xpElemVerbatim)
) )
) )

4
source/Network/Xmpp/Stream.hs

@ -488,7 +488,7 @@ xmppNoStream = StreamState {
streamConnectionState = Closed streamConnectionState = Closed
, streamHandle = zeroHandle , streamHandle = zeroHandle
, streamEventSource = zeroSource , streamEventSource = zeroSource
, streamFeatures = StreamFeatures Nothing [] [] , streamFeatures = StreamFeatures Nothing [] False []
, streamAddress = Nothing , streamAddress = Nothing
, streamFrom = Nothing , streamFrom = Nothing
, streamId = Nothing , streamId = Nothing
@ -522,7 +522,7 @@ createStream realm config = do
{ streamConnectionState = Plain { streamConnectionState = Plain
, streamHandle = hand , streamHandle = hand
, streamEventSource = eSource , streamEventSource = eSource
, streamFeatures = StreamFeatures Nothing [] [] , streamFeatures = StreamFeatures Nothing [] False []
, streamAddress = Just $ Text.pack realm , streamAddress = Just $ Text.pack realm
, streamFrom = Nothing , streamFrom = Nothing
, streamId = Nothing , streamId = Nothing

1
source/Network/Xmpp/Types.hs

@ -823,6 +823,7 @@ langTagParser = do
data StreamFeatures = StreamFeatures data StreamFeatures = StreamFeatures
{ streamTls :: !(Maybe Bool) { streamTls :: !(Maybe Bool)
, streamSaslMechanisms :: ![Text.Text] , streamSaslMechanisms :: ![Text.Text]
, rosterVer :: !Bool
, streamOtherFeatures :: ![Element] -- TODO: All feature elements instead? , streamOtherFeatures :: ![Element] -- TODO: All feature elements instead?
} deriving Show } deriving Show

Loading…
Cancel
Save