xmpptask.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright 2004 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPTASK_H_
  11. #define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPTASK_H_
  12. #include <deque>
  13. #include <memory>
  14. #include <string>
  15. #include "base/macros.h"
  16. #include "third_party/libjingle_xmpp/task_runner/task.h"
  17. #include "third_party/libjingle_xmpp/task_runner/taskparent.h"
  18. #include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
  19. #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
  20. namespace jingle_xmpp {
  21. /////////////////////////////////////////////////////////////////////
  22. //
  23. // XMPPTASK
  24. //
  25. /////////////////////////////////////////////////////////////////////
  26. //
  27. // See Task and XmppClient first.
  28. //
  29. // XmppTask is a task that is designed to go underneath XmppClient and be
  30. // useful there. It has a way of finding its XmppClient parent so you
  31. // can have it nested arbitrarily deep under an XmppClient and it can
  32. // still find the XMPP services.
  33. //
  34. // Tasks register themselves to listen to particular kinds of stanzas
  35. // that are sent out by the client. Rather than processing stanzas
  36. // right away, they should decide if they own the sent stanza,
  37. // and if so, queue it and Wake() the task, or if a stanza does not belong
  38. // to you, return false right away so the next XmppTask can take a crack.
  39. // This technique (synchronous recognize, but asynchronous processing)
  40. // allows you to have arbitrary logic for recognizing stanzas yet still,
  41. // for example, disconnect a client while processing a stanza -
  42. // without reentrancy problems.
  43. //
  44. /////////////////////////////////////////////////////////////////////
  45. class XmppTask;
  46. // XmppClientInterface is an abstract interface for sending and
  47. // handling stanzas. It can be implemented for unit tests or
  48. // different network environments. It will usually be implemented by
  49. // XmppClient.
  50. class XmppClientInterface {
  51. public:
  52. XmppClientInterface();
  53. virtual ~XmppClientInterface();
  54. virtual XmppEngine::State GetState() const = 0;
  55. virtual const Jid& jid() const = 0;
  56. virtual std::string NextId() = 0;
  57. virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0;
  58. virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza,
  59. XmppStanzaError error_code,
  60. const std::string& message) = 0;
  61. virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0;
  62. virtual void RemoveXmppTask(XmppTask* task) = 0;
  63. sigslot::signal0<> SignalDisconnected;
  64. DISALLOW_COPY_AND_ASSIGN(XmppClientInterface);
  65. };
  66. // XmppTaskParentInterface is the interface require for any parent of
  67. // an XmppTask. It needs, for example, a way to get an
  68. // XmppClientInterface.
  69. // We really ought to inherit from a TaskParentInterface, but we tried
  70. // that and it's way too complicated to change
  71. // Task/TaskParent/TaskRunner. For now, this works.
  72. class XmppTaskParentInterface : public jingle_xmpp::Task {
  73. public:
  74. explicit XmppTaskParentInterface(jingle_xmpp::TaskParent* parent)
  75. : Task(parent) {
  76. }
  77. virtual ~XmppTaskParentInterface() {}
  78. virtual XmppClientInterface* GetClient() = 0;
  79. DISALLOW_COPY_AND_ASSIGN(XmppTaskParentInterface);
  80. };
  81. class XmppTaskBase : public XmppTaskParentInterface {
  82. public:
  83. explicit XmppTaskBase(XmppTaskParentInterface* parent)
  84. : XmppTaskParentInterface(parent),
  85. parent_(parent) {
  86. }
  87. virtual ~XmppTaskBase() {}
  88. virtual XmppClientInterface* GetClient() {
  89. return parent_->GetClient();
  90. }
  91. protected:
  92. XmppTaskParentInterface* parent_;
  93. DISALLOW_COPY_AND_ASSIGN(XmppTaskBase);
  94. };
  95. class XmppTask : public XmppTaskBase,
  96. public XmppStanzaHandler,
  97. public sigslot::has_slots<>
  98. {
  99. public:
  100. XmppTask(XmppTaskParentInterface* parent,
  101. XmppEngine::HandlerLevel level = XmppEngine::HL_NONE);
  102. virtual ~XmppTask();
  103. std::string task_id() const { return id_; }
  104. void set_task_id(std::string id) { id_ = id; }
  105. #if !defined(NDEBUG)
  106. void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; }
  107. #endif
  108. virtual bool HandleStanza(const XmlElement* stanza) { return false; }
  109. protected:
  110. XmppReturnStatus SendStanza(const XmlElement* stanza);
  111. XmppReturnStatus SetResult(const std::string& code);
  112. XmppReturnStatus SendStanzaError(const XmlElement* element_original,
  113. XmppStanzaError code,
  114. const std::string& text);
  115. virtual void Stop();
  116. virtual void OnDisconnect();
  117. virtual void QueueStanza(const XmlElement* stanza);
  118. const XmlElement* NextStanza();
  119. bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid);
  120. bool MatchResponseIq(const XmlElement* stanza, const Jid& to,
  121. const std::string& task_id);
  122. static bool MatchRequestIq(const XmlElement* stanza, const std::string& type,
  123. const QName& qn);
  124. static XmlElement *MakeIqResult(const XmlElement* query);
  125. static XmlElement *MakeIq(const std::string& type,
  126. const Jid& to, const std::string& task_id);
  127. // Returns true if the task is under the specified rate limit and updates the
  128. // rate limit accordingly
  129. bool VerifyTaskRateLimit(const std::string task_name, int max_count,
  130. int per_x_seconds);
  131. private:
  132. void StopImpl();
  133. bool stopped_;
  134. std::deque<XmlElement*> stanza_queue_;
  135. std::unique_ptr<XmlElement> next_stanza_;
  136. std::string id_;
  137. #if !defined(NDEBUG)
  138. bool debug_force_timeout_;
  139. #endif
  140. };
  141. } // namespace jingle_xmpp
  142. #endif // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPTASK_H_