hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r984949 - in /httpcomponents/httpclient/trunk/httpclient-cache/src: main/java/org/apache/http/client/cache/ main/java/org/apache/http/impl/client/cache/ test/java/org/apache/http/impl/client/cache/
Date Thu, 12 Aug 2010 20:32:54 GMT
Author: olegk
Date: Thu Aug 12 20:32:54 2010
New Revision: 984949

URL: http://svn.apache.org/viewvc?rev=984949&view=rev
Log:
SizeLimitedResponseReader can now generate arbitrary type of cache resources using resource
factory

Added:
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
  (with props)
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
  (with props)
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
  (with props)
Removed:
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedInputStream.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedInputStream.java
Modified:
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFactory.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResourceFactory.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResourceFactory.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLimitedResponseReader.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSizeLimitedResponseReader.java

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java?rev=984949&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
(added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
Thu Aug 12 20:32:54 2010
@@ -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.
+ * ====================================================================
+ *
+ * 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.http.client.cache;
+
+/**
+ * @since 4.1
+ */
+public class InputLimit {
+
+    private final long value;
+    private boolean reached;
+
+    public InputLimit(long value) {
+        super();
+        this.value = value;
+        this.reached = false;
+    }
+
+    public long getValue() {
+        return this.value;
+    }
+
+    public void reached() {
+        this.reached = true;
+    }
+
+    public boolean isReached() {
+        return this.reached;
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFactory.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFactory.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFactory.java
Thu Aug 12 20:32:54 2010
@@ -27,6 +27,7 @@
 package org.apache.http.client.cache;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 /**
  * Generates {@link Resource} instances.
@@ -35,7 +36,7 @@ import java.io.IOException;
  */
 public interface ResourceFactory {
 
-    Resource generate(String requestId, byte[] body) throws IOException;
+    Resource generate(String requestId, InputStream instream, InputLimit limit) throws IOException;
 
     Resource copy(String requestId, Resource resource) throws IOException;
 

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
Thu Aug 12 20:32:54 2010
@@ -602,8 +602,7 @@ public class CachingHttpClient implement
                 variants);
     }
 
-    HttpResponse correctIncompleteResponse(HttpResponse resp,
-                                                     byte[] bodyBytes) {
+    HttpResponse correctIncompleteResponse(HttpResponse resp, Resource resource) {
         int status = resp.getStatusLine().getStatusCode();
         if (status != HttpStatus.SC_OK
             && status != HttpStatus.SC_PARTIAL_CONTENT) {
@@ -617,13 +616,14 @@ public class CachingHttpClient implement
         } catch (NumberFormatException nfe) {
             return resp;
         }
-        if (bodyBytes.length >= contentLength) return resp;
+        if (resource.length() >= contentLength) return resp;
         HttpResponse error =
             new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_GATEWAY, "Bad Gateway");
         error.setHeader("Content-Type","text/plain;charset=UTF-8");
-        String msg = String.format("Received incomplete response with Content-Length %d but
actual body length %d", contentLength, bodyBytes.length);
+        String msg = String.format("Received incomplete response " +
+                "with Content-Length %d but actual body length %d", contentLength, resource.length());
         byte[] msgBytes = msg.getBytes();
-        error.setHeader("Content-Length", String.format("%d",msgBytes.length));
+        error.setHeader("Content-Length", Integer.toString(msgBytes.length));
         error.setEntity(new ByteArrayEntity(msgBytes));
         return error;
     }
@@ -643,19 +643,17 @@ public class CachingHttpClient implement
         HttpResponse corrected = backendResponse;
         if (cacheable) {
 
-            SizeLimitedResponseReader responseReader = getResponseReader(backendResponse);
+            SizeLimitedResponseReader responseReader = getResponseReader(request, backendResponse);
+            responseReader.readResponse();
 
-            if (responseReader.isResponseTooLarge()) {
+            if (responseReader.isLimitReached()) {
                 return responseReader.getReconstructedResponse();
             }
 
-            byte[] responseBytes = responseReader.getResponseBytes();
-            corrected = correctIncompleteResponse(backendResponse,
-                                                               responseBytes);
+            Resource resource = responseReader.getResource();
+            corrected = correctIncompleteResponse(backendResponse, resource);
             int correctedStatus = corrected.getStatusLine().getStatusCode();
             if (HttpStatus.SC_BAD_GATEWAY != correctedStatus) {
-                Resource resource = resourceFactory.generate(
-                        request.getRequestLine().getUri(), responseBytes);
                 HttpCacheEntry entry = new HttpCacheEntry(
                             requestDate,
                             responseDate,
@@ -673,8 +671,9 @@ public class CachingHttpClient implement
         return corrected;
     }
 
-    SizeLimitedResponseReader getResponseReader(HttpResponse backEndResponse) {
-        return new SizeLimitedResponseReader(maxObjectSizeBytes, backEndResponse);
+    SizeLimitedResponseReader getResponseReader(HttpRequest request, HttpResponse backEndResponse)
{
+        return new SizeLimitedResponseReader(
+                resourceFactory, maxObjectSizeBytes, request, backEndResponse);
     }
 
 }

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java?rev=984949&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
(added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
Thu Aug 12 20:32:54 2010
@@ -0,0 +1,105 @@
+/*
+ * ====================================================================
+ * 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.http.impl.client.cache;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.SequenceInputStream;
+
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.client.cache.Resource;
+import org.apache.http.entity.AbstractHttpEntity;
+
+@NotThreadSafe
+class CombinedEntity extends AbstractHttpEntity {
+
+    private final Resource resource;
+    private final InputStream combinedStream;
+
+    CombinedEntity(final Resource resource, final InputStream instream) throws IOException
{
+        super();
+        this.resource = resource;
+        this.combinedStream = new SequenceInputStream(
+                new ResourceStream(resource.getInputStream()), instream);
+    }
+
+    public long getContentLength() {
+        return -1;
+    }
+
+    public boolean isRepeatable() {
+        return false;
+    }
+
+    public boolean isStreaming() {
+        return true;
+    }
+
+    public InputStream getContent() throws IOException, IllegalStateException {
+        return this.combinedStream;
+    }
+
+    public void writeTo(final OutputStream outstream) throws IOException {
+        if (outstream == null) {
+            throw new IllegalArgumentException("Output stream may not be null");
+        }
+        InputStream instream = getContent();
+        try {
+            int l;
+            byte[] tmp = new byte[2048];
+            while ((l = instream.read(tmp)) != -1) {
+                outstream.write(tmp, 0, l);
+            }
+        } finally {
+            instream.close();
+        }
+    }
+
+    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();
+            }
+        }
+
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResourceFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResourceFactory.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResourceFactory.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResourceFactory.java
Thu Aug 12 20:32:54 2010
@@ -29,8 +29,10 @@ package org.apache.http.impl.client.cach
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.client.cache.InputLimit;
 import org.apache.http.client.cache.Resource;
 import org.apache.http.client.cache.ResourceFactory;
 
@@ -67,18 +69,33 @@ public class FileResourceFactory impleme
         return new File(this.cacheDir, buffer.toString());
     }
 
-    public Resource generate(final String requestId, final byte[] body) throws IOException
{
+    public Resource generate(
+            final String requestId,
+            final InputStream instream,
+            final InputLimit limit) throws IOException {
         File file = generateUniqueCacheFile(requestId);
         FileOutputStream outstream = new FileOutputStream(file);
         try {
-            outstream.write(body);
+            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;
+                }
+            }
         } finally {
             outstream.close();
         }
         return new FileResource(file);
     }
 
-    public Resource copy(final String requestId, final Resource resource) throws IOException
{
+    public Resource copy(
+            final String requestId,
+            final Resource resource) throws IOException {
         File file = generateUniqueCacheFile(requestId);
 
         if (resource instanceof FileResource) {

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResourceFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResourceFactory.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResourceFactory.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResourceFactory.java
Thu Aug 12 20:32:54 2010
@@ -28,8 +28,10 @@ package org.apache.http.impl.client.cach
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.apache.http.annotation.Immutable;
+import org.apache.http.client.cache.InputLimit;
 import org.apache.http.client.cache.Resource;
 import org.apache.http.client.cache.ResourceFactory;
 
@@ -41,11 +43,28 @@ import org.apache.http.client.cache.Reso
 @Immutable
 public class HeapResourceFactory implements ResourceFactory {
 
-    public Resource generate(final String requestId, final byte[] body) throws IOException
{
-        return new HeapResource(body);
+    public Resource generate(
+            final String requestId,
+            final InputStream instream,
+            final InputLimit limit) throws IOException {
+        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
+        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 new HeapResource(outstream.toByteArray());
     }
 
-    public Resource copy(final String requestId, final Resource resource) throws IOException
{
+    public Resource copy(
+            final String requestId,
+            final Resource resource) throws IOException {
         byte[] body;
         if (resource instanceof HeapResource) {
             body = ((HeapResource) resource).getByteArray();

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLimitedResponseReader.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLimitedResponseReader.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLimitedResponseReader.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLimitedResponseReader.java
Thu Aug 12 20:32:54 2010
@@ -26,132 +26,101 @@
  */
 package org.apache.http.impl.client.cache;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
 import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
-import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.client.cache.InputLimit;
+import org.apache.http.client.cache.Resource;
+import org.apache.http.client.cache.ResourceFactory;
 import org.apache.http.message.BasicHttpResponse;
 
 /**
  * @since 4.1
  */
+@NotThreadSafe
 class SizeLimitedResponseReader {
 
-    private final int maxResponseSizeBytes;
+    private final ResourceFactory resourceFactory;
+    private final long maxResponseSizeBytes;
+    private final HttpRequest request;
     private final HttpResponse response;
 
-    private ByteArrayOutputStream outputStream;
-    private InputStream contentInputStream;
-    private boolean isTooLarge;
-    private boolean responseIsConsumed;
-    private byte[] sizeLimitedContent;
-    private boolean outputStreamConsumed;
+    private InputStream instream;
+    private InputLimit limit;
+    private Resource resource;
+    private boolean consumed;
 
     /**
      * Create an {@link HttpResponse} that is limited in size, this allows for checking
      * the size of objects that will be stored in the cache.
-     *
-     * @param maxResponseSizeBytes
-     *      Maximum size that a response can be to be eligible for cache inclusion
-     *
-     * @param response
-     *      The {@link HttpResponse}
      */
-    public SizeLimitedResponseReader(int maxResponseSizeBytes, HttpResponse response) {
+    public SizeLimitedResponseReader(
+            ResourceFactory resourceFactory,
+            long maxResponseSizeBytes,
+            HttpRequest request,
+            HttpResponse response) {
+        super();
+        this.resourceFactory = resourceFactory;
         this.maxResponseSizeBytes = maxResponseSizeBytes;
+        this.request = request;
         this.response = response;
     }
 
-    protected boolean isResponseTooLarge() throws IOException {
-        if (!responseIsConsumed)
-            isTooLarge = consumeResponse();
-
-        return isTooLarge;
-    }
-
-    private boolean consumeResponse() throws IOException {
-
-        if (responseIsConsumed)
-            throw new IllegalStateException(
-                    "You cannot call this method more than once, because it consumes an underlying
stream");
-
-        responseIsConsumed = true;
-
-        HttpEntity entity = response.getEntity();
-        if (entity == null)
-            return false;
-
-        contentInputStream = entity.getContent();
-        int bytes = 0;
-
-        outputStream = new ByteArrayOutputStream();
-
-        int current;
-
-        while (bytes < maxResponseSizeBytes && (current = contentInputStream.read())
!= -1) {
-            outputStream.write(current);
-            bytes++;
+    protected void readResponse() throws IOException {
+        if (!consumed) {
+            doConsume();
         }
-
-        if ((current = contentInputStream.read()) != -1) {
-            outputStream.write(current);
-            return true;
-        }
-
-        return false;
     }
 
-    private void consumeOutputStream() {
-        if (outputStreamConsumed)
-            throw new IllegalStateException(
-                    "underlying output stream has already been written to byte[]");
-
-        if (!responseIsConsumed)
-            throw new IllegalStateException("Must call consumeResponse first.");
-
-        sizeLimitedContent = outputStream.toByteArray();
-        outputStreamConsumed = true;
+    private void ensureNotConsumed() {
+        if (consumed) {
+            throw new IllegalStateException("Response has already been consumed");
+        }
     }
 
-    protected byte[] getResponseBytes() {
-        if (!outputStreamConsumed)
-            consumeOutputStream();
-
-        return sizeLimitedContent;
+    private void ensureConsumed() {
+        if (!consumed) {
+            throw new IllegalStateException("Response has not been consumed");
+        }
     }
 
-    protected HttpResponse getReconstructedResponse() {
+    private void doConsume() throws IOException {
+        ensureNotConsumed();
+        consumed = true;
 
-        InputStream combinedStream = getCombinedInputStream();
+        limit = new InputLimit(maxResponseSizeBytes);
 
-        return constructResponse(response, combinedStream);
+        HttpEntity entity = response.getEntity();
+        if (entity == null) {
+            return;
+        }
+        String uri = request.getRequestLine().getUri();
+        instream = entity.getContent();
+        resource = resourceFactory.generate(uri, instream, limit);
     }
 
-    protected InputStream getCombinedInputStream() {
-        InputStream input1 = new ByteArrayInputStream(getResponseBytes());
-        InputStream input2 = getContentInputStream();
-        return new CombinedInputStream(input1, input2);
+    boolean isLimitReached() {
+        ensureConsumed();
+        return limit.isReached();
     }
 
-    protected InputStream getContentInputStream() {
-        return contentInputStream;
+    Resource getResource() {
+        ensureConsumed();
+        return resource;
     }
 
-    protected HttpResponse constructResponse(HttpResponse originalResponse,
-            InputStream combinedStream) {
-        HttpResponse response = new BasicHttpResponse(originalResponse.getProtocolVersion(),
+    HttpResponse getReconstructedResponse() throws IOException {
+        ensureConsumed();
+        HttpResponse reconstructed = new BasicHttpResponse(response.getProtocolVersion(),
                 HttpStatus.SC_OK, "Success");
-
-        HttpEntity entity = new InputStreamEntity(combinedStream, -1);
-        response.setEntity(entity);
-        response.setHeaders(originalResponse.getAllHeaders());
-
-        return response;
+        reconstructed.setHeaders(response.getAllHeaders());
+        reconstructed.setEntity(new CombinedEntity(resource, instream));
+        return reconstructed;
     }
 
 }

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
Thu Aug 12 20:32:54 2010
@@ -239,10 +239,9 @@ public class TestCachingHttpClient {
         responseProtocolValidationIsCalled();
 
         getMockResponseReader();
-        responseIsTooLarge(false);
-        byte[] buf = responseReaderReturnsBufferOfSize(100);
-
-        generateResource(buf);
+        responseRead();
+        responseLimitReached(false);
+        responseGetResource();
         storeInCacheWasCalled();
         responseIsGeneratedFromCache();
         responseStatusLineIsInspectable();
@@ -553,8 +552,9 @@ public class TestCachingHttpClient {
         getCurrentDateReturns(responseDate);
         responsePolicyAllowsCaching(true);
         getMockResponseReader();
-        responseIsTooLarge(true);
-        readerReturnsReconstructedResponse();
+        responseRead();
+        responseLimitReached(true);
+        responseGetReconstructed();
 
         replayMocks();
 
@@ -575,9 +575,9 @@ public class TestCachingHttpClient {
         getCurrentDateReturns(responseDate);
         responsePolicyAllowsCaching(true);
         getMockResponseReader();
-        responseIsTooLarge(false);
-        byte[] buf = responseReaderReturnsBufferOfSize(100);
-        generateResource(buf);
+        responseRead();
+        responseLimitReached(false);
+        responseGetResource();
         storeInCacheWasCalled();
         responseIsGeneratedFromCache();
         responseStatusLineIsInspectable();
@@ -961,7 +961,7 @@ public class TestCachingHttpClient {
         resp.setEntity(new ByteArrayEntity(bytes));
         resp.setHeader("Content-Length","128");
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp, result));
     }
 
@@ -974,7 +974,7 @@ public class TestCachingHttpClient {
         resp.setHeader("Content-Length","128");
         resp.setHeader("Content-Range","bytes 0-127/255");
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp, result));
     }
 
@@ -986,7 +986,7 @@ public class TestCachingHttpClient {
         resp.setEntity(new ByteArrayEntity(bytes));
         resp.setHeader("Content-Length","256");
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Assert.assertTrue(HttpStatus.SC_BAD_GATEWAY == result.getStatusLine().getStatusCode());
     }
 
@@ -998,7 +998,7 @@ public class TestCachingHttpClient {
         resp.setEntity(new ByteArrayEntity(bytes));
         resp.setHeader("Content-Length","256");
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp, result));
     }
 
@@ -1009,7 +1009,7 @@ public class TestCachingHttpClient {
         byte[] bytes = HttpTestUtils.getRandomBytes(128);
         resp.setEntity(new ByteArrayEntity(bytes));
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp, result));
     }
 
@@ -1021,7 +1021,7 @@ public class TestCachingHttpClient {
         resp.setHeader("Content-Length","foo");
         resp.setEntity(new ByteArrayEntity(bytes));
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp, result));
     }
 
@@ -1033,7 +1033,7 @@ public class TestCachingHttpClient {
         resp.setEntity(new ByteArrayEntity(bytes));
         resp.setHeader("Content-Length","256");
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         Header ctype = result.getFirstHeader("Content-Type");
         Assert.assertEquals("text/plain;charset=UTF-8", ctype.getValue());
     }
@@ -1046,7 +1046,7 @@ public class TestCachingHttpClient {
         resp.setEntity(new ByteArrayEntity(bytes));
         resp.setHeader("Content-Length","256");
 
-        HttpResponse result = impl.correctIncompleteResponse(resp, bytes);
+        HttpResponse result = impl.correctIncompleteResponse(resp, new HeapResource(bytes));
         int clen = Integer.parseInt(result.getFirstHeader("Content-Length").getValue());
         Assert.assertTrue(clen > 0);
         HttpEntity body = result.getEntity();
@@ -1130,6 +1130,7 @@ public class TestCachingHttpClient {
 
     private void getMockResponseReader() {
         EasyMock.expect(impl.getResponseReader(
+                EasyMock.<HttpRequest>anyObject(),
                 EasyMock.<HttpResponse>anyObject())).andReturn(mockResponseReader);
     }
 
@@ -1147,19 +1148,20 @@ public class TestCachingHttpClient {
             .andReturn(null).anyTimes();
     }
 
-    private byte[] responseReaderReturnsBufferOfSize(int bufferSize) {
-        byte[] buffer = new byte[bufferSize];
-        EasyMock.expect(mockResponseReader.getResponseBytes()).andReturn(buffer);
-        return buffer;
+    private void responseRead() throws Exception {
+        mockResponseReader.readResponse();
+    }
+
+    private void responseLimitReached(boolean limitReached) throws Exception {
+        EasyMock.expect(mockResponseReader.isLimitReached()).andReturn(limitReached);
     }
 
-    private void readerReturnsReconstructedResponse() {
-        EasyMock.expect(mockResponseReader.getReconstructedResponse()).andReturn(
-                mockReconstructedResponse);
+    private void responseGetResource() throws Exception {
+        EasyMock.expect(mockResponseReader.getResource()).andReturn(new HeapResource(new
byte[] {} ));
     }
 
-    private void responseIsTooLarge(boolean tooLarge) throws Exception {
-        EasyMock.expect(mockResponseReader.isResponseTooLarge()).andReturn(tooLarge);
+    private void responseGetReconstructed() throws Exception {
+        EasyMock.expect(mockResponseReader.getReconstructedResponse()).andReturn(mockReconstructedResponse);
     }
 
     private void backendCallWasMadeWithRequest(HttpRequest request) throws IOException {
@@ -1245,13 +1247,6 @@ public class TestCachingHttpClient {
         mockCache.putEntry(theURI, entry);
     }
 
-    private void generateResource(byte [] b) throws IOException {
-        EasyMock.expect(
-                mockResourceFactory.generate(
-                        EasyMock.<String>anyObject(),
-                        EasyMock.same(b))).andReturn(new HeapResource(b));
-    }
-
     private void copyResource() throws IOException {
         EasyMock.expect(
                 mockResourceFactory.copy(

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java?rev=984949&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
(added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
Thu Aug 12 20:32:54 2010
@@ -0,0 +1,59 @@
+/*
+ * ====================================================================
+ * 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.http.impl.client.cache;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.http.client.cache.Resource;
+import org.apache.http.util.EntityUtils;
+import org.easymock.classextension.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestCombinedEntity {
+
+    @Test
+    public void testCombinedEntityBasics() throws Exception {
+        Resource resource = EasyMock.createMock(Resource.class);
+        EasyMock.expect(resource.getInputStream()).andReturn(
+                new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 }));
+        resource.dispose();
+        EasyMock.replay(resource);
+
+        ByteArrayInputStream instream = new ByteArrayInputStream(new byte[] { 6, 7, 8, 9,
10 });
+        CombinedEntity entity = new CombinedEntity(resource, instream);
+        Assert.assertEquals(-1, entity.getContentLength());
+        Assert.assertFalse(entity.isRepeatable());
+        Assert.assertTrue(entity.isStreaming());
+
+        byte[] result = EntityUtils.toByteArray(entity);
+        Assert.assertArrayEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, result);
+
+        EasyMock.verify(resource);
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSizeLimitedResponseReader.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSizeLimitedResponseReader.java?rev=984949&r1=984948&r2=984949&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSizeLimitedResponseReader.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSizeLimitedResponseReader.java
Thu Aug 12 20:32:54 2010
@@ -32,8 +32,11 @@ import java.io.InputStream;
 
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
+import org.apache.http.HttpVersion;
+import org.apache.http.message.BasicRequestLine;
+import org.apache.http.util.EntityUtils;
 import org.easymock.classextension.EasyMock;
 import org.junit.Assert;
 import org.junit.Before;
@@ -41,211 +44,134 @@ import org.junit.Test;
 
 public class TestSizeLimitedResponseReader {
 
-    private static final int MAX_SIZE = 4;
+    private static final long MAX_SIZE = 4;
 
     private SizeLimitedResponseReader impl;
+    private HttpRequest mockRequest;
     private HttpResponse mockResponse;
     private HttpEntity mockEntity;
-    private InputStream mockInputStream;
-    private ProtocolVersion mockVersion;
 
     private boolean mockedImpl;
 
     @Before
     public void setUp() {
+        mockRequest = EasyMock.createMock(HttpRequest.class);
         mockResponse = EasyMock.createMock(HttpResponse.class);
         mockEntity = EasyMock.createMock(HttpEntity.class);
-        mockInputStream = EasyMock.createMock(InputStream.class);
-        mockVersion = EasyMock.createMock(ProtocolVersion.class);
-
     }
 
     @Test
     public void testLargeResponseIsTooLarge() throws Exception {
+        byte[] buf = new byte[] { 1, 2, 3, 4, 5};
+        requestReturnsRequestLine();
+        responseReturnsProtocolVersion();
+        responseReturnsHeaders();
+        responseReturnsContent(new ByteArrayInputStream(buf));
+        initReader();
+        replayMocks();
 
-        responseHasValidEntity();
-        entityHasValidContentStream();
-        inputStreamReturnsValidBytes(5);
-
-        getReader();
+        impl.readResponse();
+        boolean tooLarge = impl.isLimitReached();
+        HttpResponse response = impl.getReconstructedResponse();
+        byte[] result = EntityUtils.toByteArray(response.getEntity());
 
-        replayMocks();
-        boolean tooLarge = impl.isResponseTooLarge();
-        byte[] result = impl.getResponseBytes();
         verifyMocks();
-
         Assert.assertTrue(tooLarge);
-
-        Assert.assertArrayEquals(new byte[] { 1, 1, 1, 1, 1 }, result);
+        Assert.assertArrayEquals(buf, result);
     }
 
     @Test
     public void testExactSizeResponseIsNotTooLarge() throws Exception {
-        responseHasValidEntity();
-        entityHasValidContentStream();
-        inputStreamReturnsValidBytes(4);
-        inputStreamReturnsEndOfStream();
-
-        getReader();
-        replayMocks();
-        boolean tooLarge = impl.isResponseTooLarge();
-        byte[] result = impl.getResponseBytes();
-        verifyMocks();
-
-        Assert.assertFalse(tooLarge);
-
-        Assert.assertArrayEquals(new byte[] { 1, 1, 1, 1 }, result);
-    }
-
-    @Test
-    public void testSmallResponseIsNotTooLarge() throws Exception {
-        responseHasValidEntity();
-        entityHasValidContentStream();
-
-        org.easymock.EasyMock.expect(mockInputStream.read()).andReturn(1).times(3);
-
-        org.easymock.EasyMock.expect(mockInputStream.read()).andReturn(-1).times(2);
-
-        getReader();
+        byte[] buf = new byte[] { 1, 2, 3, 4 };
+        requestReturnsRequestLine();
+        responseReturnsProtocolVersion();
+        responseReturnsHeaders();
+        responseReturnsContent(new ByteArrayInputStream(buf));
+        initReader();
         replayMocks();
-        boolean tooLarge = impl.isResponseTooLarge();
-        byte[] result = impl.getResponseBytes();
-        verifyMocks();
-
-        Assert.assertFalse(tooLarge);
 
-        Assert.assertArrayEquals(new byte[] { 1, 1, 1 }, result);
-    }
-
-    @Test
-    public void testResponseWithNoEntityIsNotTooLarge() throws Exception {
-        responseHasNullEntity();
+        impl.readResponse();
+        boolean tooLarge = impl.isLimitReached();
+        HttpResponse response = impl.getReconstructedResponse();
+        byte[] result = EntityUtils.toByteArray(response.getEntity());
 
-        getReader();
-        replayMocks();
-        boolean tooLarge = impl.isResponseTooLarge();
         verifyMocks();
-
         Assert.assertFalse(tooLarge);
+        Assert.assertArrayEquals(buf, result);
     }
 
     @Test
-    public void testReconstructedSmallResponseHasCorrectLength() throws Exception {
-
-        byte[] expectedArray = new byte[] { 1, 1, 1, 1 };
-
-        InputStream stream = new ByteArrayInputStream(new byte[] {});
-
-        responseReturnsHeaders();
+    public void testSmallResponseIsNotTooLarge() throws Exception {
+        byte[] buf = new byte[] { 1, 2, 3 };
+        requestReturnsRequestLine();
         responseReturnsProtocolVersion();
-
-        getReader();
-        mockImplMethods("getResponseBytes", "getContentInputStream");
-        getContentInputStreamReturns(stream);
-        getResponseBytesReturns(expectedArray);
+        responseReturnsHeaders();
+        responseReturnsContent(new ByteArrayInputStream(buf));
+        initReader();
         replayMocks();
 
+        impl.readResponse();
+        boolean tooLarge = impl.isLimitReached();
         HttpResponse response = impl.getReconstructedResponse();
-
+        byte[] result = EntityUtils.toByteArray(response.getEntity());
         verifyMocks();
 
-        Assert.assertNotNull("Response should not be null", response);
-        InputStream resultStream = response.getEntity().getContent();
-
-        byte[] buffer = new byte[expectedArray.length];
-        resultStream.read(buffer);
-
-        Assert.assertArrayEquals(expectedArray, buffer);
-    }
-
-    private void getContentInputStreamReturns(InputStream inputStream) {
-        org.easymock.EasyMock.expect(impl.getContentInputStream()).andReturn(inputStream);
+        Assert.assertFalse(tooLarge);
+        Assert.assertArrayEquals(buf, result);
     }
 
     @Test
-    public void testReconstructedLargeResponseHasCorrectLength() throws Exception {
-
-        byte[] expectedArray = new byte[] { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 };
-        byte[] arrayAfterConsumedBytes = new byte[] { 1, 1, 1, 1, 1, 1, 1 };
-        byte[] smallArray = new byte[] { 2, 2, 2, 2, };
-        InputStream is = new ByteArrayInputStream(arrayAfterConsumedBytes);
-
-        responseReturnsHeaders();
-        responseReturnsProtocolVersion();
-
-        getReader();
-        mockImplMethods("getResponseBytes", "getContentInputStream");
-        getResponseBytesReturns(smallArray);
-        getContentInputStreamReturns(is);
+    public void testResponseWithNoEntityIsNotTooLarge() throws Exception {
+        responseHasNullEntity();
 
+        initReader();
         replayMocks();
-
-        HttpResponse response = impl.getReconstructedResponse();
-
+        impl.readResponse();
+        boolean tooLarge = impl.isLimitReached();
         verifyMocks();
 
-        InputStream resultStream = response.getEntity().getContent();
-
-        byte[] buffer = new byte[expectedArray.length];
-        resultStream.read(buffer);
-
-        Assert.assertArrayEquals(expectedArray, buffer);
-    }
-
-    private void getResponseBytesReturns(byte[] expectedArray) {
-        org.easymock.EasyMock.expect(impl.getResponseBytes()).andReturn(expectedArray);
-    }
-
-    private void responseReturnsHeaders() {
-        org.easymock.EasyMock.expect(mockResponse.getAllHeaders()).andReturn(new Header[]
{});
-    }
-
-    private void entityHasValidContentStream() throws IOException {
-        org.easymock.EasyMock.expect(mockEntity.getContent()).andReturn(mockInputStream);
+        Assert.assertFalse(tooLarge);
     }
 
-    private void inputStreamReturnsEndOfStream() throws IOException {
-        org.easymock.EasyMock.expect(mockInputStream.read()).andReturn(-1);
+    private void responseReturnsContent(InputStream buffer) throws IOException {
+        EasyMock.expect(mockResponse.getEntity()).andReturn(mockEntity);
+        EasyMock.expect(mockEntity.getContent()).andReturn(buffer);
     }
 
-    private void responseHasValidEntity() {
-        org.easymock.EasyMock.expect(mockResponse.getEntity()).andReturn(mockEntity);
+    private void requestReturnsRequestLine() {
+        EasyMock.expect(mockRequest.getRequestLine()).andReturn(
+                new BasicRequestLine("GET", "/", HttpVersion.HTTP_1_1));
     }
 
     private void responseReturnsProtocolVersion() {
-        org.easymock.EasyMock.expect(mockResponse.getProtocolVersion()).andReturn(mockVersion);
+        EasyMock.expect(mockResponse.getProtocolVersion()).andReturn(HttpVersion.HTTP_1_1);
     }
 
-    private void inputStreamReturnsValidBytes(int times) throws IOException {
-        org.easymock.EasyMock.expect(mockInputStream.read()).andReturn(1).times(times);
+    private void responseReturnsHeaders() {
+        EasyMock.expect(mockResponse.getAllHeaders()).andReturn(new Header[] {});
     }
 
     private void responseHasNullEntity() {
-        org.easymock.EasyMock.expect(mockResponse.getEntity()).andReturn(null);
+        EasyMock.expect(mockResponse.getEntity()).andReturn(null);
     }
 
     private void verifyMocks() {
-        EasyMock.verify(mockResponse, mockEntity, mockInputStream, mockVersion);
+        EasyMock.verify(mockRequest, mockResponse, mockEntity);
         if (mockedImpl) {
             EasyMock.verify(impl);
         }
     }
 
     private void replayMocks() {
-        EasyMock.replay(mockResponse, mockEntity, mockInputStream, mockVersion);
+        EasyMock.replay(mockRequest, mockResponse, mockEntity);
         if (mockedImpl) {
             EasyMock.replay(impl);
         }
     }
 
-    private void getReader() {
-        impl = new SizeLimitedResponseReader(MAX_SIZE, mockResponse);
-    }
-
-    private void mockImplMethods(String... methods) {
-        mockedImpl = true;
-        impl = EasyMock.createMockBuilder(SizeLimitedResponseReader.class).withConstructor(
-                MAX_SIZE, mockResponse).addMockedMethods(methods).createMock();
+    private void initReader() {
+        impl = new SizeLimitedResponseReader(
+                new HeapResourceFactory(), MAX_SIZE, mockRequest, mockResponse);
     }
 
 }



Mime
View raw message