diff options
-rw-r--r-- | Presence/XMPP.hs | 57 |
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 | |||
20 | import ByteStringOperators | 20 | import ByteStringOperators |
21 | import ControlMaybe | 21 | import ControlMaybe |
22 | 22 | ||
23 | import Data.Maybe (catMaybes) | ||
23 | import Data.HList | 24 | import Data.HList |
24 | import Network.Socket | 25 | import Network.Socket |
25 | ( Family | 26 | ( Family |
@@ -95,6 +96,9 @@ import GHC.Conc | |||
95 | , ThreadId | 96 | , ThreadId |
96 | ) | 97 | ) |
97 | 98 | ||
99 | textToByteString x = L.fromChunks [S.encodeUtf8 x] | ||
100 | |||
101 | |||
98 | data Commands = | 102 | data 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 | |||
616 | handlePeerPresence session stanza False = do | 620 | handlePeerPresence 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) |
621 | handlePeerPresence session stanza True = do | 625 | handlePeerPresence 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 | |||
673 | handlePresenceProbe session stanza = do | 677 | handlePresenceProbe 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 | ||
752 | peerRequestsSubsription session stanza = do | 756 | peerRequestsSubsription 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 | ||
763 | clientApprovesSubscription session stanza = do | 790 | clientApprovesSubscription session stanza = do |
@@ -822,6 +849,7 @@ fromPeer session = doNestingXML $ do | |||
822 | data OutBoundMessage = OutBoundPresence Presence | 849 | data 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 | ||
827 | newServerConnections = newTVar Map.empty | 855 | newServerConnections = 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 | ||