hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject [1/7] httpcomponents-client git commit: Redesign of HTTP cache resource APIs
Date Tue, 03 Oct 2017 08:51:36 GMT
Repository: httpcomponents-client
Updated Branches:
  refs/heads/master e2a464084 -> 212d7a2e8


Redesign of HTTP cache resource APIs


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/73c67f22
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/73c67f22
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/73c67f22

Branch: refs/heads/master
Commit: 73c67f221db8dc4a3f1f61876fcb79adac04fbe0
Parents: e2a4640
Author: Oleg Kalnichevski <olegk@apache.org>
Authored: Sat Sep 23 18:15:40 2017 +0200
Committer: Oleg Kalnichevski <olegk@apache.org>
Committed: Mon Oct 2 17:33:41 2017 +0200

----------------------------------------------------------------------
 .../hc/client5/http/cache/InputLimit.java       |  73 -------
 .../apache/hc/client5/http/cache/Resource.java  |  31 ++-
 .../hc/client5/http/cache/ResourceFactory.java  |  34 ++--
 .../client5/http/cache/ResourceIOException.java |  45 +++++
 .../client5/http/impl/cache/BasicHttpCache.java |  66 +++----
 .../hc/client5/http/impl/cache/CachingExec.java |   2 +-
 .../client5/http/impl/cache/CombinedEntity.java |  71 ++++---
 .../client5/http/impl/cache/FileResource.java   |  68 +++++--
 .../http/impl/cache/FileResourceFactory.java    |  46 +++--
 .../client5/http/impl/cache/HeapResource.java   |  31 +--
 .../http/impl/cache/HeapResourceFactory.java    |  48 ++---
 .../impl/cache/SizeLimitedResponseReader.java   | 146 --------------
 .../http/impl/cache/TestBasicHttpCache.java     |  48 +----
 .../http/impl/cache/TestCombinedEntity.java     |  25 ++-
 .../cache/TestSizeLimitedResponseReader.java    | 196 -------------------
 15 files changed, 288 insertions(+), 642 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/InputLimit.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/InputLimit.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/InputLimit.java
deleted file mode 100644
index 9f1e63e..0000000
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/InputLimit.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ====================================================================
- * 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
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.cache;
-
-/**
- * Used to limiting the size of an incoming response body of
- * unknown size that is optimistically being read in anticipation
- * of caching it.
- * @since 4.1
- */
-public class InputLimit {
-
-    private final long value;
-    private boolean reached;
-
-    /**
-     * Create a limit for how many bytes of a response body to
-     * read.
-     * @param value maximum length in bytes
-     */
-    public InputLimit(final long value) {
-        super();
-        this.value = value;
-        this.reached = false;
-    }
-
-    /**
-     * Returns the current maximum limit that was set on
-     * creation.
-     */
-    public long getValue() {
-        return this.value;
-    }
-
-    /**
-     * Used to report that the limit has been reached.
-     */
-    public void reached() {
-        this.reached = true;
-    }
-
-    /**
-     * Returns {@code true} if the input limit has been reached.
-     */
-    public boolean isReached() {
-        return this.reached;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/Resource.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/Resource.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/Resource.java
index 992b784..66afc53 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/Resource.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/Resource.java
@@ -26,7 +26,7 @@
  */
 package org.apache.hc.client5.http.cache;
 
-import java.io.IOException;
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.Serializable;
 
@@ -36,25 +36,40 @@ import java.io.Serializable;
  *
  * @since 4.1
  */
-public interface Resource extends Serializable {
+public abstract class Resource implements Serializable {
 
     /**
-     * Returns an {@link InputStream} from which the response
-     * body can be read.
-     * @throws IOException
+     * Returns resource content as a {@link InputStream}.
+     *
+     * @throws ResourceIOException
      */
-    InputStream getInputStream() throws IOException;
+    public InputStream getInputStream() throws ResourceIOException {
+        return new ByteArrayInputStream(get());
+    }
+
+    /**
+     * Returns resource content as a byte array.
+     * <p>
+     * Please note for memory efficiency some resource implementations
+     * may return a reference to the underlying byte array. The returned
+     * value should be treated as immutable.
+     *
+     * @throws ResourceIOException
+     *
+     * @since 5.0
+     */
+    public abstract byte[] get() throws ResourceIOException;
 
     /**
      * Returns the length in bytes of the response body.
      */
-    long length();
+    public abstract long length();
 
     /**
      * Indicates the system no longer needs to keep this
      * response body and any system resources associated with
      * it may be reclaimed.
      */
-    void dispose();
+    public abstract void dispose();
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceFactory.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceFactory.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceFactory.java
index 7bd1d1f..e94a82b 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceFactory.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceFactory.java
@@ -26,9 +26,6 @@
  */
 package org.apache.hc.client5.http.cache;
 
-import java.io.IOException;
-import java.io.InputStream;
-
 /**
  * Generates {@link Resource} instances for handling cached
  * HTTP response bodies.
@@ -39,20 +36,25 @@ public interface ResourceFactory {
 
     /**
      * Creates a {@link Resource} from a given response body.
-     * @param requestId a unique identifier for this particular
-     *   response body
-     * @param instream the original {@link InputStream}
-     *   containing the response body of the origin HTTP response.
-     * @param limit maximum number of bytes to consume of the
-     *   response body; if this limit is reached before the
-     *   response body is fully consumed, mark the limit has
-     *   having been reached and return a {@code Resource}
-     *   containing the data read to that point.
+     * @param requestId a unique identifier for this particular response body.
+     * @param content byte array that represents the origin HTTP response body.
+     * @return a {@code Resource} containing however much of
+     *   the response body was successfully read.
+     * @throws ResourceIOException
+     */
+    Resource generate(String requestId, byte[] content) throws ResourceIOException;
+
+    /**
+     * Creates a {@link Resource} from a given response body.
+     * @param requestId a unique identifier for this particular response body.
+     * @param content byte array that represents the origin HTTP response body.
+     * @param off   the start offset in the array.
+     * @param len   the number of bytes to read from the array.
      * @return a {@code Resource} containing however much of
      *   the response body was successfully read.
-     * @throws IOException
+     * @throws ResourceIOException
      */
-    Resource generate(String requestId, InputStream instream, InputLimit limit) throws IOException;
+    Resource generate(String requestId, byte[] content, int off, int len) throws ResourceIOException;
 
     /**
      * Clones an existing {@link Resource}.
@@ -60,8 +62,8 @@ public interface ResourceFactory {
      *   with the cloned response body.
      * @param resource the original response body to clone.
      * @return the {@code Resource} copy
-     * @throws IOException
+     * @throws ResourceIOException
      */
-    Resource copy(String requestId, Resource resource) throws IOException;
+    Resource copy(String requestId, Resource resource) throws ResourceIOException;
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceIOException.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceIOException.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceIOException.java
new file mode 100644
index 0000000..6ec7fec
--- /dev/null
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/ResourceIOException.java
@@ -0,0 +1,45 @@
+/*
+ * ====================================================================
+ * 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
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.cache;
+
+import java.io.IOException;
+
+/**
+ * Signals a generic resource I/O error.
+ */
+public class ResourceIOException extends IOException {
+
+    public ResourceIOException(final String message) {
+        super();
+    }
+
+    public ResourceIOException(final String message, final Throwable cause) {
+        super(message);
+        initCause(cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
index 9d57149..d692fa4 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
@@ -27,6 +27,7 @@
 package org.apache.hc.client5.http.impl.cache;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
@@ -44,6 +45,7 @@ import org.apache.hc.client5.http.cache.Resource;
 import org.apache.hc.client5.http.cache.ResourceFactory;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
@@ -51,6 +53,7 @@ import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.util.ByteArrayBuffer;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -288,41 +291,38 @@ class BasicHttpCache implements HttpCache {
             final ClassicHttpResponse originResponse,
             final Date requestSent,
             final Date responseReceived) throws IOException {
-
-        boolean closeOriginResponse = true;
-        final SizeLimitedResponseReader responseReader = getResponseReader(request, originResponse);
-        try {
-            responseReader.readResponse();
-
-            if (responseReader.isLimitReached()) {
-                closeOriginResponse = false;
-                return responseReader.getReconstructedResponse();
-            }
-
-            final Resource resource = responseReader.getResource();
-            if (isIncompleteResponse(originResponse, resource)) {
-                return generateIncompleteResponseError(originResponse, resource);
-            }
-
-            final HttpCacheEntry entry = new HttpCacheEntry(
-                    requestSent,
-                    responseReceived,
-                    originResponse.getCode(),
-                    originResponse.getAllHeaders(),
-                    resource);
-            storeInCache(host, request, entry);
-            return responseGenerator.generateResponse(request, entry);
-        } finally {
-            if (closeOriginResponse) {
-                originResponse.close();
+        final Resource resource;
+        final HttpEntity entity = originResponse.getEntity();
+        if (entity != null) {
+            final ByteArrayBuffer buf = new ByteArrayBuffer(1024);
+            final InputStream instream = entity.getContent();
+            final byte[] tmp = new byte[2048];
+            long total = 0;
+            int l;
+            while ((l = instream.read(tmp)) != -1) {
+                buf.append(tmp, 0, l);
+                total += l;
+                if (total > maxObjectSizeBytes) {
+                    originResponse.setEntity(new CombinedEntity(entity, buf));
+                    return originResponse;
+                }
             }
+            resource = resourceFactory.generate(request.getRequestUri(), buf.array(), 0, buf.length());
+        } else {
+            resource = null;
         }
-    }
-
-    SizeLimitedResponseReader getResponseReader(final HttpRequest request,
-            final ClassicHttpResponse backEndResponse) {
-        return new SizeLimitedResponseReader(
-                resourceFactory, maxObjectSizeBytes, request, backEndResponse);
+        originResponse.close();
+        if (isIncompleteResponse(originResponse, resource)) {
+            return generateIncompleteResponseError(originResponse, resource);
+        }
+        final HttpCacheEntry entry = new HttpCacheEntry(
+                requestSent,
+                responseReceived,
+                originResponse.getCode(),
+                originResponse.getAllHeaders(),
+                resource);
+        storeInCache(host, request, entry);
+        return responseGenerator.generateResponse(request, entry);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
index 2db9a93..d1670b1 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
@@ -298,7 +298,7 @@ public class CachingExec implements ExecChainHandler {
             final ExecChain.Scope scope,
             final ExecChain chain,
             final HttpCacheEntry entry,
-            final Date now) throws HttpException {
+            final Date now) throws HttpException, IOException {
 
         final HttpClientContext context = scope.clientContext;
         try {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CombinedEntity.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CombinedEntity.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CombinedEntity.java
index b41a326..40ab706 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CombinedEntity.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CombinedEntity.java
@@ -26,26 +26,31 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
-import java.io.FilterInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.SequenceInputStream;
+import java.util.List;
+import java.util.Set;
 
-import org.apache.hc.client5.http.cache.Resource;
-import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.ByteArrayBuffer;
 
-class CombinedEntity extends AbstractHttpEntity {
+class CombinedEntity implements HttpEntity {
 
-    private final Resource resource;
+    private final HttpEntity entity;
     private final InputStream combinedStream;
 
-    CombinedEntity(final Resource resource, final InputStream instream) throws IOException {
+    CombinedEntity(final HttpEntity entity, final ByteArrayBuffer buf) throws IOException {
         super();
-        this.resource = resource;
+        this.entity = entity;
         this.combinedStream = new SequenceInputStream(
-                new ResourceStream(resource.getInputStream()), instream);
+                new ByteArrayInputStream(buf.array(), 0, buf.length()),
+                entity.getContent());
     }
 
     @Override
@@ -54,6 +59,21 @@ class CombinedEntity extends AbstractHttpEntity {
     }
 
     @Override
+    public String getContentType() {
+        return entity.getContentType();
+    }
+
+    @Override
+    public String getContentEncoding() {
+        return entity.getContentEncoding();
+    }
+
+    @Override
+    public boolean isChunked() {
+        return true;
+    }
+
+    @Override
     public boolean isRepeatable() {
         return false;
     }
@@ -69,6 +89,16 @@ class CombinedEntity extends AbstractHttpEntity {
     }
 
     @Override
+    public Set<String> getTrailerNames() {
+        return entity.getTrailerNames();
+    }
+
+    @Override
+    public Supplier<List<? extends Header>> getTrailers() {
+        return entity.getTrailers();
+    }
+
+    @Override
     public void writeTo(final OutputStream outstream) throws IOException {
         Args.notNull(outstream, "Output stream");
         try (InputStream instream = getContent()) {
@@ -82,28 +112,11 @@ class CombinedEntity extends AbstractHttpEntity {
 
     @Override
     public void close() throws IOException {
-        dispose();
-    }
-
-    private void dispose() {
-        this.resource.dispose();
-    }
-
-    class ResourceStream extends FilterInputStream {
-
-        protected ResourceStream(final InputStream in) {
-            super(in);
-        }
-
-        @Override
-        public void close() throws IOException {
-            try {
-                super.close();
-            } finally {
-                dispose();
-            }
+        try {
+            combinedStream.close();
+        } finally {
+            entity.close();
         }
-
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResource.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResource.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResource.java
index e92ae9a..321e200 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResource.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResource.java
@@ -28,12 +28,17 @@ package org.apache.hc.client5.http.impl.cache;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.hc.client5.http.cache.Resource;
+import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.ByteArrayBuffer;
 
 /**
  * Cache resource backed by a file.
@@ -41,41 +46,70 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
  * @since 4.1
  */
 @Contract(threading = ThreadingBehavior.SAFE)
-public class FileResource implements Resource {
+public class FileResource extends Resource {
 
     private static final long serialVersionUID = 4132244415919043397L;
 
-    private final File file;
-
-    private volatile boolean disposed;
+    private final AtomicReference<File> fileRef;
 
     public FileResource(final File file) {
         super();
-        this.file = file;
-        this.disposed = false;
+        this.fileRef = new AtomicReference<>(Args.notNull(file, "File"));
+    }
+
+    File getFile() {
+        return this.fileRef.get();
     }
 
-    synchronized File getFile() {
-        return this.file;
+    @Override
+    public byte[] get() throws ResourceIOException {
+        final File file = this.fileRef.get();
+        if (file == null) {
+            throw new ResourceIOException("Resouce already dispoased");
+        }
+        try (final InputStream in = new FileInputStream(file)) {
+            final ByteArrayBuffer buf = new ByteArrayBuffer(1024);
+            final byte[] tmp = new byte[2048];
+            int len;
+            while ((len = in.read(tmp)) != -1) {
+                buf.append(tmp, 0, len);
+            }
+            return buf.toByteArray();
+        } catch (final IOException ex) {
+            throw new ResourceIOException(ex.getMessage(), ex);
+        }
     }
 
     @Override
-    public synchronized InputStream getInputStream() throws IOException {
-        return new FileInputStream(this.file);
+    public InputStream getInputStream() throws ResourceIOException {
+        final File file = this.fileRef.get();
+        if (file != null) {
+            try {
+                return new FileInputStream(file);
+            } catch (final FileNotFoundException ex) {
+                throw new ResourceIOException(ex.getMessage(), ex);
+            }
+        } else {
+            throw new ResourceIOException("Resouce already dispoased");
+        }
     }
 
     @Override
-    public synchronized long length() {
-        return this.file.length();
+    public long length() {
+        final File file = this.fileRef.get();
+        if (file != null) {
+            return file.length();
+        } else {
+            return -1;
+        }
     }
 
     @Override
-    public synchronized void dispose() {
-        if (this.disposed) {
-            return;
+    public void dispose() {
+        final File file = this.fileRef.getAndSet(null);
+        if (file != null) {
+            file.delete();
         }
-        this.disposed = true;
-        this.file.delete();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResourceFactory.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResourceFactory.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResourceFactory.java
index 253385a..b3c59ff 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResourceFactory.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/FileResourceFactory.java
@@ -29,13 +29,13 @@ package org.apache.hc.client5.http.impl.cache;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 
-import org.apache.hc.client5.http.cache.InputLimit;
 import org.apache.hc.client5.http.cache.Resource;
 import org.apache.hc.client5.http.cache.ResourceFactory;
+import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.util.Args;
 
 /**
  * Generates {@link Resource} instances whose body is stored in a temporary file.
@@ -73,37 +73,41 @@ public class FileResourceFactory implements ResourceFactory {
     @Override
     public Resource generate(
             final String requestId,
-            final InputStream instream,
-            final InputLimit limit) throws IOException {
+            final byte[] content, final int off, final int len) throws ResourceIOException {
+        Args.notNull(requestId, "Request id");
         final File file = generateUniqueCacheFile(requestId);
         try (FileOutputStream outstream = new FileOutputStream(file)) {
-            final byte[] buf = new byte[2048];
-            long total = 0;
-            int l;
-            while ((l = instream.read(buf)) != -1) {
-                outstream.write(buf, 0, l);
-                total += l;
-                if (limit != null && total > limit.getValue()) {
-                    limit.reached();
-                    break;
-                }
+            if (content != null) {
+                outstream.write(content, off, len);
             }
+        } catch (final IOException ex) {
+            throw new ResourceIOException(ex.getMessage(), ex);
         }
         return new FileResource(file);
     }
 
     @Override
+    public Resource generate(final String requestId, final byte[] content) throws ResourceIOException {
+        Args.notNull(content, "Content");
+        return generate(requestId, content, 0, content.length);
+    }
+
+    @Override
     public Resource copy(
             final String requestId,
-            final Resource resource) throws IOException {
+            final Resource resource) throws ResourceIOException {
         final File file = generateUniqueCacheFile(requestId);
 
-        if (resource instanceof FileResource) {
-            final File src = ((FileResource) resource).getFile();
-            IOUtils.copyFile(src, file);
-        } else {
-            final FileOutputStream out = new FileOutputStream(file);
-            IOUtils.copyAndClose(resource.getInputStream(), out);
+        try {
+            if (resource instanceof FileResource) {
+                final File src = ((FileResource) resource).getFile();
+                IOUtils.copyFile(src, file);
+            } else {
+                final FileOutputStream out = new FileOutputStream(file);
+                IOUtils.copyAndClose(resource.getInputStream(), out);
+            }
+        } catch (final IOException ex) {
+            throw new ResourceIOException(ex.getMessage(), ex);
         }
         return new FileResource(file);
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResource.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResource.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResource.java
index bbb0bee..2473205 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResource.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResource.java
@@ -26,10 +26,10 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.hc.client5.http.cache.Resource;
+import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 
@@ -39,33 +39,40 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
  * @since 4.1
  */
 @Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class HeapResource implements Resource {
+public class HeapResource extends Resource {
 
     private static final long serialVersionUID = -2078599905620463394L;
 
-    private final byte[] b;
+    private final AtomicReference<byte[]> arrayRef;
 
     public HeapResource(final byte[] b) {
         super();
-        this.b = b;
-    }
-
-    byte[] getByteArray() {
-        return this.b;
+        this.arrayRef = new AtomicReference<>(b);
     }
 
     @Override
-    public InputStream getInputStream() {
-        return new ByteArrayInputStream(this.b);
+    public byte[] get() throws ResourceIOException {
+        final byte[] byteArray = this.arrayRef.get();
+        if (byteArray != null) {
+            return byteArray;
+        } else {
+            throw new ResourceIOException("Resouce already dispoased");
+        }
     }
 
     @Override
     public long length() {
-        return this.b.length;
+        final byte[] byteArray = this.arrayRef.get();
+        if (byteArray != null) {
+            return byteArray.length;
+        } else {
+            return -1;
+        }
     }
 
     @Override
     public void dispose() {
+        this.arrayRef.set(null);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResourceFactory.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResourceFactory.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResourceFactory.java
index b3528a0..7b7d439 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResourceFactory.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HeapResourceFactory.java
@@ -26,15 +26,12 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.hc.client5.http.cache.InputLimit;
 import org.apache.hc.client5.http.cache.Resource;
 import org.apache.hc.client5.http.cache.ResourceFactory;
+import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.util.Args;
 
 /**
  * Generates {@link Resource} instances stored entirely in heap.
@@ -47,40 +44,23 @@ public class HeapResourceFactory implements ResourceFactory {
     @Override
     public Resource generate(
             final String requestId,
-            final InputStream instream,
-            final InputLimit limit) throws IOException {
-        final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-        final byte[] buf = new byte[2048];
-        long total = 0;
-        int l;
-        while ((l = instream.read(buf)) != -1) {
-            outstream.write(buf, 0, l);
-            total += l;
-            if (limit != null && total > limit.getValue()) {
-                limit.reached();
-                break;
-            }
-        }
-        return createResource(outstream.toByteArray());
+            final byte[] content, final int off, final int len) throws ResourceIOException {
+        final byte[] copy = new byte[len];
+        System.arraycopy(content, off, copy, 0, len);
+        return new HeapResource(copy);
     }
 
     @Override
-    public Resource copy(
-            final String requestId,
-            final Resource resource) throws IOException {
-        final byte[] body;
-        if (resource instanceof HeapResource) {
-            body = ((HeapResource) resource).getByteArray();
-        } else {
-            final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
-            IOUtils.copyAndClose(resource.getInputStream(), outstream);
-            body = outstream.toByteArray();
-        }
-        return createResource(body);
+    public Resource generate(final String requestId, final byte[] content) {
+        return new HeapResource(content != null ? content.clone() : null);
     }
 
-    Resource createResource(final byte[] buf) {
-        return new HeapResource(buf);
+    @Override
+    public Resource copy(
+            final String requestId,
+            final Resource resource) throws ResourceIOException {
+        Args.notNull(resource, "Resource");
+        return new HeapResource(resource.get());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/SizeLimitedResponseReader.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/SizeLimitedResponseReader.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/SizeLimitedResponseReader.java
deleted file mode 100644
index 56a7259..0000000
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/SizeLimitedResponseReader.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * ====================================================================
- * 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
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.cache;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.hc.client5.http.cache.InputLimit;
-import org.apache.hc.client5.http.cache.Resource;
-import org.apache.hc.client5.http.cache.ResourceFactory;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
-
-/**
- * @since 4.1
- */
-class SizeLimitedResponseReader {
-
-    private final ResourceFactory resourceFactory;
-    private final long maxResponseSizeBytes;
-    private final HttpRequest request;
-    private final ClassicHttpResponse response;
-
-    private InputStream instream;
-    private InputLimit limit;
-    private Resource resource;
-    private boolean consumed;
-
-    /**
-     * Create an {@link ClassicHttpResponse} that is limited in size, this allows for checking
-     * the size of objects that will be stored in the cache.
-     */
-    public SizeLimitedResponseReader(
-            final ResourceFactory resourceFactory,
-            final long maxResponseSizeBytes,
-            final HttpRequest request,
-            final ClassicHttpResponse response) {
-        super();
-        this.resourceFactory = resourceFactory;
-        this.maxResponseSizeBytes = maxResponseSizeBytes;
-        this.request = request;
-        this.response = response;
-    }
-
-    protected void readResponse() throws IOException {
-        if (!consumed) {
-            doConsume();
-        }
-    }
-
-    private void ensureNotConsumed() {
-        if (consumed) {
-            throw new IllegalStateException("Response has already been consumed");
-        }
-    }
-
-    private void ensureConsumed() {
-        if (!consumed) {
-            throw new IllegalStateException("Response has not been consumed");
-        }
-    }
-
-    private void doConsume() throws IOException {
-        ensureNotConsumed();
-        consumed = true;
-
-        limit = new InputLimit(maxResponseSizeBytes);
-
-        final HttpEntity entity = response.getEntity();
-        if (entity == null) {
-            return;
-        }
-        final String uri = request.getRequestUri();
-        instream = entity.getContent();
-        try {
-            resource = resourceFactory.generate(uri, instream, limit);
-        } finally {
-            if (!limit.isReached()) {
-                instream.close();
-            }
-        }
-    }
-
-    boolean isLimitReached() {
-        ensureConsumed();
-        return limit.isReached();
-    }
-
-    Resource getResource() {
-        ensureConsumed();
-        return resource;
-    }
-
-    ClassicHttpResponse getReconstructedResponse() throws IOException {
-        ensureConsumed();
-        final ClassicHttpResponse reconstructed = new BasicClassicHttpResponse(response.getCode()) {
-
-            @Override
-            public void close() throws IOException {
-                try {
-                    super.close();
-                } finally {
-                    response.close();
-                }
-            }
-        };
-        reconstructed.setHeaders(response.getAllHeaders());
-
-        final CombinedEntity combinedEntity = new CombinedEntity(resource, instream);
-        final HttpEntity entity = response.getEntity();
-        if (entity != null) {
-            combinedEntity.setContentType(entity.getContentType());
-            combinedEntity.setContentEncoding(entity.getContentEncoding());
-            combinedEntity.setChunked(entity.isChunked());
-        }
-        reconstructed.setEntity(combinedEntity);
-        return reconstructed;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
index 2caba32..6b4d473 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java
@@ -35,7 +35,6 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.Date;
 import java.util.HashMap;
@@ -359,7 +358,7 @@ public class TestBasicHttpCache {
 
         final ClassicHttpResponse result = impl.cacheAndReturnResponse(host, request, originResponse, requestSent, responseReceived);
         assertEquals(0, backing.map.size());
-        assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result));
+        assertSame(originResponse, result);
     }
 
 
@@ -521,53 +520,10 @@ public class TestBasicHttpCache {
         assertTrue(inputStream.wasClosed());
     }
 
-    static class DisposableResource implements Resource {
-
-        private static final long serialVersionUID = 1L;
-
-        private final byte[] b;
-        private boolean dispoased;
-
-        public DisposableResource(final byte[] b) {
-            super();
-            this.b = b;
-        }
-
-        byte[] getByteArray() {
-            return this.b;
-        }
-
-        @Override
-        public InputStream getInputStream() throws IOException {
-            if (dispoased) {
-                throw new IOException("Already dispoased");
-            }
-            return new ByteArrayInputStream(this.b);
-        }
-
-        @Override
-        public long length() {
-            return this.b.length;
-        }
-
-        @Override
-        public void dispose() {
-            this.dispoased = true;
-        }
-
-    }
-
     @Test
     public void testEntryUpdate() throws Exception {
 
-        final HeapResourceFactory rf = new HeapResourceFactory() {
-
-            @Override
-            Resource createResource(final byte[] buf) {
-                return new DisposableResource(buf);
-            }
-
-        };
+        final HeapResourceFactory rf = new HeapResourceFactory();
 
         impl = new BasicHttpCache(rf, backing, CacheConfig.DEFAULT);
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCombinedEntity.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCombinedEntity.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCombinedEntity.java
index 788c176..aa9d247 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCombinedEntity.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCombinedEntity.java
@@ -32,8 +32,9 @@ import static org.mockito.Mockito.when;
 
 import java.io.ByteArrayInputStream;
 
-import org.apache.hc.client5.http.cache.Resource;
+import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.util.ByteArrayBuffer;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -41,21 +42,25 @@ public class TestCombinedEntity {
 
     @Test
     public void testCombinedEntityBasics() throws Exception {
-        final Resource resource = mock(Resource.class);
-        when(resource.getInputStream()).thenReturn(
-                new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 }));
+        final HttpEntity httpEntity = mock(HttpEntity.class);
+        when(httpEntity.getContent()).thenReturn(
+                new ByteArrayInputStream(new byte[] { 6, 7, 8, 9, 10 }));
 
-        final ByteArrayInputStream instream = new ByteArrayInputStream(new byte[] { 6, 7, 8, 9, 10 });
-        final CombinedEntity entity = new CombinedEntity(resource, instream);
+        final ByteArrayBuffer buf = new ByteArrayBuffer(1024);
+        final byte[] tmp = new byte[] { 1, 2, 3, 4, 5 };
+        buf.append(tmp, 0, tmp.length);
+        final CombinedEntity entity = new CombinedEntity(httpEntity, buf);
         Assert.assertEquals(-1, entity.getContentLength());
         Assert.assertFalse(entity.isRepeatable());
         Assert.assertTrue(entity.isStreaming());
 
-        final byte[] result = EntityUtils.toByteArray(entity);
-        Assert.assertArrayEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, result);
+        Assert.assertArrayEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, EntityUtils.toByteArray(entity));
 
-        verify(resource).getInputStream();
-        verify(resource).dispose();
+        verify(httpEntity).getContent();
+
+        entity.close();
+
+        verify(httpEntity).close();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/73c67f22/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestSizeLimitedResponseReader.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestSizeLimitedResponseReader.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestSizeLimitedResponseReader.java
deleted file mode 100644
index 49454ed..0000000
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestSizeLimitedResponseReader.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * ====================================================================
- * 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
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.cache;
-
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.hc.client5.http.classic.methods.HttpGet;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestSizeLimitedResponseReader {
-
-    private static final long MAX_SIZE = 4;
-
-    private HttpRequest request;
-    private SizeLimitedResponseReader impl;
-
-    @Before
-    public void setUp() {
-        request = new HttpGet("http://foo.example.com/bar");
-    }
-
-    @Test
-    public void testLargeResponseIsTooLarge() throws Exception {
-        final byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
-        final ClassicHttpResponse response = make200Response(buf);
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-        final ClassicHttpResponse result = impl.getReconstructedResponse();
-        final byte[] body = EntityUtils.toByteArray(result.getEntity());
-
-        Assert.assertTrue(tooLarge);
-        Assert.assertArrayEquals(buf, body);
-    }
-
-    @Test
-    public void testExactSizeResponseIsNotTooLarge() throws Exception {
-        final byte[] buf = new byte[] { 1, 2, 3, 4 };
-        final ClassicHttpResponse response = make200Response(buf);
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-        final ClassicHttpResponse reconstructed = impl.getReconstructedResponse();
-        final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity());
-
-        Assert.assertFalse(tooLarge);
-        Assert.assertArrayEquals(buf, result);
-    }
-
-    @Test
-    public void testSmallResponseIsNotTooLarge() throws Exception {
-        final byte[] buf = new byte[] { 1, 2, 3 };
-        final ClassicHttpResponse response = make200Response(buf);
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-        final ClassicHttpResponse reconstructed = impl.getReconstructedResponse();
-        final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity());
-
-        Assert.assertFalse(tooLarge);
-        Assert.assertArrayEquals(buf, result);
-    }
-
-    @Test
-    public void testResponseWithNoEntityIsNotTooLarge() throws Exception {
-        final ClassicHttpResponse response = make200Response();
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-
-        Assert.assertFalse(tooLarge);
-    }
-
-    @Test
-    public void testTooLargeEntityHasOriginalContentTypes() throws Exception {
-        final ClassicHttpResponse response = make200Response();
-        final StringEntity entity = new StringEntity("large entity content");
-        response.setEntity(entity);
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-        final ClassicHttpResponse result = impl.getReconstructedResponse();
-        final HttpEntity reconstructedEntity = result.getEntity();
-        Assert.assertEquals(entity.getContentEncoding(), reconstructedEntity.getContentEncoding());
-        Assert.assertEquals(entity.getContentType(), reconstructedEntity.getContentType());
-
-        final String content = EntityUtils.toString(reconstructedEntity);
-
-        Assert.assertTrue(tooLarge);
-        Assert.assertEquals("large entity content", content);
-    }
-
-    @Test
-    public void testTooLargeResponseCombinedClosed() throws Exception {
-        final AtomicBoolean closed = new AtomicBoolean(false);
-        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK") {
-            @Override
-            public void close() throws IOException {
-                closed.set(true);
-            }
-        };
-        final StringEntity entity = new StringEntity("large entity content");
-        response.setEntity(entity);
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-        try (ClassicHttpResponse result = impl.getReconstructedResponse()) {
-            final HttpEntity reconstructedEntity = result.getEntity();
-            Assert.assertEquals(entity.getContentEncoding(), reconstructedEntity.getContentEncoding());
-            Assert.assertEquals(entity.getContentType(), reconstructedEntity.getContentType());
-
-            Assert.assertFalse(closed.get());
-            final String content = EntityUtils.toString(reconstructedEntity);
-
-            Assert.assertTrue(tooLarge);
-            Assert.assertEquals("large entity content", content);
-        }
-        Assert.assertTrue(closed.get());
-    }
-
-    @Test
-    public void testResponseCopiesAllOriginalHeaders() throws Exception {
-        final byte[] buf = new byte[] { 1, 2, 3 };
-        final ClassicHttpResponse response = make200Response(buf);
-        response.setHeader("Content-Encoding", "gzip");
-
-        impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
-
-        impl.readResponse();
-        final boolean tooLarge = impl.isLimitReached();
-        final ClassicHttpResponse reconstructed = impl.getReconstructedResponse();
-        final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity());
-
-        Assert.assertFalse(tooLarge);
-        Assert.assertArrayEquals(buf, result);
-        Assert.assertEquals("gzip", reconstructed.getFirstHeader("Content-Encoding").getValue());
-    }
-
-    private ClassicHttpResponse make200Response() {
-        return new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK");
-    }
-
-    private ClassicHttpResponse make200Response(final byte[] buf) {
-        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK");
-        response.setEntity(new ByteArrayEntity(buf));
-        return response;
-    }
-
-}


Mime
View raw message