diff options
author | joe <joe@jerkface.net> | 2013-06-28 00:17:14 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-06-28 00:17:14 -0400 |
commit | 81e891b5661f066a96c32e39232d5fd1445efd11 (patch) | |
tree | ce2f863f29699b43f108458f25973b3b0b076dbf /Presence/XMPP.hs | |
parent | 559a7c3d2bb908036fb0ab9b2b8bc90e0a1c438c (diff) |
xml-conduit parsing for packets inbound from clients
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r-- | Presence/XMPP.hs | 101 |
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 #-} | ||
2 | module XMPP | 3 | module XMPP |
3 | ( module XMPPTypes | 4 | ( module XMPPTypes |
4 | , listenForXmppClients | 5 | , listenForXmppClients |
@@ -9,19 +10,105 @@ module XMPP | |||
9 | 10 | ||
10 | import ServerC | 11 | import ServerC |
11 | import XMPPTypes | 12 | import XMPPTypes |
13 | import SocketLike | ||
14 | import ByteStringOperators | ||
12 | 15 | ||
13 | import Data.HList | 16 | import Data.HList |
14 | import Network.Socket (Family) | 17 | import Network.Socket (Family) |
15 | import Network.BSD (PortNumber) | 18 | import Network.BSD (PortNumber) |
16 | import Control.Concurrent.STM | 19 | import Control.Concurrent.STM |
20 | import Data.Conduit | ||
21 | import qualified Data.Conduit.List as CL | ||
22 | import Data.ByteString (ByteString) | ||
23 | import qualified Data.ByteString.Lazy.Char8 as L | ||
24 | ( putStrLn | ||
25 | ) | ||
26 | import Control.Concurrent (forkIO,killThread) | ||
27 | import Control.Exception (handle,SomeException(..),finally) | ||
28 | import Control.Monad.IO.Class | ||
29 | import Control.Monad.Trans.Maybe | ||
30 | import Todo | ||
31 | import Control.Monad as Monad | ||
32 | import Text.XML.Stream.Parse | ||
17 | 33 | ||
18 | listenForXmppClients | 34 | data 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 | |
37 | xmlifyPresenceForClient :: Presence -> IO [x] | ||
38 | xmlifyPresenceForClient presence = todo | ||
39 | |||
40 | handleClient | ||
41 | :: (SocketLike sock, HHead l (XMPPClass session), | ||
42 | XMPPSession session) => | ||
43 | HCons sock (HCons t l) -> Source IO ByteString -> Sink ByteString IO () -> IO () | ||
44 | handleClient 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 | |||
106 | listenForXmppClients :: | ||
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 | ||
21 | listenForXmppClients addr_family session_factory port st = do | 110 | listenForXmppClients 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 | ||
26 | listenForRemotePeers | 113 | listenForRemotePeers |
27 | :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) => | 114 | :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) => |