⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmpp_c2s.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 2 页
字号:
void XMPP::C2S::StreamHandler::OnSessionReleased(){  m_SessionReleasedHandlers.Fire(*this);}void XMPP::C2S::StreamHandler::OnElement(PXML& pdu){  switch (m_State)  {  case Null:    HandleNullState(pdu);    break;  case RegStarted:    HandleRegStartedState(pdu);    break;  case TLSStarted:    HandleTLSStartedState(pdu);    break;#if P_SASL2  case SASLStarted:    HandleSASLStartedState(pdu);    break;#endif  case NonSASLStarted:    HandleNonSASLStartedState(pdu);    break;  case StreamSent:    HandleStreamSentState(pdu);    break;  case BindSent:    HandleBindSentState(pdu);    break;  case SessionSent:    HandleSessionSentState(pdu);    break;  case Established:    HandleEstablishedState(pdu);    break;  default:    // Error    PAssertAlways(PLogicError);  }}void XMPP::C2S::StreamHandler::HandleNullState(PXML& pdu){  if (pdu.GetRootElement()->GetName() != "stream:features")  {    Stop();    return;  }  /* This is what we are kind of expecting (more or less)  <stream:features>    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>      <required/>    </starttls>    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>      <mechanism>DIGEST-MD5</mechanism>      <mechanism>PLAIN</mechanism>    </mechanisms>  </stream:features>  *///  PXMLElement * starttls = pdu.GetRootElement()->GetElement("starttls");  PStringSet ourMechSet;  // We might have to negotiate the TLS first, but we set up the SASL phase now#if P_SASL2  PXMLElement * mechList = pdu.GetRootElement()->GetElement("mechanisms");  if (!mechList || !m_SASL.Init(m_JID.GetServer(), ourMechSet))  {    // SASL initialisation failed, goodbye...    Stop();    return;  }  PXMLElement * mech;  PINDEX i = 0;  while ((mech = mechList->GetElement("mechanism", i++)) != 0)  {    if (ourMechSet.Contains(mech->GetData())) // Hit      break;  }  if (mech != NULL)    m_Mechanism = mech->GetData();#endif  // That's how it'll be once we support TLS  /*if (starttls && (m_UseTLS || starttls->GetElement("required") != 0))  {    // we must start the TLS nogotiation...    SetState(XMPP::C2S::StreamHandler::TLSStarted);  }  else*/    StartAuthNegotiation();}void XMPP::C2S::StreamHandler::HandleRegStartedState(PXML& pdu){  PXMLElement * elem = pdu.GetRootElement();  if (elem->GetName() != "iq" || elem->GetAttribute("type") != "result") {    Stop();    return;  }  m_NewAccount = FALSE;  StartAuthNegotiation();}void XMPP::C2S::StreamHandler::HandleTLSStartedState(PXML& /*pdu*/){  PAssertAlways(PUnimplementedFunction);}#if P_SASL2void XMPP::C2S::StreamHandler::HandleSASLStartedState(PXML& pdu){  PString name = pdu.GetRootElement()->GetName();  if (name == "challenge")  {    PString input = pdu.GetRootElement()->GetData();    PString output;    if (m_SASL.Negotiate(input, output) == PSASLClient::Fail)    {      Stop();      return;    }    PString response("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'");    if (output.IsEmpty())      response += "/>";    else    {      response += ">";      response += output;      response += "</response>";    }    m_Stream->Write(response);  }  else if (name == "success")  {    m_SASL.End();    OnOpen(*m_Stream, 0); // open the inner stream (i.e. reset the parser)    SetState(XMPP::C2S::StreamHandler::StreamSent);  }  else  {    Stop();  }}#endifvoid XMPP::C2S::StreamHandler::HandleNonSASLStartedState(PXML& pdu){  PXMLElement * elem = pdu.GetRootElement();  if (elem->GetName() != "iq" || elem->GetAttribute("type") != "result") {    Stop();    return;  }  elem = elem->GetElement(XMPP::IQQuery);  if (elem == NULL) { // Authentication succeded    SetState(XMPP::C2S::StreamHandler::Established);  }  else {    PString auth(PString::Printf, "<iq type='set' to='%s' id='auth2'>"                                     "<query xmlns='jabber:iq:auth'>", (const char *)m_JID.GetServer());    PINDEX i = 0;    PXMLElement * item;    BOOL uid = FALSE, pwd = FALSE, digest = FALSE, res = FALSE;    while ((item = (PXMLElement *)elem->GetElement(i++)) != NULL) {      PString name = item->GetName();      if (name *= "username")        uid = TRUE;      else if (name *= "password")        pwd = TRUE;      else if (name *= "digest")        digest = TRUE;      else if (name *= "resource")        res = TRUE;    }    if (uid)      auth += "<username>" + m_JID.GetUser() + "</username>";    if (res)      auth += "<resource>" + m_JID.GetResource() + "</resource>";#if P_SSL    if (digest) {      PMessageDigest::Result bin_digest;      PMessageDigestSHA1::Encode(m_StreamID + m_Password, bin_digest);      PString digest;      const BYTE * data = bin_digest.GetPointer();      for (PINDEX i = 0, max = bin_digest.GetSize(); i < max ; i++)        digest.sprintf("%02x", (unsigned)data[i]);      auth += "<digest>" + digest + "</digest>";    }    else #endif    if (pwd)      auth += "<password>" + m_Password + "</password>";    auth += "</query></iq>";    m_Stream->Write(auth);  }}void XMPP::C2S::StreamHandler::HandleStreamSentState(PXML& pdu){  if (pdu.GetRootElement()->GetName() != "stream:features")  {    Stop();    return;  }  /*  <stream:features>  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>  <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>  </stream:features>  */  m_HasBind = pdu.GetRootElement()->GetElement("bind") != NULL;  m_HasSession = pdu.GetRootElement()->GetElement("session") != NULL;  if (m_HasBind)  {    PString bind("<iq type='set' id='bind_1'>"      "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'");    if (m_JID.GetResource().IsEmpty())      bind += "/></iq>";    else    {      bind += "><resource>";      bind += m_JID.GetResource();      bind += "</resource></bind></iq>";    }    m_Stream->Write(bind);    SetState(XMPP::C2S::StreamHandler::BindSent);  }  else if (m_HasSession)    HandleBindSentState(pdu);  else    SetState(XMPP::C2S::StreamHandler::Established);}void XMPP::C2S::StreamHandler::HandleBindSentState(PXML& pdu){  if (m_State == XMPP::C2S::StreamHandler::BindSent)  {    PXMLElement * elem = pdu.GetRootElement();    if (elem->GetName() != "iq" || elem->GetAttribute("type") != "result")    {      Stop();      return;    }    if ((elem = elem->GetElement("bind")) == NULL || (elem = elem->GetElement("jid")) == NULL)    {      Stop();      return;    }    PString jid = elem->GetData();  }  if (m_HasSession)  {    PString session = "<iq id='sess_1' type='set'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>";    m_Stream->Write(session);    SetState(XMPP::C2S::StreamHandler::SessionSent);  }  else    SetState(XMPP::C2S::StreamHandler::Established);}void XMPP::C2S::StreamHandler::HandleSessionSentState(PXML& pdu){  PXMLElement * elem = pdu.GetRootElement();  if (elem->GetName() != "iq" || elem->GetAttribute("type") != "result")  {    Stop();    return;  }  SetState(XMPP::C2S::StreamHandler::Established);}void XMPP::C2S::StreamHandler::HandleEstablishedState(PXML& pdu){  PCaselessString name = pdu.GetRootElement()->GetName();  if (name == "stream:error") {    OnError(pdu);    Stop();  }  else if (name == XMPP::MessageStanza) {    XMPP::Message msg(pdu);    if (msg.IsValid())      OnMessage(msg);    else      Stop("bad-format");  }  else if (name == XMPP::PresenceStanza) {    XMPP::Presence pre(pdu);    if (pre.IsValid())      OnPresence(pre);    else      Stop("bad-format");  }  else if (name == XMPP::IQStanza) {    XMPP::IQ iq(pdu);    if (iq.IsValid())      OnIQ(iq);    else      Stop("bad-format");  }  else    Stop("unsupported-stanza-type");}void XMPP::C2S::StreamHandler::OnError(PXML& pdu){  m_ErrorHandlers.Fire(pdu);}void XMPP::C2S::StreamHandler::OnMessage(XMPP::Message& pdu){  JID from = pdu.GetFrom();  /* Fire the generic message handles only if there isn't a notifier list   for this particular originator or the list is empty  */  if (!m_MessageSenderHandlers.Contains(from) || !m_MessageSenderHandlers[from].Fire(pdu))    m_MessageHandlers.Fire(pdu);}void XMPP::C2S::StreamHandler::OnPresence(XMPP::Presence& pdu){  m_PresenceHandlers.Fire(pdu);}void XMPP::C2S::StreamHandler::OnIQ(XMPP::IQ& pdu){  XMPP::IQ::IQType type = pdu.GetType();  XMPP::IQ * origMsg = NULL;  if (type == XMPP::IQ::Result || type == XMPP::IQ::Error) {    PString id = pdu.GetID();    m_PendingIQsLock.Wait();    for (PINDEX i = 0, max = m_PendingIQs.GetSize() ; i < max ; i++)      if (((XMPP::IQ&)(m_PendingIQs[i])).GetID() == id) {        origMsg = (XMPP::IQ *)m_PendingIQs.RemoveAt(i);        pdu.SetOriginalMessage(origMsg);      }    m_PendingIQsLock.Signal();  }  if (origMsg != NULL)    origMsg->GetResponseHandlers().Fire(pdu);  // Let's see if someone is registered to handle this namespace  PXMLElement * query = (PXMLElement *)pdu.GetRootElement()->GetElement(0);  PString xmlns = query != NULL ? query->GetAttribute(XMPP::Namespace) : PString::Empty();  if (!xmlns.IsEmpty() && m_IQNamespaceHandlers.Contains(xmlns))    m_IQNamespaceHandlers[xmlns].Fire(pdu);  // Now the "normal" handlers  m_IQHandlers.Fire(pdu);  // If it was a set or a get and nobody took care of it, we send and error back  if ((type == XMPP::IQ::Set || type == XMPP::IQ::Get) && !pdu.HasBeenProcessed()) {    XMPP::IQ * error = pdu.BuildError("cancel", "feature-not-implemented");    Send(error);  }}#endif // P_EXPAT// End of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -