1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
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          
96          if (method instanceof HttpMethodBase) {
97          	if (((HttpMethodBase)method).isAborted()) {
98                  return false;
99          	}
100         }
101         if (executionCount > this.retryCount) {
102             
103             return false;
104         }
105         if (exception instanceof NoHttpResponseException) {
106             
107             return true;
108         }
109         if (exception instanceof InterruptedIOException) {
110             
111             return false;
112         }
113         if (exception instanceof UnknownHostException) {
114             
115             return false;
116         }
117         if (exception instanceof NoRouteToHostException) {
118             
119             return false;
120         }
121         if (SSL_HANDSHAKE_EXCEPTION != null && SSL_HANDSHAKE_EXCEPTION.isInstance(exception)) {
122             
123             return false;
124         }
125         if (!method.isRequestSent() || this.requestSentRetryEnabled) {
126             
127             
128             return true;
129         }
130         
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 }