diff options
author | joe <joe@jerkface.net> | 2014-02-15 23:50:41 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-02-15 23:50:41 -0500 |
commit | b0992c304dd48190f7cca0e7222501fd7eb56062 (patch) | |
tree | e1830d987f1b22e795eb245a16290d39ed419de8 /Presence | |
parent | 9d01ddf6dabc1fdd1a40d7f79b7d21d3e2c6baf1 (diff) |
send service-unavailable responses for iq queries
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/XMPPServer.hs | 105 |
1 files changed, 71 insertions, 34 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs index ceb83476..ccdffabe 100644 --- a/Presence/XMPPServer.hs +++ b/Presence/XMPPServer.hs | |||
@@ -103,6 +103,7 @@ data Stanza | |||
103 | -} | 103 | -} |
104 | 104 | ||
105 | data StanzaType = Unrecognized | Ping | Pong | RequestResource (Maybe Text) | SetResource | 105 | data StanzaType = Unrecognized | Ping | Pong | RequestResource (Maybe Text) | SetResource |
106 | | SessionRequest | UnrecognizedQuery Name | Error | ||
106 | deriving Show | 107 | deriving Show |
107 | 108 | ||
108 | data StanzaOrigin = LocalPeer | NetworkOrigin ConnectionKey (TChan Stanza) | 109 | data StanzaOrigin = LocalPeer | NetworkOrigin ConnectionKey (TChan Stanza) |
@@ -173,7 +174,7 @@ grokStanzaIQGet stanza = do | |||
173 | flip (maybe $ return Nothing) mtag $ \tag -> do | 174 | flip (maybe $ return Nothing) mtag $ \tag -> do |
174 | case tagName tag of | 175 | case tagName tag of |
175 | "{urn:xmpp:ping}ping" -> return $ Just Ping | 176 | "{urn:xmpp:ping}ping" -> return $ Just Ping |
176 | _ -> return Nothing | 177 | name -> return . Just $ UnrecognizedQuery name |
177 | 178 | ||
178 | grokStanzaIQResult :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType) | 179 | grokStanzaIQResult :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType) |
179 | grokStanzaIQResult stanza = do | 180 | grokStanzaIQResult stanza = do |
@@ -195,6 +196,8 @@ grokStanzaIQSet stanza = do | |||
195 | return . Just $ RequestResource (Just rsc) | 196 | return . Just $ RequestResource (Just rsc) |
196 | Just _ -> return Nothing | 197 | Just _ -> return Nothing |
197 | Nothing -> return . Just $ RequestResource Nothing | 198 | Nothing -> return . Just $ RequestResource Nothing |
199 | "{urn:ietf:params:xml:ns:xmpp-session}session" -> do | ||
200 | return $ Just SessionRequest | ||
198 | _ -> return Nothing | 201 | _ -> return Nothing |
199 | 202 | ||
200 | 203 | ||
@@ -359,32 +362,6 @@ greet' namespace host = | |||
359 | consid Nothing = id | 362 | consid Nothing = id |
360 | consid (Just sid) = (("id",[ContentText sid]):) | 363 | consid (Just sid) = (("id",[ContentText sid]):) |
361 | 364 | ||
362 | iq_bind_reply :: Maybe Text -> Text -> [XML.Event] | ||
363 | iq_bind_reply mid jid = | ||
364 | [ EventBeginElement "{jabber:client}iq" (consid mid [("type",[ContentText "result"])]) | ||
365 | , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}bind" | ||
366 | [("xmlns",[ContentText "urn:ietf:params:xml:ns:xmpp-bind"])] | ||
367 | , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}jid" [] | ||
368 | , EventContent (ContentText jid) | ||
369 | , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}jid" | ||
370 | , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}bind" | ||
371 | , EventEndElement "{jabber:client}iq" | ||
372 | ] | ||
373 | |||
374 | {- | ||
375 | greet namespace = | ||
376 | [ EventBeginDocument | ||
377 | , EventBeginElement (streamP "stream") | ||
378 | [ attr "xmlns" namespace | ||
379 | , attr "version" "1.0" | ||
380 | ] | ||
381 | ] | ||
382 | -} | ||
383 | |||
384 | goodbye = | ||
385 | [ EventEndElement (streamP "stream") | ||
386 | , EventEndDocument | ||
387 | ] | ||
388 | 365 | ||
389 | data XMPPState | 366 | data XMPPState |
390 | = PingSlot | 367 | = PingSlot |
@@ -407,6 +384,7 @@ makePing namespace mid to from = | |||
407 | , EventEndElement $ mkname namespace "iq"] | 384 | , EventEndElement $ mkname namespace "iq"] |
408 | 385 | ||
409 | makePong namespace mid to from = | 386 | makePong namespace mid to from = |
387 | -- Note: similar to session reply | ||
410 | [ EventBeginElement (mkname namespace "iq") | 388 | [ EventBeginElement (mkname namespace "iq") |
411 | $(case mid of | 389 | $(case mid of |
412 | Just c -> (("id",[ContentText c]):) | 390 | Just c -> (("id",[ContentText c]):) |
@@ -418,6 +396,56 @@ makePong namespace mid to from = | |||
418 | , EventEndElement (mkname namespace "iq") | 396 | , EventEndElement (mkname namespace "iq") |
419 | ] | 397 | ] |
420 | 398 | ||
399 | iq_bind_reply :: Maybe Text -> Text -> [XML.Event] | ||
400 | iq_bind_reply mid jid = | ||
401 | [ EventBeginElement "{jabber:client}iq" (consid mid [("type",[ContentText "result"])]) | ||
402 | , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}bind" | ||
403 | [("xmlns",[ContentText "urn:ietf:params:xml:ns:xmpp-bind"])] | ||
404 | , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}jid" [] | ||
405 | , EventContent (ContentText jid) | ||
406 | , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}jid" | ||
407 | , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}bind" | ||
408 | , EventEndElement "{jabber:client}iq" | ||
409 | ] | ||
410 | |||
411 | iq_session_reply mid host = | ||
412 | -- Note: similar to Pong | ||
413 | [ EventBeginElement "{jabber:client}iq" | ||
414 | (consid mid [("from",[ContentText host]) | ||
415 | ,("type",[ContentText "result"]) | ||
416 | ]) | ||
417 | , EventEndElement "{jabber:client}iq" | ||
418 | ] | ||
419 | |||
420 | iq_service_unavailable mid host {- mjid -} req = | ||
421 | [ EventBeginElement "{jabber:client}iq" | ||
422 | (consid mid [("type",[ContentText "error"]) | ||
423 | -- , TODO: set "from" if isJust mjid | ||
424 | ]) | ||
425 | , EventBeginElement req [] | ||
426 | , EventEndElement req | ||
427 | , EventBeginElement "{jabber:client}error" [("type",[ContentText "cancel"])] | ||
428 | , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-stanzas}service-unavailable" [] | ||
429 | , EventEndElement "{urn:ietf:params:xml:ns:xmpp-stanzas}service-unavailable" | ||
430 | , EventEndElement "{jabber:client}error" | ||
431 | , EventEndElement "{jabber:client}iq" | ||
432 | ] | ||
433 | |||
434 | |||
435 | {- | ||
436 | greet namespace = | ||
437 | [ EventBeginDocument | ||
438 | , EventBeginElement (streamP "stream") | ||
439 | [ attr "xmlns" namespace | ||
440 | , attr "version" "1.0" | ||
441 | ] | ||
442 | ] | ||
443 | -} | ||
444 | |||
445 | goodbye = | ||
446 | [ EventEndElement (streamP "stream") | ||
447 | , EventEndDocument | ||
448 | ] | ||
421 | 449 | ||
422 | forkConnection :: Server ConnectionKey | 450 | forkConnection :: Server ConnectionKey |
423 | -> ConnectionKey | 451 | -> ConnectionKey |
@@ -569,14 +597,23 @@ monitor sv params = do | |||
569 | _ -> return () | 597 | _ -> return () |
570 | , readTChan stanzas >>= \stanza -> return $ do | 598 | , readTChan stanzas >>= \stanza -> return $ do |
571 | forkIO $ do | 599 | forkIO $ do |
572 | case (stanzaType stanza,stanzaOrigin stanza) of | 600 | case stanzaOrigin stanza of |
573 | (RequestResource wanted, NetworkOrigin k@(ClientKey{}) replyto) -> do | 601 | NetworkOrigin k@(ClientKey {}) replyto -> |
574 | sock <- socketFromKey sv k | 602 | case stanzaType stanza of |
575 | rsc <- getResourceName sock wanted | 603 | RequestResource wanted -> do |
576 | let reply = iq_bind_reply (stanzaId stanza) rsc | 604 | sock <- socketFromKey sv k |
577 | sendReply quitVar SetResource reply replyto | 605 | rsc <- getResourceName sock wanted |
606 | let reply = iq_bind_reply (stanzaId stanza) rsc | ||
607 | sendReply quitVar SetResource reply replyto | ||
608 | SessionRequest -> do | ||
609 | let reply = iq_session_reply (stanzaId stanza) "localhost" | ||
610 | sendReply quitVar Pong reply replyto | ||
611 | UnrecognizedQuery query -> do | ||
612 | let reply = iq_service_unavailable (stanzaId stanza) "localhost" query | ||
613 | sendReply quitVar Error reply replyto | ||
614 | _ -> return () | ||
578 | _ -> return () | 615 | _ -> return () |
579 | let typ = Strict8.pack $ c ++ "->"++(show (stanzaType stanza))++" " | 616 | let typ = Strict8.pack $ c ++ "->"++(concat . take 1 . words $ show (stanzaType stanza))++" " |
580 | c = case stanzaOrigin stanza of | 617 | c = case stanzaOrigin stanza of |
581 | LocalPeer -> "*" | 618 | LocalPeer -> "*" |
582 | NetworkOrigin (ClientKey {}) _ -> "C" | 619 | NetworkOrigin (ClientKey {}) _ -> "C" |