diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index eab2710c2..96012c3e6 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -41,6 +41,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode; +import org.jivesoftware.smack.SmackConfiguration.UnknownIqRequestReplyMode; import org.jivesoftware.smack.SmackException.AlreadyConnectedException; import org.jivesoftware.smack.SmackException.AlreadyLoggedInException; import org.jivesoftware.smack.SmackException.NoResponseException; @@ -991,20 +992,31 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { replyTimeout = timeout; } - private static boolean replyToUnknownIqDefault = true; - /** * Set the default value used to determine if new connection will reply to unknown IQ requests. The pre-configured * default is 'true'. * * @param replyToUnkownIqDefault * @see #setReplyToUnknownIq(boolean) + * @deprecated Use {@link SmackConfiguration#setUnknownIqRequestReplyMode(org.jivesoftware.smack.SmackConfiguration.UnknownIqRequestReplyMode)} instead. */ + @Deprecated + // TODO Remove in Smack 4.3 public static void setReplyToUnknownIqDefault(boolean replyToUnkownIqDefault) { - AbstractXMPPConnection.replyToUnknownIqDefault = replyToUnkownIqDefault; + SmackConfiguration.UnknownIqRequestReplyMode mode; + if (replyToUnkownIqDefault) { + mode = SmackConfiguration.UnknownIqRequestReplyMode.replyServiceUnavailable; + } else { + mode = SmackConfiguration.UnknownIqRequestReplyMode.doNotReply; + } + SmackConfiguration.setUnknownIqRequestReplyMode(mode); } - private boolean replyToUnkownIq = replyToUnknownIqDefault; + private SmackConfiguration.UnknownIqRequestReplyMode unknownIqRequestReplyMode = SmackConfiguration.getUnknownIqRequestReplyMode(); + + public void setUnknownIqRequestReplyMode(UnknownIqRequestReplyMode unknownIqRequestReplyMode) { + this.unknownIqRequestReplyMode = Objects.requireNonNull(unknownIqRequestReplyMode, "Mode must not be null"); + } /** * Set if Smack will automatically send @@ -1012,9 +1024,18 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * registered {@link IQRequestHandler} is received. * * @param replyToUnknownIq + * @deprecated use {@link #setUnknownIqRequestReplyMode(UnknownIqRequestReplyMode)} instead. */ + @Deprecated + // TODO Remove in Smack 4.3 public void setReplyToUnknownIq(boolean replyToUnknownIq) { - this.replyToUnkownIq = replyToUnknownIq; + SmackConfiguration.UnknownIqRequestReplyMode mode; + if (replyToUnknownIq) { + mode = SmackConfiguration.UnknownIqRequestReplyMode.replyServiceUnavailable; + } else { + mode = SmackConfiguration.UnknownIqRequestReplyMode.doNotReply; + } + unknownIqRequestReplyMode = mode; } protected void parseAndProcessStanza(XmlPullParser parser) throws Exception { @@ -1089,13 +1110,24 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { throw new IllegalStateException("Should only encounter IQ type 'get' or 'set'"); } if (iqRequestHandler == null) { - if (!replyToUnkownIq) { + XMPPError.Condition replyCondition; + switch (unknownIqRequestReplyMode) { + case doNotReply: return; + case replyFeatureNotImplemented: + replyCondition = XMPPError.Condition.feature_not_implemented; + break; + case replyServiceUnavailable: + replyCondition = XMPPError.Condition.service_unavailable; + break; + default: + throw new AssertionError(); } + // If the IQ stanza is of type "get" or "set" with no registered IQ request handler, then answer an // IQ of type 'error' with condition 'service-unavailable'. ErrorIQ errorIQ = IQ.createErrorResponse(iq, XMPPError.getBuilder(( - XMPPError.Condition.service_unavailable))); + replyCondition))); try { sendStanza(errorIQ); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index 2e6770c7a..dafd97810 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -34,6 +34,7 @@ import org.jivesoftware.smack.debugger.SmackDebugger; import org.jivesoftware.smack.debugger.SmackDebuggerFactory; import org.jivesoftware.smack.parsing.ExceptionThrowingCallback; import org.jivesoftware.smack.parsing.ParsingExceptionCallback; +import org.jivesoftware.smack.util.Objects; /** * Represents the configuration of Smack. The configuration is used for: @@ -370,4 +371,20 @@ public final class SmackConfiguration { return defaultHostnameVerififer; } + enum UnknownIqRequestReplyMode { + doNotReply, + replyFeatureNotImplemented, + replyServiceUnavailable, + } + + // TODO Change to replyFeatureNotImplemented in Smack 4.3 + private static UnknownIqRequestReplyMode unknownIqRequestReplyMode = UnknownIqRequestReplyMode.replyServiceUnavailable; + + public static UnknownIqRequestReplyMode getUnknownIqRequestReplyMode() { + return unknownIqRequestReplyMode; + } + + public static void setUnknownIqRequestReplyMode(UnknownIqRequestReplyMode unknownIqRequestReplyMode) { + SmackConfiguration.unknownIqRequestReplyMode = Objects.requireNonNull(unknownIqRequestReplyMode, "Must set mode"); + } }