Index: remoting/protocol/jingle_messages.cc |
diff --git a/remoting/protocol/jingle_messages.cc b/remoting/protocol/jingle_messages.cc |
index 3113873b01280f3e310b165bb005364e44fbaa38..bc1a1b8e67a0bfff95bb9d73eaf71de6aead6171 100644 |
--- a/remoting/protocol/jingle_messages.cc |
+++ b/remoting/protocol/jingle_messages.cc |
@@ -149,6 +149,15 @@ XmlElement* FormatIceCandidate( |
return result; |
} |
+XmlElement* EnsureJingleTag(XmlElement* iq) { |
+ XmlElement* jingle = iq->FirstNamed(QName(kJingleNamespace, "jingle")); |
+ if (!jingle) { |
+ jingle = new XmlElement(QName(kJingleNamespace, "jingle"), true); |
+ iq->AddElement(jingle); |
+ } |
+ return jingle; |
+} |
+ |
// Represents the XML attrbute names for the various address fields in the |
// iq stanza. |
enum class Field { JID, CHANNEL, ENDPOINT_ID }; |
@@ -172,13 +181,27 @@ buzz::QName GetQNameByField(Field attr, bool from) { |
} |
SignalingAddress ParseAddress( |
- const buzz::XmlElement* stanza, bool from, std::string* error) { |
+ const buzz::XmlElement* iq, bool from, std::string* error) { |
SignalingAddress empty_instance; |
- std::string jid(stanza->Attr(GetQNameByField(Field::JID, from))); |
+ std::string jid(iq->Attr(GetQNameByField(Field::JID, from))); |
+ |
+ const XmlElement* jingle = iq->FirstNamed(QName(kJingleNamespace, "jingle")); |
+ |
+ if (!jingle) { |
+ return SignalingAddress(jid); |
+ } |
+ |
+ std::string type(iq->Attr(QName(std::string(), "type"))); |
+ // For error IQs, flips the |from| flag as the jingle node represents the |
+ // original request. |
+ if (type == "error") { |
+ from = !from; |
+ } |
+ |
std::string endpoint_id( |
- stanza->Attr(GetQNameByField(Field::ENDPOINT_ID, from))); |
- std::string channel_str(stanza->Attr(GetQNameByField(Field::CHANNEL, from))); |
+ jingle->Attr(GetQNameByField(Field::ENDPOINT_ID, from))); |
+ std::string channel_str(jingle->Attr(GetQNameByField(Field::CHANNEL, from))); |
SignalingAddress::Channel channel; |
if (channel_str.empty()) { |
@@ -199,27 +222,35 @@ SignalingAddress ParseAddress( |
return SignalingAddress(jid, endpoint_id, channel); |
} |
-void SetAddress(buzz::XmlElement* iqElement, |
+void SetAddress(buzz::XmlElement* iq, |
const SignalingAddress& address, |
bool from) { |
- // Start from a fresh slate regardless of the previous address format. |
- iqElement->ClearAttr(GetQNameByField(Field::JID, from)); |
- iqElement->ClearAttr(GetQNameByField(Field::CHANNEL, from)); |
- iqElement->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, from)); |
- |
if (address.empty()) { |
return; |
} |
// Always set the JID. |
- iqElement->AddAttr(GetQNameByField(Field::JID, from), address.jid); |
+ iq->SetAttr(GetQNameByField(Field::JID, from), address.jid); |
+ |
+ // Do not tamper the routing-info in the jingle tag for error IQ's, as |
+ // it corresponds to the original message. |
+ std::string type(iq->Attr(QName(std::string(), "type"))); |
+ if (type == "error") { |
+ return; |
+ } |
+ |
+ // Start from a fresh slate regardless of the previous address format. |
+ XmlElement* jingle = EnsureJingleTag(iq); |
Sergey Ulanov
2016/06/04 17:10:31
I suggest passing a pointer to <jingle> explicitly
kelvinp
2016/06/06 20:43:41
Done.
|
+ jingle->ClearAttr(GetQNameByField(Field::CHANNEL, from)); |
Sergey Ulanov
2016/06/04 17:10:31
I this necessary? SetAddress() is always called wi
kelvinp
2016/06/06 20:43:41
This is true. For the sake of future maintenance,
|
+ jingle->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, from)); |
// Only set the channel and endpoint_id in the LCS channel. |
if (address.channel == SignalingAddress::Channel::LCS) { |
- iqElement->AddAttr(GetQNameByField(Field::ENDPOINT_ID, from), |
- address.endpoint_id); |
- const char* channel_str = ValueToName(kChannelTypes, address.channel); |
- iqElement->AddAttr(GetQNameByField(Field::CHANNEL, from), channel_str); |
+ jingle->AddAttr( |
+ GetQNameByField(Field::ENDPOINT_ID, from), address.endpoint_id); |
+ jingle->AddAttr( |
+ GetQNameByField(Field::CHANNEL, from), |
+ ValueToName(kChannelTypes, address.channel)); |
} |
} |
@@ -402,9 +433,7 @@ std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { |
SetAddress(root.get(), from, true); |
root->SetAttr(QName(kEmptyNamespace, "type"), "set"); |
- XmlElement* jingle_tag = |
- new XmlElement(QName(kJingleNamespace, "jingle"), true); |
- root->AddElement(jingle_tag); |
+ XmlElement* jingle_tag = EnsureJingleTag(root.get()); |
jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); |
const char* action_attr = ValueToName(kActionTypes, action); |
@@ -479,17 +508,19 @@ std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( |
std::unique_ptr<XmlElement> iq( |
new XmlElement(QName(kJabberNamespace, "iq"), true)); |
+ iq->SetAttr(QName(kEmptyNamespace, "id"), |
+ request_stanza->Attr(QName(kEmptyNamespace, "id"))); |
+ |
+ std::string type_string(type == REPLY_RESULT ? "result" : "error"); |
+ iq->SetAttr(QName(kEmptyNamespace, "type"), type_string); |
+ |
SignalingAddress original_from; |
std::string error_message; |
original_from = ParseAddress(request_stanza, true, &error_message); |
DCHECK(error_message.empty()); |
SetAddress(iq.get(), original_from, false); |
- iq->SetAttr(QName(kEmptyNamespace, "id"), |
- request_stanza->Attr(QName(kEmptyNamespace, "id"))); |
- |
if (type == REPLY_RESULT) { |
- iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); |
return iq; |
} |