/ org.apache.commons.httpclient / src / org / apache / commons / httpclient / DefaultHttpMethodRetryHandler.java
DefaultHttpMethodRetryHandler.java
  1  /*
  2   * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/DefaultHttpMethodRetryHandler.java,v 1.3 2004/12/20 11:47:46 olegk Exp $
  3   * $Revision: 480424 $
  4   * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
  5   *
  6   * ====================================================================
  7   *
  8   *  Licensed to the Apache Software Foundation (ASF) under one or more
  9   *  contributor license agreements.  See the NOTICE file distributed with
 10   *  this work for additional information regarding copyright ownership.
 11   *  The ASF licenses this file to You under the Apache License, Version 2.0
 12   *  (the "License"); you may not use this file except in compliance with
 13   *  the License.  You may obtain a copy of the License at
 14   *
 15   *      http://www.apache.org/licenses/LICENSE-2.0
 16   *
 17   *  Unless required by applicable law or agreed to in writing, software
 18   *  distributed under the License is distributed on an "AS IS" BASIS,
 19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 20   *  See the License for the specific language governing permissions and
 21   *  limitations under the License.
 22   * ====================================================================
 23   *
 24   * This software consists of voluntary contributions made by many
 25   * individuals on behalf of the Apache Software Foundation.  For more
 26   * information on the Apache Software Foundation, please see
 27   * <http://www.apache.org/>.
 28   *
 29   */
 30  
 31  package org.apache.commons.httpclient;
 32  
 33  import java.io.IOException;
 34  import java.io.InterruptedIOException;
 35  import java.net.NoRouteToHostException;
 36  import java.net.UnknownHostException;
 37  
 38  /**
 39   * The default {@link HttpMethodRetryHandler} used by {@link HttpMethod}s.
 40   * 
 41   * @author Michael Becke
 42   * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
 43   */
 44  public class DefaultHttpMethodRetryHandler implements HttpMethodRetryHandler {
 45  
 46  
 47      private static Class SSL_HANDSHAKE_EXCEPTION = null;
 48      
 49      static {
 50          try {
 51              SSL_HANDSHAKE_EXCEPTION = Class.forName("javax.net.ssl.SSLHandshakeException");
 52          } catch (ClassNotFoundException ignore) {           
 53          }
 54      }
 55      /** the number of times a method will be retried */
 56      private int retryCount;
 57      
 58      /** Whether or not methods that have successfully sent their request will be retried */
 59      private boolean requestSentRetryEnabled;
 60      
 61      /**
 62       * Creates a new DefaultHttpMethodRetryHandler.
 63       * @param retryCount the number of times a method will be retried
 64       * @param requestSentRetryEnabled if true, methods that have successfully sent their request will be retried
 65       */
 66      public DefaultHttpMethodRetryHandler(int retryCount, boolean requestSentRetryEnabled) {
 67          super();
 68          this.retryCount = retryCount;
 69          this.requestSentRetryEnabled = requestSentRetryEnabled;
 70      }
 71      
 72      /**
 73       * Creates a new DefaultHttpMethodRetryHandler that retries up to 3 times
 74       * but does not retry methods that have successfully sent their requests.
 75       */
 76      public DefaultHttpMethodRetryHandler() {
 77          this(3, false);
 78      }
 79      /** 
 80       * Used <code>retryCount</code> and <code>requestSentRetryEnabled</code> to determine
 81       * if the given method should be retried.
 82       * 
 83       * @see HttpMethodRetryHandler#retryMethod(HttpMethod, IOException, int)
 84       */
 85      public boolean retryMethod(
 86          final HttpMethod method, 
 87          final IOException exception, 
 88          int executionCount) {
 89          if (method == null) {
 90              throw new IllegalArgumentException("HTTP method may not be null");
 91          }
 92          if (exception == null) {
 93              throw new IllegalArgumentException("Exception parameter may not be null");
 94          }
 95          // HttpMethod interface is the WORST thing ever done to HttpClient
 96          if (method instanceof HttpMethodBase) {
 97              if (((HttpMethodBase)method).isAborted()) {
 98                  return false;
 99              }
100          }
101          if (executionCount > this.retryCount) {
102              // Do not retry if over max retry count
103              return false;
104          }
105          if (exception instanceof NoHttpResponseException) {
106              // Retry if the server dropped connection on us
107              return true;
108          }
109          if (exception instanceof InterruptedIOException) {
110              // Timeout
111              return false;
112          }
113          if (exception instanceof UnknownHostException) {
114              // Unknown host
115              return false;
116          }
117          if (exception instanceof NoRouteToHostException) {
118              // Host unreachable
119              return false;
120          }
121          if (SSL_HANDSHAKE_EXCEPTION != null && SSL_HANDSHAKE_EXCEPTION.isInstance(exception)) {
122              // SSL handshake exception
123              return false;
124          }
125          if (!method.isRequestSent() || this.requestSentRetryEnabled) {
126              // Retry if the request has not been sent fully or
127              // if it's OK to retry methods that have been sent
128              return true;
129          }
130          // otherwise do not retry
131          return false;
132      }
133      
134      /**
135       * @return <code>true</code> if this handler will retry methods that have 
136       * successfully sent their request, <code>false</code> otherwise
137       */
138      public boolean isRequestSentRetryEnabled() {
139          return requestSentRetryEnabled;
140      }
141  
142      /**
143       * @return the maximum number of times a method will be retried
144       */
145      public int getRetryCount() {
146          return retryCount;
147      }
148  }