View Javadoc

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