summaryrefslogtreecommitdiff
path: root/Presence/XMPP.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r--Presence/XMPP.hs83
1 files changed, 76 insertions, 7 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index c2ff6739..5c5cbaef 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -35,7 +35,7 @@ import Control.Monad.Trans.Class
35import Control.Monad.Trans.Maybe 35import Control.Monad.Trans.Maybe
36import Todo 36import Todo
37import Control.Monad as Monad 37import Control.Monad as Monad
38import Text.XML.Stream.Parse 38import Text.XML.Stream.Parse (parseBytes,content)
39import Text.XML.Stream.Render 39import Text.XML.Stream.Render
40import Data.XML.Types as XML 40import Data.XML.Types as XML
41import Network.BSD (getHostName,hostName,hostAliases) 41import Network.BSD (getHostName,hostName,hostAliases)
@@ -51,6 +51,7 @@ import Data.Conduit.Blaze
51#endif 51#endif
52import Data.List (find) 52import Data.List (find)
53import qualified Text.Show.ByteString as L 53import qualified Text.Show.ByteString as L
54import NestingXML
54 55
55data Commands = Send [XML.Event] | QuitThread 56data Commands = Send [XML.Event] | QuitThread
56 deriving Prelude.Show 57 deriving Prelude.Show
@@ -254,15 +255,72 @@ doIQ session cmdChan tag@(EventBeginElement name attrs) = do
254 xs <- gatherElement tag Seq.empty 255 xs <- gatherElement tag Seq.empty
255 prettyPrint "client-in: ignoring iq:" (toList xs) 256 prettyPrint "client-in: ignoring iq:" (toList xs)
256 257
257fromClient :: (MonadIO m, XMPPSession session) => 258withJust (Just x) f = f x
259withJust Nothing f = return ()
260
261whenJust acn f = do
262 x <- acn
263 withJust x f
264
265tagAttrs (EventBeginElement _ xs) = xs
266tagAttrs _ = []
267
268tagName (EventBeginElement n _) = n
269tagName _ = ""
270
271handleIQSetBind session cmdChan stanza_id = do
272 whenJust nextElement $ \child -> do
273 let unhandledBind = liftIO $ putStrLn $ "unhandled-bind: "++show child
274 case tagName child of
275 "{urn:ietf:params:xml:ns:xmpp-bind}resource"
276 -> do
277 rsc <- lift content
278 liftIO $ do
279 putStrLn $ "iq-set-bind-resource " ++ show rsc
280 setResource session (L.fromChunks [S.encodeUtf8 rsc])
281 jid <- getJID session
282 atomically $ writeTChan cmdChan (Send $ iq_bind_reply stanza_id (toStrict $ L.decodeUtf8 $ L.show jid) )
283 _ -> unhandledBind
284
285handleIQSet session cmdChan tag = do
286 withJust (lookupAttrib "id" (tagAttrs tag)) $ \stanza_id -> do
287 whenJust nextElement $ \child -> do
288 let unhandledSet = liftIO $ putStrLn ("iq-set: "++show (stanza_id,child))
289 case tagName child of
290 "{urn:ietf:params:xml:ns:xmpp-bind}bind"
291 -> handleIQSetBind session cmdChan stanza_id
292 _ -> unhandledSet
293
294matchAttrib name value attrs =
295 case find ( (==name) . fst) attrs of
296 Just (_,[ContentText x]) | x==value -> True
297 Just (_,[ContentEntity x]) | x==value -> True
298 _ -> False
299
300lookupAttrib name attrs =
301 case find ( (==name) . fst) attrs of
302 Just (_,[ContentText x]) -> Just x
303 Just (_,[ContentEntity x]) -> Just x
304 _ -> Nothing
305
306iqTypeSet = "set"
307
308isIQOf (EventBeginElement name attrs) testType
309 | name=="{jabber:client}iq"
310 && matchAttrib "type" testType attrs
311 = True
312isIQOf _ _ = False
313
314fromClient :: (MonadThrow m,MonadIO m, XMPPSession session) =>
258 session -> TChan Commands -> Sink XML.Event m () 315 session -> TChan Commands -> Sink XML.Event m ()
259fromClient session cmdChan = voidMaybeT $ do 316fromClient session cmdChan = doNestingXML $ do
260 let log = liftIO . L.putStrLn . ("client-in: " <++>) 317 let log = liftIO . L.putStrLn . ("client-in: " <++>)
261 send = liftIO . atomically . writeTChan cmdChan . Send 318 send = liftIO . atomically . writeTChan cmdChan . Send
262 mawait >>= guard . (==EventBeginDocument) 319 withXML $ \begindoc -> do
320 when (begindoc==EventBeginDocument) $ do
263 log "begin-doc" 321 log "begin-doc"
264 xml <- mawait 322 withXML $ \xml -> do
265 stream_attrs <- elementAttrs "stream" xml 323 withJust (elementAttrs "stream" xml) $ \stream_attrs -> do
266 log $ "stream " <++> bshow stream_attrs 324 log $ "stream " <++> bshow stream_attrs
267 host <- liftIO $ do 325 host <- liftIO $ do
268 jid <- getJID session 326 jid <- getJID session
@@ -270,6 +328,7 @@ fromClient session cmdChan = voidMaybeT $ do
270 return (S.decodeUtf8 . head $ names) 328 return (S.decodeUtf8 . head $ names)
271 send $ greet host 329 send $ greet host
272 330
331{-
273 fix $ \loop -> do 332 fix $ \loop -> do
274 xml <- mawait 333 xml <- mawait
275 log $ bshow xml 334 log $ bshow xml
@@ -283,9 +342,19 @@ fromClient session cmdChan = voidMaybeT $ do
283 prettyPrint "client-in: ignoring..." (toList xs) 342 prettyPrint "client-in: ignoring..." (toList xs)
284 loop 343 loop
285 _ -> loop 344 _ -> loop
345-}
346 fix $ \loop -> do
347 whenJust nextElement $ \stanza -> do
348 stanza_lvl <- nesting
349 let unhandledStanza = liftIO $ putStrLn ("ignoring stanza: "++show stanza)
350 case () of
351 _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza
352 _ | otherwise -> unhandledStanza
353 awaitCloser stanza_lvl
354 loop
286 355
287 log $ "end of stream" 356 log $ "end of stream"
288 xml <- mawait 357 withXML $ \xml -> do
289 log $ "end-of-document: " <++> bshow xml 358 log $ "end-of-document: " <++> bshow xml
290 359
291prettyPrint prefix xs = 360prettyPrint prefix xs =