diff options
author | joe <joe@jerkface.net> | 2013-06-30 15:58:23 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-06-30 15:58:23 -0400 |
commit | b2b10356bea2887fa7f2430cf119114e711cce2c (patch) | |
tree | 1eaf53f9759a0d407a571844b7570e301f6dfef6 | |
parent | 2136b30a030a6e8ed56ff2487a4d6fc860d3a10b (diff) |
regarding outbound-to-peer connections: changed from socket Handle to
a ByteString sink.
-rw-r--r-- | Presence/XMPP.hs | 90 |
1 files changed, 63 insertions, 27 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index 417b3ce7..70f2905a 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -103,11 +103,11 @@ xmlifyPresenceForClient (Presence jid stat) = do | |||
103 | return (concatMap presenceEvents jidstrs) | 103 | return (concatMap presenceEvents jidstrs) |
104 | where | 104 | where |
105 | presenceEvents jidstr = | 105 | presenceEvents jidstr = |
106 | [ EventBeginElement "presence" (("from",[ContentText jidstr]):typ stat) | 106 | [ EventBeginElement "{jabber:client}presence" (("from",[ContentText jidstr]):typ stat) |
107 | , EventBeginElement "show" [] | 107 | , EventBeginElement "{jabber:client}show" [] |
108 | , EventContent (ContentText . shw $ stat) | 108 | , EventContent (ContentText . shw $ stat) |
109 | , EventEndElement "show" | 109 | , EventEndElement "{jabber:client}show" |
110 | , EventEndElement "presence" | 110 | , EventEndElement "{jabber:client}presence" |
111 | ] | 111 | ] |
112 | typ Offline = [("type",[ContentText "unavailable"])] | 112 | typ Offline = [("type",[ContentText "unavailable"])] |
113 | typ _ = [] | 113 | typ _ = [] |
@@ -607,24 +607,56 @@ connect_to_server chan peer = (>> return ()) . runMaybeT $ do | |||
607 | liftIO $ do | 607 | liftIO $ do |
608 | h <- socketToHandle sock ReadWriteMode | 608 | h <- socketToHandle sock ReadWriteMode |
609 | hSetBuffering h NoBuffering | 609 | hSetBuffering h NoBuffering |
610 | L.hPutStrLn h "<stream>" | 610 | let snk = packetSink h |
611 | L.putStrLn $ "OUT peer: <stream>" | ||
612 | cache <- fmap Map.assocs . readIORef $ cached | 611 | cache <- fmap Map.assocs . readIORef $ cached |
613 | writeIORef cached Map.empty -- hint garbage collector: we're done with this | 612 | writeIORef cached Map.empty -- hint garbage collector: we're done with this |
614 | forM_ cache $ \(jid,st) -> do | 613 | handleOutgoingToPeer (restrictSocket sock) cache chan snk |
615 | r <- xmlifyPresenceForPeer sock (Presence jid st) | 614 | |
616 | L.hPutStrLn h r | 615 | |
617 | L.putStrLn $ "OUT peer: (cache)\n" <++> r <++> "\n" | 616 | greetPeer = |
618 | fix $ \loop -> do | 617 | [ EventBeginDocument |
619 | event <- atomically $ readTChan chan | 618 | , EventBeginElement (streamP "stream") |
620 | case event of | 619 | [("xmlns",[ContentText "jabber:server"]) |
621 | OutBoundPresence p -> do | 620 | ,("xmlns:stream",[ContentText "http://etherx.jabber.org/streams"]) |
622 | r <- xmlifyPresenceForPeer sock p | 621 | ,("version",[ContentText "1.0"]) |
623 | L.hPutStrLn h r | 622 | ] |
624 | L.putStrLn $ "OUT peer:\n" <++> r <++> "\n" | 623 | ] |
625 | loop | 624 | |
626 | L.hPutStrLn h "</stream>" | 625 | goodbyePeer = |
627 | L.putStrLn $ "OUT peer: </stream>" | 626 | [ EventEndElement "{jabber:server}stream" |
627 | , EventEndDocument | ||
628 | ] | ||
629 | |||
630 | toPeer sock cache chan = do | ||
631 | let log = liftIO . L.putStrLn . ("(>P) " <++>) | ||
632 | yield greetPeer | ||
633 | log "<stream>" | ||
634 | forM_ cache $ \(jid,st) -> do | ||
635 | r <- lift $ xmlifyPresenceForPeer sock (Presence jid st) | ||
636 | yield r | ||
637 | log $ "(cache) \n" <++> bshow r | ||
638 | fix $ \loop -> do | ||
639 | event <- lift . atomically $ readTChan chan | ||
640 | case event of | ||
641 | OutBoundPresence p -> do | ||
642 | r <- lift $ xmlifyPresenceForPeer sock p | ||
643 | yield r | ||
644 | log (bshow r) | ||
645 | loop | ||
646 | yield goodbyePeer | ||
647 | log "</stream>" | ||
648 | |||
649 | handleOutgoingToPeer sock cache chan snk = do | ||
650 | #ifdef RENDERFLUSH | ||
651 | toPeer sock cache chan | ||
652 | $$ flushList | ||
653 | =$= renderBuilderFlush def | ||
654 | =$= builderToByteStringFlush | ||
655 | =$= discardFlush | ||
656 | =$ snk | ||
657 | #else | ||
658 | toPeer sock cache chan $$ renderChunks =$ snk | ||
659 | #endif | ||
628 | 660 | ||
629 | connect' :: SockAddr -> Int -> IO (Maybe Socket) | 661 | connect' :: SockAddr -> Int -> IO (Maybe Socket) |
630 | connect' addr port = do | 662 | connect' addr port = do |
@@ -720,15 +752,19 @@ xmlifyPresenceForPeer sock (Presence jid stat) = do | |||
720 | addr <- getSocketName sock | 752 | addr <- getSocketName sock |
721 | let n = name jid | 753 | let n = name jid |
722 | rsc = resource jid | 754 | rsc = resource jid |
723 | jid_str = n <$++> "@" <?++> showPeer (RemotePeer addr) <++?> "/" <++$> rsc | 755 | jidstr = toStrict . L.decodeUtf8 |
724 | return . L.unlines $ | 756 | $ n <$++> "@" <?++> showPeer (RemotePeer addr) <++?> "/" <++$> rsc |
725 | [ "<presence from='" <++> jid_str <++> "' " <++> typ stat <++> ">" | 757 | return |
726 | , "<show>" <++> shw stat <++> "</show>" | 758 | [ EventBeginElement "{jabber:server}presence" |
727 | , "</presence>" | 759 | (("from",[ContentText jidstr]):typ stat) |
760 | , EventBeginElement "{jabber:server}show" [] | ||
761 | , EventContent (ContentText . shw $ stat) | ||
762 | , EventEndElement "{jabber:server}show" | ||
763 | , EventEndElement "{jabber:server}presence" | ||
728 | ] | 764 | ] |
729 | where | 765 | where |
730 | typ Offline = " type='unavailable'" | 766 | typ Offline = [("type",[ContentText "unavailable"])] |
731 | typ _ = "" | 767 | typ _ = [] |
732 | shw Available = "chat" | 768 | shw Available = "chat" |
733 | shw Away = "away" | 769 | shw Away = "away" |
734 | shw Offline = "away" -- Is this right? | 770 | shw Offline = "away" -- Is this right? |