mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 22:32:06 +01:00
Improve stream compression for TCP connections
Fix a race condition in useCompression where the compression request was send outside the synchronized block, this could cause notify() to be called without a previoius call to wait(). s/streamCompressionDenied/streamCompressionNegotiationDone/ and re-use the method once the server ack'd stream compression. Also don't call notifyConnectionError() when requestStreamCompression() encounters an exception, instead throw the exception.
This commit is contained in:
parent
9b235d0d8f
commit
d17f64ed9a
2 changed files with 16 additions and 21 deletions
|
@ -231,7 +231,7 @@ class PacketReader {
|
||||||
// Stream compression has been denied. This is a recoverable
|
// Stream compression has been denied. This is a recoverable
|
||||||
// situation. It is still possible to authenticate and
|
// situation. It is still possible to authenticate and
|
||||||
// use the connection but using an uncompressed connection
|
// use the connection but using an uncompressed connection
|
||||||
connection.streamCompressionDenied();
|
connection.streamCompressionNegotiationDone();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// SASL authentication has failed. The server may close the connection
|
// SASL authentication has failed. The server may close the connection
|
||||||
|
|
|
@ -776,8 +776,9 @@ public class XMPPTCPConnection extends XMPPConnection {
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @return true if stream compression negotiation was successful.
|
* @return true if stream compression negotiation was successful.
|
||||||
|
* @throws IOException if the compress stanza could not be send
|
||||||
*/
|
*/
|
||||||
private boolean useCompression() {
|
private boolean useCompression() throws IOException {
|
||||||
// If stream compression was offered by the server and we want to use
|
// If stream compression was offered by the server and we want to use
|
||||||
// compression then send compression request to the server
|
// compression then send compression request to the server
|
||||||
if (authenticated) {
|
if (authenticated) {
|
||||||
|
@ -785,9 +786,9 @@ public class XMPPTCPConnection extends XMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((compressionHandler = maybeGetCompressionHandler()) != null) {
|
if ((compressionHandler = maybeGetCompressionHandler()) != null) {
|
||||||
|
synchronized (this) {
|
||||||
requestStreamCompression(compressionHandler.getCompressionMethod());
|
requestStreamCompression(compressionHandler.getCompressionMethod());
|
||||||
// Wait until compression is being used or a timeout happened
|
// Wait until compression is being used or a timeout happened
|
||||||
synchronized (this) {
|
|
||||||
try {
|
try {
|
||||||
wait(getPacketReplyTimeout());
|
wait(getPacketReplyTimeout());
|
||||||
}
|
}
|
||||||
|
@ -804,24 +805,20 @@ public class XMPPTCPConnection extends XMPPConnection {
|
||||||
* Request the server that we want to start using stream compression. When using TLS
|
* Request the server that we want to start using stream compression. When using TLS
|
||||||
* then negotiation of stream compression can only happen after TLS was negotiated. If TLS
|
* then negotiation of stream compression can only happen after TLS was negotiated. If TLS
|
||||||
* compression is being used the stream compression should not be used.
|
* compression is being used the stream compression should not be used.
|
||||||
|
* @throws IOException if the compress stanza could not be send
|
||||||
*/
|
*/
|
||||||
private void requestStreamCompression(String method) {
|
private void requestStreamCompression(String method) throws IOException {
|
||||||
try {
|
|
||||||
writer.write("<compress xmlns='http://jabber.org/protocol/compress'>");
|
writer.write("<compress xmlns='http://jabber.org/protocol/compress'>");
|
||||||
writer.write("<method>" + method + "</method></compress>");
|
writer.write("<method>" + method + "</method></compress>");
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
|
||||||
notifyConnectionError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start using stream compression since the server has acknowledged stream compression.
|
* Start using stream compression since the server has acknowledged stream compression.
|
||||||
*
|
*
|
||||||
* @throws Exception if there is an exception starting stream compression.
|
* @throws IOException if there is an exception starting stream compression.
|
||||||
*/
|
*/
|
||||||
void startStreamCompression() throws Exception {
|
void startStreamCompression() throws IOException {
|
||||||
serverAckdCompression = true;
|
serverAckdCompression = true;
|
||||||
// Initialize the reader and writer with the new secured version
|
// Initialize the reader and writer with the new secured version
|
||||||
initReaderAndWriter();
|
initReaderAndWriter();
|
||||||
|
@ -831,16 +828,14 @@ public class XMPPTCPConnection extends XMPPConnection {
|
||||||
// Send a new opening stream to the server
|
// Send a new opening stream to the server
|
||||||
packetWriter.openStream();
|
packetWriter.openStream();
|
||||||
// Notify that compression is being used
|
// Notify that compression is being used
|
||||||
synchronized (this) {
|
streamCompressionNegotiationDone();
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the XMPP connection that stream compression was denied so that
|
* Notifies the XMPP connection that stream compression negotiation is done so that the
|
||||||
* the connection process can proceed.
|
* connection process can proceed.
|
||||||
*/
|
*/
|
||||||
synchronized void streamCompressionDenied() {
|
synchronized void streamCompressionNegotiationDone() {
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue