diff options
author | joe <joe@jerkface.net> | 2013-07-01 00:48:20 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-07-01 00:48:20 -0400 |
commit | d0eb0e8d0db2fdd55511d8176467675816b0a179 (patch) | |
tree | caf5e64b9ea780bb0354b55444d792ac2aa75ec4 /Presence | |
parent | b70209c295681a89b64f7527a2ecae23d9bb9bc2 (diff) |
fixed gatherElement bug (it was bypassing the NestingXML api)
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/XMPP.hs | 101 |
1 files changed, 31 insertions, 70 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index 36630bc7..2917d833 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -177,12 +177,12 @@ filterMapElement ret opentag empty = loop (empty `mplus` ret opentag) 1 | |||
177 | 177 | ||
178 | gatherElement :: | 178 | gatherElement :: |
179 | (Monad m, MonadPlus mp) => | 179 | (Monad m, MonadPlus mp) => |
180 | Event -> mp Event -> MaybeT (ConduitM Event o m) (mp Event) | 180 | Event -> mp Event -> NestingXML o m (mp Event) |
181 | gatherElement opentag empty = loop (empty `mplus` return opentag) 1 | 181 | gatherElement opentag empty = loop (empty `mplus` return opentag) 1 |
182 | where | 182 | where |
183 | loop ts 0 = return ts | 183 | loop ts 0 = return ts |
184 | loop ts cnt = do | 184 | loop ts cnt = do |
185 | tag <- mawait | 185 | maybeXML (return ts) $ \tag -> do |
186 | let ts' = mplus ts (return tag) | 186 | let ts' = mplus ts (return tag) |
187 | case () of | 187 | case () of |
188 | _ | eventIsEndElement tag -> loop ts' (cnt-1) | 188 | _ | eventIsEndElement tag -> loop ts' (cnt-1) |
@@ -224,68 +224,6 @@ uncontent cs = head $ map getText cs | |||
224 | getText (ContentText x) = x | 224 | getText (ContentText x) = x |
225 | getText (ContentEntity x ) = x | 225 | getText (ContentEntity x ) = x |
226 | 226 | ||
227 | -- doIQ :: MonadIO m => Event -> MaybeT (ConduitM Event o m) () | ||
228 | doIQ session cmdChan tag@(EventBeginElement name attrs) = do | ||
229 | (_,uncontent->iq_id) <- MaybeT . return $ find (\(n,v)->isId n) attrs | ||
230 | -- The 'id' attribute is REQUIRED for IQ stanzas. | ||
231 | -- todo: handle it's absence more gracefully | ||
232 | case (find (\(n,v)->isType n) attrs) of | ||
233 | Just (_,[ContentText "get"]) -> discard | ||
234 | Just (_,[ContentText "set"]) -> do | ||
235 | fix $ \iqsetloop -> do | ||
236 | setwhat <- mawait | ||
237 | liftIO (putStrLn $ "IQ-set " ++ show setwhat) | ||
238 | case setwhat of | ||
239 | bind@(EventBeginElement name attrs) | isBind name -> do | ||
240 | fix $ \again -> do | ||
241 | rscElem <- mawait | ||
242 | liftIO (putStrLn $ "IQ-set-bind " ++ show rscElem) | ||
243 | case rscElem of | ||
244 | bindchild@(EventBeginElement name _) | isResource name -> do | ||
245 | let isContent (EventContent (ContentText v)) = return v | ||
246 | isContent _ = mzero | ||
247 | xs <- filterMapElement isContent bindchild Nothing | ||
248 | case xs of | ||
249 | Just rsrc -> | ||
250 | liftIO $ do | ||
251 | setResource session (L.fromChunks [S.encodeUtf8 rsrc]) | ||
252 | jid <- getJID session | ||
253 | atomically $ writeTChan cmdChan (Send $ iq_bind_reply iq_id (toStrict $ L.decodeUtf8 $ L.show jid) ) | ||
254 | Nothing -> return () -- TODO: empty resource tag? | ||
255 | void $ gatherElement bind Nothing | ||
256 | bindchild@(EventBeginElement _ _) -> do | ||
257 | liftIO (putStrLn "unknown bind child") | ||
258 | gatherElement bindchild Nothing | ||
259 | void $ gatherElement bind Nothing | ||
260 | EventEndElement _ -> do | ||
261 | liftIO (putStrLn "empty bind") | ||
262 | -- TODO | ||
263 | -- A server that supports resource binding MUST be able to | ||
264 | -- generate a resource identifier on behalf of a client. A | ||
265 | -- resource identifier generated by the server MUST be unique | ||
266 | -- for that <node@domain>. | ||
267 | _ -> again | ||
268 | discard | ||
269 | req@(EventBeginElement name attrs) -> do | ||
270 | liftIO (putStrLn $ "IQ-set-unknown " ++ show req) | ||
271 | gatherElement req Nothing | ||
272 | discard | ||
273 | endtag@(EventEndElement _) -> do | ||
274 | liftIO (putStrLn $ "IQ-set-empty" ++ show endtag) | ||
275 | _ -> iqsetloop | ||
276 | Just (_,[ContentText "result"]) -> discard | ||
277 | Just (_,[ContentText "error"]) -> discard | ||
278 | Just _ -> discard -- error: type must be one of {get,set,result,error} | ||
279 | Nothing -> discard -- error: The 'type' attribute is REQUIRED for IQ stanzas. | ||
280 | where | ||
281 | isId n = n=="id" | ||
282 | isType n = n=="type" | ||
283 | isResource n = n=="{urn:ietf:params:xml:ns:xmpp-bind}resource" | ||
284 | isBind n = n=="{urn:ietf:params:xml:ns:xmpp-bind}bind" | ||
285 | discard = do | ||
286 | xs <- gatherElement tag Seq.empty | ||
287 | prettyPrint "client-in: ignoring iq:" (toList xs) | ||
288 | |||
289 | withJust (Just x) f = f x | 227 | withJust (Just x) f = f x |
290 | withJust Nothing f = return () | 228 | withJust Nothing f = return () |
291 | 229 | ||
@@ -391,7 +329,30 @@ handleIQGet session cmdChan tag = do | |||
391 | liftIO . atomically . writeTChan cmdChan . Send $ iq_service_unavailable host stanza_id Nothing req | 329 | liftIO . atomically . writeTChan cmdChan . Send $ iq_service_unavailable host stanza_id Nothing req |
392 | case tagName child of | 330 | case tagName child of |
393 | -- "{http://jabber.org/protocol/disco#items}query" -> liftIO $ putStrLn "iq-get-query-items" | 331 | -- "{http://jabber.org/protocol/disco#items}query" -> liftIO $ putStrLn "iq-get-query-items" |
394 | -- "{urn:xmpp:ping}ping" -> todo | 332 | {- |
333 | IN client: | ||
334 | <iq type="get" id="purple8f8224d6" | ||
335 | ><ping xmlns="urn:xmpp:ping"/></iq> | ||
336 | |||
337 | |||
338 | OUT client: | ||
339 | <iq from='blackbird' id='purple8f8224d6' type='result'/> | ||
340 | -} | ||
341 | "{urn:xmpp:ping}ping" -> liftIO $ do | ||
342 | putStrLn ("iq-ping: "++show (stanza_id,child)) | ||
343 | let mjid = lookupAttrib "from" (tagAttrs tag) | ||
344 | L.putStrLn $ "PING! from=" <++> bshow mjid | ||
345 | let pong = [ EventBeginElement "{jabber:client}iq" | ||
346 | $ (case mjid of | ||
347 | Just jid -> (("to",[ContentText jid]):) | ||
348 | _ -> id) | ||
349 | [("type",[ContentText "result"]) | ||
350 | ,("id",[ContentText stanza_id]) | ||
351 | ,("from",[ContentText host]) | ||
352 | ] | ||
353 | , EventEndElement "{jabber:client}iq" | ||
354 | ] | ||
355 | atomically . writeTChan cmdChan . Send $ pong | ||
395 | req -> unhandledGet req | 356 | req -> unhandledGet req |
396 | 357 | ||
397 | 358 | ||
@@ -418,8 +379,8 @@ fromClient session cmdChan = doNestingXML $ do | |||
418 | stanza_lvl <- nesting | 379 | stanza_lvl <- nesting |
419 | 380 | ||
420 | let unhandledStanza = do | 381 | let unhandledStanza = do |
421 | mb <- lift . runMaybeT $ gatherElement stanza Seq.empty | 382 | xs <- gatherElement stanza Seq.empty |
422 | withJust mb $ \xs -> prettyPrint "C: " (toList xs) | 383 | prettyPrint "unhandled-C: " (toList xs) |
423 | case () of | 384 | case () of |
424 | _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza | 385 | _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza |
425 | _ | stanza `isIQOf` iqTypeGet -> handleIQGet session cmdChan stanza | 386 | _ | stanza `isIQOf` iqTypeGet -> handleIQGet session cmdChan stanza |
@@ -612,11 +573,11 @@ fromPeer session = doNestingXML $ do | |||
612 | stanza_lvl <- nesting | 573 | stanza_lvl <- nesting |
613 | 574 | ||
614 | let unhandledStanza = do | 575 | let unhandledStanza = do |
615 | mb <- lift . runMaybeT $ gatherElement stanza Seq.empty | 576 | xs <- gatherElement stanza Seq.empty |
616 | withJust mb $ \xs -> prettyPrint "P: " (toList xs) | 577 | prettyPrint "P: " (toList xs) |
617 | case () of | 578 | case () of |
618 | _ | stanza `isPresenceOf` presenceTypeOnline | 579 | _ | stanza `isPresenceOf` presenceTypeOnline |
619 | -> log "peer online!" >> handlePeerPresence session stanza True | 580 | -> handlePeerPresence session stanza True |
620 | _ | stanza `isPresenceOf` presenceTypeOffline | 581 | _ | stanza `isPresenceOf` presenceTypeOffline |
621 | -> handlePeerPresence session stanza False | 582 | -> handlePeerPresence session stanza False |
622 | _ -> unhandledStanza | 583 | _ -> unhandledStanza |