mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-22 20:47:57 +01:00
Merge branch '4.0'
Also slightly improve OfflineMessageManager.getMessages() Conflicts: build.gradle smack-extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java
This commit is contained in:
commit
92a6d01507
12 changed files with 123 additions and 46 deletions
|
@ -26,6 +26,7 @@ allprojects {
|
|||
}
|
||||
group = 'org.igniterealtime.smack'
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = sourceCompatibility
|
||||
version = shortVersion
|
||||
if (isSnapshot) {
|
||||
version += '-SNAPSHOT'
|
||||
|
@ -97,7 +98,7 @@ import org.apache.tools.ant.filters.ReplaceTokens
|
|||
task prepareReleasedocs(type: Copy) {
|
||||
from 'resources/releasedocs'
|
||||
into releasedocsDir
|
||||
filter(ReplaceTokens, tokens: [version: version, releasedate: buildDate])
|
||||
filter(ReplaceTokens, tokens: [version: version, releasedate: buildDate, targetCompatibility: targetCompatibility.toString()])
|
||||
}
|
||||
|
||||
task distributionZip(type: Zip, dependsOn: [javadocAll, prepareReleasedocs]) {
|
||||
|
|
|
@ -23,10 +23,8 @@ important classes and concepts.
|
|||
JAR Files and Requirements
|
||||
</p>
|
||||
|
||||
Smack is meant to be easily embedded into any existing JDK 1.5 or later Java application.
|
||||
It has no external dependencies (except for the Jingle voice chat functionality) and is optimized
|
||||
to be as small as possible. The library ships as several JAR files to provide more flexibility
|
||||
over which features applications require:
|
||||
Smack is meant to be easily embedded into any existing Java application.
|
||||
The library ships as several JAR files to provide more flexibility over which features applications require:
|
||||
|
||||
<ul>
|
||||
<li><tt>smack-core.jar</tt> -- provides core XMPP functionality. All XMPP features that are
|
||||
|
|
|
@ -154,18 +154,27 @@ hr {
|
|||
</table>
|
||||
|
||||
<p>
|
||||
Thank you for downloading Smack!
|
||||
<p>
|
||||
Thank you for downloading Smack! This version of Smack is compatible
|
||||
with JVMs @targetCompatibility@ or higher. If you dont' use a
|
||||
dependency resolution system, like gradle or maven, then you will need
|
||||
to download at least
|
||||
the <a href="http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1/">Xml
|
||||
Pull Parser 3rd Edition (XPP3) library</a> or any other library that
|
||||
implements the XmlPullParser interface
|
||||
(like <a href="http://kxml.org/">kXML</a>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Start off by viewing the <a href="documentation/index.html">documentation</a>
|
||||
that can be found in the "documentation" directory included with this distribution.
|
||||
<p>
|
||||
</p>
|
||||
Further information can be found on the <a href="http://www.igniterealtime.org/projects/smack">
|
||||
Smack website</a>. If you need help using or would like to make contributions or
|
||||
fixes to the code, please visit the
|
||||
<a href="https://community.igniterealtime.org">online forum</a>.
|
||||
|
||||
<p><b>About the Distribution</b><p>
|
||||
</p>
|
||||
|
||||
<p><b>About the Distribution</b></p>
|
||||
|
||||
The <tt>smack-core.jar</tt> file in the main distribution folder. The optional
|
||||
<tt>smack-extensions.jar</tt> contains the <a href="documentation/extensions/index.html">Smack extensions</a>
|
||||
|
|
|
@ -58,7 +58,9 @@ public class JzlibInputOutputStream extends XMPPInputOutputStream {
|
|||
@Override
|
||||
public OutputStream getOutputStream(OutputStream outputStream) throws IOException {
|
||||
final DeflaterOutputStream os = new DeflaterOutputStream(outputStream);
|
||||
os.setSyncFlush(true);
|
||||
if (flushMethod == FlushMethod.SYNC_FLUSH) {
|
||||
os.setSyncFlush(true);
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.jivesoftware.smack;
|
|||
import org.jivesoftware.smack.packet.Session;
|
||||
import org.jivesoftware.smack.proxy.ProxyInfo;
|
||||
import org.jivesoftware.smack.util.DNSUtil;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.dns.HostAddress;
|
||||
import org.jxmpp.util.XmppStringUtils;
|
||||
|
||||
|
@ -191,6 +192,9 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
}
|
||||
|
||||
protected void init(String serviceName, ProxyInfo proxy) {
|
||||
if (StringUtils.isEmpty(serviceName)) {
|
||||
throw new IllegalArgumentException("serviceName must not be the empty String");
|
||||
}
|
||||
this.serviceName = serviceName;
|
||||
this.proxy = proxy;
|
||||
|
||||
|
@ -645,6 +649,9 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
}
|
||||
|
||||
private void initHostAddresses(String host, int port) {
|
||||
if (StringUtils.isEmpty(host)) {
|
||||
throw new IllegalArgumentException("host must not be the empty String");
|
||||
}
|
||||
hostAddresses = new ArrayList<HostAddress>(1);
|
||||
HostAddress hostAddress;
|
||||
hostAddress = new HostAddress(host, port);
|
||||
|
|
|
@ -48,6 +48,9 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
|
|||
private final static boolean supported;
|
||||
private final static int compressionLevel = Deflater.DEFAULT_COMPRESSION;
|
||||
|
||||
private static final int SYNC_FLUSH_INT = 2;
|
||||
private static final int FULL_FLUSH_INT = 3;
|
||||
|
||||
static {
|
||||
Method m = null;
|
||||
try {
|
||||
|
@ -100,25 +103,23 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
|
|||
|
||||
@Override
|
||||
public OutputStream getOutputStream(OutputStream outputStream) {
|
||||
final int flushMethodInt;
|
||||
if (flushMethod == FlushMethod.SYNC_FLUSH) {
|
||||
flushMethodInt = SYNC_FLUSH_INT;
|
||||
} else {
|
||||
flushMethodInt = FULL_FLUSH_INT;
|
||||
}
|
||||
return new DeflaterOutputStream(outputStream, new Deflater(compressionLevel)) {
|
||||
public void flush() throws IOException {
|
||||
if (!supported) {
|
||||
super.flush();
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
if (!def.needsInput()) {
|
||||
do {
|
||||
count = def.deflate(buf, 0, buf.length);
|
||||
out.write(buf, 0, count);
|
||||
} while (count > 0);
|
||||
out.flush();
|
||||
}
|
||||
try {
|
||||
do {
|
||||
count = (Integer) method.invoke(def, buf, 0, buf.length, 2);
|
||||
int count;
|
||||
while ((count = (Integer) method.invoke(def, buf, 0, buf.length, flushMethodInt)) != 0) {
|
||||
out.write(buf, 0, count);
|
||||
} while (count > 0);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException("Can't flush");
|
||||
} catch (IllegalAccessException e) {
|
||||
|
|
|
@ -20,6 +20,21 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
|
||||
public abstract class XMPPInputOutputStream {
|
||||
|
||||
protected static FlushMethod flushMethod;
|
||||
|
||||
/**
|
||||
* Set the used flushed method when compressing data. The default is full flush which may not
|
||||
* achieve the best compression ratio, but provides better security against certain attacks.
|
||||
* Only use sync flush if you fully understand the implications.
|
||||
*
|
||||
* @see <a href="https://blog.thijsalkema.de/blog/2014/08/07/https-attacks-and-xmpp-2-crime-and-breach/">Attacks against XMPP when using compression</a>
|
||||
* @param flushMethod
|
||||
*/
|
||||
public static void setFlushMethod(FlushMethod flushMethod) {
|
||||
XMPPInputOutputStream.flushMethod = flushMethod;
|
||||
}
|
||||
|
||||
protected String compressionMethod;
|
||||
|
||||
public String getCompressionMethod() {
|
||||
|
@ -31,4 +46,9 @@ public abstract class XMPPInputOutputStream {
|
|||
public abstract InputStream getInputStream(InputStream inputStream) throws Exception;
|
||||
|
||||
public abstract OutputStream getOutputStream(OutputStream outputStream) throws Exception;
|
||||
|
||||
public enum FlushMethod {
|
||||
FULL_FLUSH,
|
||||
SYNC_FLUSH,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,13 +279,23 @@ public class StringUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given CharSequence is not null or empty.
|
||||
* Returns true if the given CharSequence is null or empty.
|
||||
*
|
||||
* @param cs
|
||||
* @return true if the given CharSequence is not null or empty
|
||||
* @return true if the given CharSequence is null or empty
|
||||
*/
|
||||
public static boolean isNullOrEmpty(CharSequence cs) {
|
||||
return cs == null || cs.length() == 0;
|
||||
return cs == null || isEmpty(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given CharSequence is empty
|
||||
*
|
||||
* @param cs
|
||||
* @return true if the given CharSequence is empty
|
||||
*/
|
||||
public static boolean isEmpty(CharSequence cs) {
|
||||
return cs.length() == 0;
|
||||
}
|
||||
|
||||
public static String collectionToString(Collection<String> collection) {
|
||||
|
|
|
@ -73,7 +73,12 @@ public class Socks5Proxy {
|
|||
private static Socks5Proxy socks5Server;
|
||||
|
||||
private static boolean localSocks5ProxyEnabled = true;
|
||||
private static int localSocks5ProxyPort = 7777;
|
||||
|
||||
/**
|
||||
* The port of the local Socks5 Proxy. If this value is negative, the next ports will be tried
|
||||
* until a unused is found.
|
||||
*/
|
||||
private static int localSocks5ProxyPort = -7777;
|
||||
|
||||
/* reusable implementation of a SOCKS5 proxy server process */
|
||||
private Socks5ServerProcess serverProcess;
|
||||
|
@ -142,6 +147,9 @@ public class Socks5Proxy {
|
|||
* @param localSocks5ProxyPort the port of the local Socks5 proxy to set
|
||||
*/
|
||||
public static void setLocalSocks5ProxyPort(int localSocks5ProxyPort) {
|
||||
if (Math.abs(localSocks5ProxyPort) > 65535) {
|
||||
throw new IllegalArgumentException("localSocks5ProxyPort must be within (-65535,65535)");
|
||||
}
|
||||
Socks5Proxy.localSocks5ProxyPort = localSocks5ProxyPort;
|
||||
}
|
||||
|
||||
|
|
|
@ -154,20 +154,24 @@ public class OfflineMessageManager {
|
|||
}
|
||||
});
|
||||
PacketCollector messageCollector = connection.createPacketCollector(messageFilter);
|
||||
connection.createPacketCollectorAndSend(request).nextResultOrThrow();
|
||||
// Collect the received offline messages
|
||||
Message message = (Message) messageCollector.nextResult();
|
||||
while (message != null) {
|
||||
messages.add(message);
|
||||
message = (Message) messageCollector.nextResult();
|
||||
try {
|
||||
connection.createPacketCollectorAndSend(request).nextResultOrThrow();
|
||||
// Collect the received offline messages
|
||||
Message message = (Message) messageCollector.nextResult();
|
||||
while (message != null) {
|
||||
messages.add(message);
|
||||
message = (Message) messageCollector.nextResult();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Stop queuing offline messages
|
||||
messageCollector.cancel();
|
||||
}
|
||||
// Stop queuing offline messages
|
||||
messageCollector.cancel();
|
||||
return messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator with all the offline <tt>Messages</tt> of the user. The returned offline
|
||||
* Returns a List of Messages with all the offline <tt>Messages</tt> of the user. The returned offline
|
||||
* messages will not be deleted from the server. Use {@link #deleteMessages(java.util.List)}
|
||||
* to delete the messages.
|
||||
*
|
||||
|
@ -181,17 +185,23 @@ public class OfflineMessageManager {
|
|||
List<Message> messages = new ArrayList<Message>();
|
||||
OfflineMessageRequest request = new OfflineMessageRequest();
|
||||
request.setFetch(true);
|
||||
connection.createPacketCollectorAndSend(request).nextResultOrThrow();
|
||||
|
||||
PacketCollector messageCollector = connection.createPacketCollector(PACKET_FILTER);
|
||||
// Collect the received offline messages
|
||||
Message message = (Message) messageCollector.nextResult();
|
||||
while (message != null) {
|
||||
messages.add(message);
|
||||
message = (Message) messageCollector.nextResult();
|
||||
PacketCollector resultCollector = connection.createPacketCollectorAndSend(request);
|
||||
|
||||
try {
|
||||
// Collect the received offline messages
|
||||
Message message = (Message) messageCollector.nextResult();
|
||||
while (message != null) {
|
||||
messages.add(message);
|
||||
message = (Message) messageCollector.nextResult();
|
||||
}
|
||||
resultCollector.nextResultOrThrow();
|
||||
}
|
||||
finally {
|
||||
messageCollector.cancel();
|
||||
resultCollector.cancel();
|
||||
}
|
||||
// Stop queuing offline messages
|
||||
messageCollector.cancel();
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
|
|
@ -577,12 +577,23 @@ public class ConfigureForm extends Form
|
|||
* Determines if subscriptions are allowed.
|
||||
*
|
||||
* @return true if subscriptions are allowed, false otherwise
|
||||
* @deprecated use {@link #isSubscribe()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isSubscibe()
|
||||
{
|
||||
return parseBoolean(getFieldValue(ConfigureNodeFields.subscribe));
|
||||
return isSubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if subscriptions are allowed.
|
||||
*
|
||||
* @return true if subscriptions are allowed, false otherwise
|
||||
*/
|
||||
public boolean isSubscribe() {
|
||||
return parseBoolean(getFieldValue(ConfigureNodeFields.subscribe));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether subscriptions are allowed.
|
||||
*
|
||||
|
|
|
@ -313,7 +313,7 @@ public class FormField {
|
|||
*/
|
||||
public static class Option {
|
||||
|
||||
public static final String ELEMNT = "option";
|
||||
public static final String ELEMENT = "option";
|
||||
|
||||
private final String value;
|
||||
private String label;
|
||||
|
@ -352,7 +352,7 @@ public class FormField {
|
|||
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(ELEMNT);
|
||||
xml.halfOpenElement(ELEMENT);
|
||||
// Add attribute
|
||||
xml.optAttribute("label", getLabel());
|
||||
xml.rightAngelBracket();
|
||||
|
|
Loading…
Reference in a new issue