-
Notifications
You must be signed in to change notification settings - Fork 880
XEP-0478: Stream Limits Advertisement: initial support #692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,90 @@ | ||||||
| /* | ||||||
| * | ||||||
| * Copyright © 2014-2026 Florian Schmaus | ||||||
| * | ||||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
| * you may not use this file except in compliance with the License. | ||||||
| * You may obtain a copy of the License at | ||||||
| * | ||||||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||||||
| * | ||||||
| * Unless required by applicable law or agreed to in writing, software | ||||||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
| * See the License for the specific language governing permissions and | ||||||
| * limitations under the License. | ||||||
| */ | ||||||
| package org.jivesoftware.smack.packet; | ||||||
|
|
||||||
| import javax.xml.namespace.QName; | ||||||
|
|
||||||
| import org.jivesoftware.smack.util.XmlStringBuilder; | ||||||
|
|
||||||
| /** | ||||||
| * Limits feature. | ||||||
| * For any XMPP stream, there is an "initiating entity" (a client or server) and a "responding entity" that they are connecting to. | ||||||
| * The responding entity advertises its limits in the <code><stream:features/></code> element that it sends at the start of the stream. | ||||||
| * <a href="https://xmpp.org/extensions/xep-0478.html">XEP-0478: Stream Limits Advertisement</a> | ||||||
| */ | ||||||
| public class Limits implements ExtensionElement { | ||||||
| public static final String ELEMENT = "limits"; | ||||||
| public static final String NAMESPACE = "urn:xmpp:stream-limits:0"; | ||||||
| public static final QName QNAME = new QName(NAMESPACE, ELEMENT); | ||||||
|
|
||||||
| /** | ||||||
| * The maximum size of any first-level stream elements (including stanzas), | ||||||
| * in bytes the announcing entity is willing to accept. | ||||||
| * Guidance on acceptable limits is provided in RFC 6120 section 13.12. | ||||||
| * If the responding entity is unable to determine its limits, this child can be absent. | ||||||
| * Element: <code><max-bytes/></code>. Type UnsignedInt. | ||||||
| */ | ||||||
| public final int maxBytes; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
Suggested change
|
||||||
|
|
||||||
| /** | ||||||
| * The number of seconds without any traffic from the initiating entity after which | ||||||
| * the server may consider the stream idle, and either perform liveness checks | ||||||
| * (using e.g. Stream Management (XEP-0198) or XMPP Ping (XEP-0199)) or terminate the stream. | ||||||
| * Guidance on handling idle connections is provided in RFC 6120 section 4.6. | ||||||
| * If the responding entity is unable to determine its limits, this child can be absent. | ||||||
| * Element: <code><idle-seconds/></code>. Type UnsignedInt. | ||||||
| */ | ||||||
| public final int idleSeconds; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| public Limits(int maxBytes, int idleSeconds) { | ||||||
| this.maxBytes = maxBytes; | ||||||
| this.idleSeconds = idleSeconds; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public String getElementName() { | ||||||
| return ELEMENT; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public String getNamespace() { | ||||||
| return NAMESPACE; | ||||||
| } | ||||||
|
|
||||||
| public int getMaxBytes() { | ||||||
| return maxBytes; | ||||||
| } | ||||||
|
|
||||||
| public int getIdleSeconds() { | ||||||
| return idleSeconds; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public XmlStringBuilder toXML(XmlEnvironment enclosingNamespace) { | ||||||
| XmlStringBuilder xml = new XmlStringBuilder(this); | ||||||
| xml.rightAngleBracket(); | ||||||
| if (maxBytes != 0) { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
now, since we denote the absence of the element with |
||||||
| xml.element("max-bytes", String.valueOf(maxBytes)); | ||||||
| } | ||||||
| if (idleSeconds != 0) { | ||||||
| xml.element("idle-seconds", String.valueOf(idleSeconds)); | ||||||
| } | ||||||
| xml.closeElement(this); | ||||||
| return xml; | ||||||
| } | ||||||
|
|
||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| /* | ||
| * | ||
| * Copyright 2018-2026 Florian Schmaus. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.jivesoftware.smack; | ||
|
|
||
| import static org.junit.Assert.assertTrue; | ||
| import static org.junit.Assert.assertEquals; | ||
| import static java.util.Arrays.asList; | ||
|
|
||
| import java.io.ByteArrayInputStream; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| import java.nio.charset.StandardCharsets; | ||
|
|
||
| import org.jivesoftware.smack.packet.Bind; | ||
| import org.jivesoftware.smack.packet.Limits; | ||
| import org.jivesoftware.smack.packet.Mechanisms; | ||
| import org.jivesoftware.smack.packet.Session; | ||
| import org.jivesoftware.smack.parsing.SmackParsingException; | ||
| import org.jivesoftware.smack.test.util.SmackTestSuite; | ||
| import org.jivesoftware.smack.util.PacketParserUtils; | ||
| import org.jivesoftware.smack.xml.XmlPullParser; | ||
| import org.jivesoftware.smack.xml.XmlPullParserException; | ||
|
|
||
| import org.junit.Test; | ||
|
|
||
| public class AbstractXMPPConnectionTest extends SmackTestSuite { | ||
| private final DummyConnection connection = new DummyConnection(); | ||
|
|
||
| @Test | ||
| public void parseFeatures() throws XmlPullParserException, IOException, SmackParsingException { | ||
| String featureStr = "<features xmlns='http://etherx.jabber.org/streams'>" + | ||
| "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + | ||
| " <mechanism>OAUTHBEARER</mechanism>" + | ||
| " <mechanism>SCRAM-SHA-1</mechanism>" + | ||
| " <mechanism>PLAIN</mechanism>" + | ||
| " <mechanism>SCRAM-SHA-1-PLUS</mechanism>" + | ||
| "</mechanisms>" + | ||
| "<sasl-channel-binding xmlns='urn:xmpp:sasl-cb:0'>" + | ||
| " <channel-binding type='tls-exporter' />" + | ||
| "</sasl-channel-binding>" + | ||
| "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>" + | ||
| " <required />" + | ||
| "</bind>" + | ||
| "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'>" + | ||
| " <optional />" + | ||
| "</session>" + | ||
| "<limits xmlns='urn:xmpp:stream-limits:0'>" + | ||
| " <max-bytes>262144</max-bytes>" + | ||
| " <idle-seconds>840</idle-seconds>" + | ||
| "</limits>" + | ||
| "<register xmlns='urn:xmpp:invite' />" + | ||
| "<register xmlns='urn:xmpp:ibr-token:0' />" + | ||
| "<register xmlns='http://jabber.org/features/iq-register' />" + | ||
| "<ver xmlns='urn:xmpp:features:rosterver' />" + | ||
| "<sub xmlns='urn:xmpp:features:pre-approval' />" + | ||
| "<csi xmlns='urn:xmpp:csi:0' />" + | ||
| "<c hash='sha-1' node='http://prosody.im'" + | ||
| " ver='uWfOTni5YjTtMRfYAjNKsj2GUXM=' xmlns='http://jabber.org/protocol/caps' />" + | ||
| "</features>"; | ||
| InputStream input = new ByteArrayInputStream(featureStr.getBytes(StandardCharsets.UTF_8)); | ||
| XmlPullParser parser = PacketParserUtils.getParserFor(input); | ||
| connection.parseFeatures(parser); | ||
|
|
||
| assertTrue(connection.hasFeature("mechanisms", "urn:ietf:params:xml:ns:xmpp-sasl")); | ||
| Mechanisms featMechanisms = connection.getFeature(Mechanisms.class); | ||
| assertEquals(asList("OAUTHBEARER", "SCRAM-SHA-1", "PLAIN", "SCRAM-SHA-1-PLUS"), featMechanisms.getMechanisms()); | ||
|
|
||
| assertTrue(connection.hasFeature("bind", "urn:ietf:params:xml:ns:xmpp-bind")); | ||
| Bind.Feature featBind = connection.getFeature(Bind.Feature.class); | ||
| assertEquals(Bind.Feature.INSTANCE, featBind); | ||
|
|
||
| assertTrue(connection.hasFeature("session", "urn:ietf:params:xml:ns:xmpp-session")); | ||
| Session.Feature featSession = connection.getFeature(Session.Feature.class); | ||
| assertTrue(featSession.isOptional()); | ||
|
|
||
| assertTrue(connection.hasFeature("limits", "urn:xmpp:stream-limits:0")); | ||
| Limits featLimits = connection.getFeature(Limits.class); | ||
| assertEquals(262144, featLimits.getMaxBytes()); | ||
| assertEquals(840, featLimits.getIdleSeconds()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I have the copyright on this code, have I?