cleanup: removed stream compression
This commit is contained in:
parent
5acd471880
commit
9d52f62767
|
@ -1,54 +0,0 @@
|
||||||
package eu.siacs.conversations.utils.zlib;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.zip.Inflater;
|
|
||||||
import java.util.zip.InflaterInputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZLibInputStream is a zlib and input stream compatible version of an
|
|
||||||
* InflaterInputStream. This class solves the incompatibility between
|
|
||||||
* {@link InputStream#available()} and {@link InflaterInputStream#available()}.
|
|
||||||
*/
|
|
||||||
public class ZLibInputStream extends InflaterInputStream {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a ZLibInputStream, reading data from the underlying stream.
|
|
||||||
*
|
|
||||||
* @param is
|
|
||||||
* The {@code InputStream} to read data from.
|
|
||||||
* @throws IOException
|
|
||||||
* If an {@code IOException} occurs.
|
|
||||||
*/
|
|
||||||
public ZLibInputStream(InputStream is) throws IOException {
|
|
||||||
super(is, new Inflater(), 512);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a more InputStream compatible version of available. A return
|
|
||||||
* value of 1 means that it is likly to read one byte without blocking, 0
|
|
||||||
* means that the system is known to block for more input.
|
|
||||||
*
|
|
||||||
* @return 0 if no data is available, 1 otherwise
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int available() throws IOException {
|
|
||||||
/*
|
|
||||||
* This is one of the funny code blocks. InflaterInputStream.available
|
|
||||||
* violates the contract of InputStream.available, which breaks kXML2.
|
|
||||||
*
|
|
||||||
* I'm not sure who's to blame, oracle/sun for a broken api or the
|
|
||||||
* google guys for mixing a sun bug with a xml reader that can't handle
|
|
||||||
* it....
|
|
||||||
*
|
|
||||||
* Anyway, this simple if breaks suns distorted reality, but helps to
|
|
||||||
* use the api as intended.
|
|
||||||
*/
|
|
||||||
if (inf.needsInput()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return super.available();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package eu.siacs.conversations.utils.zlib;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.zip.Deflater;
|
|
||||||
import java.util.zip.DeflaterOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Android 2.2 includes Java7 FLUSH_SYNC option, which will be used by this
|
|
||||||
* Implementation, preferable via reflection. The @hide was remove in API level
|
|
||||||
* 19. This class might thus go away in the future.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Please use {@link ZLibOutputStream#SUPPORTED} to check for flush
|
|
||||||
* compatibility.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class ZLibOutputStream extends DeflaterOutputStream {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The reflection based flush method.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private final static Method method;
|
|
||||||
/**
|
|
||||||
* SUPPORTED is true if a flush compatible method exists.
|
|
||||||
*/
|
|
||||||
public final static boolean SUPPORTED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static block to initialize {@link #SUPPORTED} and {@link #method}.
|
|
||||||
*/
|
|
||||||
static {
|
|
||||||
Method m = null;
|
|
||||||
try {
|
|
||||||
m = Deflater.class.getMethod("deflate", byte[].class, int.class,
|
|
||||||
int.class, int.class);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
}
|
|
||||||
method = m;
|
|
||||||
SUPPORTED = (method != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new ZLib compatible output stream wrapping the given low level
|
|
||||||
* stream. ZLib compatiblity means we will send a zlib header.
|
|
||||||
*
|
|
||||||
* @param os
|
|
||||||
* OutputStream The underlying stream.
|
|
||||||
* @throws IOException
|
|
||||||
* In case of a lowlevel transfer problem.
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
* In case of a {@link Deflater} error.
|
|
||||||
*/
|
|
||||||
public ZLibOutputStream(OutputStream os) throws IOException,
|
|
||||||
NoSuchAlgorithmException {
|
|
||||||
super(os, new Deflater(Deflater.BEST_COMPRESSION));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the given stream, preferring Java7 FLUSH_SYNC if available.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* In case of a lowlevel exception.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void flush() throws IOException {
|
|
||||||
if (!SUPPORTED) {
|
|
||||||
super.flush();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
int count = 0;
|
|
||||||
do {
|
|
||||||
count = (Integer) method.invoke(def, buf, 0, buf.length, 3);
|
|
||||||
if (count > 0) {
|
|
||||||
out.write(buf, 0, count);
|
|
||||||
}
|
|
||||||
} while (count > 0);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw new IOException("Can't flush");
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new IOException("Can't flush");
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
throw new IOException("Can't flush");
|
|
||||||
}
|
|
||||||
super.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -50,8 +50,6 @@ import eu.siacs.conversations.crypto.sasl.ScramSha1;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.DNSHelper;
|
import eu.siacs.conversations.utils.DNSHelper;
|
||||||
import eu.siacs.conversations.utils.zlib.ZLibInputStream;
|
|
||||||
import eu.siacs.conversations.utils.zlib.ZLibOutputStream;
|
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xml.Tag;
|
import eu.siacs.conversations.xml.Tag;
|
||||||
import eu.siacs.conversations.xml.TagWriter;
|
import eu.siacs.conversations.xml.TagWriter;
|
||||||
|
@ -92,7 +90,6 @@ public class XmppConnection implements Runnable {
|
||||||
private int smVersion = 3;
|
private int smVersion = 3;
|
||||||
private SparseArray<String> messageReceipts = new SparseArray<>();
|
private SparseArray<String> messageReceipts = new SparseArray<>();
|
||||||
|
|
||||||
private boolean enabledCompression = false;
|
|
||||||
private boolean enabledEncryption = false;
|
private boolean enabledEncryption = false;
|
||||||
private boolean enabledCarbons = false;
|
private boolean enabledCarbons = false;
|
||||||
|
|
||||||
|
@ -144,7 +141,6 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
protected void connect() {
|
protected void connect() {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting");
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting");
|
||||||
enabledCompression = false;
|
|
||||||
enabledEncryption = false;
|
enabledEncryption = false;
|
||||||
lastConnect = SystemClock.elapsedRealtime();
|
lastConnect = SystemClock.elapsedRealtime();
|
||||||
lastPingSent = SystemClock.elapsedRealtime();
|
lastPingSent = SystemClock.elapsedRealtime();
|
||||||
|
@ -261,8 +257,6 @@ public class XmppConnection implements Runnable {
|
||||||
processStreamFeatures(nextTag);
|
processStreamFeatures(nextTag);
|
||||||
} else if (nextTag.isStart("proceed")) {
|
} else if (nextTag.isStart("proceed")) {
|
||||||
switchOverToTls(nextTag);
|
switchOverToTls(nextTag);
|
||||||
} else if (nextTag.isStart("compressed")) {
|
|
||||||
switchOverToZLib(nextTag);
|
|
||||||
} else if (nextTag.isStart("success")) {
|
} else if (nextTag.isStart("success")) {
|
||||||
final String challenge = tagReader.readElement(nextTag).getContent();
|
final String challenge = tagReader.readElement(nextTag).getContent();
|
||||||
try {
|
try {
|
||||||
|
@ -498,28 +492,6 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendCompressionZlib() throws IOException {
|
|
||||||
Element compress = new Element("compress");
|
|
||||||
compress.setAttribute("xmlns", "http://jabber.org/protocol/compress");
|
|
||||||
compress.addChild("method").setContent("zlib");
|
|
||||||
tagWriter.writeElement(compress);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void switchOverToZLib(final Tag currentTag)
|
|
||||||
throws XmlPullParserException, IOException,
|
|
||||||
NoSuchAlgorithmException {
|
|
||||||
tagReader.readTag(); // read tag close
|
|
||||||
tagWriter.setOutputStream(new ZLibOutputStream(tagWriter
|
|
||||||
.getOutputStream()));
|
|
||||||
tagReader
|
|
||||||
.setInputStream(new ZLibInputStream(tagReader.getInputStream()));
|
|
||||||
|
|
||||||
sendStartStream();
|
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": compression enabled");
|
|
||||||
enabledCompression = true;
|
|
||||||
processStream(tagReader.readTag());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendStartTLS() throws IOException {
|
private void sendStartTLS() throws IOException {
|
||||||
Tag startTLS = Tag.empty("starttls");
|
Tag startTLS = Tag.empty("starttls");
|
||||||
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
|
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
|
||||||
|
@ -601,8 +573,6 @@ public class XmppConnection implements Runnable {
|
||||||
this.streamFeatures = tagReader.readElement(currentTag);
|
this.streamFeatures = tagReader.readElement(currentTag);
|
||||||
if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) {
|
if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) {
|
||||||
sendStartTLS();
|
sendStartTLS();
|
||||||
} else if (compressionAvailable()) {
|
|
||||||
sendCompressionZlib();
|
|
||||||
} else if (this.streamFeatures.hasChild("register")
|
} else if (this.streamFeatures.hasChild("register")
|
||||||
&& account.isOptionSet(Account.OPTION_REGISTER)
|
&& account.isOptionSet(Account.OPTION_REGISTER)
|
||||||
&& enabledEncryption) {
|
&& enabledEncryption) {
|
||||||
|
@ -658,28 +628,6 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean compressionAvailable() {
|
|
||||||
if (!this.streamFeatures.hasChild("compression",
|
|
||||||
"http://jabber.org/features/compress"))
|
|
||||||
return false;
|
|
||||||
if (!ZLibOutputStream.SUPPORTED)
|
|
||||||
return false;
|
|
||||||
if (!account.isOptionSet(Account.OPTION_USECOMPRESSION))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Element compression = this.streamFeatures.findChild("compression",
|
|
||||||
"http://jabber.org/features/compress");
|
|
||||||
for (Element child : compression.getChildren()) {
|
|
||||||
if (!"method".equals(child.getName()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ("zlib".equalsIgnoreCase(child.getContent())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> extractMechanisms(Element stream) {
|
private List<String> extractMechanisms(Element stream) {
|
||||||
ArrayList<String> mechanisms = new ArrayList<>(stream
|
ArrayList<String> mechanisms = new ArrayList<>(stream
|
||||||
.getChildren().size());
|
.getChildren().size());
|
||||||
|
@ -1147,9 +1095,5 @@ public class XmppConnection implements Runnable {
|
||||||
return connection
|
return connection
|
||||||
.findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
|
.findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean compression() {
|
|
||||||
return connection.enabledCompression;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue