Index: httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.java
===================================================================
--- httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.java (revision 1059221)
+++ httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.java (working copy)
@@ -33,12 +33,13 @@
import java.net.UnknownHostException;
import javax.net.ssl.SSLException;
+import org.apache.http.HttpEntity;
import org.apache.http.annotation.Immutable;
import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpRequest;
import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.methods.HttpPost;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.ExecutionContext;
@@ -54,16 +55,20 @@
/** the number of times a method will be retried */
private final int retryCount;
- /** Whether or not methods that have successfully sent their request will be retried */
- private final boolean requestSentRetryEnabled;
+ /**
+ * Whether or not all the methods defined as idempotent in
+ * RFC-2616 section 9.1.2 (GET, HEAD, PUT, DELETE, OPTIONS, and TRACE)
+ * should be assumed to be idempotent and retried
+ */
+ private final boolean retryIdempotentMethodsEnabled;
/**
* Default constructor
*/
- public DefaultHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled) {
+ public DefaultHttpRequestRetryHandler(int retryCount, boolean retryIdempotentMethodsEnabled) {
super();
this.retryCount = retryCount;
- this.requestSentRetryEnabled = requestSentRetryEnabled;
+ this.retryIdempotentMethodsEnabled = retryIdempotentMethodsEnabled;
}
/**
@@ -73,7 +78,8 @@
this(3, false);
}
/**
- * Used retryCount and requestSentRetryEnabled to determine
+ * Used retryCount and
+ * retryIdempotentMethodsEnabled to determine
* if the given method should be retried.
*/
public boolean retryRequest(
@@ -107,33 +113,50 @@
return false;
}
- HttpRequest request = (HttpRequest)
- context.getAttribute(ExecutionContext.HTTP_REQUEST);
- boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
- if (idempotent) {
- // Retry if the request is considered idempotent
+ Boolean b = (Boolean)context.getAttribute(ExecutionContext.HTTP_REQ_SENT);
+ boolean sent = (b != null && b.booleanValue());
+ if (!sent) {
+ // Retry if the request has not been sent fully
return true;
}
- Boolean b = (Boolean)
- context.getAttribute(ExecutionContext.HTTP_REQ_SENT);
- boolean sent = (b != null && b.booleanValue());
+ // Consider retrying idempotent Methods?
+ if (!this.retryIdempotentMethodsEnabled) {
+ return false;
+ }
- if (!sent || this.requestSentRetryEnabled) {
- // Retry if the request has not been sent fully or
- // if it's OK to retry methods that have been sent
+ Object requestObj = context.getAttribute(ExecutionContext.HTTP_REQUEST);
+ if (requestObj instanceof HttpEntityEnclosingRequest) {
+ HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest)requestObj;
+ HttpEntity entity = request.getEntity();
+
+ if (entity != null && !entity.isRepeatable()) {
+ // Don't retry if we can't resend the enclosed HttpEntity anyway
+ return false;
+ }
+ }
+
+ // From the current list of supported HTTP methods:
+ // GET, HEAD, POST, PUT, DELETE, OPTIONS, and TRACE
+ // RFC-2616 section 9.1.2 declares the following should be idempotent:
+ // GET, HEAD, PUT, DELETE, OPTIONS, and TRACE
+ boolean idempotent = !(requestObj instanceof HttpPost);
+ if (idempotent) {
+ // Retry if the request is considered idempotent
return true;
}
+
// otherwise do not retry
return false;
}
/**
- * @return true if this handler will retry methods that have
- * successfully sent their request, false otherwise
+ * @return true if this handler will attempt to retry
+ * GET, HEAD, PUT, DELETE, OPTIONS, and TRACE methods that were
+ * already sent, false otherwise
*/
- public boolean isRequestSentRetryEnabled() {
- return requestSentRetryEnabled;
+ public boolean isRetryIdempotentMethodsEnabled() {
+ return retryIdempotentMethodsEnabled;
}
/**