mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 22:32:06 +01:00
Don't throw an IOException if IBBStream got closed by the remote
Smack should not throw an IOException in case a stream got closed by the remote peer and the user is trying to read() from the stream. This commit fixes that, by making Smack return '-1' if the stream got closed by the remote. An IOException will only be thrown if the user tries to read from a stream that got already closed by *himself*. SMACK-468
This commit is contained in:
parent
a19181ce04
commit
d790db5729
2 changed files with 4 additions and 56 deletions
|
@ -395,8 +395,9 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
* @throws IOException if stream is closed and no data should be read anymore
|
* @throws IOException if stream is closed and no data should be read anymore
|
||||||
*/
|
*/
|
||||||
private void checkClosed() throws IOException {
|
private void checkClosed() throws IOException {
|
||||||
/* throw no exception if there is data available, but not if close method was invoked */
|
// Throw an exception if, and only if, this stream has been already
|
||||||
if ((isClosed && this.dataQueue.isEmpty()) || closeInvoked) {
|
// closed by the user using the close() method
|
||||||
|
if (closeInvoked) {
|
||||||
// clear data queue in case additional data was received after stream was closed
|
// clear data queue in case additional data was received after stream was closed
|
||||||
this.dataQueue.clear();
|
this.dataQueue.clear();
|
||||||
throw new IOException("Stream is closed");
|
throw new IOException("Stream is closed");
|
||||||
|
@ -408,7 +409,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (isClosed) {
|
if (closeInvoked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -609,59 +609,6 @@ public class InBandBytestreamSessionTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If the session is closed the input stream and output stream should be closed as well.
|
|
||||||
*
|
|
||||||
* @throws Exception should not happen
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void shouldCloseBothStreamsIfSessionIsClosed() throws Exception {
|
|
||||||
// acknowledgment for data packet
|
|
||||||
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
|
||||||
protocol.addResponse(resultIQ);
|
|
||||||
|
|
||||||
// acknowledgment for close request
|
|
||||||
protocol.addResponse(resultIQ, Verification.correspondingSenderReceiver,
|
|
||||||
Verification.requestTypeSET);
|
|
||||||
|
|
||||||
// get IBB sessions data packet listener
|
|
||||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
|
||||||
initiatorJID);
|
|
||||||
InputStream inputStream = session.getInputStream();
|
|
||||||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
|
||||||
|
|
||||||
// build data packet
|
|
||||||
String base64Data = StringUtils.encodeBase64("Data");
|
|
||||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, 0, base64Data);
|
|
||||||
Data data = new Data(dpe);
|
|
||||||
|
|
||||||
// add data packets
|
|
||||||
listener.processPacket(data);
|
|
||||||
|
|
||||||
session.close();
|
|
||||||
|
|
||||||
protocol.verifyAll();
|
|
||||||
|
|
||||||
try {
|
|
||||||
while (inputStream.read() != -1) {
|
|
||||||
}
|
|
||||||
inputStream.read();
|
|
||||||
fail("should throw an exception");
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
assertTrue(e.getMessage().contains("closed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
session.getOutputStream().flush();
|
|
||||||
fail("should throw an exception");
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
assertTrue(e.getMessage().contains("closed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the input stream is closed concurrently there should be no deadlock.
|
* If the input stream is closed concurrently there should be no deadlock.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue