diff options
author | joe <joe@jerkface.net> | 2013-06-19 20:51:43 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-06-19 20:51:43 -0400 |
commit | dbcf30d5239043eafa1282caa369c577130938e9 (patch) | |
tree | 1789875ed8abcf20e97738b9c243df73097090ad | |
parent | 875f4abfd5853ec3ef189d7e5289ee9cbaa7cc7f (diff) |
Shared hostname with client-connection.
-rw-r--r-- | Presence/ByteStringOperators.hs | 8 | ||||
-rw-r--r-- | Presence/XMPPServer.hs | 61 | ||||
-rw-r--r-- | Presence/main.hs | 22 |
3 files changed, 55 insertions, 36 deletions
diff --git a/Presence/ByteStringOperators.hs b/Presence/ByteStringOperators.hs index 2815f05a..9e6cc938 100644 --- a/Presence/ByteStringOperators.hs +++ b/Presence/ByteStringOperators.hs | |||
@@ -2,6 +2,7 @@ module ByteStringOperators where | |||
2 | 2 | ||
3 | import qualified Data.ByteString as S (ByteString) | 3 | import qualified Data.ByteString as S (ByteString) |
4 | import Data.ByteString.Lazy.Char8 as L | 4 | import Data.ByteString.Lazy.Char8 as L |
5 | import Control.Applicative | ||
5 | 6 | ||
6 | -- These two were imported to provide an NFData instance. | 7 | -- These two were imported to provide an NFData instance. |
7 | import qualified Data.ByteString.Lazy.Internal as L (ByteString(..)) | 8 | import qualified Data.ByteString.Lazy.Internal as L (ByteString(..)) |
@@ -21,6 +22,13 @@ infixr 5 <.++> | |||
21 | infixr 5 <++> | 22 | infixr 5 <++> |
22 | infixr 5 <++.> | 23 | infixr 5 <++.> |
23 | 24 | ||
25 | a <++$> b = fmap (a<++>) b | ||
26 | a <$++> b = fmap (<++>b) a | ||
27 | a <$++$> b = liftA2 (<++>) a b | ||
28 | infixr 6 <++$> | ||
29 | infixr 6 <$++> | ||
30 | infixr 6 <$++$> | ||
31 | |||
24 | Nothing <?++> b = b | 32 | Nothing <?++> b = b |
25 | Just a <?++> b = a <++> b | 33 | Just a <?++> b = a <++> b |
26 | infixr 5 <?++> | 34 | infixr 5 <?++> |
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs index 6d7841ff..6c0b609e 100644 --- a/Presence/XMPPServer.hs +++ b/Presence/XMPPServer.hs | |||
@@ -44,6 +44,9 @@ import Control.DeepSeq | |||
44 | import Control.Concurrent.STM | 44 | import Control.Concurrent.STM |
45 | import Control.Concurrent | 45 | import Control.Concurrent |
46 | import Control.Exception | 46 | import Control.Exception |
47 | import Text.Show.ByteString as L | ||
48 | import Data.Binary.Builder as B | ||
49 | import Data.Binary.Put | ||
47 | 50 | ||
48 | -- | Jabber ID (JID) datatype | 51 | -- | Jabber ID (JID) datatype |
49 | data JID = JID { name :: Maybe ByteString | 52 | data JID = JID { name :: Maybe ByteString |
@@ -52,8 +55,11 @@ data JID = JID { name :: Maybe ByteString | |||
52 | } | 55 | } |
53 | deriving (Ord,Eq) | 56 | deriving (Ord,Eq) |
54 | 57 | ||
55 | instance Show JID where | 58 | instance L.Show JID where |
56 | show (JID n s r ) = L.unpack $ fmap (<++>"@") n <?++> s <++?> fmap ("/"<++>) r | 59 | showp (JID n s r ) = putBuilder . B.fromLazyByteString $ n <$++> "@" <?++> s <++?> "/" <++$> r |
60 | |||
61 | instance Prelude.Show JID where | ||
62 | show jid = L.unpack $ L.show jid | ||
57 | 63 | ||
58 | instance NFData JID where | 64 | instance NFData JID where |
59 | rnf v@(JID n s r) = n `seq` s `seq` r `seq` () | 65 | rnf v@(JID n s r) = n `seq` s `seq` r `seq` () |
@@ -63,13 +69,13 @@ jid user host rsrc = JID (Just user) host (Just rsrc) | |||
63 | data JabberShow = Offline | 69 | data JabberShow = Offline |
64 | | Away | 70 | | Away |
65 | | Available | 71 | | Available |
66 | deriving (Show,Enum,Ord,Eq,Read) | 72 | deriving (Prelude.Show,Enum,Ord,Eq,Read) |
67 | 73 | ||
68 | data Presence = Presence JID JabberShow | 74 | data Presence = Presence JID JabberShow |
69 | deriving Show | 75 | deriving Prelude.Show |
70 | 76 | ||
71 | xmlifyPresence (Presence jid stat) = L.unlines | 77 | xmlifyPresence (Presence jid stat) = L.unlines |
72 | [ "<presence from='" <++> bshow jid <++> "' " <++> typ stat <++> ">" | 78 | [ "<presence from='" <++> L.show jid <++> "' " <++> typ stat <++> ">" |
73 | , "<show>" <++> shw stat <++> "</show>" | 79 | , "<show>" <++> shw stat <++> "</show>" |
74 | , "</presence>" | 80 | , "</presence>" |
75 | ] | 81 | ] |
@@ -88,7 +94,7 @@ class XMPPSession session where | |||
88 | data XMPPClass session | 94 | data XMPPClass session |
89 | newSession :: XMPPClass session -> Socket -> Handle -> IO session | 95 | newSession :: XMPPClass session -> Socket -> Handle -> IO session |
90 | setResource :: session -> ByteString -> IO () | 96 | setResource :: session -> ByteString -> IO () |
91 | getJID :: session -> IO ByteString | 97 | getJID :: session -> IO JID |
92 | closeSession :: session -> IO () | 98 | closeSession :: session -> IO () |
93 | subscribe :: session -> Maybe JID -> IO (TChan Presence) | 99 | subscribe :: session -> Maybe JID -> IO (TChan Presence) |
94 | 100 | ||
@@ -114,15 +120,15 @@ greet host = L.unlines | |||
114 | -- data TaggedXMPPSession s = TaggedXMPPSession s | 120 | -- data TaggedXMPPSession s = TaggedXMPPSession s |
115 | 121 | ||
116 | data Commands = Send ByteString | 122 | data Commands = Send ByteString |
117 | deriving Show | 123 | deriving Prelude.Show |
118 | 124 | ||
119 | startCon session_factory sock st = do | 125 | startCon session_factory sock st = do |
120 | let h = hOccursFst st :: Handle | 126 | let h = hOccursFst st :: Handle |
121 | cred <- getLocalPeerCred sock | 127 | cred <- getLocalPeerCred sock |
122 | Prelude.putStrLn $ "PEER CRED: "++show cred | 128 | Prelude.putStrLn $ "PEER CRED: "++Prelude.show cred |
123 | pname <- getPeerName sock | 129 | pname <- getPeerName sock |
124 | session <- newSession session_factory sock h | 130 | session <- newSession session_factory sock h |
125 | Prelude.putStrLn $ "PEER NAME: "++show pname | 131 | Prelude.putStrLn $ "PEER NAME: "++Prelude.show pname |
126 | pchan <- subscribe session Nothing | 132 | pchan <- subscribe session Nothing |
127 | cmdChan <- atomically newTChan | 133 | cmdChan <- atomically newTChan |
128 | reader <- forkIO $ | 134 | reader <- forkIO $ |
@@ -150,9 +156,7 @@ startCon session_factory sock st = do | |||
150 | 156 | ||
151 | iq_query_unavailable host id mjid xmlns kind = L.unlines $ | 157 | iq_query_unavailable host id mjid xmlns kind = L.unlines $ |
152 | [ "<iq type='error'" | 158 | [ "<iq type='error'" |
153 | , " from='" <++> host <++> "'" | 159 | , " from='" <++> host <++> "'" <++?> " to='" <++$> mjid <$++> "'" |
154 | , case mjid of Just jid -> " to='" <++> jid <++> "'" | ||
155 | Nothing -> "" | ||
156 | , " id='" <++> id <++> "'>" | 160 | , " id='" <++> id <++> "'>" |
157 | , " <" <++> kind <++> " xmlns='" <++> xmlns <++> "'/>" | 161 | , " <" <++> kind <++> " xmlns='" <++> xmlns <++> "'/>" |
158 | , " <error type='cancel'>" | 162 | , " <error type='cancel'>" |
@@ -195,11 +199,10 @@ iq_session_reply host id = L.unlines $ | |||
195 | , " /> " | 199 | , " /> " |
196 | ] | 200 | ] |
197 | 201 | ||
202 | {- | ||
198 | iqresult_info host id mjid = L.unlines $ | 203 | iqresult_info host id mjid = L.unlines $ |
199 | [ "<iq type='result'" | 204 | [ "<iq type='result'" |
200 | , " from='" <++> host <++> "'" | 205 | , " from='" <++> host <++> "'" <++?> " to='" <++$> mjid <$++> "'" |
201 | , case mjid of Just jid -> " to='" <++> jid <++> "'" | ||
202 | Nothing -> "" | ||
203 | , " id='" <++> id <++> "'>" | 206 | , " id='" <++> id <++> "'>" |
204 | , " <query xmlns='http://jabber.org/protocol/disco#info'>" | 207 | , " <query xmlns='http://jabber.org/protocol/disco#info'>" |
205 | , " <identity" | 208 | , " <identity" |
@@ -211,10 +214,12 @@ iqresult_info host id mjid = L.unlines $ | |||
211 | , " </query>" | 214 | , " </query>" |
212 | , "</iq>" | 215 | , "</iq>" |
213 | ] | 216 | ] |
217 | -} | ||
214 | 218 | ||
215 | iqresponse session host (Elem _ attrs content) = runMaybeT $ do | 219 | iqresponse session host (Elem _ attrs content) = runMaybeT $ do |
216 | id <- MaybeT . return $ fmap pack (lookup (N "id") attrs >>= unattr) | 220 | id <- MaybeT . return $ fmap pack (lookup (N "id") attrs >>= unattr) |
217 | typ <- MaybeT . return $ fmap pack (lookup (N "type") attrs >>= unattr) | 221 | typ <- MaybeT . return $ fmap pack (lookup (N "type") attrs >>= unattr) |
222 | host <- fmap server $ getJID session | ||
218 | case typ of | 223 | case typ of |
219 | "set" -> do | 224 | "set" -> do |
220 | let string (CString _ s _) = [s] | 225 | let string (CString _ s _) = [s] |
@@ -224,7 +229,7 @@ iqresponse session host (Elem _ attrs content) = runMaybeT $ do | |||
224 | liftIO $ do | 229 | liftIO $ do |
225 | setResource session rsrc | 230 | setResource session rsrc |
226 | jid <- getJID session | 231 | jid <- getJID session |
227 | return $ iq_bind_reply id jid ) | 232 | return $ iq_bind_reply id (L.show jid) ) |
228 | (do | 233 | (do |
229 | guard (hasElem "session" content) | 234 | guard (hasElem "session" content) |
230 | return (iq_session_reply host id)) | 235 | return (iq_session_reply host id)) |
@@ -234,11 +239,11 @@ iqresponse session host (Elem _ attrs content) = runMaybeT $ do | |||
234 | xmlns <- MaybeT . return $ fmap pack $ listToMaybe . astring $ as | 239 | xmlns <- MaybeT . return $ fmap pack $ listToMaybe . astring $ as |
235 | let servicekind = case tag of { (N s) -> pack s ; _ -> "query" } | 240 | let servicekind = case tag of { (N s) -> pack s ; _ -> "query" } |
236 | case xmlns of | 241 | case xmlns of |
237 | "urn:xmpp:ping" -> do | 242 | "urn:xmpp:ping" -> |
238 | let to = case fmap pack (lookup (N "from") attrs >>= unattr) of | 243 | return $ |
239 | Just jid -> "to='" <++> jid <++> "' " | 244 | "<iq from='" <++> host |
240 | Nothing -> "" | 245 | <++> ("' " <++?> "to='" <++$> fmap pack (lookup (N "from") attrs >>= unattr) <$++> "' ") |
241 | return $ "<iq from='" <++> host <++> "' " <++> to <++> "id='" <++> id <++> "' type='result'/>" | 246 | <++> "id='" <++> id <++> "' type='result'/>" |
242 | 247 | ||
243 | _ -> return (iq_query_unavailable host id Nothing xmlns servicekind) | 248 | _ -> return (iq_query_unavailable host id Nothing xmlns servicekind) |
244 | _ -> MaybeT (return Nothing) | 249 | _ -> MaybeT (return Nothing) |
@@ -256,14 +261,14 @@ presence_response host (Elem _ attrs content) = do | |||
256 | 261 | ||
257 | doCon st elem cont = do | 262 | doCon st elem cont = do |
258 | let h = hOccursFst st :: Handle | 263 | let h = hOccursFst st :: Handle |
259 | host = "localhost" | ||
260 | (session,cmdChan) = hHead st | 264 | (session,cmdChan) = hHead st |
261 | hsend r = do | 265 | hsend r = do |
262 | atomically $ writeTChan cmdChan (Send r) | 266 | atomically $ writeTChan cmdChan (Send r) |
263 | -- hPutStrLn h r | 267 | -- hPutStrLn h r |
264 | L.putStrLn $ "\nOUT:\n" <++> r | 268 | L.putStrLn $ "\nOUT:\n" <++> r |
265 | 269 | host <- fmap server $ getJID session | |
266 | putStrLn $ (show $ hang (text "\nIN:") 2 $ pp elem) ++ "\n" | 270 | |
271 | putStrLn $ (Prelude.show $ hang (text "\nIN:") 2 $ pp elem) ++ "\n" | ||
267 | 272 | ||
268 | case elem of | 273 | case elem of |
269 | OpenTag _ -> | 274 | OpenTag _ -> |
@@ -282,7 +287,7 @@ doCon st elem cont = do | |||
282 | 287 | ||
283 | cont () | 288 | cont () |
284 | 289 | ||
285 | instance Show Hax.ElemTag where | 290 | instance Prelude.Show Hax.ElemTag where |
286 | show _ = "elemtag" | 291 | show _ = "elemtag" |
287 | 292 | ||
288 | data XmppObject | 293 | data XmppObject |
@@ -290,10 +295,10 @@ data XmppObject | |||
290 | | ProcessingInstruction Hax.ProcessingInstruction | 295 | | ProcessingInstruction Hax.ProcessingInstruction |
291 | | OpenTag ElemTag | 296 | | OpenTag ElemTag |
292 | | CloseTag () | 297 | | CloseTag () |
293 | deriving Show | 298 | deriving Prelude.Show |
294 | 299 | ||
295 | pp (Element e) = PP.element e | 300 | pp (Element e) = PP.element e |
296 | pp o = fromString (show o) | 301 | pp o = fromString (Prelude.show o) |
297 | 302 | ||
298 | streamName = QN (Namespace {nsPrefix= "stream" , nsURI="http://etherx.jabber.org/streams" }) "stream" | 303 | streamName = QN (Namespace {nsPrefix= "stream" , nsURI="http://etherx.jabber.org/streams" }) "stream" |
299 | 304 | ||
@@ -349,3 +354,5 @@ listenForRemotePeers session_factory port st = do | |||
349 | dopkt | 354 | dopkt |
350 | start | 355 | start |
351 | 356 | ||
357 | seekRemotePeers session_factory st = do | ||
358 | return () | ||
diff --git a/Presence/main.hs b/Presence/main.hs index 86503a62..e416d7cc 100644 --- a/Presence/main.hs +++ b/Presence/main.hs | |||
@@ -46,6 +46,7 @@ import Data.ByteString.Lazy.Char8 as L (ByteString,putStrLn) | |||
46 | import qualified Prelude | 46 | import qualified Prelude |
47 | import Prelude hiding (putStrLn) | 47 | import Prelude hiding (putStrLn) |
48 | import System.Environment | 48 | import System.Environment |
49 | import qualified Text.Show.ByteString as L | ||
49 | 50 | ||
50 | 51 | ||
51 | data UnixSession = UnixSession { | 52 | data UnixSession = UnixSession { |
@@ -79,14 +80,19 @@ instance XMPPSession UnixSession where | |||
79 | ) | 80 | ) |
80 | muid | 81 | muid |
81 | rsc <- readIORef (unix_resource s) | 82 | rsc <- readIORef (unix_resource s) |
82 | let suf = maybe "" ("/"<++>) rsc | 83 | -- let jid = user <++> "@" <++> host <++?> "/" <++$> rsc |
83 | jid = user <++> "@" <++> host <++> suf | 84 | L.putStrLn $ "SESSION: jid " <++> L.show (JID (Just user) host rsc) |
84 | L.putStrLn $ "SESSION: jid " <++> jid | 85 | return (JID (Just user) host rsc) |
85 | return jid | ||
86 | closeSession _ = L.putStrLn "SESSION: close" | 86 | closeSession _ = L.putStrLn "SESSION: close" |
87 | subscribe session Nothing = do | 87 | subscribe session Nothing = do |
88 | let tmvar = greedySubscriber (presence_state session) | 88 | let tmvar = greedySubscriber (presence_state session) |
89 | chan <- atomically $ | 89 | atomically $ subscribeToChan tmvar |
90 | subscribe session (Just jid) = do | ||
91 | let tvar = subscriberMap (presence_state session) | ||
92 | atomically $ subscribeToMap tvar jid | ||
93 | |||
94 | |||
95 | subscribeToChan tmvar = | ||
90 | (do (cnt,chan) <- takeTMVar tmvar | 96 | (do (cnt,chan) <- takeTMVar tmvar |
91 | putTMVar tmvar (cnt+1,chan) | 97 | putTMVar tmvar (cnt+1,chan) |
92 | chan' <- dupTChan chan | 98 | chan' <- dupTChan chan |
@@ -95,10 +101,8 @@ instance XMPPSession UnixSession where | |||
95 | (do chan <- newTChan | 101 | (do chan <- newTChan |
96 | putTMVar tmvar (1,chan) | 102 | putTMVar tmvar (1,chan) |
97 | return chan ) | 103 | return chan ) |
98 | return chan | 104 | |
99 | subscribe session (Just jid) = do | 105 | subscribeToMap tvar jid = do |
100 | let tvar = subscriberMap (presence_state session) | ||
101 | atomically $ do | ||
102 | subs <- readTVar tvar | 106 | subs <- readTVar tvar |
103 | let mbchan = Map.lookup jid subs | 107 | let mbchan = Map.lookup jid subs |
104 | (chan,subs') <- | 108 | (chan,subs') <- |