You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.0 KiB

14 years ago
{-# LANGUAGE NoMonomorphismRestriction, OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
14 years ago
module Network.XMPP.Stream where
import Control.Applicative((<$>))
14 years ago
import Control.Monad(unless)
import Control.Monad.Trans.Class
14 years ago
import Control.Monad.Trans.State
import Control.Monad.IO.Class
14 years ago
import Network.XMPP.Monad
import Network.XMPP.Pickle
import Network.XMPP.Types
14 years ago
import Data.Conduit
import Data.Conduit.List as CL
14 years ago
import Data.Default(def)
14 years ago
import qualified Data.List as L
import Data.Text as T
14 years ago
import Data.XML.Types
import Data.XML.Pickle
import qualified Text.XML.Stream.Parse as XP
import Text.XML.Stream.Elements
14 years ago
-- import Text.XML.Stream.Elements
14 years ago
throwOutJunk = do
next <- peek
case next of
Nothing -> return ()
Just (EventBeginElement _ _) -> return ()
_ -> CL.drop 1 >> throwOutJunk
openElementFromEvents = do
throwOutJunk
Just (EventBeginElement name attrs) <- CL.head
return $ Element name attrs []
14 years ago
14 years ago
xmppStartStream :: XMPPMonad ()
14 years ago
xmppStartStream = do
hostname <- gets sHostname
pushOpen $ pickleElem pickleStream ("1.0",Nothing, Just hostname)
14 years ago
features <- pulls xmppStream
modify (\s -> s {sFeatures = features})
return ()
14 years ago
xmppRestartStream :: XMPPMonad ()
xmppRestartStream = do
raw <- gets sRawSrc
src <- gets sConSrc
14 years ago
newsrc <- lift (bufferSource $ raw $= XP.parseBytes def)
modify (\s -> s{sConSrc = newsrc})
xmppStartStream
14 years ago
14 years ago
xmppStream :: Sink Event (ResourceT IO) ServerFeatures
14 years ago
xmppStream = do
xmppStreamHeader
xmppStreamFeatures
14 years ago
xmppStreamHeader :: Sink Event (ResourceT IO) ()
14 years ago
xmppStreamHeader = do
throwOutJunk
(ver, _, _) <- unpickleElem pickleStream <$> openElementFromEvents
unless (ver == "1.0") $ error "Not XMPP version 1.0 "
return()
14 years ago
xmppStreamFeatures :: Sink Event (ResourceT IO) ServerFeatures
xmppStreamFeatures = unpickleElem pickleStreamFeatures <$> elementFromEvents
-- Pickling
14 years ago
pickleStream :: PU [Node] (Text, Maybe Text, Maybe Text)
pickleStream = xpWrap snd (((),()),) .
xpElemAttrs "stream:stream" $
xpPair
(xpPair
(xpAttrFixed "xmlns" "jabber:client" )
(xpAttrFixed "xmlns:stream" "http://etherx.jabber.org/streams" )
)
(xpTriple
14 years ago
(xpAttr "version" xpId)
(xpOption $ xpAttr "from" xpId)
(xpOption $ xpAttr "to" xpId)
)
14 years ago
pickleTLSFeature :: PU [Node] Bool
pickleTLSFeature = ignoreAttrs $
xpElem "starttls"
(xpAttrFixed "xmlns" "urn:ietf:params:xml:ns:xmpp-tls")
(xpElemExists "required")
14 years ago
pickleSaslFeature :: PU [Node] [Text]
pickleSaslFeature = ignoreAttrs $
xpElem "mechanisms"
(xpAttrFixed "xmlns" "urn:ietf:params:xml:ns:xmpp-sasl")
(xpList0 $
14 years ago
xpElemNodes "mechanism" (xpContent xpId) )
14 years ago
14 years ago
pickleStreamFeatures :: PU [Node] ServerFeatures
pickleStreamFeatures = xpWrap ( \(tls, sasl, rest) -> SF tls (mbl sasl) rest)
(\(SF tls sasl rest) -> (tls, lmb sasl, rest))
$
xpElemNodes "stream:features"
(xpTriple
(xpOption pickleTLSFeature)
(xpOption pickleSaslFeature)
14 years ago
(xpAll xpElemVerbatim)
)
14 years ago