summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
Diffstat (limited to 'Presence')
-rw-r--r--Presence/XMPPServer.hs56
1 files changed, 48 insertions, 8 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index af986645..eb680002 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -14,6 +14,7 @@ module XMPPServer
14 , peerKeyToText 14 , peerKeyToText
15 , peerKeyToResolvedName 15 , peerKeyToResolvedName
16 , addrToText 16 , addrToText
17 , sendModifiedStanzaToPeer
17 ) where 18 ) where
18import Debug.Trace 19import Debug.Trace
19import Control.Monad.Trans.Resource (runResourceT) 20import Control.Monad.Trans.Resource (runResourceT)
@@ -245,6 +246,38 @@ prettyPrint prefix =
245 =$= CB.lines 246 =$= CB.lines
246 =$ CL.mapM_ (wlogb . (prefix <>)) 247 =$ CL.mapM_ (wlogb . (prefix <>))
247 248
249swapNamespace old new = awaitForever swapit
250 where
251 swapit (EventBeginElement n as) | nameNamespace n==Just old =
252 yield $ EventBeginElement (n { nameNamespace = Just new }) as
253 swapit (EventEndElement n) | nameNamespace n==Just old =
254 yield $ EventEndElement (n { nameNamespace = Just new })
255 swapit x = yield x
256
257fixHeaders Stanza { stanzaTo=mto, stanzaFrom=mfrom } = do
258 x <- await
259 maybe (return ()) f x
260 where
261 f (EventBeginElement n as) = do yield $ EventBeginElement n (update as)
262 awaitForever yield
263 f x = yield x >> awaitForever yield
264 update as = as''
265 where
266 as' = maybe as (\to->attr "to" to:as) mto
267 as'' = maybe as' (\from->attr "from" from:as') mfrom
268
269
270sendModifiedStanzaToPeer stanza chan = do
271 (echan,clsrs,quitvar) <- conduitToChan c
272 ioWriteChan chan
273 stanza { stanzaChan = echan
274 , stanzaClosers = clsrs
275 , stanzaInterrupt = quitvar
276 -- TODO id? origin?
277 }
278 where
279 c = stanzaToConduit stanza =$= swapNamespace "jabber:client" "jabber:server" =$= fixHeaders stanza
280
248-- id,to, and from are taken as-is from reply list 281-- id,to, and from are taken as-is from reply list
249sendReply donevar stype reply replychan = do 282sendReply donevar stype reply replychan = do
250 if null reply then return () 283 if null reply then return ()
@@ -802,6 +835,15 @@ xmlifyRosterItems solicited stype set = mapM_ item (Set.toList set)
802 else [] ) 835 else [] )
803 yield $ EventEndElement "{jabber:iq:roster}item" 836 yield $ EventEndElement "{jabber:iq:roster}item"
804 837
838conduitToChan c = do
839 chan <- atomically newTChan
840 clsrs <- atomically $ newTVar (Just [])
841 quitvar <- atomically $ newEmptyTMVar
842 forkIO $ do
843 c =$= copyToChannel id chan clsrs $$ awaitForever (const $ return ())
844 atomically $ writeTVar clsrs Nothing
845 return (chan,clsrs,quitvar)
846
805sendRoster query xmpp replyto = do 847sendRoster query xmpp replyto = do
806 let k = case stanzaOrigin query of 848 let k = case stanzaOrigin query of
807 NetworkOrigin k _ -> Just k 849 NetworkOrigin k _ -> Just k
@@ -834,12 +876,7 @@ sendRoster query xmpp replyto = do
834 xmlifyRosterItems solicited "none" subnone 876 xmlifyRosterItems solicited "none" subnone
835 yield $ EventEndElement "{jabber:iq:roster}query" 877 yield $ EventEndElement "{jabber:iq:roster}query"
836 yield $ EventEndElement "{jabber:client}iq" 878 yield $ EventEndElement "{jabber:client}iq"
837 chan <- atomically newTChan 879 (chan,clsrs,quitvar) <- conduitToChan roster
838 clsrs <- atomically $ newTVar (Just [])
839 quitvar <- atomically $ newEmptyTMVar
840 forkIO $ do
841 roster =$= copyToChannel id chan clsrs $$ awaitForever (const $ return ())
842 atomically $ writeTVar clsrs Nothing
843 ioWriteChan replyto 880 ioWriteChan replyto
844 Stanza { stanzaType = Roster 881 Stanza { stanzaType = Roster
845 , stanzaId = (stanzaId query) 882 , stanzaId = (stanzaId query)
@@ -904,7 +941,8 @@ monitor sv params xmpp = do
904 sendRoster stanza xmpp replyto 941 sendRoster stanza xmpp replyto
905 xmppSubscribeToRoster xmpp k 942 xmppSubscribeToRoster xmpp k
906 Message {} -> do 943 Message {} -> do
907 let fail = return () -- todo 944 let fail = wlog $ "Failed delivery id="++show (stanzaId stanza) -- TODO
945 stanza2 <- atomically $ cloneStanza stanza
908 xmppDeliverMessage xmpp fail stanza 946 xmppDeliverMessage xmpp fail stanza
909 PresenceStatus {} -> do 947 PresenceStatus {} -> do
910 xmppInformClientPresence xmpp k stanza 948 xmppInformClientPresence xmpp k stanza
@@ -914,13 +952,15 @@ monitor sv params xmpp = do
914 sendReply quitVar Error reply replyto 952 sendReply quitVar Error reply replyto
915 _ -> return () 953 _ -> return ()
916 _ -> return () 954 _ -> return ()
955 -- We need to clone in the case the stanza is passed on as for Message.
956 dup <- atomically $ cloneStanza stanza
917 let typ = Strict8.pack $ c ++ "->"++(concat . take 1 . words $ show (stanzaType stanza))++" " 957 let typ = Strict8.pack $ c ++ "->"++(concat . take 1 . words $ show (stanzaType stanza))++" "
918 c = case stanzaOrigin stanza of 958 c = case stanzaOrigin stanza of
919 LocalPeer -> "*" 959 LocalPeer -> "*"
920 NetworkOrigin (ClientKey {}) _ -> "C" 960 NetworkOrigin (ClientKey {}) _ -> "C"
921 NetworkOrigin (PeerKey {}) _ -> "P" 961 NetworkOrigin (PeerKey {}) _ -> "P"
922 wlog "" 962 wlog ""
923 stanzaToConduit stanza $$ prettyPrint typ 963 stanzaToConduit dup $$ prettyPrint typ
924 964
925 ] 965 ]
926 action 966 action