summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Presence/XMPP.hs57
1 files changed, 45 insertions, 12 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index 6d187132..ce1ea7c5 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -20,6 +20,7 @@ import SocketLike
20import ByteStringOperators 20import ByteStringOperators
21import ControlMaybe 21import ControlMaybe
22 22
23import Data.Maybe (catMaybes)
23import Data.HList 24import Data.HList
24import Network.Socket 25import Network.Socket
25 ( Family 26 ( Family
@@ -95,6 +96,9 @@ import GHC.Conc
95 , ThreadId 96 , ThreadId
96 ) 97 )
97 98
99textToByteString x = L.fromChunks [S.encodeUtf8 x]
100
101
98data Commands = 102data Commands =
99 Send [XML.Event] 103 Send [XML.Event]
100 | BoundToResource 104 | BoundToResource
@@ -257,7 +261,7 @@ handleIQSetBind session cmdChan stanza_id = do
257 "{urn:ietf:params:xml:ns:xmpp-bind}resource" 261 "{urn:ietf:params:xml:ns:xmpp-bind}resource"
258 -> do 262 -> do
259 rsc <- lift content 263 rsc <- lift content
260 return $ L.fromChunks [S.encodeUtf8 rsc] 264 return . textToByteString $ rsc
261 _ -> unhandledBind 265 _ -> unhandledBind
262 Nothing -> do 266 Nothing -> do
263 liftIO $ putStrLn $ "empty bind request!" 267 liftIO $ putStrLn $ "empty bind request!"
@@ -616,13 +620,13 @@ handlePeer st src snk = do
616handlePeerPresence session stanza False = do 620handlePeerPresence session stanza False = do
617 -- Offline 621 -- Offline
618 withJust (lookupAttrib "from" (tagAttrs stanza)) $ \jid -> do 622 withJust (lookupAttrib "from" (tagAttrs stanza)) $ \jid -> do
619 peer_jid <- liftIO $ parseAddressJID (L.fromChunks [S.encodeUtf8 jid]) 623 peer_jid <- liftIO $ parseAddressJID (textToByteString jid)
620 liftIO $ announcePresence session (Presence peer_jid Offline) 624 liftIO $ announcePresence session (Presence peer_jid Offline)
621handlePeerPresence session stanza True = do 625handlePeerPresence session stanza True = do
622 -- online (Available or Away) 626 -- online (Available or Away)
623 let log = liftIO . L.putStrLn . ("(P) " <++>) 627 let log = liftIO . L.putStrLn . ("(P) " <++>)
624 withJust (lookupAttrib "from" (tagAttrs stanza)) $ \jid -> do 628 withJust (lookupAttrib "from" (tagAttrs stanza)) $ \jid -> do
625 pjid <- liftIO $ parseAddressJID (L.fromChunks [S.encodeUtf8 jid]) 629 pjid <- liftIO $ parseAddressJID (textToByteString jid)
626 -- stat <- show element content 630 -- stat <- show element content
627 let parseChildren stat = do 631 let parseChildren stat = do
628 child <- nextElement 632 child <- nextElement
@@ -673,7 +677,7 @@ isClientPresenceOf _ _ = False
673handlePresenceProbe session stanza = do 677handlePresenceProbe session stanza = do
674 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to -> do 678 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to -> do
675 -- withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from -> do 679 -- withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from -> do
676 jid <- liftIO $ parseAddressJID $ L.fromChunks [S.encodeUtf8 to] 680 jid <- liftIO $ parseAddressJID $ textToByteString to
677 withJust (name jid) $ \user -> do 681 withJust (name jid) $ \user -> do
678 liftIO $ L.putStrLn $ "RECEIVED PROBE "<++>bshow (peerAddress session,to) 682 liftIO $ L.putStrLn $ "RECEIVED PROBE "<++>bshow (peerAddress session,to)
679 liftIO $ do 683 liftIO $ do
@@ -735,7 +739,7 @@ clientRequestsSubscription session cmdChan stanza = do
735 handleError e = do 739 handleError e = do
736 putStrLn $ "ERROR: "++ show e 740 putStrLn $ "ERROR: "++ show e
737 handleIO handleError $ do 741 handleIO handleError $ do
738 let to_str' = (L.fromChunks [S.encodeUtf8 to_str]) 742 let to_str' = textToByteString to_str
739 to_jid <- fmap bare $ parseHostNameJID to_str' 743 to_jid <- fmap bare $ parseHostNameJID to_str'
740 if (is_remote . peer) to_jid 744 if (is_remote . peer) to_jid
741 then do 745 then do
@@ -751,13 +755,36 @@ clientRequestsSubscription session cmdChan stanza = do
751 755
752peerRequestsSubsription session stanza = do 756peerRequestsSubsription session stanza = do
753 liftIO $ putStrLn $ "PEER PRESENCE SUBSCRIBE " ++ show stanza 757 liftIO $ putStrLn $ "PEER PRESENCE SUBSCRIBE " ++ show stanza
754 -- TODO 758 withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from0-> do
755 -- if already subscribed 759 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to0 -> do
756 -- reply 760 let to = textToByteString to0
757 -- else if no client: 761 from = textToByteString from0
758 -- add pending 762 factory = peerSessionFactory session
759 -- else: 763 mjid <- liftIO $ handleIO_ (return Nothing) (fmap Just $ parseAddressJID to)
760 -- notify client(s) 764 mfrom <- liftIO $ handleIO_ (return Nothing) (fmap Just $ parseAddressJID from)
765 withJust (mfrom >>= name) $ \from -> do
766 withJust mjid $ \tojid -> do
767 withJust (name tojid) $ \user -> do
768 subs <- liftIO $ do
769 subs <- getSubscribers factory user
770 msubs <- flip mapM subs $ \str -> do
771 handleIO_ (return Nothing)
772 (fmap Just $ parseHostNameJID str)
773 return (catMaybes msubs)
774 let peer = peerAddress session
775 fromjid = JID (Just from) peer Nothing
776 if elem fromjid subs
777 then do
778 liftIO . L.putStrLn $ bshow fromjid <++> " already subscribed to " <++> user
779 -- if already subscribed
780 -- reply
781 return ()
782 else
783 -- if no client:
784 -- add pending
785 -- else:
786 -- notify client(s)
787 return ()
761 return () 788 return ()
762 789
763clientApprovesSubscription session stanza = do 790clientApprovesSubscription session stanza = do
@@ -822,6 +849,7 @@ fromPeer session = doNestingXML $ do
822data OutBoundMessage = OutBoundPresence Presence 849data OutBoundMessage = OutBoundPresence Presence
823 | PresenceProbe JID JID 850 | PresenceProbe JID JID
824 | Solicitation JID JID 851 | Solicitation JID JID
852 | Approval JID JID
825 deriving Prelude.Show 853 deriving Prelude.Show
826 854
827newServerConnections = newTVar Map.empty 855newServerConnections = newTVar Map.empty
@@ -851,6 +879,7 @@ connect_to_server chan peer = (>> return ()) . runMaybeT $ do
851 cache <- readIORef cached 879 cache <- readIORef cached
852 let probes' = Map.adjust (Set.insert (False,from)) to $ probes cache 880 let probes' = Map.adjust (Set.insert (False,from)) to $ probes cache
853 writeIORef cached (cache { probes=probes' }) 881 writeIORef cached (cache { probes=probes' })
882 cacheCmd (Approval from to) cached = return () -- Subscription approvals are not cached.
854 883
855 fix $ \sendmsgs -> do 884 fix $ \sendmsgs -> do
856 connected <- liftIO . async $ connect' (peerAddr peer) port 885 connected <- liftIO . async $ connect' (peerAddr peer) port
@@ -979,6 +1008,10 @@ toPeer sock cache chan fail = do
979 Solicitation from to -> do 1008 Solicitation from to -> do
980 liftIO $ L.putStrLn "sending live solicitation..." 1009 liftIO $ L.putStrLn "sending live solicitation..."
981 sendSolicitation from to 1010 sendSolicitation from to
1011 Approval from to -> do
1012 liftIO . L.putStrLn $ "sending approval "<++>bshow (from,to)
1013 r <- liftIO $ presenceProbe sock from to "subscribed"
1014 send r
982 loop 1015 loop
983 send goodbyePeer 1016 send goodbyePeer
984 1017