diff options
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r-- | Presence/XMPP.hs | 83 |
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 | |||
35 | import Control.Monad.Trans.Maybe | 35 | import Control.Monad.Trans.Maybe |
36 | import Todo | 36 | import Todo |
37 | import Control.Monad as Monad | 37 | import Control.Monad as Monad |
38 | import Text.XML.Stream.Parse | 38 | import Text.XML.Stream.Parse (parseBytes,content) |
39 | import Text.XML.Stream.Render | 39 | import Text.XML.Stream.Render |
40 | import Data.XML.Types as XML | 40 | import Data.XML.Types as XML |
41 | import Network.BSD (getHostName,hostName,hostAliases) | 41 | import Network.BSD (getHostName,hostName,hostAliases) |
@@ -51,6 +51,7 @@ import Data.Conduit.Blaze | |||
51 | #endif | 51 | #endif |
52 | import Data.List (find) | 52 | import Data.List (find) |
53 | import qualified Text.Show.ByteString as L | 53 | import qualified Text.Show.ByteString as L |
54 | import NestingXML | ||
54 | 55 | ||
55 | data Commands = Send [XML.Event] | QuitThread | 56 | data 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 | ||
257 | fromClient :: (MonadIO m, XMPPSession session) => | 258 | withJust (Just x) f = f x |
259 | withJust Nothing f = return () | ||
260 | |||
261 | whenJust acn f = do | ||
262 | x <- acn | ||
263 | withJust x f | ||
264 | |||
265 | tagAttrs (EventBeginElement _ xs) = xs | ||
266 | tagAttrs _ = [] | ||
267 | |||
268 | tagName (EventBeginElement n _) = n | ||
269 | tagName _ = "" | ||
270 | |||
271 | handleIQSetBind 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 | |||
285 | handleIQSet 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 | |||
294 | matchAttrib 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 | |||
300 | lookupAttrib name attrs = | ||
301 | case find ( (==name) . fst) attrs of | ||
302 | Just (_,[ContentText x]) -> Just x | ||
303 | Just (_,[ContentEntity x]) -> Just x | ||
304 | _ -> Nothing | ||
305 | |||
306 | iqTypeSet = "set" | ||
307 | |||
308 | isIQOf (EventBeginElement name attrs) testType | ||
309 | | name=="{jabber:client}iq" | ||
310 | && matchAttrib "type" testType attrs | ||
311 | = True | ||
312 | isIQOf _ _ = False | ||
313 | |||
314 | fromClient :: (MonadThrow m,MonadIO m, XMPPSession session) => | ||
258 | session -> TChan Commands -> Sink XML.Event m () | 315 | session -> TChan Commands -> Sink XML.Event m () |
259 | fromClient session cmdChan = voidMaybeT $ do | 316 | fromClient 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 | ||
291 | prettyPrint prefix xs = | 360 | prettyPrint prefix xs = |