diff --git a/parsers/ChangeLog b/parsers/ChangeLog index 13be68cd..b32a827b 100644 --- a/parsers/ChangeLog +++ b/parsers/ChangeLog @@ -19,6 +19,7 @@ XXXX-YY-ZZ RELEASER - Stream Features (RFC 6120) (!400) - Extensible SASL Profile (XEP-0388) - SASL Channel-Binding Type Capability (XEP-0440) + - Stream Limits Advertisement (XEP-0478) Version 0.21.0: 2024-07-25 Emmanuel Gil Peyrot diff --git a/parsers/doap.xml b/parsers/doap.xml index df1bded8..6d8250c9 100644 --- a/parsers/doap.xml +++ b/parsers/doap.xml @@ -658,6 +658,14 @@ 0.20.0 + + + + complete + 0.2.0 + NEXT + + diff --git a/parsers/src/lib.rs b/parsers/src/lib.rs index a5b148ca..a58c0895 100644 --- a/parsers/src/lib.rs +++ b/parsers/src/lib.rs @@ -281,5 +281,8 @@ pub mod sasl_cb; /// XEP-0444: Message Reactions pub mod reactions; +/// XEP-0478: Stream Limits Advertisement +pub mod stream_limits; + /// XEP-0484: Fast Authentication Streamlining Tokens pub mod fast; diff --git a/parsers/src/ns.rs b/parsers/src/ns.rs index e87e4f04..25a46e7a 100644 --- a/parsers/src/ns.rs +++ b/parsers/src/ns.rs @@ -302,6 +302,9 @@ pub const SASL_CB: &str = "urn:xmpp:sasl-cb:0"; /// XEP-0444: Message Reactions pub const REACTIONS: &str = "urn:xmpp:reactions:0"; +/// XEP-0478: Stream Limits Advertisement +pub const STREAM_LIMITS: &str = "urn:xmpp:stream-limits:0"; + /// XEP-0484: Fast Authentication Streamlining Tokens pub const FAST: &str = "urn:xmpp:fast:0"; diff --git a/parsers/src/stream_features.rs b/parsers/src/stream_features.rs index 09b48cf6..c5a11fee 100644 --- a/parsers/src/stream_features.rs +++ b/parsers/src/stream_features.rs @@ -9,6 +9,7 @@ use xso::{AsXml, FromXml}; use crate::bind::BindFeature; use crate::ns; +use crate::stream_limits::Limits; /// Wraps ``, usually the very first nonza of a /// XMPP stream. Indicates which features are supported. @@ -27,6 +28,10 @@ pub struct StreamFeatures { #[xml(child(default))] pub sasl_mechanisms: SaslMechanisms, + /// Limits advertised by the server. + #[xml(child(default))] + pub limits: Option, + /// Other stream features advertised /// /// If some features you use end up here, you may want to contribute @@ -91,7 +96,7 @@ mod tests { assert_size!(SaslMechanisms, 12); assert_size!(RequiredStartTls, 0); assert_size!(StartTls, 1); - assert_size!(StreamFeatures, 28); + assert_size!(StreamFeatures, 40); } #[cfg(target_pointer_width = "64")] @@ -101,7 +106,7 @@ mod tests { assert_size!(SaslMechanisms, 24); assert_size!(RequiredStartTls, 0); assert_size!(StartTls, 1); - assert_size!(StreamFeatures, 56); + assert_size!(StreamFeatures, 64); } #[test] diff --git a/parsers/src/stream_limits.rs b/parsers/src/stream_limits.rs new file mode 100644 index 00000000..551950c5 --- /dev/null +++ b/parsers/src/stream_limits.rs @@ -0,0 +1,74 @@ +// Copyright (c) 2024 Emmanuel Gil Peyrot +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use xso::{AsXml, FromXml}; + +use crate::ns; +use std::num::NonZeroU32; + +/// Advertises limits on this stream. +#[derive(FromXml, AsXml, Debug, Clone, PartialEq)] +#[xml(namespace = ns::STREAM_LIMITS, name = "limits")] +pub struct Limits { + /// Maximum size of any first-level stream elements (including stanzas), in bytes the + /// announcing entity is willing to accept. + // TODO: Replace that with a direct u32 once xso supports that. + #[xml(child(default))] + pub max_bytes: Option, + + /// Number of seconds without any traffic from the iniating entity after which the server may + /// consider the stream idle, and either perform liveness checks or terminate the stream. + // TODO: Replace that with a direct u32 once xso supports that. + #[xml(child(default))] + pub idle_seconds: Option, +} + +/// Maximum size of any first-level stream elements (including stanzas), in bytes the +/// announcing entity is willing to accept. +#[derive(FromXml, AsXml, Debug, Clone, PartialEq)] +#[xml(namespace = ns::STREAM_LIMITS, name = "max-bytes")] +pub struct MaxBytes { + /// The number of bytes. + #[xml(text)] + pub value: NonZeroU32, +} + +/// Number of seconds without any traffic from the iniating entity after which the server may +/// consider the stream idle, and either perform liveness checks or terminate the stream. +#[derive(FromXml, AsXml, Debug, Clone, PartialEq)] +#[xml(namespace = ns::STREAM_LIMITS, name = "idle-seconds")] +pub struct IdleSeconds { + /// The number of seconds. + #[xml(text)] + pub value: NonZeroU32, +} + +#[cfg(test)] +mod tests { + use super::*; + use minidom::Element; + + #[test] + fn test_size() { + assert_size!(Limits, 8); + assert_size!(MaxBytes, 4); + assert_size!(IdleSeconds, 4); + } + + #[test] + fn test_simple() { + let elem: Element = + "262144" + .parse() + .unwrap(); + let limits = Limits::try_from(elem).unwrap(); + assert_eq!( + limits.max_bytes.unwrap().value, + NonZeroU32::new(262144).unwrap() + ); + assert!(limits.idle_seconds.is_none()); + } +}