[HTTPCLIENT-1865] DefaultServiceUnavailableRetryStrategy does not
respect HttpEntity#isRepeatable.
This commit is contained in:
parent
f2146cab62
commit
9efcba8730
|
@ -39,6 +39,7 @@ import org.apache.hc.core5.annotation.Contract;
|
|||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
@ -82,6 +83,10 @@ final class ServiceUnavailableRetryExec implements ExecChainHandler {
|
|||
for (int c = 1;; c++) {
|
||||
final ClassicHttpResponse response = chain.proceed(currentRequest, scope);
|
||||
try {
|
||||
final HttpEntity entity = request.getEntity();
|
||||
if (entity != null && !entity.isRepeatable()) {
|
||||
return response;
|
||||
}
|
||||
if (this.retryStrategy.retryRequest(response, c, context)) {
|
||||
response.close();
|
||||
final long nextInterval = this.retryStrategy.getRetryInterval(response, context);
|
||||
|
|
|
@ -26,17 +26,22 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.sync;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.apache.hc.client5.http.HttpRoute;
|
||||
import org.apache.hc.client5.http.entity.EntityBuilder;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.sync.ExecChain;
|
||||
import org.apache.hc.client5.http.sync.ExecRuntime;
|
||||
import org.apache.hc.client5.http.sync.ServiceUnavailableRetryStrategy;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpPost;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
@ -113,4 +118,31 @@ public class TestServiceUnavailableRetryExec {
|
|||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonRepeatableEntityResponseReturnedImmediately() throws Exception {
|
||||
final HttpRoute route = new HttpRoute(target);
|
||||
|
||||
final HttpPost request = new HttpPost("/test");
|
||||
request.setEntity(EntityBuilder.create()
|
||||
.setStream(new ByteArrayInputStream(new byte[]{}))
|
||||
.build());
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
|
||||
Mockito.when(chain.proceed(
|
||||
Mockito.<ClassicHttpRequest>any(),
|
||||
Mockito.<ExecChain.Scope>any())).thenReturn(response);
|
||||
Mockito.when(retryStrategy.retryRequest(
|
||||
Mockito.<HttpResponse>any(),
|
||||
Mockito.anyInt(),
|
||||
Mockito.<HttpContext>any())).thenReturn(Boolean.TRUE, Boolean.FALSE);
|
||||
|
||||
final ExecChain.Scope scope = new ExecChain.Scope(route, request, endpoint, context);
|
||||
final ClassicHttpResponse finalResponse = retryExec.execute(request, scope, chain);
|
||||
|
||||
Assert.assertSame(response, finalResponse);
|
||||
Mockito.verify(response, Mockito.times(0)).close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue