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.execchain;
29
30 import java.io.IOException;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.http.Header;
35 import org.apache.http.HttpException;
36 import org.apache.http.annotation.Immutable;
37 import org.apache.http.client.HttpRequestRetryHandler;
38 import org.apache.http.client.NonRepeatableRequestException;
39 import org.apache.http.client.methods.CloseableHttpResponse;
40 import org.apache.http.client.methods.HttpExecutionAware;
41 import org.apache.http.client.methods.HttpRequestWrapper;
42 import org.apache.http.client.protocol.HttpClientContext;
43 import org.apache.http.conn.routing.HttpRoute;
44 import org.apache.http.util.Args;
45
46
47
48
49 @Immutable
50 public class RetryExec implements ClientExecChain {
51
52 private final Log log = LogFactory.getLog(getClass());
53
54 private final ClientExecChain requestExecutor;
55 private final HttpRequestRetryHandler retryHandler;
56
57 public RetryExec(
58 final ClientExecChain requestExecutor,
59 final HttpRequestRetryHandler retryHandler) {
60 Args.notNull(requestExecutor, "HTTP request executor");
61 Args.notNull(retryHandler, "HTTP request retry handler");
62 this.requestExecutor = requestExecutor;
63 this.retryHandler = retryHandler;
64 }
65
66 public CloseableHttpResponse execute(
67 final HttpRoute route,
68 final HttpRequestWrapper request,
69 final HttpClientContext context,
70 final HttpExecutionAware execAware) throws IOException, HttpException {
71 Args.notNull(route, "HTTP route");
72 Args.notNull(request, "HTTP request");
73 Args.notNull(context, "HTTP context");
74 final Header[] origheaders = request.getAllHeaders();
75 for (int execCount = 1;; execCount++) {
76 try {
77 return this.requestExecutor.execute(route, request, context, execAware);
78 } catch (final IOException ex) {
79 if (execAware != null && execAware.isAborted()) {
80 this.log.debug("Request has been aborted");
81 throw ex;
82 }
83 if (retryHandler.retryRequest(ex, execCount, context)) {
84 if (this.log.isInfoEnabled()) {
85 this.log.info("I/O exception ("+ ex.getClass().getName() +
86 ") caught when processing request: "
87 + ex.getMessage());
88 }
89 if (this.log.isDebugEnabled()) {
90 this.log.debug(ex.getMessage(), ex);
91 }
92 if (!Proxies.isRepeatable(request)) {
93 this.log.debug("Cannot retry non-repeatable request");
94 throw new NonRepeatableRequestException("Cannot retry request " +
95 "with a non-repeatable request entity", ex);
96 }
97 request.setHeaders(origheaders);
98 this.log.info("Retrying request");
99 } else {
100 throw ex;
101 }
102 }
103 }
104 }
105
106 }