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_XMPPENGINEIMPL_H_ | |
12 #define WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_ | |
13 | |
14 #include <memory> | |
15 #include <sstream> | |
16 #include <vector> | |
17 | |
18 #include "webrtc/libjingle/xmpp/xmppengine.h" | |
19 #include "webrtc/libjingle/xmpp/xmppstanzaparser.h" | |
20 | |
21 namespace buzz { | |
22 | |
23 class XmppLoginTask; | |
24 class XmppEngine; | |
25 class XmppIqEntry; | |
26 class SaslHandler; | |
27 class SaslMechanism; | |
28 | |
29 //! The XMPP connection engine. | |
30 //! This engine implements the client side of the 'core' XMPP protocol. | |
31 //! To use it, register an XmppOutputHandler to handle socket output | |
32 //! and pass socket input to HandleInput. Then application code can | |
33 //! set up the connection with a user, password, and other settings, | |
34 //! and then call Connect() to initiate the connection. | |
35 //! An application can listen for events and receive stanzas by | |
36 //! registering an XmppStanzaHandler via AddStanzaHandler(). | |
37 class XmppEngineImpl : public XmppEngine { | |
38 public: | |
39 XmppEngineImpl(); | |
40 virtual ~XmppEngineImpl(); | |
41 | |
42 // SOCKET INPUT AND OUTPUT ------------------------------------------------ | |
43 | |
44 //! Registers the handler for socket output | |
45 virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh); | |
46 | |
47 //! Provides socket input to the engine | |
48 virtual XmppReturnStatus HandleInput(const char* bytes, size_t len); | |
49 | |
50 //! Advises the engine that the socket has closed | |
51 virtual XmppReturnStatus ConnectionClosed(int subcode); | |
52 | |
53 // SESSION SETUP --------------------------------------------------------- | |
54 | |
55 //! Indicates the (bare) JID for the user to use. | |
56 virtual XmppReturnStatus SetUser(const Jid& jid); | |
57 | |
58 //! Get the login (bare) JID. | |
59 virtual const Jid& GetUser(); | |
60 | |
61 //! Indicates the autentication to use. Takes ownership of the object. | |
62 virtual XmppReturnStatus SetSaslHandler(SaslHandler* sasl_handler); | |
63 | |
64 //! Sets whether TLS will be used within the connection (default true). | |
65 virtual XmppReturnStatus SetTls(TlsOptions use_tls); | |
66 | |
67 //! Sets an alternate domain from which we allows TLS certificates. | |
68 //! This is for use in the case where a we want to allow a proxy to | |
69 //! serve up its own certificate rather than one owned by the underlying | |
70 //! domain. | |
71 virtual XmppReturnStatus SetTlsServer(const std::string& proxy_hostname, | |
72 const std::string& proxy_domain); | |
73 | |
74 //! Gets whether TLS will be used within the connection. | |
75 virtual TlsOptions GetTls(); | |
76 | |
77 //! Sets the request resource name, if any (optional). | |
78 //! Note that the resource name may be overridden by the server; after | |
79 //! binding, the actual resource name is available as part of FullJid(). | |
80 virtual XmppReturnStatus SetRequestedResource(const std::string& resource); | |
81 | |
82 //! Gets the request resource name. | |
83 virtual const std::string& GetRequestedResource(); | |
84 | |
85 //! Sets language | |
86 virtual void SetLanguage(const std::string& lang) { | |
87 lang_ = lang; | |
88 } | |
89 | |
90 // SESSION MANAGEMENT --------------------------------------------------- | |
91 | |
92 //! Set callback for state changes. | |
93 virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler); | |
94 | |
95 //! Initiates the XMPP connection. | |
96 //! After supplying connection settings, call this once to initiate, | |
97 //! (optionally) encrypt, authenticate, and bind the connection. | |
98 virtual XmppReturnStatus Connect(); | |
99 | |
100 //! The current engine state. | |
101 virtual State GetState() { return state_; } | |
102 | |
103 //! Returns true if the connection is encrypted (under TLS) | |
104 virtual bool IsEncrypted() { return encrypted_; } | |
105 | |
106 //! The error code. | |
107 //! Consult this after XmppOutputHandler.OnClose(). | |
108 virtual Error GetError(int *subcode) { | |
109 if (subcode) { | |
110 *subcode = subcode_; | |
111 } | |
112 return error_code_; | |
113 } | |
114 | |
115 //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM. | |
116 //! Notice the stanza returned is owned by the XmppEngine and | |
117 //! is deleted when the engine is destroyed. | |
118 virtual const XmlElement* GetStreamError() { return stream_error_.get(); } | |
119 | |
120 //! Closes down the connection. | |
121 //! Sends CloseConnection to output, and disconnects and registered | |
122 //! session handlers. After Disconnect completes, it is guaranteed | |
123 //! that no further callbacks will be made. | |
124 virtual XmppReturnStatus Disconnect(); | |
125 | |
126 // APPLICATION USE ------------------------------------------------------- | |
127 | |
128 //! Adds a listener for session events. | |
129 //! Stanza delivery is chained to session handlers; the first to | |
130 //! return 'true' is the last to get each stanza. | |
131 virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, | |
132 XmppEngine::HandlerLevel level); | |
133 | |
134 //! Removes a listener for session events. | |
135 virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler); | |
136 | |
137 //! Sends a stanza to the server. | |
138 virtual XmppReturnStatus SendStanza(const XmlElement* stanza); | |
139 | |
140 //! Sends raw text to the server | |
141 virtual XmppReturnStatus SendRaw(const std::string& text); | |
142 | |
143 //! Sends an iq to the server, and registers a callback for the result. | |
144 //! Returns the cookie passed to the result handler. | |
145 virtual XmppReturnStatus SendIq(const XmlElement* stanza, | |
146 XmppIqHandler* iq_handler, | |
147 XmppIqCookie* cookie); | |
148 | |
149 //! Unregisters an iq callback handler given its cookie. | |
150 //! No callback will come to this handler after it's unregistered. | |
151 virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie, | |
152 XmppIqHandler** iq_handler); | |
153 | |
154 //! Forms and sends an error in response to the given stanza. | |
155 //! Swaps to and from, sets type to "error", and adds error information | |
156 //! based on the passed code. Text is optional and may be STR_EMPTY. | |
157 virtual XmppReturnStatus SendStanzaError(const XmlElement* pelOriginal, | |
158 XmppStanzaError code, | |
159 const std::string& text); | |
160 | |
161 //! The fullly bound JID. | |
162 //! This JID is only valid after binding has succeeded. If the value | |
163 //! is JID_NULL, the binding has not succeeded. | |
164 virtual const Jid& FullJid() { return bound_jid_; } | |
165 | |
166 //! The next unused iq id for this connection. | |
167 //! Call this when building iq stanzas, to ensure that each iq | |
168 //! gets its own unique id. | |
169 virtual std::string NextId(); | |
170 | |
171 private: | |
172 friend class XmppLoginTask; | |
173 friend class XmppIqEntry; | |
174 | |
175 void IncomingStanza(const XmlElement *stanza); | |
176 void IncomingStart(const XmlElement *stanza); | |
177 void IncomingEnd(bool isError); | |
178 | |
179 void InternalSendStart(const std::string& domainName); | |
180 void InternalSendStanza(const XmlElement* stanza); | |
181 std::string ChooseBestSaslMechanism( | |
182 const std::vector<std::string>& mechanisms, bool encrypted); | |
183 SaslMechanism* GetSaslMechanism(const std::string& name); | |
184 void SignalBound(const Jid& fullJid); | |
185 void SignalStreamError(const XmlElement* streamError); | |
186 void SignalError(Error errorCode, int subCode); | |
187 bool HasError(); | |
188 void DeleteIqCookies(); | |
189 bool HandleIqResponse(const XmlElement* element); | |
190 void StartTls(const std::string& domain); | |
191 void RaiseReset() { raised_reset_ = true; } | |
192 | |
193 class StanzaParseHandler : public XmppStanzaParseHandler { | |
194 public: | |
195 StanzaParseHandler(XmppEngineImpl* outer) : outer_(outer) {} | |
196 virtual ~StanzaParseHandler() {} | |
197 | |
198 virtual void StartStream(const XmlElement* stream) { | |
199 outer_->IncomingStart(stream); | |
200 } | |
201 virtual void Stanza(const XmlElement* stanza) { | |
202 outer_->IncomingStanza(stanza); | |
203 } | |
204 virtual void EndStream() { | |
205 outer_->IncomingEnd(false); | |
206 } | |
207 virtual void XmlError() { | |
208 outer_->IncomingEnd(true); | |
209 } | |
210 | |
211 private: | |
212 XmppEngineImpl* const outer_; | |
213 }; | |
214 | |
215 class EnterExit { | |
216 public: | |
217 EnterExit(XmppEngineImpl* engine); | |
218 ~EnterExit(); | |
219 private: | |
220 XmppEngineImpl* engine_; | |
221 State state_; | |
222 }; | |
223 | |
224 friend class StanzaParseHandler; | |
225 friend class EnterExit; | |
226 | |
227 StanzaParseHandler stanza_parse_handler_; | |
228 XmppStanzaParser stanza_parser_; | |
229 | |
230 // state | |
231 int engine_entered_; | |
232 Jid user_jid_; | |
233 std::string password_; | |
234 std::string requested_resource_; | |
235 TlsOptions tls_option_; | |
236 std::string tls_server_hostname_; | |
237 std::string tls_server_domain_; | |
238 std::unique_ptr<XmppLoginTask> login_task_; | |
239 std::string lang_; | |
240 | |
241 int next_id_; | |
242 Jid bound_jid_; | |
243 State state_; | |
244 bool encrypted_; | |
245 Error error_code_; | |
246 int subcode_; | |
247 std::unique_ptr<XmlElement> stream_error_; | |
248 bool raised_reset_; | |
249 XmppOutputHandler* output_handler_; | |
250 XmppSessionHandler* session_handler_; | |
251 | |
252 XmlnsStack xmlns_stack_; | |
253 | |
254 typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector; | |
255 std::unique_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT]; | |
256 | |
257 typedef std::vector<XmppIqEntry*> IqEntryVector; | |
258 std::unique_ptr<IqEntryVector> iq_entries_; | |
259 | |
260 std::unique_ptr<SaslHandler> sasl_handler_; | |
261 | |
262 std::unique_ptr<std::stringstream> output_; | |
263 }; | |
264 | |
265 } // namespace buzz | |
266 | |
267 #endif // WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_ | |
OLD | NEW |