xmppengineimpl.h 9.1 KB

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