diff options
author | joe <joe@jerkface.net> | 2014-02-12 20:35:52 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-02-12 20:35:52 -0500 |
commit | 7ccaa169bc2309df7df2db118dd646177867f2b0 (patch) | |
tree | 82b5e8f7e744f7d919b49ebcb0b0654def7d7d32 /xmppServer.hs | |
parent | 5ad7794bcd86a0049d1e62cae2f04f6088a0ef34 (diff) |
Reply to pings with pongs.
Diffstat (limited to 'xmppServer.hs')
-rw-r--r-- | xmppServer.hs | 64 |
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) | |||
23 | import qualified Text.XML.Stream.Render as XML | 23 | import qualified Text.XML.Stream.Render as XML |
24 | import qualified Text.XML.Stream.Parse as XML | 24 | import qualified Text.XML.Stream.Parse as XML |
25 | import Data.XML.Types as XML | 25 | import Data.XML.Types as XML |
26 | import Data.Maybe (catMaybes) | 26 | import Data.Maybe (catMaybes,fromJust) |
27 | import Data.Monoid ( (<>) ) | 27 | import Data.Monoid ( (<>) ) |
28 | import Data.Text (Text) | 28 | import Data.Text (Text) |
29 | import qualified Data.Text as Text (pack) | 29 | import qualified Data.Text as Text (pack) |
30 | 30 | ||
31 | import qualified Control.Concurrent.STM.UpdateStream as Slotted | 31 | import qualified Control.Concurrent.STM.UpdateStream as Slotted |
32 | import ControlMaybe | 32 | import ControlMaybe |
33 | import NestingXML | 33 | import Nesting |
34 | import EventUtil | 34 | import EventUtil |
35 | import Server | 35 | import Server |
36 | 36 | ||
@@ -80,6 +80,17 @@ type WriteCommand = ByteString -> IO Bool | |||
80 | 80 | ||
81 | data Stanza | 81 | data 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 | |||
88 | copyToChannel f chan = awaitForever copy | ||
89 | where | ||
90 | copy x = do | ||
91 | liftIO . atomically $ writeTChan chan (f x) | ||
92 | yield x | ||
93 | |||
83 | 94 | ||
84 | prettyPrint prefix xs = | 95 | prettyPrint 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 | ||
102 | grockStanzaIQGet :: Monad m => XML.Event -> NestingXML o m (Maybe (TChan (Maybe Event) -> Stanza)) | ||
103 | grockStanzaIQGet 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 | |||
113 | ioWriteChan c v = liftIO . atomically $ writeTChan c v | ||
114 | |||
91 | xmppInbound :: ConnectionKey -> FlagCommand | 115 | xmppInbound :: 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 | ||
116 | chanContents :: TChan x -> IO [x] | 152 | chanContents :: TChan x -> IO [x] |