From 983078f120a574bb0019afec44ac9beca52dd7ae Mon Sep 17 00:00:00 2001 From: O01eg Date: Tue, 8 Jan 2019 13:41:39 +0300 Subject: [PATCH 1/2] Add prefix support to decoder to accept xml:lang in presence statuses. --- src/xmpp_codec.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/xmpp_codec.rs b/src/xmpp_codec.rs index 9c59bac8..199627ba 100644 --- a/src/xmpp_codec.rs +++ b/src/xmpp_codec.rs @@ -104,7 +104,11 @@ impl ParserSink { "xmlns" => (), _ if is_prefix_xmlns(attr) => (), _ => { - el_builder = el_builder.attr(attr.name.local.as_ref(), attr.value.as_ref()); + if let Some(ref prefix) = attr.name.prefix { + el_builder = el_builder.attr(format!("{}:{}", prefix, attr.name.local), attr.value.as_ref()); + } else { + el_builder = el_builder.attr(attr.name.local.as_ref(), attr.value.as_ref()); + } } } } @@ -428,6 +432,28 @@ mod tests { }); } + /// test case for https://gitlab.com/xmpp-rs/tokio-xmpp/issues/3 + #[test] + fn test_atrribute_prefix() { + let mut c = XMPPCodec::new(); + let mut b = BytesMut::with_capacity(1024); + b.put(r""); + let r = c.decode(&mut b); + assert!(match r { + Ok(Some(Packet::StreamStart(_))) => true, + _ => false, + }); + + b.clear(); + b.put(r"Test status"); + let r = c.decode(&mut b); + assert!(match r { + Ok(Some(Packet::Stanza(ref el))) if el.name() == "status" && el.text() == "Test status" && el.attr("xml:lang").map_or(false, |a| a == "en") => true, + _ => false, + }); + + } + /// By default, encode() only get's a BytesMut that has 8kb space reserved. #[test] fn test_large_stanza() { From 1225bf7027f624ad7cc0624ebe44943bc410e781 Mon Sep 17 00:00:00 2001 From: Astro Date: Sun, 13 Jan 2019 21:05:19 +0100 Subject: [PATCH 2/2] prefix support DRY --- src/xmpp_codec.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/xmpp_codec.rs b/src/xmpp_codec.rs index 199627ba..69ab5fc2 100644 --- a/src/xmpp_codec.rs +++ b/src/xmpp_codec.rs @@ -14,6 +14,7 @@ use std::io; use std::iter::FromIterator; use std::rc::Rc; use std::str::from_utf8; +use std::borrow::Cow; use tokio_codec::{Decoder, Encoder}; use xml5ever::interface::Attribute; use xml5ever::tokenizer::{Tag, TagKind, Token, TokenSink, XmlTokenizer}; @@ -104,11 +105,12 @@ impl ParserSink { "xmlns" => (), _ if is_prefix_xmlns(attr) => (), _ => { - if let Some(ref prefix) = attr.name.prefix { - el_builder = el_builder.attr(format!("{}:{}", prefix, attr.name.local), attr.value.as_ref()); + let attr_name = if let Some(ref prefix) = attr.name.prefix { + Cow::Owned(format!("{}:{}", prefix, attr.name.local)) } else { - el_builder = el_builder.attr(attr.name.local.as_ref(), attr.value.as_ref()); - } + Cow::Borrowed(attr.name.local.as_ref()) + }; + el_builder = el_builder.attr(attr_name, attr.value.as_ref()); } } }