Chromium Code Reviews| 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; |
| } |