OLD | NEW |
| (Empty) |
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 | |
11 #ifndef WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ | |
12 #define WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ | |
13 | |
14 #include <deque> | |
15 #include <memory> | |
16 #include <string> | |
17 | |
18 #include "webrtc/libjingle/xmpp/xmppengine.h" | |
19 #include "webrtc/base/constructormagic.h" | |
20 #include "webrtc/base/sigslot.h" | |
21 #include "webrtc/base/task.h" | |
22 #include "webrtc/base/taskparent.h" | |
23 | |
24 namespace buzz { | |
25 | |
26 ///////////////////////////////////////////////////////////////////// | |
27 // | |
28 // XMPPTASK | |
29 // | |
30 ///////////////////////////////////////////////////////////////////// | |
31 // | |
32 // See Task and XmppClient first. | |
33 // | |
34 // XmppTask is a task that is designed to go underneath XmppClient and be | |
35 // useful there. It has a way of finding its XmppClient parent so you | |
36 // can have it nested arbitrarily deep under an XmppClient and it can | |
37 // still find the XMPP services. | |
38 // | |
39 // Tasks register themselves to listen to particular kinds of stanzas | |
40 // that are sent out by the client. Rather than processing stanzas | |
41 // right away, they should decide if they own the sent stanza, | |
42 // and if so, queue it and Wake() the task, or if a stanza does not belong | |
43 // to you, return false right away so the next XmppTask can take a crack. | |
44 // This technique (synchronous recognize, but asynchronous processing) | |
45 // allows you to have arbitrary logic for recognizing stanzas yet still, | |
46 // for example, disconnect a client while processing a stanza - | |
47 // without reentrancy problems. | |
48 // | |
49 ///////////////////////////////////////////////////////////////////// | |
50 | |
51 class XmppTask; | |
52 | |
53 // XmppClientInterface is an abstract interface for sending and | |
54 // handling stanzas. It can be implemented for unit tests or | |
55 // different network environments. It will usually be implemented by | |
56 // XmppClient. | |
57 class XmppClientInterface { | |
58 public: | |
59 XmppClientInterface(); | |
60 virtual ~XmppClientInterface(); | |
61 | |
62 virtual XmppEngine::State GetState() const = 0; | |
63 virtual const Jid& jid() const = 0; | |
64 virtual std::string NextId() = 0; | |
65 virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0; | |
66 virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza, | |
67 XmppStanzaError error_code, | |
68 const std::string& message) = 0; | |
69 virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0; | |
70 virtual void RemoveXmppTask(XmppTask* task) = 0; | |
71 sigslot::signal0<> SignalDisconnected; | |
72 | |
73 RTC_DISALLOW_COPY_AND_ASSIGN(XmppClientInterface); | |
74 }; | |
75 | |
76 // XmppTaskParentInterface is the interface require for any parent of | |
77 // an XmppTask. It needs, for example, a way to get an | |
78 // XmppClientInterface. | |
79 | |
80 // We really ought to inherit from a TaskParentInterface, but we tried | |
81 // that and it's way too complicated to change | |
82 // Task/TaskParent/TaskRunner. For now, this works. | |
83 class XmppTaskParentInterface : public rtc::Task { | |
84 public: | |
85 explicit XmppTaskParentInterface(rtc::TaskParent* parent) | |
86 : Task(parent) { | |
87 } | |
88 virtual ~XmppTaskParentInterface() {} | |
89 | |
90 virtual XmppClientInterface* GetClient() = 0; | |
91 | |
92 RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskParentInterface); | |
93 }; | |
94 | |
95 class XmppTaskBase : public XmppTaskParentInterface { | |
96 public: | |
97 explicit XmppTaskBase(XmppTaskParentInterface* parent) | |
98 : XmppTaskParentInterface(parent), | |
99 parent_(parent) { | |
100 } | |
101 virtual ~XmppTaskBase() {} | |
102 | |
103 virtual XmppClientInterface* GetClient() { | |
104 return parent_->GetClient(); | |
105 } | |
106 | |
107 protected: | |
108 XmppTaskParentInterface* parent_; | |
109 | |
110 RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskBase); | |
111 }; | |
112 | |
113 class XmppTask : public XmppTaskBase, | |
114 public XmppStanzaHandler, | |
115 public sigslot::has_slots<> | |
116 { | |
117 public: | |
118 XmppTask(XmppTaskParentInterface* parent, | |
119 XmppEngine::HandlerLevel level = XmppEngine::HL_NONE); | |
120 virtual ~XmppTask(); | |
121 | |
122 std::string task_id() const { return id_; } | |
123 void set_task_id(std::string id) { id_ = id; } | |
124 | |
125 #if !defined(NDEBUG) | |
126 void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; } | |
127 #endif | |
128 | |
129 virtual bool HandleStanza(const XmlElement* stanza) { return false; } | |
130 | |
131 protected: | |
132 XmppReturnStatus SendStanza(const XmlElement* stanza); | |
133 XmppReturnStatus SetResult(const std::string& code); | |
134 XmppReturnStatus SendStanzaError(const XmlElement* element_original, | |
135 XmppStanzaError code, | |
136 const std::string& text); | |
137 | |
138 virtual void Stop(); | |
139 virtual void OnDisconnect(); | |
140 | |
141 virtual void QueueStanza(const XmlElement* stanza); | |
142 const XmlElement* NextStanza(); | |
143 | |
144 bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid); | |
145 | |
146 bool MatchResponseIq(const XmlElement* stanza, const Jid& to, | |
147 const std::string& task_id); | |
148 | |
149 static bool MatchRequestIq(const XmlElement* stanza, const std::string& type, | |
150 const QName& qn); | |
151 static XmlElement *MakeIqResult(const XmlElement* query); | |
152 static XmlElement *MakeIq(const std::string& type, | |
153 const Jid& to, const std::string& task_id); | |
154 | |
155 // Returns true if the task is under the specified rate limit and updates the | |
156 // rate limit accordingly | |
157 bool VerifyTaskRateLimit(const std::string task_name, int max_count, | |
158 int per_x_seconds); | |
159 | |
160 private: | |
161 void StopImpl(); | |
162 | |
163 bool stopped_; | |
164 std::deque<XmlElement*> stanza_queue_; | |
165 std::unique_ptr<XmlElement> next_stanza_; | |
166 std::string id_; | |
167 | |
168 #if !defined(NDEBUG) | |
169 bool debug_force_timeout_; | |
170 #endif | |
171 }; | |
172 | |
173 } // namespace buzz | |
174 | |
175 #endif // WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ | |
OLD | NEW |