Commit fa6beb91 authored by Guus der Kinderen's avatar Guus der Kinderen Committed by daryl herzmann

OF-210: Additional work. (#923)

* Support for Roster Versioning (without send the modifications via roster pushes)

* Roster versioning comparison clearing

* Implementation Note: This empty IQ-result is different from an empty <query/> element, thus disambiguating this usage from an empty roster.

* Avoid cache miss while updating roster

When the roster is updated via group renaming, group user adding or removing, the roster pushes only happen if there is a cache hit. If there is a cache miss (what can happen if the cache is full or if the admin cleaned up the cache) the user is not properly notified about the roster update. Thus only update rosters in memory can lead to this undesired behavior.

This commit avoids the use of the cache directly (where there can be a cache miss or a cache hit). It is using the method getRoster(username) that instantiante a new Roster in the case of a cache miss.

* Clarify the code

* OF-210: Base roster version on its hashCode.

This commit removes all fields from the Roster class that do not relate to its state
(replacing them with method variables - which seems harmless, as they're all final
singletons). This allows for an easy override of Object#hashCode() and equals().
These, in turn, are used to calculate the roster version from.

* Simplified loop

* Prevent potential NPEs.

* Log exceptions for exceptions that cannot happen.

If they cannot happen, we should scream murder if they do...

* OF-210: Roster versioning enabled by default.
parent 1494c6b2
......@@ -182,7 +182,23 @@ public class IQRosterHandler extends IQHandler implements ServerFeaturesProvider
Roster cachedRoster = userManager.getUser(sender.getNode()).getRoster();
if (IQ.Type.get == type) {
returnPacket = cachedRoster.getReset();
if (RosterManager.isRosterVersioningEnabled()) {
String clientVersion = packet.getChildElement().attributeValue("ver");
String latestVersion = String.valueOf( cachedRoster.hashCode() );
// Whether or not the roster has been modified since the version ID enumerated by the client, ...
if (!latestVersion.equals(clientVersion)) {
// ... the server MUST either return the complete roster
// (including a 'ver' attribute that signals the latest version)
returnPacket = cachedRoster.getReset();
returnPacket.getChildElement().addAttribute("ver", latestVersion );
} else {
// ... or return an empty IQ-result
returnPacket = new org.xmpp.packet.IQ();
}
} else {
returnPacket = cachedRoster.getReset();
}
returnPacket.setType(IQ.Type.result);
returnPacket.setTo(sender);
returnPacket.setID(packet.getID());
......@@ -343,4 +359,4 @@ public class IQRosterHandler extends IQHandler implements ServerFeaturesProvider
public Iterator<String> getFeatures() {
return Collections.singleton("jabber:iq:roster").iterator();
}
}
\ No newline at end of file
}
......@@ -29,6 +29,7 @@ import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.privacy.PrivacyList;
import org.jivesoftware.openfire.privacy.PrivacyListManager;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.spi.ConnectionConfiguration;
import org.jivesoftware.openfire.streammanagement.StreamManager;
import org.jivesoftware.openfire.user.PresenceEventDispatcher;
......@@ -877,6 +878,12 @@ public class LocalClientSession extends LocalSession implements ClientSession {
"<compression xmlns=\"http://jabber.org/features/compress\"><method>zlib</method></compression>");
}
// If a server supports roster versioning,
// then it MUST advertise the following stream feature during stream negotiation.
if (RosterManager.isRosterVersioningEnabled()) {
sb.append("<ver xmlns=\"urn:xmpp:features:rosterver\"/>");
}
if (getAuthToken() == null) {
// Advertise that the server supports Non-SASL Authentication
if ( XMPPServer.getInstance().getIQRouter().supports( "jabber:iq:auth" ) ) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment