summaryrefslogtreecommitdiff
path: root/xmppServer.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-02-12 20:35:52 -0500
committerjoe <joe@jerkface.net>2014-02-12 20:35:52 -0500
commit7ccaa169bc2309df7df2db118dd646177867f2b0 (patch)
tree82b5e8f7e744f7d919b49ebcb0b0654def7d7d32 /xmppServer.hs
parent5ad7794bcd86a0049d1e62cae2f04f6088a0ef34 (diff)
Reply to pings with pongs.
Diffstat (limited to 'xmppServer.hs')
-rw-r--r--xmppServer.hs64
1 files changed, 50 insertions, 14 deletions
diff --git a/xmppServer.hs b/xmppServer.hs
index 85e0cb5c..f91c20ce 100644
--- a/xmppServer.hs
+++ b/xmppServer.hs
@@ -23,14 +23,14 @@ import Data.Conduit.Blaze (builderToByteStringFlush)
23import qualified Text.XML.Stream.Render as XML 23import qualified Text.XML.Stream.Render as XML
24import qualified Text.XML.Stream.Parse as XML 24import qualified Text.XML.Stream.Parse as XML
25import Data.XML.Types as XML 25import Data.XML.Types as XML
26import Data.Maybe (catMaybes) 26import Data.Maybe (catMaybes,fromJust)
27import Data.Monoid ( (<>) ) 27import Data.Monoid ( (<>) )
28import Data.Text (Text) 28import Data.Text (Text)
29import qualified Data.Text as Text (pack) 29import qualified Data.Text as Text (pack)
30 30
31import qualified Control.Concurrent.STM.UpdateStream as Slotted 31import qualified Control.Concurrent.STM.UpdateStream as Slotted
32import ControlMaybe 32import ControlMaybe
33import NestingXML 33import Nesting
34import EventUtil 34import EventUtil
35import Server 35import Server
36 36
@@ -80,6 +80,17 @@ type WriteCommand = ByteString -> IO Bool
80 80
81data Stanza 81data Stanza
82 = UnrecognizedStanza { stanzaChan :: TChan (Maybe XML.Event) } 82 = UnrecognizedStanza { stanzaChan :: TChan (Maybe XML.Event) }
83 | PingStanza { stanzaId :: Maybe Text
84 , stanzaChan :: TChan (Maybe XML.Event) }
85 | PongStanza { -- stanzaId :: Maybe Text
86 stanzaChan :: TChan (Maybe XML.Event) }
87
88copyToChannel f chan = awaitForever copy
89 where
90 copy x = do
91 liftIO . atomically $ writeTChan chan (f x)
92 yield x
93
83 94
84prettyPrint prefix xs = 95prettyPrint prefix xs =
85 liftIO $ 96 liftIO $
@@ -88,6 +99,19 @@ prettyPrint prefix xs =
88 =$= CB.lines 99 =$= CB.lines
89 $$ CL.mapM_ (wlogb . (prefix <>)) 100 $$ CL.mapM_ (wlogb . (prefix <>))
90 101
102grockStanzaIQGet :: Monad m => XML.Event -> NestingXML o m (Maybe (TChan (Maybe Event) -> Stanza))
103grockStanzaIQGet stanza = do
104 let mid = lookupAttrib "id" (tagAttrs stanza)
105 -- mfrom = lookupAttrib "from" (tagAttrs stanza)
106 mtag <- nextElement
107 flip (maybe $ return Nothing) mtag $ \tag -> do
108 case tagName tag of
109 "{urn:xmpp:ping}ping" -> do
110 return $ Just (PingStanza mid)
111 _ -> return Nothing
112
113ioWriteChan c v = liftIO . atomically $ writeTChan c v
114
91xmppInbound :: ConnectionKey -> FlagCommand 115xmppInbound :: ConnectionKey -> FlagCommand
92 -> Source IO XML.Event 116 -> Source IO XML.Event
93 -> TChan Stanza 117 -> TChan Stanza
@@ -99,18 +123,30 @@ xmppInbound k pingflag src stanzas output = doNestingXML $ do
99 whenJust nextElement $ \xml -> do 123 whenJust nextElement $ \xml -> do
100 withJust (elementAttrs "stream" xml) $ \stream_attrs -> do 124 withJust (elementAttrs "stream" xml) $ \stream_attrs -> do
101 fix $ \loop -> do 125 fix $ \loop -> do
102 -- liftIO . wlog $ "waiting for stanza." 126 -- liftIO . wlog $ "waiting for stanza."
103 chan <- liftIO $ atomically newTChan 127 chan <- liftIO $ atomically newTChan
104 whenJust nextElement $ \stanza -> do 128 whenJust nextElement $ \stanza -> do
105 stanza_lvl <- nesting 129 stanza_lvl <- nesting
106 liftIO . atomically $ writeTChan chan (Just stanza) 130 ioWriteChan chan (Just stanza)
107 131 copyToChannel Just chan =$= do
108 liftIO . atomically $ writeTChan stanzas $ 132 dispatch <-
109 UnrecognizedStanza chan 133 case () of
110 doUntilCloser stanza_lvl $ \xml -> do 134 _ | stanza `isServerIQOf` "get" -> grockStanzaIQGet stanza
111 liftIO . atomically $ writeTChan chan (Just xml) 135 _ -> return $ Just UnrecognizedStanza
112 liftIO . atomically $ writeTChan chan Nothing 136 flip (maybe $ return ()) dispatch $ \dispatch ->
113 loop 137 case dispatch chan of
138 d@(PingStanza {}) -> do
139 let to = "todo"
140 from = "todo"
141 let pong = peerPong (stanzaId d) to from
142 pongChan <- liftIO $ atomically newTChan
143 ioWriteChan output (PongStanza pongChan)
144 mapM_ (ioWriteChan pongChan . Just) pong
145 ioWriteChan pongChan Nothing
146 disp -> ioWriteChan stanzas disp
147 awaitCloser stanza_lvl
148 ioWriteChan chan Nothing
149 loop
114 150
115 151
116chanContents :: TChan x -> IO [x] 152chanContents :: TChan x -> IO [x]