SLING-9053 reworking the solution
diff --git a/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java b/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java
index 1087158..bf573fd 100644
--- a/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java
@@ -453,12 +453,6 @@
         return doStreamRequest(request, headers, expectedStatus);
     }
 
-    private boolean isServiceUnavailable(SlingHttpResponse response) {
-        StatusLine statusLine = response.getStatusLine();
-        return statusLine != null && statusLine.getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
-    }
-
-
     /**
      * <p>Execute an HTTP request and consumes the entity in the response. The content is cached and can be retrieved using
      * {@code response.getContent()}.
@@ -473,33 +467,10 @@
      * @throws ClientException if the request could not be executed
      */
     public  SlingHttpResponse doRequest(HttpUriRequest request, List<Header> headers, int... expectedStatus) throws ClientException {
-        int maxRetries = Constants.HTTP_RETRIES;
-        boolean needRetry = false;
-        SlingHttpResponse response = null;
-        do {
-            try {
-                if (needRetry) {
-                    // add some pacing
-                    Thread.sleep(Constants.HTTP_RETRIES_DELAY);
-                }
-                response = doStreamRequest(request, headers, expectedStatus);
-                needRetry = maxRetries > 0 && isServiceUnavailable(response);
-                // Consume entity and cache the content so the connection is closed
-                response.getContent();
-            } catch (ClientException | RuntimeException ex ) {
-                needRetry = ex.getMessage().contains("Could not read content from response")
-                        || ex.getMessage().contains("Instead 503 was returned!");
+        SlingHttpResponse response = doStreamRequest(request, headers, expectedStatus);
 
-                if (needRetry) {
-                    log.warn("Retry needed due to " + ex.getMessage());
-                }
-                if (maxRetries == 0) {
-                    throw ex;
-                }
-            } catch (InterruptedException ex) {
-                throw new ClientException("Interrupted while pacing request", ex);
-            }
-       } while (needRetry && maxRetries-- > 0);
+        // Consume entity and cache the content so the connection is closed
+        response.getContent();
 
         return response;
     }
diff --git a/src/main/java/org/apache/sling/testing/clients/Constants.java b/src/main/java/org/apache/sling/testing/clients/Constants.java
index 9b8fb73..18eafc1 100644
--- a/src/main/java/org/apache/sling/testing/clients/Constants.java
+++ b/src/main/java/org/apache/sling/testing/clients/Constants.java
@@ -16,6 +16,10 @@
  */
 package org.apache.sling.testing.clients;
 
+import org.apache.http.client.ServiceUnavailableRetryStrategy;
+import org.apache.http.impl.client.DefaultServiceUnavailableRetryStrategy;
+import org.apache.sling.testing.clients.util.LoggedServiceUnavailableRetryStrategy;
+
 public class Constants {
 
     /**
@@ -33,16 +37,21 @@
     private static int retries;
 
     // Custom delay between retries in millisec
-    private static long retriesDelay;
+    private static int retriesDelay;
+
+    // Custom log retries
+    private static boolean logRetries;
     static {
         try {
             Constants.delay = Long.getLong(Constants.CONFIG_PROP_PREFIX + "http.delay", 0);
             Constants.retries = Integer.getInteger(Constants.CONFIG_PROP_PREFIX + "http.retries", 5);
-            Constants.retriesDelay = Long.getLong(Constants.CONFIG_PROP_PREFIX + "http.retriesDelay", 1000);
+            Constants.retriesDelay = Integer.getInteger(Constants.CONFIG_PROP_PREFIX + "http.retriesDelay", 1000);
+            Constants.logRetries = Boolean.getBoolean(Constants.CONFIG_PROP_PREFIX + "http.logRetries");
         } catch (NumberFormatException e) {
             Constants.delay = 0;
             Constants.retries = 5;
             Constants.retriesDelay = 1000;
+            Constants.logRetries = false;
         }
     }
 
@@ -53,16 +62,13 @@
     public static final long HTTP_DELAY = delay;
 
     /**
-     * Custom number of retries after an HTTP request failed due to 503 or any broken connection issues.
-     * Used by {@link org.apache.sling.testing.clients.AbstractSlingClient}
+     * Custom ServiceUnavailableRetryStrategy.
+     * Used by {@link org.apache.sling.testing.clients.SlingClient}
+     * and {@link org.apache.sling.testing.clients.interceptors.FormBasedAuthInterceptor}
      */
-    public static final int HTTP_RETRIES = retries;
-
-    /**
-     * Custom delay in milliseconds between each retries, default to 1000 milliseconds.
-     * Used by {@link org.apache.sling.testing.clients.AbstractSlingClient}
-     */
-    public static final long HTTP_RETRIES_DELAY = retriesDelay;
+    public static final ServiceUnavailableRetryStrategy HTTP_RETRY_STRATEGY = logRetries
+            ? new LoggedServiceUnavailableRetryStrategy(retries, retriesDelay)
+            : new DefaultServiceUnavailableRetryStrategy(retries, retriesDelay);
 
     /**
      * Handle to OSGI console
diff --git a/src/main/java/org/apache/sling/testing/clients/SlingClient.java b/src/main/java/org/apache/sling/testing/clients/SlingClient.java
index b96e979..4ecf731 100644
--- a/src/main/java/org/apache/sling/testing/clients/SlingClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/SlingClient.java
@@ -626,7 +626,8 @@
         private final HttpClientBuilder httpClientBuilder;
 
         protected InternalBuilder(URI url, String user, String password) {
-            this.httpClientBuilder = HttpClientBuilder.create();
+            this.httpClientBuilder = HttpClientBuilder.create()
+                    .setServiceUnavailableRetryStrategy(Constants.HTTP_RETRY_STRATEGY);
             this.configBuilder = SlingClientConfig.Builder.create().setUrl(url).setUser(user).setPassword(password);
 
             setDefaults();
diff --git a/src/main/java/org/apache/sling/testing/clients/interceptors/FormBasedAuthInterceptor.java b/src/main/java/org/apache/sling/testing/clients/interceptors/FormBasedAuthInterceptor.java
index ca461e6..9360f4b 100644
--- a/src/main/java/org/apache/sling/testing/clients/interceptors/FormBasedAuthInterceptor.java
+++ b/src/main/java/org/apache/sling/testing/clients/interceptors/FormBasedAuthInterceptor.java
@@ -27,8 +27,7 @@
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HttpContext;
-import org.apache.sling.testing.clients.ClientException;
-import org.apache.sling.testing.clients.SlingClient;
+import org.apache.sling.testing.clients.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,7 +75,9 @@
 
         HttpPost loginPost = new HttpPost(URI.create(request.getRequestLine().getUri()).resolve(loginPath));
         loginPost.setEntity(httpEntity);
-        final CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();
+        final CloseableHttpClient client = HttpClientBuilder.create()
+                .setServiceUnavailableRetryStrategy(Constants.HTTP_RETRY_STRATEGY)
+                .disableRedirectHandling().build();
 
         client.execute(host, loginPost, context);
 
diff --git a/src/main/java/org/apache/sling/testing/clients/util/LoggedServiceUnavailableRetryStrategy.java b/src/main/java/org/apache/sling/testing/clients/util/LoggedServiceUnavailableRetryStrategy.java
new file mode 100644
index 0000000..65bcf9f
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/clients/util/LoggedServiceUnavailableRetryStrategy.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.clients.util;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.annotation.Immutable;
+import org.apache.http.impl.client.DefaultServiceUnavailableRetryStrategy;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+@Immutable
+public class LoggedServiceUnavailableRetryStrategy extends DefaultServiceUnavailableRetryStrategy {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(LoggedServiceUnavailableRetryStrategy.class);
+
+    public LoggedServiceUnavailableRetryStrategy(final int maxRetries, final int retryInterval) {
+        super(maxRetries, retryInterval);
+    }
+
+    @Override
+    public boolean retryRequest(final HttpResponse response, final int executionCount, final HttpContext context) {
+        boolean needRetry = super.retryRequest(response, executionCount, context);
+        if (needRetry) {
+            LOGGER.warn("Request retry needed due to service unavailable response");
+            LOGGER.warn("Response headers contained:");
+            Arrays.stream(response.getAllHeaders()).forEach(h -> LOGGER.warn("Header {}:{}", h.getName(), h.getValue()));
+            try {
+                LOGGER.warn("Response content: {}", EntityUtils.toString(response.getEntity()));
+            } catch (IOException exc) {
+                LOGGER.warn("Response as no content");
+            }
+        }
+        return needRetry;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/clients/util/package-info.java b/src/main/java/org/apache/sling/testing/clients/util/package-info.java
index 7d4ac3b..d4c0bc1 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("1.0.0")
+@Version("1.1.0")
 package org.apache.sling.testing.clients.util;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/test/java/org/apache/sling/testing/clients/SlingClientRetryServiceUnavailableTest.java b/src/test/java/org/apache/sling/testing/clients/SlingClientRetryServiceUnavailableTest.java
new file mode 100644
index 0000000..2670983
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/clients/SlingClientRetryServiceUnavailableTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.clients;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class SlingClientRetryServiceUnavailableTest {
+    private static final String GET_UNAVAILABLE_PATH = "/test/unavailable/resource";
+    private static final String NOK_RESPONSE = "TEST_NOK";
+    private static final String OK_RESPONSE = "TEST_OK";
+
+    private static final int MAX_RETRIES = 5;
+
+    private static int requestCount = 0;
+    private static int availableAtRequestCount = Integer.MAX_VALUE;
+
+    static {
+        System.setProperty(Constants.CONFIG_PROP_PREFIX + "http.logRetries", "true");
+    }
+
+    @ClassRule
+    public static HttpServerRule httpServer = new HttpServerRule() {
+        @Override
+        protected void registerHandlers() throws IOException {
+            serverBootstrap.registerHandler(GET_UNAVAILABLE_PATH, new HttpRequestHandler() {
+                @Override
+                public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+                    requestCount++;
+                    if (requestCount == availableAtRequestCount) {
+                        response.setEntity(new StringEntity(OK_RESPONSE));
+                        response.setStatusCode(200);
+                    } else {
+                        response.setEntity(new StringEntity(NOK_RESPONSE));
+                        response.setStatusCode(503);
+                    }
+                }
+            });
+        }
+    };
+
+    @Test
+    public void testRetryReallyUnavailable() throws Exception {
+        requestCount = 0;
+        availableAtRequestCount = Integer.MAX_VALUE; // never available
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        SlingHttpResponse slingHttpResponse = c.doGet(GET_UNAVAILABLE_PATH, 503, 10);
+        assertEquals(MAX_RETRIES + 1, requestCount);
+        assertEquals(NOK_RESPONSE, slingHttpResponse.getContent());
+    }
+
+    @Test
+    public void testRetryEventuallyAvailable() throws Exception {
+        requestCount = 0;
+        availableAtRequestCount = 3;
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        SlingHttpResponse slingHttpResponse = c.doGet(GET_UNAVAILABLE_PATH, 200, 10);
+        assertEquals(availableAtRequestCount, requestCount);
+        assertEquals(OK_RESPONSE, slingHttpResponse.getContent());
+
+    }
+
+}