diff options
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r-- | Presence/XMPP.hs | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index 8589999b..498106b9 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -30,6 +30,7 @@ import Data.Maybe (catMaybes) | |||
30 | import Data.HList | 30 | import Data.HList |
31 | import Network.Socket ( Family ) | 31 | import Network.Socket ( Family ) |
32 | import Control.Concurrent.STM | 32 | import Control.Concurrent.STM |
33 | import Control.Concurrent.STM.Delay | ||
33 | import Data.Conduit | 34 | import Data.Conduit |
34 | import Data.Maybe | 35 | import Data.Maybe |
35 | import Data.ByteString (ByteString) | 36 | import Data.ByteString (ByteString) |
@@ -888,6 +889,7 @@ peerRejectsSubscription session stanza = do | |||
888 | handlePeerIQGet :: (JabberPeerSession session, MonadIO m) => | 889 | handlePeerIQGet :: (JabberPeerSession session, MonadIO m) => |
889 | session -> XML.Event -> NestingXML o m () | 890 | session -> XML.Event -> NestingXML o m () |
890 | handlePeerIQGet session tag = do | 891 | handlePeerIQGet session tag = do |
892 | -- TODO: Pings should not require an id field. | ||
891 | withJust (lookupAttrib "id" (tagAttrs tag)) $ \stanza_id -> do | 893 | withJust (lookupAttrib "id" (tagAttrs tag)) $ \stanza_id -> do |
892 | whenJust nextElement $ \child -> do | 894 | whenJust nextElement $ \child -> do |
893 | let unhandledGet req = do | 895 | let unhandledGet req = do |
@@ -925,6 +927,8 @@ fromPeer session = doNestingXML $ do | |||
925 | whenJust nextElement $ \stanza -> do | 927 | whenJust nextElement $ \stanza -> do |
926 | stanza_lvl <- nesting | 928 | stanza_lvl <- nesting |
927 | 929 | ||
930 | liftIO $ sendPeerMessage session ActivityBump -- reset ping timer | ||
931 | |||
928 | let unhandledStanza = do | 932 | let unhandledStanza = do |
929 | xs <- gatherElement stanza Seq.empty | 933 | xs <- gatherElement stanza Seq.empty |
930 | prettyPrint "P: " (toList xs) | 934 | prettyPrint "P: " (toList xs) |
@@ -983,6 +987,7 @@ instance CommandCache CachedMessages where | |||
983 | updateCache (OutBoundMessage msg) cache = cache -- TODO | 987 | updateCache (OutBoundMessage msg) cache = cache -- TODO |
984 | updateCache (Pong _ _ _) cache = cache -- pings are not cached | 988 | updateCache (Pong _ _ _) cache = cache -- pings are not cached |
985 | updateCache (Unsupported _ _ _ _) cache = cache -- error messages are not cached | 989 | updateCache (Unsupported _ _ _ _) cache = cache -- error messages are not cached |
990 | updateCache ActivityBump cache = cache | ||
986 | 991 | ||
987 | instance ThreadChannelCommand OutBoundMessage where | 992 | instance ThreadChannelCommand OutBoundMessage where |
988 | isQuitCommand Disconnect = True | 993 | isQuitCommand Disconnect = True |
@@ -1007,14 +1012,23 @@ goodbyePeer = | |||
1007 | , EventEndDocument | 1012 | , EventEndDocument |
1008 | ] | 1013 | ] |
1009 | 1014 | ||
1010 | presenceStanza sock fromjid tojid typ = do | 1015 | peerJidTextLocal sock jid = do |
1011 | addr <- getSocketName sock | 1016 | addr <- getSocketName sock |
1012 | let jidstr jid = toStrict . L.decodeUtf8 | 1017 | return . toStrict . L.decodeUtf8 |
1013 | $ name jid <$++> "@" | 1018 | $ name jid <$++> "@" |
1019 | <?++> showPeer (RemotePeer addr) | ||
1020 | <++?> "/" <++$> resource jid | ||
1021 | |||
1022 | peerJidTextRemote sock jid = do | ||
1023 | addr <- getPeerName sock | ||
1024 | return . toStrict . L.decodeUtf8 | ||
1025 | $ name jid <$++> "@" | ||
1014 | <?++> showPeer (RemotePeer addr) | 1026 | <?++> showPeer (RemotePeer addr) |
1015 | <++?> "/" <++$> resource jid | 1027 | <++?> "/" <++$> resource jid |
1016 | from = jidstr fromjid | 1028 | |
1017 | to = toStrict . L.decodeUtf8 | 1029 | presenceStanza sock fromjid tojid typ = do |
1030 | from <- peerJidTextLocal sock fromjid | ||
1031 | let to = toStrict . L.decodeUtf8 | ||
1018 | $ name tojid <$++> "@" | 1032 | $ name tojid <$++> "@" |
1019 | <?++> showPeer (peer tojid) | 1033 | <?++> showPeer (peer tojid) |
1020 | return | 1034 | return |
@@ -1074,8 +1088,8 @@ toPeer sock cache chan fail = do | |||
1074 | Just c -> (("id",[c]):) | 1088 | Just c -> (("id",[c]):) |
1075 | _ -> id ) | 1089 | _ -> id ) |
1076 | [ attr "type" "result" | 1090 | [ attr "type" "result" |
1077 | , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) | 1091 | , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) -- TODO: should send numeric address |
1078 | , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) | 1092 | , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) -- TODO: should send numeric address |
1079 | ] | 1093 | ] |
1080 | , EventEndElement "{jabber:server}iq" | 1094 | , EventEndElement "{jabber:server}iq" |
1081 | ] | 1095 | ] |
@@ -1090,8 +1104,8 @@ toPeer sock cache chan fail = do | |||
1090 | Just c -> (("id",[c]):) | 1104 | Just c -> (("id",[c]):) |
1091 | _ -> id ) | 1105 | _ -> id ) |
1092 | [("type",[ContentText "error"]) | 1106 | [("type",[ContentText "error"]) |
1093 | , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) | 1107 | , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) -- TODO: should send numeric address |
1094 | , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) | 1108 | , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) -- TODO: should send numeric address |
1095 | ] | 1109 | ] |
1096 | , EventBeginElement req [] | 1110 | , EventBeginElement req [] |
1097 | , EventEndElement req | 1111 | , EventEndElement req |
@@ -1120,28 +1134,58 @@ toPeer sock cache chan fail = do | |||
1120 | liftIO $ debugL "sending cached solicitation..." | 1134 | liftIO $ debugL "sending cached solicitation..." |
1121 | sendSolicitation from to | 1135 | sendSolicitation from to |
1122 | 1136 | ||
1123 | 1137 | ||
1138 | let five_sec = 5 * 1000000 :: Int | ||
1139 | ping_timer <- liftIO $ newDelay five_sec | ||
1140 | let bump = updateDelay ping_timer five_sec | ||
1141 | |||
1124 | fix $ \loop -> do | 1142 | fix $ \loop -> do |
1125 | event <- lift . atomically $ readTChan chan | 1143 | event <- lift . atomically $ orElse (Left `fmap` readTChan chan) |
1126 | case event of | 1144 | (Right `fmap` waitDelay ping_timer) |
1127 | OutBoundPresence p -> sendPresence p | 1145 | let sendPing () = do |
1128 | PresenceProbe from to -> do | 1146 | ping <- liftIO makePing |
1129 | liftIO $ debugL "sending live probe..." | 1147 | yield ping |
1130 | sendProbe from to | 1148 | loop |
1131 | Solicitation from to -> do | 1149 | where makePing = do |
1132 | liftIO $ debugL "sending live solicitation..." | 1150 | addr <- getSocketName sock |
1133 | sendSolicitation from to | 1151 | remote <- getPeerName sock |
1134 | Approval from to -> do | 1152 | let from = toStrict . L.decodeUtf8 . showPeer $ RemotePeer addr |
1135 | liftIO . debugL $ "sending approval "<++>bshow (from,to) | 1153 | to = toStrict . L.decodeUtf8 . showPeer $ RemotePeer remote |
1136 | sendApproval True from to | 1154 | mid = Just (ContentText "iduno") |
1137 | Rejection from to -> do | 1155 | return $ |
1138 | liftIO . debugL $ "sending rejection "<++>bshow (from,to) | 1156 | [ EventBeginElement "{jabber:server}iq" |
1139 | sendApproval False from to | 1157 | $ (case mid of |
1140 | OutBoundMessage msg -> sendMessage msg | 1158 | Just c -> (("id",[c]):) |
1141 | Pong from to mid -> sendPong from to mid | 1159 | _ -> id ) |
1142 | Unsupported from to mid tag -> sendUnsupported from to mid tag | 1160 | [("type",[ContentText "error"]) |
1143 | Disconnect -> return () | 1161 | , attr "to" to |
1144 | when (not . isQuitCommand $ event) loop | 1162 | , attr "from" from |
1163 | ] | ||
1164 | , EventBeginElement "{urn:xmpp:ping}ping" [] | ||
1165 | , EventEndElement "{urn:xmpp:ping}ping" | ||
1166 | , EventEndElement "{jabber:server}iq" ] | ||
1167 | chanEvent event = do | ||
1168 | case event of | ||
1169 | OutBoundPresence p -> sendPresence p | ||
1170 | PresenceProbe from to -> do | ||
1171 | liftIO $ debugL "sending live probe..." | ||
1172 | sendProbe from to | ||
1173 | Solicitation from to -> do | ||
1174 | liftIO $ debugL "sending live solicitation..." | ||
1175 | sendSolicitation from to | ||
1176 | Approval from to -> do | ||
1177 | liftIO . debugL $ "sending approval "<++>bshow (from,to) | ||
1178 | sendApproval True from to | ||
1179 | Rejection from to -> do | ||
1180 | liftIO . debugL $ "sending rejection "<++>bshow (from,to) | ||
1181 | sendApproval False from to | ||
1182 | OutBoundMessage msg -> sendMessage msg | ||
1183 | Pong from to mid -> sendPong from to mid | ||
1184 | Unsupported from to mid tag -> sendUnsupported from to mid tag | ||
1185 | Disconnect -> return () | ||
1186 | ActivityBump -> liftIO bump | ||
1187 | when (not . isQuitCommand $ event) loop | ||
1188 | either chanEvent sendPing event | ||
1145 | return () | 1189 | return () |
1146 | -- send goodbyePeer -- TODO: why does this cause an exception? | 1190 | -- send goodbyePeer -- TODO: why does this cause an exception? |
1147 | -- Text/XML/Stream/Render.hs:169:5-15: | 1191 | -- Text/XML/Stream/Render.hs:169:5-15: |