Skip to content

Commit

Permalink
Merge branch 'master' into serverless
Browse files Browse the repository at this point in the history
Conflicts:
	smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java
  • Loading branch information
Flowdalic committed Dec 2, 2014
2 parents 34e13e5 + af5363e commit 48bb3bd
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
*
* Copyright © 2014 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.smackx.caps;

public class CapsVersionAndHash {
public final String version;
public final String hash;

public CapsVersionAndHash(String version, String hash) {
this.version = version;
this.hash = hash;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.stringencoder.Base64;
import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache;
import org.jivesoftware.smackx.caps.packet.CapsExtension;
Expand All @@ -46,7 +47,6 @@
import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.util.cache.LruCache;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
Expand Down Expand Up @@ -78,8 +78,13 @@ public class EntityCapsManager extends Manager {
public static final String NAMESPACE = CapsExtension.NAMESPACE;
public static final String ELEMENT = CapsExtension.ELEMENT;

public static final String DEFAULT_HASH = "sha-1";
private static final Map<String, MessageDigest> SUPPORTED_HASHES = new HashMap<String, MessageDigest>();

/**
* The default hash. Currently 'sha-1'.
*/
private static final String DEFAULT_HASH = StringUtils.SHA1;

private static String DEFAULT_ENTITY_NODE = "http://www.igniterealtime.org/projects/smack";

protected static EntityCapsPersistentCache persistentCache;
Expand All @@ -96,7 +101,7 @@ public class EntityCapsManager extends Manager {
private static final PacketFilter PRESENCES = PacketTypeFilter.PRESENCE;

/**
* Map of (node + '#" + hash algorithm) to DiscoverInfo data
* Map of "node + '#' + hash" to DiscoverInfo data
*/
private static final LruCache<String, DiscoverInfo> CAPS_CACHE = new LruCache<String, DiscoverInfo>(1000);

Expand Down Expand Up @@ -131,7 +136,7 @@ public void connectionCreated(XMPPConnection connection) {
}

public interface CapsVerListener {
public void capsVerUpdated(String ver);
public void capsVerUpdated(CapsVersionAndHash capsVersionAndHash);
}

public static void addCapsVerListener(CapsVerListener capsVerListener) {
Expand All @@ -142,10 +147,6 @@ public static void removeCapsVerListener(CapsVerListener capsVerListener) {
capsVerListeners.remove(capsVerListener);
}

public static Collection<CapsVerListener> getCapsVerListeners() {
return Collections.unmodifiableCollection(capsVerListeners);
}

/**
* Set the default entity node that will be used for new EntityCapsManagers
*
Expand Down Expand Up @@ -275,12 +276,12 @@ private static void addCapsExtensionInfo(String from, CapsExtension capsExtensio
JID_TO_NODEVER_CACHE.put(from, new NodeVerHash(node, ver, hash));
}

private final Queue<String> lastLocalCapsVersions = new ConcurrentLinkedQueue<String>();
private final Queue<CapsVersionAndHash> lastLocalCapsVersions = new ConcurrentLinkedQueue<>();

private final ServiceDiscoveryManager sdm;

private boolean entityCapsEnabled;
private String currentCapsVersion;
private CapsVersionAndHash currentCapsVersion;
private boolean presenceSend = false;

/**
Expand Down Expand Up @@ -373,8 +374,8 @@ public void processPacket(Packet packet) {
public void processPacket(Packet packet) {
if (!entityCapsEnabled)
return;

CapsExtension caps = new CapsExtension(entityNode, getCapsVersion(), DEFAULT_HASH);
CapsVersionAndHash capsVersionAndHash = getCapsVersion();
CapsExtension caps = new CapsExtension(entityNode, capsVersionAndHash.version, capsVersionAndHash.hash);
packet.addExtension(caps);
}
};
Expand Down Expand Up @@ -447,7 +448,7 @@ public void addUserCapsNode(String user, String node, String ver) {
*
* @return our own caps version
*/
public String getCapsVersion() {
public CapsVersionAndHash getCapsVersion() {
return currentCapsVersion;
}

Expand Down Expand Up @@ -504,17 +505,16 @@ public void updateLocalEntityCaps() {
discoverInfo.setFrom(connection.getUser());
sdm.addDiscoverInfoTo(discoverInfo);

currentCapsVersion = generateVerificationString(discoverInfo, DEFAULT_HASH);
currentCapsVersion = generateVerificationString(discoverInfo);
addDiscoverInfoByNode(entityNode + '#' + currentCapsVersion, discoverInfo);
if (lastLocalCapsVersions.size() > 10) {
String oldCapsVersion = lastLocalCapsVersions.poll();
sdm.removeNodeInformationProvider(entityNode + '#' + oldCapsVersion);
CapsVersionAndHash oldCapsVersion = lastLocalCapsVersions.poll();
sdm.removeNodeInformationProvider(entityNode + '#' + oldCapsVersion.version);
}
lastLocalCapsVersions.add(currentCapsVersion);

CAPS_CACHE.put(currentCapsVersion, discoverInfo);
if (connection != null)
JID_TO_NODEVER_CACHE.put(connection.getUser(), new NodeVerHash(entityNode, currentCapsVersion, DEFAULT_HASH));
JID_TO_NODEVER_CACHE.put(connection.getUser(), new NodeVerHash(entityNode, currentCapsVersion));

final List<Identity> identities = new LinkedList<Identity>(ServiceDiscoveryManager.getInstanceFor(connection).getIdentities());
sdm.setNodeInformationProvider(entityNode + '#' + currentCapsVersion, new AbstractNodeInformationProvider() {
Expand Down Expand Up @@ -549,7 +549,7 @@ public List<PacketExtension> getNodePacketExtensions() {
}
}

for (CapsVerListener listener : getCapsVerListeners()) {
for (CapsVerListener listener : capsVerListeners) {
listener.capsVerUpdated(currentCapsVersion);
}
}
Expand Down Expand Up @@ -579,7 +579,7 @@ public static boolean verifyDiscoverInfoVersion(String ver, String hash, Discove
if (verifyPacketExtensions(info))
return false;

String calculatedVer = generateVerificationString(info, hash);
String calculatedVer = generateVerificationString(info, hash).version;

if (!ver.equals(calculatedVer))
return false;
Expand Down Expand Up @@ -611,6 +611,10 @@ protected static boolean verifyPacketExtensions(DiscoverInfo info) {
return false;
}

protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo) {
return generateVerificationString(discoverInfo, null);
}

/**
* Generates a XEP-115 Verification String
*
Expand All @@ -619,11 +623,14 @@ protected static boolean verifyPacketExtensions(DiscoverInfo info) {
*
* @param discoverInfo
* @param hash
* the used hash function
* the used hash function, if null, default hash will be used
* @return The generated verification String or null if the hash is not
* supported
*/
protected static String generateVerificationString(DiscoverInfo discoverInfo, String hash) {
protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo, String hash) {
if (hash == null) {
hash = DEFAULT_HASH;
}
MessageDigest md = SUPPORTED_HASHES.get(hash.toLowerCase(Locale.US));
if (md == null)
return null;
Expand Down Expand Up @@ -726,7 +733,8 @@ public int compare(FormField f1, FormField f2) {
synchronized(md) {
digest = md.digest(sb.toString().getBytes());
}
return Base64.encodeToString(digest);
String version = Base64.encodeToString(digest);
return new CapsVersionAndHash(version, hash);
}

private static void formFieldValuesToCaps(List<String> i, StringBuilder sb) {
Expand All @@ -746,6 +754,10 @@ public static class NodeVerHash {
private String ver;
private String nodeVer;

NodeVerHash(String node, CapsVersionAndHash capsVersionAndHash) {
this(node, capsVersionAndHash.version, capsVersionAndHash.hash);
}

NodeVerHash(String node, String ver, String hash) {
this.node = node;
this.ver = ver;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@

/**
* A XEP-0115 Entity Capabilities extension.
* <p>
* Note that this is currently in smack-core as it's a potential stream feature.
* TODO: In feature versions of Smack, it should be possible to register
* "providers" for stream features too, so that this class can be moved back to
* smack-extensions.
* </p>
*/
public class CapsExtension implements PacketExtension {
public static final String NAMESPACE = "http://jabber.org/protocol/caps";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public void initSmackTestSuite() {
public void testComplexGenerationExample() {
DiscoverInfo di = createComplexSamplePacket();

String ver = EntityCapsManager.generateVerificationString(di, "sha-1");
assertEquals("q07IKJEyjvHSyhy//CH0CxmKi8w=", ver);
CapsVersionAndHash versionAndHash = EntityCapsManager.generateVerificationString(di, "sha-1");
assertEquals("q07IKJEyjvHSyhy//CH0CxmKi8w=", versionAndHash.version);
}

@Test
Expand All @@ -82,7 +82,7 @@ private void testSimpleDirectoryCache(StringEncoder stringEncoder) throws IOExce
EntityCapsManager.setPersistentCache(cache);

DiscoverInfo di = createComplexSamplePacket();
String nodeVer = di.getNode() + "#" + EntityCapsManager.generateVerificationString(di, "sha-1");
String nodeVer = di.getNode() + "#" + EntityCapsManager.generateVerificationString(di, "sha-1").version;

// Save the data in EntityCapsManager
EntityCapsManager.addDiscoverInfoByNode(nodeVer, di);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.jivesoftware.smack.serverless.service.LLServiceStateListener;
import org.jivesoftware.smackx.disco.NodeInformationProvider;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.caps.CapsVersionAndHash;
import org.jivesoftware.smackx.caps.EntityCapsManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems;
Expand Down Expand Up @@ -548,13 +549,13 @@ public void connectionCreated(XMPPLLConnection connection) {
}

private class CapsPresenceRenewer implements EntityCapsManager.CapsVerListener {
public void capsVerUpdated(String ver) {
public void capsVerUpdated(CapsVersionAndHash versionAndHash) {
synchronized (service) {
try {
LLPresence presence = service.getLocalPresence();
presence.setHash(EntityCapsManager.DEFAULT_HASH);
presence.setNode(capsManager.getEntityNode());
presence.setVer(ver);
presence.setVer(versionAndHash.version);
presence.setHash(versionAndHash.hash);
service.updateLocalPresence(presence);
}
catch (XMPPException xe) {
Expand Down

0 comments on commit 48bb3bd

Please sign in to comment.