From c7f8a9a1cfa44d45ff2b5a7f0549b13531230732 Mon Sep 17 00:00:00 2001 From: cmeng-git Date: Mon, 27 Feb 2023 07:08:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?XEP-0047=20Send=20=E2=80=98close=E2=80=99?= =?UTF-8?q?=20stream=20only=20if=20it=20was=20not=20closed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ibb/InBandBytestreamSession.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java index df783618f9..6ba933d4fc 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java @@ -61,6 +61,7 @@ * automatically if one of them is closed. * * @author Henning Staib + * @author Eng Chong Meng */ public class InBandBytestreamSession implements BytestreamSession { @@ -93,6 +94,9 @@ public class InBandBytestreamSession implements BytestreamSession { /* flag to indicate if session is closed */ private boolean isClosed = false; + /* flag to indicate if session is already closed by peer */ + private boolean closedByPeer = false; + /** * Constructor. * @@ -188,6 +192,7 @@ protected void closeByPeer(Close closeRequest) throws NotConnectedException, Int this.inputStream.closeInternal(); this.inputStream.cleanup(); this.outputStream.closeInternal(false); + this.closedByPeer = true; // acknowledge close request IQ confirmClose = IQ.createResultIQ(closeRequest); @@ -224,18 +229,19 @@ protected synchronized void closeByLocal(boolean in) throws IOException { if (this.inputStream.isClosed && this.outputStream.isClosed) { this.isClosed = true; - // send close request - Close close = new Close(this.byteStreamRequest.getSessionID()); - close.setTo(this.remoteJID); - try { - connection.createStanzaCollectorAndSend(close).nextResultOrThrow(); - } - catch (Exception e) { - // Sadly we are unable to use the IOException(Throwable) constructor because this - // constructor is only supported from Android API 9 on. - IOException ioException = new IOException(); - ioException.initCause(e); - throw ioException; + // send close stream request if not already closed by peer + if (!closedByPeer) { + Close close = new Close(this.byteStreamRequest.getSessionID()); + close.setTo(this.remoteJID); + try { + connection.createStanzaCollectorAndSend(close).nextResultOrThrow(); + } catch (Exception e) { + // Sadly we are unable to use the IOException(Throwable) constructor because this + // constructor is only supported from Android API 9 on. + IOException ioException = new IOException(); + ioException.initCause(e); + throw ioException; + } } this.inputStream.cleanup(); From ee8bc83a1398b5da7e0950e24058df922efd95de Mon Sep 17 00:00:00 2001 From: cmeng-git Date: Thu, 23 Mar 2023 08:08:59 +0800 Subject: [PATCH 2/2] set closedByPeer as volatile as it is accessed by different threads. --- .../smackx/bytestreams/ibb/InBandBytestreamSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java index 6ba933d4fc..05bcbcd6f3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java @@ -95,7 +95,7 @@ public class InBandBytestreamSession implements BytestreamSession { private boolean isClosed = false; /* flag to indicate if session is already closed by peer */ - private boolean closedByPeer = false; + private volatile boolean closedByPeer = false; /** * Constructor.