summaryrefslogtreecommitdiff
path: root/Presence/XMPP.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-06-28 00:17:14 -0400
committerjoe <joe@jerkface.net>2013-06-28 00:17:14 -0400
commit81e891b5661f066a96c32e39232d5fd1445efd11 (patch)
treece2f863f29699b43f108458f25973b3b0b076dbf /Presence/XMPP.hs
parent559a7c3d2bb908036fb0ab9b2b8bc90e0a1c438c (diff)
xml-conduit parsing for packets inbound from clients
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r--Presence/XMPP.hs101
1 files changed, 94 insertions, 7 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index e158eea2..248d1ffb 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -1,4 +1,5 @@
1{-# LANGUAGE FlexibleContexts #-} 1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE FlexibleContexts #-}
2module XMPP 3module XMPP
3 ( module XMPPTypes 4 ( module XMPPTypes
4 , listenForXmppClients 5 , listenForXmppClients
@@ -9,19 +10,105 @@ module XMPP
9 10
10import ServerC 11import ServerC
11import XMPPTypes 12import XMPPTypes
13import SocketLike
14import ByteStringOperators
12 15
13import Data.HList 16import Data.HList
14import Network.Socket (Family) 17import Network.Socket (Family)
15import Network.BSD (PortNumber) 18import Network.BSD (PortNumber)
16import Control.Concurrent.STM 19import Control.Concurrent.STM
20import Data.Conduit
21import qualified Data.Conduit.List as CL
22import Data.ByteString (ByteString)
23import qualified Data.ByteString.Lazy.Char8 as L
24 ( putStrLn
25 )
26import Control.Concurrent (forkIO,killThread)
27import Control.Exception (handle,SomeException(..),finally)
28import Control.Monad.IO.Class
29import Control.Monad.Trans.Maybe
30import Todo
31import Control.Monad as Monad
32import Text.XML.Stream.Parse
17 33
18listenForXmppClients 34data Commands x = Send [x] | QuitThread
19 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) => 35 deriving Prelude.Show
20 Family -> XMPPClass t -> e -> l -> IO ServerHandle 36
37xmlifyPresenceForClient :: Presence -> IO [x]
38xmlifyPresenceForClient presence = todo
39
40handleClient
41 :: (SocketLike sock, HHead l (XMPPClass session),
42 XMPPSession session) =>
43 HCons sock (HCons t l) -> Source IO ByteString -> Sink ByteString IO () -> IO ()
44handleClient st src snk = do
45 let HCons sock (HCons _ st') = st
46 session_factory = hHead st'
47 pname <- getPeerName sock
48 session <- newSession session_factory sock
49 Prelude.putStrLn $ "PEER NAME: "++Prelude.show pname
50 pchan <- subscribe session Nothing
51 cmdChan <- atomically newTChan
52
53
54 {-
55 reader <- forkIO $ do
56 flip ($$) snk $
57 handle (\(SomeException e) -> liftIO (L.putStrLn $ "quit reader via exception: "<++>bshow e) >> return ()) $
58 fix $ \loop -> do
59 event <- liftIO . atomically $
60 (fmap Left $ readTChan pchan)
61 `orElse`
62 (fmap Right $ readTChan cmdChan)
63 case event of
64 Left presence -> do
65 liftIO (L.putStrLn $ "PRESENCE: " <++> bshow presence)
66 -- TODO: it violates spec to send presence information before
67 -- a resource is bound.
68 -- r <- xmlifyPresenceForClient presence
69 -- yield r
70 -- -- hPutStrLn h r
71 -- liftIO (L.putStrLn $ "\nOUT client:\n" <++> r)
72 Right (Send r) ->
73 mapM_ yield r
74 -- yield r
75 -- -- hPutStrLn h r
76 loop
77 -}
78 let outgoing = do
79 event <- liftIO . atomically $
80 (fmap Left $ readTChan pchan)
81 `orElse`
82 (fmap Right $ readTChan cmdChan)
83 case event of
84 Right QuitThread -> return ()
85 Left presence -> do
86 xs <- liftIO $ xmlifyPresenceForClient presence
87 Monad.mapM_ yield xs
88 outgoing
89
90 incomming = do
91 mb <- await
92 maybe (return ())
93 (\packet -> do
94 liftIO (L.putStrLn $ "client-in: " <++> bshow packet)
95 incomming)
96 mb
97
98 sendingThread <- forkIO (outgoing $$ snk)
99 let quit = do
100 atomically $ writeTChan cmdChan QuitThread
101 closeSession session
102 -- killThread sendingThread
103 finally ( src $= parseBytes def $$ incomming )
104 quit
105
106listenForXmppClients ::
107 (HList l, HHead l (XMPPClass session), HExtend e1 l2 l1,
108 HExtend e l1 (HCons PortNumber l), XMPPSession session) =>
109 Family -> e1 -> e -> l2 -> IO ServerHandle
21listenForXmppClients addr_family session_factory port st = do 110listenForXmppClients addr_family session_factory port st = do
22 putStrLn "unimplemented: listenForXmppClients" 111 doServer (addr_family .*. port .*. session_factory .*. st) handleClient
23 dummyServerHandle
24 -- TODO
25 112
26listenForRemotePeers 113listenForRemotePeers
27 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) => 114 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) =>