diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
new file mode 100644
index 000000000..989126553
--- /dev/null
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
@@ -0,0 +1,144 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+package org.apache.hc.client5.http.impl.cache;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.hc.client5.http.async.AsyncExecChainHandler;
+import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
+import org.apache.hc.client5.http.cache.HttpCacheStorage;
+import org.apache.hc.client5.http.cache.ResourceFactory;
+import org.apache.hc.client5.http.impl.ChainElements;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
+import org.apache.hc.core5.http.config.NamedElementChain;
+
+/**
+ * Builder for {@link org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient}
+ * instances capable of client-side caching.
+ *
+ * @since 5.0
+ */
+public class CachingHttpAsyncClientBuilder extends HttpAsyncClientBuilder {
+
+ private ResourceFactory resourceFactory;
+ private HttpCacheStorage storage;
+ private File cacheDir;
+ private CacheConfig cacheConfig;
+ private HttpCacheInvalidator httpCacheInvalidator;
+ private boolean deleteCache;
+
+ public static CachingHttpAsyncClientBuilder create() {
+ return new CachingHttpAsyncClientBuilder();
+ }
+
+ protected CachingHttpAsyncClientBuilder() {
+ super();
+ this.deleteCache = true;
+ }
+
+ public final CachingHttpAsyncClientBuilder setResourceFactory(
+ final ResourceFactory resourceFactory) {
+ this.resourceFactory = resourceFactory;
+ return this;
+ }
+
+ public final CachingHttpAsyncClientBuilder setHttpCacheStorage(
+ final HttpCacheStorage storage) {
+ this.storage = storage;
+ return this;
+ }
+
+ public final CachingHttpAsyncClientBuilder setCacheDir(
+ final File cacheDir) {
+ this.cacheDir = cacheDir;
+ return this;
+ }
+
+ public final CachingHttpAsyncClientBuilder setCacheConfig(
+ final CacheConfig cacheConfig) {
+ this.cacheConfig = cacheConfig;
+ return this;
+ }
+
+ public final CachingHttpAsyncClientBuilder setHttpCacheInvalidator(
+ final HttpCacheInvalidator cacheInvalidator) {
+ this.httpCacheInvalidator = cacheInvalidator;
+ return this;
+ }
+
+ public CachingHttpAsyncClientBuilder setDeleteCache(final boolean deleteCache) {
+ this.deleteCache = deleteCache;
+ return this;
+ }
+
+ @Override
+ protected void customizeExecChain(final NamedElementChain execChainDefinition) {
+ final CacheConfig config = this.cacheConfig != null ? this.cacheConfig : CacheConfig.DEFAULT;
+ // We copy the instance fields to avoid changing them, and rename to avoid accidental use of the wrong version
+ ResourceFactory resourceFactoryCopy = this.resourceFactory;
+ if (resourceFactoryCopy == null) {
+ if (this.cacheDir == null) {
+ resourceFactoryCopy = new HeapResourceFactory();
+ } else {
+ resourceFactoryCopy = new FileResourceFactory(cacheDir);
+ }
+ }
+ HttpCacheStorage storageCopy = this.storage;
+ if (storageCopy == null) {
+ if (this.cacheDir == null) {
+ storageCopy = new BasicHttpCacheStorage(config);
+ } else {
+ final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
+ if (this.deleteCache) {
+ addCloseable(new Closeable() {
+
+ @Override
+ public void close() throws IOException {
+ managedStorage.shutdown();
+ }
+
+ });
+ } else {
+ addCloseable(managedStorage);
+ }
+ storageCopy = managedStorage;
+ }
+ }
+ final CacheKeyGenerator uriExtractor = new CacheKeyGenerator();
+ final HttpCache httpCache = new BasicHttpCache(
+ resourceFactoryCopy,
+ storageCopy,
+ uriExtractor,
+ this.httpCacheInvalidator != null ? this.httpCacheInvalidator : new CacheInvalidator(uriExtractor, storageCopy));
+
+ final AsyncCachingExec cachingExec = new AsyncCachingExec(httpCache, config);
+ execChainDefinition.addBefore(ChainElements.PROTOCOL.name(), cachingExec, ChainElements.CACHING.name());
+ }
+
+}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClients.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClients.java
new file mode 100644
index 000000000..7356b8188
--- /dev/null
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClients.java
@@ -0,0 +1,75 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.hc.client5.http.impl.cache;
+
+import java.io.File;
+
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+
+/**
+ * Factory methods for {@link CloseableHttpAsyncClient} instances
+ * capable of client-side caching.
+ *
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public class CachingHttpAsyncClients {
+
+ private CachingHttpAsyncClients() {
+ super();
+ }
+
+ /**
+ * Creates builder object for construction of custom
+ * {@link CloseableHttpAsyncClient} instances.
+ */
+ public static CachingHttpAsyncClientBuilder custom() {
+ return CachingHttpAsyncClientBuilder.create();
+ }
+
+ /**
+ * Creates {@link CloseableHttpAsyncClient} instance that uses a memory bound
+ * response cache.
+ */
+ public static CloseableHttpAsyncClient createMemoryBound() {
+ return CachingHttpAsyncClientBuilder.create().build();
+ }
+
+ /**
+ * Creates {@link CloseableHttpAsyncClient} instance that uses a file system
+ * bound response cache.
+ *
+ * @param cacheDir location of response cache.
+ */
+ public static CloseableHttpAsyncClient createFileBound(final File cacheDir) {
+ return CachingHttpAsyncClientBuilder.create().setCacheDir(cacheDir).build();
+ }
+
+}
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
index 3a221e178..158361e55 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
@@ -138,7 +138,7 @@ public void close() throws IOException {
this.httpCacheInvalidator != null ? this.httpCacheInvalidator : new CacheInvalidator(uriExtractor, storageCopy));
final CachingExec cachingExec = new CachingExec(httpCache, config);
- execChainDefinition.addAfter(ChainElements.PROTOCOL.name(), cachingExec, "CACHING");
+ execChainDefinition.addBefore(ChainElements.PROTOCOL.name(), cachingExec, ChainElements.CACHING.name());
}
}
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ChainElements.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ChainElements.java
index d570a4b9b..99d252378 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ChainElements.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ChainElements.java
@@ -29,6 +29,6 @@
public enum ChainElements {
- REDIRECT, BACK_OFF, RETRY_SERVICE_UNAVAILABLE, RETRY_IO_ERROR, PROTOCOL, CONNECT, MAIN_TRANSPORT
+ REDIRECT, BACK_OFF, RETRY_SERVICE_UNAVAILABLE, RETRY_IO_ERROR, CACHING, PROTOCOL, CONNECT, MAIN_TRANSPORT
}
\ No newline at end of file