mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 00:02:06 +01:00
Add a setting for the used flush mode when compressing data
Fixes SMACK-593
This commit is contained in:
parent
4e588f7908
commit
c3f6c51d0e
3 changed files with 35 additions and 12 deletions
|
@ -58,7 +58,9 @@ public class JzlibInputOutputStream extends XMPPInputOutputStream {
|
||||||
@Override
|
@Override
|
||||||
public OutputStream getOutputStream(OutputStream outputStream) throws IOException {
|
public OutputStream getOutputStream(OutputStream outputStream) throws IOException {
|
||||||
final DeflaterOutputStream os = new DeflaterOutputStream(outputStream);
|
final DeflaterOutputStream os = new DeflaterOutputStream(outputStream);
|
||||||
os.setSyncFlush(true);
|
if (flushMethod == FlushMethod.SYNC_FLUSH) {
|
||||||
|
os.setSyncFlush(true);
|
||||||
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
|
||||||
private final static boolean supported;
|
private final static boolean supported;
|
||||||
private final static int compressionLevel = Deflater.DEFAULT_COMPRESSION;
|
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 {
|
static {
|
||||||
Method m = null;
|
Method m = null;
|
||||||
try {
|
try {
|
||||||
|
@ -100,25 +103,23 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream getOutputStream(OutputStream outputStream) {
|
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)) {
|
return new DeflaterOutputStream(outputStream, new Deflater(compressionLevel)) {
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
super.flush();
|
super.flush();
|
||||||
return;
|
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 {
|
try {
|
||||||
do {
|
int count;
|
||||||
count = (Integer) method.invoke(def, buf, 0, buf.length, 2);
|
while ((count = (Integer) method.invoke(def, buf, 0, buf.length, flushMethodInt)) != 0) {
|
||||||
out.write(buf, 0, count);
|
out.write(buf, 0, count);
|
||||||
} while (count > 0);
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IOException("Can't flush");
|
throw new IOException("Can't flush");
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
|
|
|
@ -20,6 +20,21 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public abstract class XMPPInputOutputStream {
|
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;
|
protected String compressionMethod;
|
||||||
|
|
||||||
public String getCompressionMethod() {
|
public String getCompressionMethod() {
|
||||||
|
@ -31,4 +46,9 @@ public abstract class XMPPInputOutputStream {
|
||||||
public abstract InputStream getInputStream(InputStream inputStream) throws Exception;
|
public abstract InputStream getInputStream(InputStream inputStream) throws Exception;
|
||||||
|
|
||||||
public abstract OutputStream getOutputStream(OutputStream outputStream) throws Exception;
|
public abstract OutputStream getOutputStream(OutputStream outputStream) throws Exception;
|
||||||
|
|
||||||
|
public enum FlushMethod {
|
||||||
|
FULL_FLUSH,
|
||||||
|
SYNC_FLUSH,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue