diff --git a/src/main/java/microsoft/exchange/webservices/data/core/request/HangingServiceRequestBase.java b/src/main/java/microsoft/exchange/webservices/data/core/request/HangingServiceRequestBase.java index 04db10e43..2d9534b25 100644 --- a/src/main/java/microsoft/exchange/webservices/data/core/request/HangingServiceRequestBase.java +++ b/src/main/java/microsoft/exchange/webservices/data/core/request/HangingServiceRequestBase.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.ObjectStreamException; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownServiceException; import java.util.ArrayList; @@ -93,6 +94,8 @@ public interface IHandleResponseObject { */ private HttpWebRequest response; + private volatile boolean disconnecting; + /** * Expected minimum frequency in response, in milliseconds. */ @@ -222,15 +225,11 @@ private void parseResponses() { } catch (SocketTimeoutException ex) { // The connection timed out. this.disconnect(HangingRequestDisconnectReason.Timeout, ex); - } catch (UnknownServiceException ex) { - // Stream is closed, so disconnect. - this.disconnect(HangingRequestDisconnectReason.Exception, ex); - } catch (ObjectStreamException ex) { - // Stream is closed, so disconnect. - this.disconnect(HangingRequestDisconnectReason.Exception, ex); } catch (IOException ex) { - // Stream is closed, so disconnect. - this.disconnect(HangingRequestDisconnectReason.Exception, ex); + if (!(disconnecting && isSocketClosed(ex))) { + // Stream was closed due to an error + this.disconnect(HangingRequestDisconnectReason.Exception, ex); + } } catch (UnsupportedOperationException ex) { LOG.error(ex); // This is thrown if we close the stream during a @@ -239,13 +238,26 @@ private void parseResponses() { //simply results in a long-running connection. this.disconnect(HangingRequestDisconnectReason.UserInitiated, null); } catch (Exception ex) { - // Stream is closed, so disconnect. - this.disconnect(HangingRequestDisconnectReason.Exception, ex); + if (!(disconnecting && isSocketClosed(ex))) { + // Stream was closed due to an error + this.disconnect(HangingRequestDisconnectReason.Exception, ex); + } + } finally { IOUtils.closeQuietly(responseCopy); } } + private static boolean isSocketClosed(Throwable e) { + while (e != null) { + if (e instanceof SocketException) { + return true; + } + e = e.getCause(); + } + return false; + } + private boolean isConnected; /** @@ -266,7 +278,8 @@ private void setIsConnected(boolean value) { */ public void disconnect() { synchronized (this) { - IOUtils.closeQuietly(this.response); + disconnecting = true; + this.response.releaseConnection(); this.disconnect(HangingRequestDisconnectReason.UserInitiated, null); } } @@ -279,7 +292,8 @@ public void disconnect() { */ public void disconnect(HangingRequestDisconnectReason reason, Exception exception) { if (this.isConnected()) { - IOUtils.closeQuietly(this.response); + disconnecting = true; + this.response.releaseConnection(); this.internalOnDisconnect(reason, exception); } } diff --git a/src/main/java/microsoft/exchange/webservices/data/core/request/HttpClientWebRequest.java b/src/main/java/microsoft/exchange/webservices/data/core/request/HttpClientWebRequest.java index 8cd6ccb8f..eaf8b32ae 100644 --- a/src/main/java/microsoft/exchange/webservices/data/core/request/HttpClientWebRequest.java +++ b/src/main/java/microsoft/exchange/webservices/data/core/request/HttpClientWebRequest.java @@ -94,6 +94,13 @@ public void close() throws IOException { httpPost = null; } + @Override + public void releaseConnection() { + if (httpPost != null) { + httpPost.releaseConnection(); + } + } + /** * Prepares the request by setting appropriate headers, authentication, timeouts, etc. */ diff --git a/src/main/java/microsoft/exchange/webservices/data/core/request/HttpWebRequest.java b/src/main/java/microsoft/exchange/webservices/data/core/request/HttpWebRequest.java index f8abec964..28758a2f2 100644 --- a/src/main/java/microsoft/exchange/webservices/data/core/request/HttpWebRequest.java +++ b/src/main/java/microsoft/exchange/webservices/data/core/request/HttpWebRequest.java @@ -495,6 +495,8 @@ public void setCredentials(String domain, String user, String pwd) { */ public abstract void close() throws IOException; + public abstract void releaseConnection(); + /** * Prepare connection. */