mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-29 23:42:06 +01:00
Compare commits
No commits in common. "daab6039a1af48199a709873020ba81096fb4b2d" and "2ef9b99e9cd673f529966ddd4a7a1648d088ea33" have entirely different histories.
daab6039a1
...
2ef9b99e9c
16 changed files with 63 additions and 259 deletions
|
@ -113,15 +113,6 @@ allprojects {
|
||||||
version += '-SNAPSHOT'
|
version += '-SNAPSHOT'
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
|
||||||
// Enable full stacktraces of failed tests. Especially handy
|
|
||||||
// for environments like Travis.
|
|
||||||
testLogging {
|
|
||||||
events "failed"
|
|
||||||
exceptionFormat "full"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ext.sharedManifest = manifest {
|
ext.sharedManifest = manifest {
|
||||||
attributes('Implementation-Version': version,
|
attributes('Implementation-Version': version,
|
||||||
'Implementation-GitRevision': ext.gitCommit,
|
'Implementation-GitRevision': ext.gitCommit,
|
||||||
|
|
|
@ -141,24 +141,6 @@ hr {
|
||||||
|
|
||||||
<div id="pageBody">
|
<div id="pageBody">
|
||||||
|
|
||||||
<h2>4.3.3 -- <span style="font-weight: normal;">2019-03-14</span></h2>
|
|
||||||
|
|
||||||
<h2> Bug
|
|
||||||
</h2>
|
|
||||||
<ul>
|
|
||||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-856'>SMACK-856</a>] - Smack fails under JDK 11 because com.sun.jndi.dns.DnsContextFactory is not inaccessible
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2> Improvement
|
|
||||||
</h2>
|
|
||||||
<ul>
|
|
||||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-858'>SMACK-858</a>] - Dependency version specifier of jxmpp and MiniDNS include alpha/beta/... versions of the follow up version when Maven is used
|
|
||||||
</li>
|
|
||||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-859'>SMACK-859</a>] - MultiUserChat enter() should reset the timeout of the collector waiting for the final self presence to prevent timeouts for large MUCs
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>4.3.2 -- <span style="font-weight: normal;">2019-02-22</span></h2>
|
<h2>4.3.2 -- <span style="font-weight: normal;">2019-02-22</span></h2>
|
||||||
|
|
||||||
<h2> Bug
|
<h2> Bug
|
||||||
|
|
|
@ -266,11 +266,6 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
client = null;
|
client = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
instantShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void instantShutdown() {
|
|
||||||
setWasAuthenticated();
|
setWasAuthenticated();
|
||||||
sessionID = null;
|
sessionID = null;
|
||||||
done = true;
|
done = true;
|
||||||
|
|
|
@ -111,7 +111,6 @@ import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||||
import org.jivesoftware.smack.provider.NonzaProvider;
|
import org.jivesoftware.smack.provider.NonzaProvider;
|
||||||
import org.jivesoftware.smack.provider.ProviderManager;
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
import org.jivesoftware.smack.sasl.core.SASLAnonymous;
|
import org.jivesoftware.smack.sasl.core.SASLAnonymous;
|
||||||
import org.jivesoftware.smack.util.Async;
|
|
||||||
import org.jivesoftware.smack.util.DNSUtil;
|
import org.jivesoftware.smack.util.DNSUtil;
|
||||||
import org.jivesoftware.smack.util.Objects;
|
import org.jivesoftware.smack.util.Objects;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
@ -358,9 +357,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
*/
|
*/
|
||||||
protected boolean authenticated = false;
|
protected boolean authenticated = false;
|
||||||
|
|
||||||
// TODO: Migrate to ZonedDateTime once Smack's minimum required Android SDK level is 26 (8.0, Oreo) or higher.
|
|
||||||
protected long authenticatedConnectionInitiallyEstablishedTimestamp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that indicates if the user was authenticated with the server when the connection
|
* Flag that indicates if the user was authenticated with the server when the connection
|
||||||
* to the server was closed (abruptly or not).
|
* to the server was closed (abruptly or not).
|
||||||
|
@ -453,12 +449,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
@Override
|
@Override
|
||||||
public abstract boolean isUsingCompression();
|
public abstract boolean isUsingCompression();
|
||||||
|
|
||||||
protected void initState() {
|
|
||||||
saslFeatureReceived.init();
|
|
||||||
lastFeaturesReceived.init();
|
|
||||||
tlsHandled.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes a connection to the XMPP server. It basically
|
* Establishes a connection to the XMPP server. It basically
|
||||||
* creates and maintains a connection to the server.
|
* creates and maintains a connection to the server.
|
||||||
|
@ -477,23 +467,21 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
throwAlreadyConnectedExceptionIfAppropriate();
|
throwAlreadyConnectedExceptionIfAppropriate();
|
||||||
|
|
||||||
// Reset the connection state
|
// Reset the connection state
|
||||||
initState();
|
|
||||||
saslAuthentication.init();
|
saslAuthentication.init();
|
||||||
|
saslFeatureReceived.init();
|
||||||
|
lastFeaturesReceived.init();
|
||||||
|
tlsHandled.init();
|
||||||
streamId = null;
|
streamId = null;
|
||||||
|
|
||||||
try {
|
// Perform the actual connection to the XMPP service
|
||||||
// Perform the actual connection to the XMPP service
|
connectInternal();
|
||||||
connectInternal();
|
|
||||||
|
|
||||||
// If TLS is required but the server doesn't offer it, disconnect
|
// If TLS is required but the server doesn't offer it, disconnect
|
||||||
// from the server and throw an error. First check if we've already negotiated TLS
|
// from the server and throw an error. First check if we've already negotiated TLS
|
||||||
// and are secure, however (features get parsed a second time after TLS is established).
|
// and are secure, however (features get parsed a second time after TLS is established).
|
||||||
if (!isSecureConnection() && getConfiguration().getSecurityMode() == SecurityMode.required) {
|
if (!isSecureConnection() && getConfiguration().getSecurityMode() == SecurityMode.required) {
|
||||||
throw new SecurityRequiredByClientException();
|
shutdown();
|
||||||
}
|
throw new SecurityRequiredByClientException();
|
||||||
} catch (SmackException | IOException | XMPPException | InterruptedException e) {
|
|
||||||
instantShutdown();
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make note of the fact that we're now connected.
|
// Make note of the fact that we're now connected.
|
||||||
|
@ -664,9 +652,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void afterSuccessfulLogin(final boolean resumed) throws NotConnectedException, InterruptedException {
|
protected void afterSuccessfulLogin(final boolean resumed) throws NotConnectedException, InterruptedException {
|
||||||
if (!resumed) {
|
|
||||||
authenticatedConnectionInitiallyEstablishedTimestamp = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
// Indicate that we're now authenticated.
|
// Indicate that we're now authenticated.
|
||||||
this.authenticated = true;
|
this.authenticated = true;
|
||||||
|
|
||||||
|
@ -849,46 +834,36 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
*
|
*
|
||||||
* @param exception the exception that causes the connection close event.
|
* @param exception the exception that causes the connection close event.
|
||||||
*/
|
*/
|
||||||
protected final void notifyConnectionError(final Exception exception) {
|
protected final synchronized void notifyConnectionError(Exception exception) {
|
||||||
if (!isConnected()) {
|
if (!isConnected()) {
|
||||||
LOGGER.log(Level.INFO, "Connection was already disconnected when attempting to handle " + exception,
|
LOGGER.log(Level.INFO, "Connection was already disconnected when attempting to handle " + exception,
|
||||||
exception);
|
exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASYNC_BUT_ORDERED.performAsyncButOrdered(this, () -> {
|
currentConnectionException = exception;
|
||||||
currentConnectionException = exception;
|
notifyAll();
|
||||||
synchronized (AbstractXMPPConnection.this) {
|
|
||||||
notifyAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (StanzaCollector collector : collectors) {
|
for (StanzaCollector collector : collectors) {
|
||||||
collector.notifyConnectionError(exception);
|
collector.notifyConnectionError(exception);
|
||||||
}
|
}
|
||||||
SmackWrappedException smackWrappedException = new SmackWrappedException(exception);
|
SmackWrappedException smackWrappedException = new SmackWrappedException(exception);
|
||||||
tlsHandled.reportGenericFailure(smackWrappedException);
|
tlsHandled.reportGenericFailure(smackWrappedException);
|
||||||
saslFeatureReceived.reportGenericFailure(smackWrappedException);
|
saslFeatureReceived.reportGenericFailure(smackWrappedException);
|
||||||
lastFeaturesReceived.reportGenericFailure(smackWrappedException);
|
lastFeaturesReceived.reportGenericFailure(smackWrappedException);
|
||||||
// TODO From XMPPTCPConnection. Was called in Smack 4.3 where notifyConnectionError() was part of
|
|
||||||
// XMPPTCPConnection. Create delegation method?
|
|
||||||
// maybeCompressFeaturesReceived.reportGenericFailure(smackWrappedException);
|
|
||||||
|
|
||||||
// Closes the connection temporary. A if the connection supports stream management, then a reconnection is
|
// Closes the connection temporary. A if the connection supports stream management, then a reconnection is
|
||||||
// possible. Note that a connection listener of e.g. XMPPTCPConnection will drop the SM state in
|
// possible. Note that a connection listener of e.g. XMPPTCPConnection will drop the SM state in
|
||||||
// case the Exception is a StreamErrorException.
|
// case the Exception is a StreamErrorException.
|
||||||
instantShutdown();
|
instantShutdown();
|
||||||
|
|
||||||
Async.go(() -> {
|
callConnectionClosedOnErrorListener(exception);
|
||||||
// Notify connection listeners of the error.
|
|
||||||
callConnectionClosedOnErrorListener(exception);
|
|
||||||
}, AbstractXMPPConnection.this + " callConnectionClosedOnErrorListener()");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected void instantShutdown() {
|
||||||
* Performs an unclean disconnect and shutdown of the connection. Does not send a closing stream stanza.
|
// Default implementation simply calls shutdown(), subclasses may override this.
|
||||||
*/
|
shutdown();
|
||||||
public abstract void instantShutdown();
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts the current connection down.
|
* Shuts the current connection down.
|
||||||
|
@ -1836,18 +1811,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
return lastStanzaReceived;
|
return lastStanzaReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the timestamp when the connection was the first time authenticated, i.e., when the first successful login was
|
|
||||||
* performed. Note that this value is not reset on disconnect, so it represents the timestamp from the last
|
|
||||||
* authenticated connection. The value is also not reset on stream resumption.
|
|
||||||
*
|
|
||||||
* @return the timestamp or {@code null}.
|
|
||||||
* @since 4.3.3
|
|
||||||
*/
|
|
||||||
public final long getAuthenticatedConnectionInitiallyEstablishedTimestamp() {
|
|
||||||
return authenticatedConnectionInitiallyEstablishedTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install a parsing exception callback, which will be invoked once an exception is encountered while parsing a
|
* Install a parsing exception callback, which will be invoked once an exception is encountered while parsing a
|
||||||
* stanza.
|
* stanza.
|
||||||
|
|
|
@ -93,24 +93,17 @@ public abstract class SmackException extends Exception {
|
||||||
return new NoResponseException(sb.toString());
|
return new NoResponseException(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public static NoResponseException newWith(XMPPConnection connection,
|
||||||
// TODO: Remove in Smack 4.4.
|
|
||||||
public static NoResponseException newWith(long timeout,
|
|
||||||
StanzaCollector collector) {
|
|
||||||
return newWith(timeout, collector.getStanzaFilter(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NoResponseException newWith(long timeout,
|
|
||||||
StanzaCollector collector, boolean stanzaCollectorCancelled) {
|
StanzaCollector collector, boolean stanzaCollectorCancelled) {
|
||||||
return newWith(timeout, collector.getStanzaFilter(), stanzaCollectorCancelled);
|
return newWith(connection, collector.getStanzaFilter(), stanzaCollectorCancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NoResponseException newWith(XMPPConnection connection, StanzaFilter filter) {
|
public static NoResponseException newWith(XMPPConnection connection, StanzaFilter filter) {
|
||||||
return newWith(connection.getReplyTimeout(), filter, false);
|
return newWith(connection, filter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NoResponseException newWith(long timeout, StanzaFilter filter, boolean stanzaCollectorCancelled) {
|
public static NoResponseException newWith(XMPPConnection connection, StanzaFilter filter, boolean stanzaCollectorCancelled) {
|
||||||
final StringBuilder sb = getWaitingFor(timeout);
|
final StringBuilder sb = getWaitingFor(connection);
|
||||||
if (stanzaCollectorCancelled) {
|
if (stanzaCollectorCancelled) {
|
||||||
sb.append(" StanzaCollector has been cancelled.");
|
sb.append(" StanzaCollector has been cancelled.");
|
||||||
}
|
}
|
||||||
|
@ -126,10 +119,7 @@ public abstract class SmackException extends Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringBuilder getWaitingFor(XMPPConnection connection) {
|
private static StringBuilder getWaitingFor(XMPPConnection connection) {
|
||||||
return getWaitingFor(connection.getReplyTimeout());
|
final long replyTimeout = connection.getReplyTimeout();
|
||||||
}
|
|
||||||
|
|
||||||
private static StringBuilder getWaitingFor(final long replyTimeout) {
|
|
||||||
final StringBuilder sb = new StringBuilder(256);
|
final StringBuilder sb = new StringBuilder(256);
|
||||||
sb.append("No response received within reply timeout. Timeout was "
|
sb.append("No response received within reply timeout. Timeout was "
|
||||||
+ replyTimeout + "ms (~"
|
+ replyTimeout + "ms (~"
|
||||||
|
|
|
@ -290,7 +290,7 @@ public class StanzaCollector implements AutoCloseable {
|
||||||
if (!connection.isConnected()) {
|
if (!connection.isConnected()) {
|
||||||
throw new NotConnectedException(connection, packetFilter);
|
throw new NotConnectedException(connection, packetFilter);
|
||||||
}
|
}
|
||||||
throw NoResponseException.newWith(timeout, this, cancelled);
|
throw NoResponseException.newWith(connection, this, cancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMPPErrorException.ifHasErrorThenThrow(result);
|
XMPPErrorException.ifHasErrorThenThrow(result);
|
||||||
|
|
|
@ -198,12 +198,6 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder("XMPPError: ");
|
StringBuilder sb = new StringBuilder("XMPPError: ");
|
||||||
sb.append(condition.toString()).append(" - ").append(type.toString());
|
sb.append(condition.toString()).append(" - ").append(type.toString());
|
||||||
|
|
||||||
String descriptiveText = getDescriptiveText();
|
|
||||||
if (descriptiveText != null) {
|
|
||||||
sb.append(" [").append(descriptiveText).append(']');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorGenerator != null) {
|
if (errorGenerator != null) {
|
||||||
sb.append(". Generated by ").append(errorGenerator);
|
sb.append(". Generated by ").append(errorGenerator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,11 +100,6 @@ public class DummyConnection extends AbstractXMPPConnection {
|
||||||
callConnectionClosedListener();
|
callConnectionClosedListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void instantShutdown() {
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecureConnection() {
|
public boolean isSecureConnection() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -231,5 +226,4 @@ public class DummyConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||||
import org.jivesoftware.smack.filter.AndFilter;
|
import org.jivesoftware.smack.filter.AndFilter;
|
||||||
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
||||||
import org.jivesoftware.smack.filter.NotFilter;
|
import org.jivesoftware.smack.filter.NotFilter;
|
||||||
|
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
import org.jivesoftware.smack.filter.ToTypeFilter;
|
import org.jivesoftware.smack.filter.ToTypeFilter;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
@ -45,12 +46,13 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
||||||
MessageTypeFilter.NORMAL_OR_CHAT_OR_HEADLINE,
|
MessageTypeFilter.NORMAL_OR_CHAT_OR_HEADLINE,
|
||||||
ToTypeFilter.ENTITY_FULL_OR_BARE_JID);
|
ToTypeFilter.ENTITY_FULL_OR_BARE_JID);
|
||||||
|
|
||||||
|
private static final StanzaFilter ORIGIN_ID_FILTER = new StanzaExtensionFilter(OriginIdElement.ELEMENT, NAMESPACE);
|
||||||
|
|
||||||
// Listener for outgoing stanzas that adds origin-ids to outgoing stanzas.
|
// Listener for outgoing stanzas that adds origin-ids to outgoing stanzas.
|
||||||
private static final StanzaListener ADD_ORIGIN_ID_INTERCEPTOR = new StanzaListener() {
|
private final StanzaListener stanzaListener = new StanzaListener() {
|
||||||
@Override
|
@Override
|
||||||
public void processStanza(Stanza stanza) {
|
public void processStanza(Stanza stanza) {
|
||||||
Message message = (Message) stanza;
|
OriginIdElement.addOriginId((Message) stanza);
|
||||||
OriginIdElement.addOriginId(message);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +95,7 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
||||||
public synchronized void enable() {
|
public synchronized void enable() {
|
||||||
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(NAMESPACE);
|
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(NAMESPACE);
|
||||||
StanzaFilter filter = new AndFilter(OUTGOING_FILTER, new NotFilter(OUTGOING_FILTER));
|
StanzaFilter filter = new AndFilter(OUTGOING_FILTER, new NotFilter(OUTGOING_FILTER));
|
||||||
connection().addStanzaInterceptor(ADD_ORIGIN_ID_INTERCEPTOR, filter);
|
connection().addStanzaInterceptor(stanzaListener, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,7 +103,7 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
||||||
*/
|
*/
|
||||||
public synchronized void disable() {
|
public synchronized void disable() {
|
||||||
ServiceDiscoveryManager.getInstanceFor(connection()).removeFeature(NAMESPACE);
|
ServiceDiscoveryManager.getInstanceFor(connection()).removeFeature(NAMESPACE);
|
||||||
connection().removeStanzaInterceptor(ADD_ORIGIN_ID_INTERCEPTOR);
|
connection().removeStanzaInterceptor(stanzaListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,11 +24,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
public class OriginIdProvider extends ExtensionElementProvider<OriginIdElement> {
|
public class OriginIdProvider extends ExtensionElementProvider<OriginIdElement> {
|
||||||
|
|
||||||
public static final OriginIdProvider INSTANCE = new OriginIdProvider();
|
public static final OriginIdProvider TEST_INSTANCE = new OriginIdProvider();
|
||||||
|
|
||||||
// TODO: Remove in Smack 4.4.
|
|
||||||
@Deprecated
|
|
||||||
public static final OriginIdProvider TEST_INSTANCE = INSTANCE;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OriginIdElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) {
|
public OriginIdElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) {
|
||||||
|
|
|
@ -24,11 +24,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
public class StanzaIdProvider extends ExtensionElementProvider<StanzaIdElement> {
|
public class StanzaIdProvider extends ExtensionElementProvider<StanzaIdElement> {
|
||||||
|
|
||||||
public static final StanzaIdProvider INSTANCE = new StanzaIdProvider();
|
public static StanzaIdProvider TEST_INSTANCE = new StanzaIdProvider();
|
||||||
|
|
||||||
// TODO: Remove in Smack 4.4.
|
|
||||||
@Deprecated
|
|
||||||
public static final StanzaIdProvider TEST_INSTANCE = INSTANCE;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StanzaIdElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) {
|
public StanzaIdElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||||
import org.jivesoftware.smack.test.util.TestUtils;
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
|
||||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||||
import org.jivesoftware.smackx.sid.element.StanzaIdElement;
|
import org.jivesoftware.smackx.sid.element.StanzaIdElement;
|
||||||
import org.jivesoftware.smackx.sid.provider.OriginIdProvider;
|
import org.jivesoftware.smackx.sid.provider.OriginIdProvider;
|
||||||
|
@ -43,7 +42,7 @@ public class StableUniqueStanzaIdTest extends SmackTestSuite {
|
||||||
assertEquals("alice@wonderland.lit", element.getBy());
|
assertEquals("alice@wonderland.lit", element.getBy());
|
||||||
assertXMLEqual(xml, element.toXML().toString());
|
assertXMLEqual(xml, element.toXML().toString());
|
||||||
|
|
||||||
StanzaIdElement parsed = StanzaIdProvider.INSTANCE.parse(TestUtils.getParser(xml));
|
StanzaIdElement parsed = StanzaIdProvider.TEST_INSTANCE.parse(TestUtils.getParser(xml));
|
||||||
assertEquals(element.getId(), parsed.getId());
|
assertEquals(element.getId(), parsed.getId());
|
||||||
assertEquals(element.getBy(), parsed.getBy());
|
assertEquals(element.getBy(), parsed.getBy());
|
||||||
}
|
}
|
||||||
|
@ -55,7 +54,7 @@ public class StableUniqueStanzaIdTest extends SmackTestSuite {
|
||||||
assertEquals("de305d54-75b4-431b-adb2-eb6b9e546013", element.getId());
|
assertEquals("de305d54-75b4-431b-adb2-eb6b9e546013", element.getId());
|
||||||
assertXMLEqual(xml, element.toXML().toString());
|
assertXMLEqual(xml, element.toXML().toString());
|
||||||
|
|
||||||
OriginIdElement parsed = OriginIdProvider.INSTANCE.parse(TestUtils.getParser(xml));
|
OriginIdElement parsed = OriginIdProvider.TEST_INSTANCE.parse(TestUtils.getParser(xml));
|
||||||
assertEquals(element.getId(), parsed.getId());
|
assertEquals(element.getId(), parsed.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,17 +81,4 @@ public class StableUniqueStanzaIdTest extends SmackTestSuite {
|
||||||
assertTrue(StanzaIdElement.hasStanzaId(message));
|
assertTrue(StanzaIdElement.hasStanzaId(message));
|
||||||
assertEquals(stanzaId, StanzaIdElement.getStanzaId(message));
|
assertEquals(stanzaId, StanzaIdElement.getStanzaId(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultipleUssidExtensions() throws Exception {
|
|
||||||
String message = "<message xmlns='jabber:client' from='e4aec989-3e20-4846-83bf-f50df89b5d07@muclight.example.com/user1@example.com' to='user1@example.com' id='6b71fe3a-3cb2-489c-9c8e-b6879761d15e' type='groupchat'>" +
|
|
||||||
"<body>Test message</body>" +
|
|
||||||
"<markable xmlns='urn:xmpp:chat-markers:0'/>" +
|
|
||||||
"<stanza-id by='e4aec989-3e20-4846-83bf-f50df89b5d07@muclight.example.com' id='B0KK24ETVC81' xmlns='urn:xmpp:sid:0'/>" +
|
|
||||||
"<stanza-id by='user1@example.com' id='B0KK24EV89G1' xmlns='urn:xmpp:sid:0'/>" +
|
|
||||||
"</message>";
|
|
||||||
Message messageStanza = PacketParserUtils.parseStanza(message);
|
|
||||||
|
|
||||||
assertTrue(StanzaIdElement.hasStanzaId(messageStanza));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,10 +341,9 @@ public class MultiUserChat {
|
||||||
|
|
||||||
// Setup the messageListeners and presenceListeners *before* the join presence is send.
|
// Setup the messageListeners and presenceListeners *before* the join presence is send.
|
||||||
connection.addSyncStanzaListener(messageListener, fromRoomGroupchatFilter);
|
connection.addSyncStanzaListener(messageListener, fromRoomGroupchatFilter);
|
||||||
StanzaFilter presenceFromRoomFilter = new AndFilter(fromRoomFilter,
|
connection.addSyncStanzaListener(presenceListener, new AndFilter(fromRoomFilter,
|
||||||
StanzaTypeFilter.PRESENCE,
|
StanzaTypeFilter.PRESENCE,
|
||||||
PossibleFromTypeFilter.ENTITY_FULL_JID);
|
PossibleFromTypeFilter.ENTITY_FULL_JID));
|
||||||
connection.addSyncStanzaListener(presenceListener, presenceFromRoomFilter);
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
connection.addSyncStanzaListener(subjectListener,
|
connection.addSyncStanzaListener(subjectListener,
|
||||||
new AndFilter(fromRoomFilter,
|
new AndFilter(fromRoomFilter,
|
||||||
|
@ -373,27 +372,15 @@ public class MultiUserChat {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
StanzaCollector presenceStanzaCollector = null;
|
|
||||||
Presence presence;
|
Presence presence;
|
||||||
try {
|
try {
|
||||||
// This stanza collector will collect the final self presence from the MUC, which also signals that we have successful entered the MUC.
|
presence = connection.createStanzaCollectorAndSend(responseFilter, joinPresence).nextResultOrThrow(conf.getTimeout());
|
||||||
StanzaCollector selfPresenceCollector = connection.createStanzaCollectorAndSend(responseFilter, joinPresence);
|
|
||||||
StanzaCollector.Configuration presenceStanzaCollectorConfguration = StanzaCollector.newConfiguration().setCollectorToReset(
|
|
||||||
selfPresenceCollector).setStanzaFilter(presenceFromRoomFilter);
|
|
||||||
// This stanza collector is used to reset the timeout of the selfPresenceCollector.
|
|
||||||
presenceStanzaCollector = connection.createStanzaCollector(presenceStanzaCollectorConfguration);
|
|
||||||
presence = selfPresenceCollector.nextResultOrThrow(conf.getTimeout());
|
|
||||||
}
|
}
|
||||||
catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) {
|
catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) {
|
||||||
// Ensure that all callbacks are removed if there is an exception
|
// Ensure that all callbacks are removed if there is an exception
|
||||||
removeConnectionCallbacks();
|
removeConnectionCallbacks();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
if (presenceStanzaCollector != null) {
|
|
||||||
presenceStanzaCollector.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may
|
// This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may
|
||||||
// performed roomnick rewriting
|
// performed roomnick rewriting
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smack.util.dns.javax;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@ -41,7 +40,6 @@ import org.minidns.dnsname.DnsName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A DNS resolver (mostly for SRV records), which makes use of the API provided in the javax.* namespace.
|
* A DNS resolver (mostly for SRV records), which makes use of the API provided in the javax.* namespace.
|
||||||
* Note that using JavaxResovler requires applications using newer Java versions (at least 11) to declare a dependency on the "sun.jdk" module.
|
|
||||||
*
|
*
|
||||||
* @author Florian Schmaus
|
* @author Florian Schmaus
|
||||||
*
|
*
|
||||||
|
@ -53,9 +51,7 @@ public class JavaxResolver extends DNSResolver implements SmackInitializer {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
Hashtable<String, String> env = new Hashtable<>();
|
dirContext = new InitialDirContext();
|
||||||
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
|
|
||||||
dirContext = new InitialDirContext(env);
|
|
||||||
} catch (NamingException e) {
|
} catch (NamingException e) {
|
||||||
LOGGER.log(Level.SEVERE, "Could not construct InitialDirContext", e);
|
LOGGER.log(Level.SEVERE, "Could not construct InitialDirContext", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,15 +257,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*/
|
*/
|
||||||
private final Collection<StanzaListener> stanzaAcknowledgedListeners = new ConcurrentLinkedQueue<>();
|
private final Collection<StanzaListener> stanzaAcknowledgedListeners = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* These listeners are invoked for every stanza that got dropped.
|
|
||||||
* <p>
|
|
||||||
* We use a {@link ConcurrentLinkedQueue} here in order to allow the listeners to remove
|
|
||||||
* themselves after they have been invoked.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
private final Collection<StanzaListener> stanzaDroppedListeners = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This listeners are invoked for a acknowledged stanza that has the given stanza ID. They will
|
* This listeners are invoked for a acknowledged stanza that has the given stanza ID. They will
|
||||||
* only be invoked once and automatically removed after that.
|
* only be invoked once and automatically removed after that.
|
||||||
|
@ -430,24 +421,9 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Inform client about failed resumption if possible, resend stanzas otherwise
|
// (Re-)send the stanzas *after* we tried to enable SM
|
||||||
// Process the stanzas synchronously so a client can re-queue them for transmission
|
for (Stanza stanza : previouslyUnackedStanzas) {
|
||||||
// before it is informed about connection success
|
sendStanzaInternal(stanza);
|
||||||
if (!stanzaDroppedListeners.isEmpty()) {
|
|
||||||
for (Stanza stanza : previouslyUnackedStanzas) {
|
|
||||||
for (StanzaListener listener : stanzaDroppedListeners) {
|
|
||||||
try {
|
|
||||||
listener.processStanza(stanza);
|
|
||||||
}
|
|
||||||
catch (InterruptedException | NotConnectedException | NotLoggedInException e) {
|
|
||||||
LOGGER.log(Level.FINER, "StanzaDroppedListener received exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (Stanza stanza : previouslyUnackedStanzas) {
|
|
||||||
sendStanzaInternal(stanza);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afterSuccessfulLogin(false);
|
afterSuccessfulLogin(false);
|
||||||
|
@ -476,6 +452,9 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
shutdown(false);
|
shutdown(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an unclean disconnect and shutdown of the connection. Does not send a closing stream stanza.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void instantShutdown() {
|
public synchronized void instantShutdown() {
|
||||||
shutdown(true);
|
shutdown(true);
|
||||||
|
@ -513,8 +492,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// Reset the stream management session id to null, since if the stream is cleanly closed, i.e. sending a closing
|
// Reset the stream management session id to null, since if the stream is cleanly closed, i.e. sending a closing
|
||||||
// stream tag, there is no longer a stream to resume.
|
// stream tag, there is no longer a stream to resume.
|
||||||
smSessionId = null;
|
smSessionId = null;
|
||||||
// Note that we deliberately do not reset authenticatedConnectionInitiallyEstablishedTimestamp here, so that the
|
|
||||||
// information is available in the connectionClosedOnError() listeners.
|
|
||||||
}
|
}
|
||||||
authenticated = false;
|
authenticated = false;
|
||||||
connected = false;
|
connected = false;
|
||||||
|
@ -522,16 +499,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
reader = null;
|
reader = null;
|
||||||
writer = null;
|
writer = null;
|
||||||
|
|
||||||
initState();
|
|
||||||
|
|
||||||
// Wait for reader and writer threads to be terminated.
|
|
||||||
readerWriterSemaphore.acquireUninterruptibly(2);
|
|
||||||
readerWriterSemaphore.release(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initState() {
|
|
||||||
super.initState();
|
|
||||||
maybeCompressFeaturesReceived.init();
|
maybeCompressFeaturesReceived.init();
|
||||||
compressSyncPoint.init();
|
compressSyncPoint.init();
|
||||||
smResumedSyncPoint.init();
|
smResumedSyncPoint.init();
|
||||||
|
@ -817,13 +784,14 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void afterFeaturesReceived() throws NotConnectedException, InterruptedException, SecurityRequiredByServerException {
|
protected void afterFeaturesReceived() throws NotConnectedException, InterruptedException {
|
||||||
StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
|
StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
|
||||||
if (startTlsFeature != null) {
|
if (startTlsFeature != null) {
|
||||||
if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
|
if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
|
||||||
SecurityRequiredByServerException smackException = new SecurityRequiredByServerException();
|
SmackException smackException = new SecurityRequiredByServerException();
|
||||||
tlsHandled.reportFailure(smackException);
|
tlsHandled.reportFailure(smackException);
|
||||||
throw smackException;
|
notifyConnectionError(smackException);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
|
if (config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
|
||||||
|
@ -1094,11 +1062,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
LOGGER.info(XMPPTCPConnection.this
|
LOGGER.info(XMPPTCPConnection.this
|
||||||
+ " received closing </stream> element."
|
+ " received closing </stream> element."
|
||||||
+ " Server wants to terminate the connection, calling disconnect()");
|
+ " Server wants to terminate the connection, calling disconnect()");
|
||||||
ASYNC_BUT_ORDERED.performAsyncButOrdered(XMPPTCPConnection.this, new Runnable() {
|
disconnect();
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
disconnect();
|
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1603,32 +1567,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
stanzaAcknowledgedListeners.clear();
|
stanzaAcknowledgedListeners.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a Stanza dropped listener.
|
|
||||||
* <p>
|
|
||||||
* Those listeners will be invoked every time a Stanza has been dropped due to a failed SM resume. They will not get
|
|
||||||
* automatically removed. If at least one StanzaDroppedListener is configured, no attempt will be made to retransmit
|
|
||||||
* the Stanzas.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param listener the listener to add.
|
|
||||||
* @since 4.3.3
|
|
||||||
*/
|
|
||||||
public void addStanzaDroppedListener(StanzaListener listener) {
|
|
||||||
stanzaDroppedListeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the given Stanza dropped listener.
|
|
||||||
*
|
|
||||||
* @param listener the listener.
|
|
||||||
* @return true if the listener was removed.
|
|
||||||
* @since 4.3.3
|
|
||||||
*/
|
|
||||||
public boolean removeStanzaDroppedListener(StanzaListener listener) {
|
|
||||||
return stanzaDroppedListeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new Stanza ID acknowledged listener for the given ID.
|
* Add a new Stanza ID acknowledged listener for the given ID.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -2,12 +2,6 @@ allprojects {
|
||||||
ext {
|
ext {
|
||||||
shortVersion = '4.4.0-alpha2'
|
shortVersion = '4.4.0-alpha2'
|
||||||
isSnapshot = true
|
isSnapshot = true
|
||||||
// When using dynamic versions for those, do *not* use [1.0,
|
|
||||||
// 2.0), since this will also pull in 2.0-alpha1. Instead use
|
|
||||||
// [1.0, 1.0.99].
|
|
||||||
// See also:
|
|
||||||
// - https://issues.apache.org/jira/browse/MNG-6232
|
|
||||||
// - https://issues.igniterealtime.org/browse/SMACK-858
|
|
||||||
jxmppVersion = '0.7.0-alpha5'
|
jxmppVersion = '0.7.0-alpha5'
|
||||||
miniDnsVersion = '0.4.0-alpha3'
|
miniDnsVersion = '0.4.0-alpha3'
|
||||||
smackMinAndroidSdk = 19
|
smackMinAndroidSdk = 19
|
||||||
|
|
Loading…
Reference in a new issue