1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <vector> 29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <algorithm> 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h" 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/xmppengineimpl.h" 32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/constants.h" 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace buzz { 35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass XmppIqEntry { 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqEntry(const std::string & id, const std::string & to, 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppEngine * pxce, XmppIqHandler * iq_handler) : 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch id_(id), 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch to_(to), 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch engine_(pxce), 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_handler_(iq_handler) { 43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochprivate: 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch friend class XmppEngineImpl; 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string id_; 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string to_; 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppEngine * const engine_; 51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqHandler * const iq_handler_; 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}; 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppReturnStatus 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppEngineImpl::SendIq(const XmlElement * element, XmppIqHandler * iq_handler, 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqCookie* cookie) { 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (state_ == STATE_CLOSED) 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADSTATE; 60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (NULL == iq_handler) 61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADARGUMENT; 62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!element || element->Name() != QN_IQ) 63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADARGUMENT; 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& type = element->Attr(QN_TYPE); 66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type != "get" && type != "set") 67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADARGUMENT; 68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!element->HasAttr(QN_ID)) 70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADARGUMENT; 71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& id = element->Attr(QN_ID); 72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqEntry * iq_entry = new XmppIqEntry(id, 74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch element->Attr(QN_TO), 75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, iq_handler); 76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_entries_->push_back(iq_entry); 77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendStanza(element); 78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (cookie) 80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *cookie = iq_entry; 81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_OK; 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppReturnStatus 87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppEngineImpl::RemoveIqHandler(XmppIqCookie cookie, 88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqHandler ** iq_handler) { 89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::vector<XmppIqEntry*, std::allocator<XmppIqEntry*> >::iterator pos; 91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pos = std::find(iq_entries_->begin(), 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_entries_->end(), 94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reinterpret_cast<XmppIqEntry*>(cookie)); 95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (pos == iq_entries_->end()) 97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADARGUMENT; 98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqEntry* entry = *pos; 100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_entries_->erase(pos); 101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iq_handler) 102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *iq_handler = entry->iq_handler_; 103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete entry; 104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_OK; 106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppEngineImpl::DeleteIqCookies() { 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (size_t i = 0; i < iq_entries_->size(); i += 1) { 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqEntry * iq_entry_ = (*iq_entries_)[i]; 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (*iq_entries_)[i] = NULL; 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete iq_entry_; 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_entries_->clear(); 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic void 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochAecImpl(XmlElement * error_element, const QName & name, 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char * type, const char * code) { 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element->AddElement(new XmlElement(QN_ERROR)); 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element->AddAttr(QN_CODE, code, 1); 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element->AddAttr(QN_TYPE, type, 1); 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element->AddElement(new XmlElement(name, true), 1); 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic void 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochAddErrorCode(XmlElement * error_element, XmppStanzaError code) { 130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (code) { 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_BAD_REQUEST: 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_BAD_REQUEST, "modify", "400"); 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_CONFLICT: 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_CONFLICT, "cancel", "409"); 136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_FEATURE_NOT_IMPLEMENTED: 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_FEATURE_NOT_IMPLEMENTED, 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch "cancel", "501"); 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_FORBIDDEN: 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_FORBIDDEN, "auth", "403"); 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_GONE: 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_GONE, "modify", "302"); 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_INTERNAL_SERVER_ERROR: 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_INTERNAL_SERVER_ERROR, "wait", "500"); 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_ITEM_NOT_FOUND: 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_ITEM_NOT_FOUND, "cancel", "404"); 152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_JID_MALFORMED: 154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_JID_MALFORMED, "modify", "400"); 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_NOT_ACCEPTABLE: 157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_NOT_ACCEPTABLE, "cancel", "406"); 158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_NOT_ALLOWED: 160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_NOT_ALLOWED, "cancel", "405"); 161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_PAYMENT_REQUIRED: 163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_PAYMENT_REQUIRED, "auth", "402"); 164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_RECIPIENT_UNAVAILABLE: 166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_RECIPIENT_UNAVAILABLE, "wait", "404"); 167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_REDIRECT: 169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_REDIRECT, "modify", "302"); 170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_REGISTRATION_REQUIRED: 172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_REGISTRATION_REQUIRED, "auth", "407"); 173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_SERVER_NOT_FOUND: 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_REMOTE_SERVER_NOT_FOUND, 176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch "cancel", "404"); 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_SERVER_TIMEOUT: 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_REMOTE_SERVER_TIMEOUT, "wait", "502"); 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_RESOURCE_CONSTRAINT: 182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_RESOURCE_CONSTRAINT, "wait", "500"); 183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_SERVICE_UNAVAILABLE: 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_SERVICE_UNAVAILABLE, "cancel", "503"); 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_SUBSCRIPTION_REQUIRED: 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_SUBSCRIPTION_REQUIRED, "auth", "407"); 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_UNDEFINED_CONDITION: 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_UNDEFINED_CONDITION, "wait", "500"); 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case XSE_UNEXPECTED_REQUEST: 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AecImpl(error_element, QN_STANZA_UNEXPECTED_REQUEST, "wait", "400"); 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppReturnStatus 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppEngineImpl::SendStanzaError(const XmlElement * element_original, 202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppStanzaError code, 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string & text) { 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (state_ == STATE_CLOSED) 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_BADSTATE; 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmlElement error_element(element_original->Name()); 209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element.AddAttr(QN_TYPE, "error"); 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // copy attrs, copy 'from' to 'to' and strip 'from' 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (const XmlAttr * attribute = element_original->FirstAttr(); 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attribute; attribute = attribute->NextAttr()) { 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch QName name = attribute->Name(); 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (name == QN_TO) 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; // no need to put a from attr. Server will stamp stanza 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else if (name == QN_FROM) 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch name = QN_TO; 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else if (name == QN_TYPE) 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element.AddAttr(name, attribute->Value()); 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // copy children 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (const XmlChild * child = element_original->FirstChild(); 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch child; 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch child = child->NextChild()) { 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (child->IsText()) { 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element.AddText(child->AsText()->Text()); 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element.AddElement(new XmlElement(*(child->AsElement()))); 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // add error information 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AddErrorCode(&error_element, code); 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (text != STR_EMPTY) { 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmlElement * text_element = new XmlElement(QN_STANZA_TEXT, true); 239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch text_element->AddText(text); 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_element.AddElement(text_element); 241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendStanza(&error_element); 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return XMPP_RETURN_OK; 246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool 250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmppEngineImpl::HandleIqResponse(const XmlElement * element) { 251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iq_entries_->empty()) 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (element->Name() != QN_IQ) 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string type = element->Attr(QN_TYPE); 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type != "result" && type != "error") 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!element->HasAttr(QN_ID)) 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string id = element->Attr(QN_ID); 261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string from = element->Attr(QN_FROM); 262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (std::vector<XmppIqEntry *>::iterator it = iq_entries_->begin(); 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch it != iq_entries_->end(); it += 1) { 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch XmppIqEntry * iq_entry = *it; 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iq_entry->id_ == id && iq_entry->to_ == from) { 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_entries_->erase(it); 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq_entry->iq_handler_->IqResponse(iq_entry, element); 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete iq_entry; 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 278