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; @@ -107,21 +108,36 @@ return false; } - HttpRequest request = (HttpRequest) - context.getAttribute(ExecutionContext.HTTP_REQUEST); - boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); + 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; + } + + 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; } - Boolean b = (Boolean) - context.getAttribute(ExecutionContext.HTTP_REQ_SENT); - boolean sent = (b != null && b.booleanValue()); - - 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 + if (this.requestSentRetryEnabled) { + // Retry special handling for non-idempotent HTTP methods return true; } // otherwise do not retry