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 package org.apache.http.impl.client;
29
30 import java.io.IOException;
31 import java.io.InterruptedIOException;
32 import java.net.ConnectException;
33 import java.net.NoRouteToHostException;
34 import java.net.UnknownHostException;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.HashSet;
38 import java.util.Set;
39
40 import javax.net.ssl.SSLException;
41
42 import org.apache.http.HttpEntityEnclosingRequest;
43 import org.apache.http.HttpRequest;
44 import org.apache.http.annotation.Contract;
45 import org.apache.http.annotation.ThreadingBehavior;
46 import org.apache.http.client.HttpRequestRetryHandler;
47 import org.apache.http.client.methods.HttpUriRequest;
48 import org.apache.http.client.protocol.HttpClientContext;
49 import org.apache.http.protocol.HttpContext;
50 import org.apache.http.util.Args;
51
52
53
54
55
56
57 @Contract(threading = ThreadingBehavior.IMMUTABLE)
58 public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler {
59
60 public static final DefaultHttpRequestRetryHandlerHandler.html#DefaultHttpRequestRetryHandler">DefaultHttpRequestRetryHandler INSTANCE = new DefaultHttpRequestRetryHandler();
61
62
63 private final int retryCount;
64
65
66 private final boolean requestSentRetryEnabled;
67
68 private final Set<Class<? extends IOException>> nonRetriableClasses;
69
70
71
72
73
74
75
76
77
78 protected DefaultHttpRequestRetryHandler(
79 final int retryCount,
80 final boolean requestSentRetryEnabled,
81 final Collection<Class<? extends IOException>> clazzes) {
82 super();
83 this.retryCount = retryCount;
84 this.requestSentRetryEnabled = requestSentRetryEnabled;
85 this.nonRetriableClasses = new HashSet<Class<? extends IOException>>();
86 this.nonRetriableClasses.addAll(clazzes);
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101 @SuppressWarnings("unchecked")
102 public DefaultHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) {
103 this(retryCount, requestSentRetryEnabled, Arrays.asList(
104 InterruptedIOException.class,
105 UnknownHostException.class,
106 ConnectException.class,
107 NoRouteToHostException.class,
108 SSLException.class));
109 }
110
111
112
113
114
115
116
117
118
119
120
121 public DefaultHttpRequestRetryHandler() {
122 this(3, false);
123 }
124
125
126
127
128 @Override
129 public boolean retryRequest(
130 final IOException exception,
131 final int executionCount,
132 final HttpContext context) {
133 Args.notNull(exception, "Exception parameter");
134 Args.notNull(context, "HTTP context");
135 if (executionCount > this.retryCount) {
136
137 return false;
138 }
139 if (this.nonRetriableClasses.contains(exception.getClass())) {
140 return false;
141 }
142 for (final Class<? extends IOException> rejectException : this.nonRetriableClasses) {
143 if (rejectException.isInstance(exception)) {
144 return false;
145 }
146 }
147 final HttpClientContext clientContext = HttpClientContext.adapt(context);
148 final HttpRequest request = clientContext.getRequest();
149
150 if(requestIsAborted(request)){
151 return false;
152 }
153
154 if (handleAsIdempotent(request)) {
155
156 return true;
157 }
158
159 if (!clientContext.isRequestSent() || this.requestSentRetryEnabled) {
160
161
162 return true;
163 }
164
165 return false;
166 }
167
168
169
170
171
172 public boolean isRequestSentRetryEnabled() {
173 return requestSentRetryEnabled;
174 }
175
176
177
178
179 public int getRetryCount() {
180 return retryCount;
181 }
182
183
184
185
186 protected boolean handleAsIdempotent(final HttpRequest request) {
187 return !(request instanceof HttpEntityEnclosingRequest);
188 }
189
190
191
192
193
194
195 @Deprecated
196 protected boolean requestIsAborted(final HttpRequest request) {
197 HttpRequest req = request;
198 if (request instanceof RequestWrapper) {
199 req = ((RequestWrapper) request).getOriginal();
200 }
201 return (req instanceof HttpUriRequest/../org/apache/http/client/methods/HttpUriRequest.html#HttpUriRequest">HttpUriRequest && ((HttpUriRequest)req).isAborted());
202 }
203
204 }