diff --git a/src/main/java/microsoft/exchange/webservices/data/autodiscover/AutodiscoverService.java b/src/main/java/microsoft/exchange/webservices/data/autodiscover/AutodiscoverService.java index 147a61c7f..2e3722df6 100644 --- a/src/main/java/microsoft/exchange/webservices/data/autodiscover/AutodiscoverService.java +++ b/src/main/java/microsoft/exchange/webservices/data/autodiscover/AutodiscoverService.java @@ -1653,7 +1653,7 @@ public HttpWebRequest prepareHttpWebRequestForUrl(URI url) throws ServiceLocalException, URISyntaxException { return this.prepareHttpWebRequestForUrl(url, false, // acceptGzipEncoding - false); // allowAutoRedirect + false, null); // allowAutoRedirect } /** diff --git a/src/main/java/microsoft/exchange/webservices/data/core/ExchangeService.java b/src/main/java/microsoft/exchange/webservices/data/core/ExchangeService.java index 529637769..063ae4adf 100644 --- a/src/main/java/microsoft/exchange/webservices/data/core/ExchangeService.java +++ b/src/main/java/microsoft/exchange/webservices/data/core/ExchangeService.java @@ -30,13 +30,11 @@ import java.util.Collection; import java.util.Date; import java.util.EnumSet; -import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; import microsoft.exchange.webservices.data.autodiscover.AutodiscoverService; import microsoft.exchange.webservices.data.autodiscover.IAutodiscoverRedirectionUrl; @@ -3734,12 +3732,12 @@ public ExchangeService(ExchangeVersion requestedServerVersion) { /** * Prepare http web request. - * + * @param timeout If specified then overrides service level timeout value * @return the http web request * @throws ServiceLocalException the service local exception * @throws java.net.URISyntaxException the uRI syntax exception */ - public HttpWebRequest prepareHttpWebRequest() + public HttpWebRequest prepareHttpWebRequest(Integer timeout) throws ServiceLocalException, URISyntaxException { try { this.url = this.adjustServiceUriFromCredentials(this.getUrl()); @@ -3747,26 +3745,26 @@ public HttpWebRequest prepareHttpWebRequest() LOG.error(e); } return this.prepareHttpWebRequestForUrl(url, this - .getAcceptGzipEncoding(), true); + .getAcceptGzipEncoding(), true, timeout); } /** * Prepares a http web request from a pooling connection manager, used for subscriptions. - * + * @param timeout If specified then overrides service level timeout value * @return A http web request * @throws ServiceLocalException The service local exception * @throws java.net.URISyntaxException the uRI syntax exception */ - public HttpWebRequest prepareHttpPoolingWebRequest() - throws ServiceLocalException, URISyntaxException { - try { - this.url = this.adjustServiceUriFromCredentials(this.getUrl()); - } catch (Exception e) { - LOG.error(e); - } - return this.prepareHttpPoolingWebRequestForUrl(url, this - .getAcceptGzipEncoding(), true); - } + public HttpWebRequest prepareHttpPoolingWebRequest(Integer timeout) + throws ServiceLocalException, URISyntaxException { + try { + this.url = this.adjustServiceUriFromCredentials(this.getUrl()); + } catch (Exception e) { + LOG.error(e); + } + return this.prepareHttpPoolingWebRequestForUrl(url, this + .getAcceptGzipEncoding(), true, timeout); + } /** * Processes an HTTP error response. diff --git a/src/main/java/microsoft/exchange/webservices/data/core/ExchangeServiceBase.java b/src/main/java/microsoft/exchange/webservices/data/core/ExchangeServiceBase.java index bb01858b4..2fe1ed12e 100644 --- a/src/main/java/microsoft/exchange/webservices/data/core/ExchangeServiceBase.java +++ b/src/main/java/microsoft/exchange/webservices/data/core/ExchangeServiceBase.java @@ -298,12 +298,13 @@ public void doOnSerializeCustomSoapHeaders(XMLStreamWriter writer) { * @param url The URL that the HttpWebRequest should target. * @param acceptGzipEncoding If true, ask server for GZip compressed content. * @param allowAutoRedirect If true, redirection response will be automatically followed. + * @param timeout If not null then override service specified timeout * @return An initialised instance of HttpWebRequest. * @throws ServiceLocalException the service local exception * @throws java.net.URISyntaxException the uRI syntax exception */ protected HttpWebRequest prepareHttpWebRequestForUrl(URI url, boolean acceptGzipEncoding, - boolean allowAutoRedirect) throws ServiceLocalException, URISyntaxException { + boolean allowAutoRedirect, Integer timeout) throws ServiceLocalException, URISyntaxException { // Verify that the protocol is something that we can handle String scheme = url.getScheme(); if (!scheme.equalsIgnoreCase(EWSConstants.HTTP_SCHEME) @@ -313,7 +314,7 @@ protected HttpWebRequest prepareHttpWebRequestForUrl(URI url, boolean acceptGzip } HttpClientWebRequest request = new HttpClientWebRequest(httpClient, httpContext); - prepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect, request); + prepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect, request, timeout); return request; } @@ -328,12 +329,13 @@ protected HttpWebRequest prepareHttpWebRequestForUrl(URI url, boolean acceptGzip * @param url The URL that the HttpWebRequest should target. * @param acceptGzipEncoding If true, ask server for GZip compressed content. * @param allowAutoRedirect If true, redirection response will be automatically followed. + * @param timeout If not null then overrides service specified timeout * @return An initialised instance of HttpWebRequest. * @throws ServiceLocalException the service local exception * @throws java.net.URISyntaxException the uRI syntax exception */ protected HttpWebRequest prepareHttpPoolingWebRequestForUrl(URI url, boolean acceptGzipEncoding, - boolean allowAutoRedirect) throws ServiceLocalException, URISyntaxException { + boolean allowAutoRedirect, Integer timeout) throws ServiceLocalException, URISyntaxException { // Verify that the protocol is something that we can handle String scheme = url.getScheme(); if (!scheme.equalsIgnoreCase(EWSConstants.HTTP_SCHEME) @@ -347,13 +349,13 @@ protected HttpWebRequest prepareHttpPoolingWebRequestForUrl(URI url, boolean acc } HttpClientWebRequest request = new HttpClientWebRequest(httpPoolingClient, httpContext); - prepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect, request); + prepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect, request, timeout); return request; } private void prepareHttpWebRequestForUrl(URI url, boolean acceptGzipEncoding, boolean allowAutoRedirect, - HttpClientWebRequest request) throws ServiceLocalException, URISyntaxException { + HttpClientWebRequest request, Integer timeout) throws ServiceLocalException, URISyntaxException { try { request.setUrl(url.toURL()); } catch (MalformedURLException e) { @@ -362,7 +364,7 @@ private void prepareHttpWebRequestForUrl(URI url, boolean acceptGzipEncoding, bo } request.setPreAuthenticate(preAuthenticate); - request.setTimeout(timeout); + request.setTimeout(timeout != null ? timeout : this.timeout); request.setContentType("text/xml; charset=utf-8"); request.setAccept("text/xml"); request.setUserAgent(userAgent); diff --git a/src/main/java/microsoft/exchange/webservices/data/core/request/ServiceRequestBase.java b/src/main/java/microsoft/exchange/webservices/data/core/request/ServiceRequestBase.java index 101d6b104..6c5b79fbd 100644 --- a/src/main/java/microsoft/exchange/webservices/data/core/request/ServiceRequestBase.java +++ b/src/main/java/microsoft/exchange/webservices/data/core/request/ServiceRequestBase.java @@ -72,6 +72,9 @@ public abstract class ServiceRequestBase { */ private ExchangeService service; + /* If included then overrides service specified timeout */ + private Integer timeout; + // Methods for subclasses to override /** @@ -122,6 +125,10 @@ protected void validate() throws Exception { this.service.validate(); } + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } + /** * Writes XML body. * @@ -657,7 +664,7 @@ protected HttpWebRequest validateAndEmitRequest() throws Exception { * @throws Exception on error */ protected HttpWebRequest buildEwsHttpWebRequest() throws Exception { - HttpWebRequest request = service.prepareHttpWebRequest(); + HttpWebRequest request = service.prepareHttpWebRequest(timeout); return buildEwsHttpWebRequest(request); } @@ -672,7 +679,7 @@ protected HttpWebRequest buildEwsHttpWebRequest() throws Exception { * @throws Exception on error */ protected HttpWebRequest buildEwsHttpPoolingWebRequest() throws Exception { - HttpWebRequest request = service.prepareHttpPoolingWebRequest(); + HttpWebRequest request = service.prepareHttpPoolingWebRequest(timeout); return buildEwsHttpWebRequest(request); } diff --git a/src/main/java/microsoft/exchange/webservices/data/notification/StreamingSubscriptionConnection.java b/src/main/java/microsoft/exchange/webservices/data/notification/StreamingSubscriptionConnection.java index dae04a0b1..33d4776f6 100644 --- a/src/main/java/microsoft/exchange/webservices/data/notification/StreamingSubscriptionConnection.java +++ b/src/main/java/microsoft/exchange/webservices/data/notification/StreamingSubscriptionConnection.java @@ -45,6 +45,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; /** * Represents a connection to an ongoing stream of events. @@ -311,6 +312,10 @@ public void open() throws ServiceLocalException, Exception { this.session, this, this.subscriptions.keySet(), this.connectionTimeout); + // Make sure socket timeout for this request is at least as large as connection timeout + // otherwise connection may get dropped too soon. + this.currentHangingRequest.setTimeout((int) TimeUnit.MINUTES.toMillis(connectionTimeout)); + this.currentHangingRequest.addOnDisconnectEvent(this); this.currentHangingRequest.internalExecute();