SizeLimitedResponseReader can now generate arbitrary type of cache resources using resource factory
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@984949 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e0a296f6b6
commit
a840e65989
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -602,8 +602,7 @@ public class CachingHttpClient implements HttpClient {
|
|||
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 implements HttpClient {
|
|||
} 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 implements HttpClient {
|
|||
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 implements HttpClient {
|
|||
return corrected;
|
||||
}
|
||||
|
||||
SizeLimitedResponseReader getResponseReader(HttpResponse backEndResponse) {
|
||||
return new SizeLimitedResponseReader(maxObjectSizeBytes, backEndResponse);
|
||||
SizeLimitedResponseReader getResponseReader(HttpRequest request, HttpResponse backEndResponse) {
|
||||
return new SizeLimitedResponseReader(
|
||||
resourceFactory, maxObjectSizeBytes, request, backEndResponse);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
105
httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
vendored
Normal file
105
httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.java
vendored
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,75 +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.http.impl.client.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A class that presents two inputstreams as a single stream
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
class CombinedInputStream extends InputStream {
|
||||
|
||||
private final InputStream inputStream1;
|
||||
private final InputStream inputStream2;
|
||||
|
||||
/**
|
||||
* Take two inputstreams and produce an object that makes them appear as if they
|
||||
* are actually a 'single' input stream.
|
||||
*
|
||||
* @param inputStream1
|
||||
* First stream to read
|
||||
* @param inputStream2
|
||||
* Second stream to read
|
||||
*/
|
||||
public CombinedInputStream(InputStream inputStream1, InputStream inputStream2) {
|
||||
if (inputStream1 == null)
|
||||
throw new IllegalArgumentException("inputStream1 cannot be null");
|
||||
if (inputStream2 == null)
|
||||
throw new IllegalArgumentException("inputStream2 cannot be null");
|
||||
|
||||
this.inputStream1 = inputStream1;
|
||||
this.inputStream2 = inputStream2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return inputStream1.available() + inputStream2.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int result = inputStream1.read();
|
||||
|
||||
if (result == -1)
|
||||
result = inputStream2.read();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -29,8 +29,10 @@ package org.apache.http.impl.client.cache;
|
|||
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 implements ResourceFactory {
|
|||
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) {
|
||||
|
|
|
@ -28,8 +28,10 @@ package org.apache.http.impl.client.cache;
|
|||
|
||||
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.ResourceFactory;
|
|||
@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();
|
||||
|
|
|
@ -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;
|
||||
protected void readResponse() throws IOException {
|
||||
if (!consumed) {
|
||||
doConsume();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean consumeResponse() throws IOException {
|
||||
private void ensureNotConsumed() {
|
||||
if (consumed) {
|
||||
throw new IllegalStateException("Response has already been consumed");
|
||||
}
|
||||
}
|
||||
|
||||
if (responseIsConsumed)
|
||||
throw new IllegalStateException(
|
||||
"You cannot call this method more than once, because it consumes an underlying stream");
|
||||
private void ensureConsumed() {
|
||||
if (!consumed) {
|
||||
throw new IllegalStateException("Response has not been consumed");
|
||||
}
|
||||
}
|
||||
|
||||
responseIsConsumed = true;
|
||||
private void doConsume() throws IOException {
|
||||
ensureNotConsumed();
|
||||
consumed = true;
|
||||
|
||||
limit = new InputLimit(maxResponseSizeBytes);
|
||||
|
||||
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++;
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
String uri = request.getRequestLine().getUri();
|
||||
instream = entity.getContent();
|
||||
resource = resourceFactory.generate(uri, instream, limit);
|
||||
}
|
||||
|
||||
if ((current = contentInputStream.read()) != -1) {
|
||||
outputStream.write(current);
|
||||
return true;
|
||||
boolean isLimitReached() {
|
||||
ensureConsumed();
|
||||
return limit.isReached();
|
||||
}
|
||||
|
||||
return false;
|
||||
Resource getResource() {
|
||||
ensureConsumed();
|
||||
return resource;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected byte[] getResponseBytes() {
|
||||
if (!outputStreamConsumed)
|
||||
consumeOutputStream();
|
||||
|
||||
return sizeLimitedContent;
|
||||
}
|
||||
|
||||
protected HttpResponse getReconstructedResponse() {
|
||||
|
||||
InputStream combinedStream = getCombinedInputStream();
|
||||
|
||||
return constructResponse(response, combinedStream);
|
||||
}
|
||||
|
||||
protected InputStream getCombinedInputStream() {
|
||||
InputStream input1 = new ByteArrayInputStream(getResponseBytes());
|
||||
InputStream input2 = getContentInputStream();
|
||||
return new CombinedInputStream(input1, input2);
|
||||
}
|
||||
|
||||
protected InputStream getContentInputStream() {
|
||||
return contentInputStream;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 readerReturnsReconstructedResponse() {
|
||||
EasyMock.expect(mockResponseReader.getReconstructedResponse()).andReturn(
|
||||
mockReconstructedResponse);
|
||||
private void responseLimitReached(boolean limitReached) throws Exception {
|
||||
EasyMock.expect(mockResponseReader.isLimitReached()).andReturn(limitReached);
|
||||
}
|
||||
|
||||
private void responseIsTooLarge(boolean tooLarge) throws Exception {
|
||||
EasyMock.expect(mockResponseReader.isResponseTooLarge()).andReturn(tooLarge);
|
||||
private void responseGetResource() throws Exception {
|
||||
EasyMock.expect(mockResponseReader.getResource()).andReturn(new HeapResource(new byte[] {} ));
|
||||
}
|
||||
|
||||
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(
|
||||
|
|
59
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
vendored
Normal file
59
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.java
vendored
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,118 +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.http.impl.client.cache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.easymock.classextension.EasyMock;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TestCombinedInputStream {
|
||||
|
||||
private InputStream mockInputStream1;
|
||||
private InputStream mockInputStream2;
|
||||
private CombinedInputStream impl;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mockInputStream1 = EasyMock.createMock(InputStream.class);
|
||||
mockInputStream2 = EasyMock.createMock(InputStream.class);
|
||||
|
||||
impl = new CombinedInputStream(mockInputStream1, mockInputStream2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatingInputStreamWithNullInputFails() {
|
||||
|
||||
boolean gotex1 = false;
|
||||
boolean gotex2 = false;
|
||||
|
||||
try {
|
||||
impl = new CombinedInputStream(null, mockInputStream2);
|
||||
} catch (Exception ex) {
|
||||
gotex1 = true;
|
||||
}
|
||||
|
||||
try {
|
||||
impl = new CombinedInputStream(mockInputStream1, null);
|
||||
} catch (Exception ex) {
|
||||
gotex2 = true;
|
||||
}
|
||||
|
||||
Assert.assertTrue(gotex1);
|
||||
Assert.assertTrue(gotex2);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailableReturnsCorrectSize() throws Exception {
|
||||
ByteArrayInputStream s1 = new ByteArrayInputStream(new byte[] { 1, 1, 1, 1, 1 });
|
||||
ByteArrayInputStream s2 = new ByteArrayInputStream(new byte[] { 1, 1, 1, 1, 1 });
|
||||
|
||||
impl = new CombinedInputStream(s1, s2);
|
||||
int avail = impl.available();
|
||||
|
||||
Assert.assertEquals(10, avail);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirstEmptyStreamReadsFromOtherStream() throws Exception {
|
||||
org.easymock.EasyMock.expect(mockInputStream1.read()).andReturn(-1);
|
||||
org.easymock.EasyMock.expect(mockInputStream2.read()).andReturn(500);
|
||||
|
||||
replayMocks();
|
||||
int result = impl.read();
|
||||
verifyMocks();
|
||||
|
||||
Assert.assertEquals(500, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatWeReadTheFirstInputStream() throws Exception {
|
||||
org.easymock.EasyMock.expect(mockInputStream1.read()).andReturn(500);
|
||||
|
||||
replayMocks();
|
||||
int result = impl.read();
|
||||
verifyMocks();
|
||||
|
||||
Assert.assertEquals(500, result);
|
||||
}
|
||||
|
||||
private void verifyMocks() {
|
||||
EasyMock.verify(mockInputStream1, mockInputStream2);
|
||||
}
|
||||
|
||||
private void replayMocks() {
|
||||
EasyMock.replay(mockInputStream1, mockInputStream2);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
responseHasValidEntity();
|
||||
entityHasValidContentStream();
|
||||
inputStreamReturnsValidBytes(5);
|
||||
|
||||
getReader();
|
||||
|
||||
byte[] buf = new byte[] { 1, 2, 3, 4, 5};
|
||||
requestReturnsRequestLine();
|
||||
responseReturnsProtocolVersion();
|
||||
responseReturnsHeaders();
|
||||
responseReturnsContent(new ByteArrayInputStream(buf));
|
||||
initReader();
|
||||
replayMocks();
|
||||
boolean tooLarge = impl.isResponseTooLarge();
|
||||
byte[] result = impl.getResponseBytes();
|
||||
|
||||
impl.readResponse();
|
||||
boolean tooLarge = impl.isLimitReached();
|
||||
HttpResponse response = impl.getReconstructedResponse();
|
||||
byte[] result = EntityUtils.toByteArray(response.getEntity());
|
||||
|
||||
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();
|
||||
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();
|
||||
|
||||
impl.readResponse();
|
||||
boolean tooLarge = impl.isLimitReached();
|
||||
HttpResponse response = impl.getReconstructedResponse();
|
||||
byte[] result = EntityUtils.toByteArray(response.getEntity());
|
||||
|
||||
verifyMocks();
|
||||
|
||||
Assert.assertFalse(tooLarge);
|
||||
|
||||
Assert.assertArrayEquals(new byte[] { 1, 1, 1, 1 }, result);
|
||||
Assert.assertArrayEquals(buf, 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 };
|
||||
requestReturnsRequestLine();
|
||||
responseReturnsProtocolVersion();
|
||||
responseReturnsHeaders();
|
||||
responseReturnsContent(new ByteArrayInputStream(buf));
|
||||
initReader();
|
||||
replayMocks();
|
||||
boolean tooLarge = impl.isResponseTooLarge();
|
||||
byte[] result = impl.getResponseBytes();
|
||||
|
||||
impl.readResponse();
|
||||
boolean tooLarge = impl.isLimitReached();
|
||||
HttpResponse response = impl.getReconstructedResponse();
|
||||
byte[] result = EntityUtils.toByteArray(response.getEntity());
|
||||
verifyMocks();
|
||||
|
||||
Assert.assertFalse(tooLarge);
|
||||
|
||||
Assert.assertArrayEquals(new byte[] { 1, 1, 1 }, result);
|
||||
Assert.assertArrayEquals(buf, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseWithNoEntityIsNotTooLarge() throws Exception {
|
||||
responseHasNullEntity();
|
||||
|
||||
getReader();
|
||||
initReader();
|
||||
replayMocks();
|
||||
boolean tooLarge = impl.isResponseTooLarge();
|
||||
impl.readResponse();
|
||||
boolean tooLarge = impl.isLimitReached();
|
||||
verifyMocks();
|
||||
|
||||
Assert.assertFalse(tooLarge);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconstructedSmallResponseHasCorrectLength() throws Exception {
|
||||
|
||||
byte[] expectedArray = new byte[] { 1, 1, 1, 1 };
|
||||
|
||||
InputStream stream = new ByteArrayInputStream(new byte[] {});
|
||||
|
||||
responseReturnsHeaders();
|
||||
responseReturnsProtocolVersion();
|
||||
|
||||
getReader();
|
||||
mockImplMethods("getResponseBytes", "getContentInputStream");
|
||||
getContentInputStreamReturns(stream);
|
||||
getResponseBytesReturns(expectedArray);
|
||||
replayMocks();
|
||||
|
||||
HttpResponse response = impl.getReconstructedResponse();
|
||||
|
||||
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 responseReturnsContent(InputStream buffer) throws IOException {
|
||||
EasyMock.expect(mockResponse.getEntity()).andReturn(mockEntity);
|
||||
EasyMock.expect(mockEntity.getContent()).andReturn(buffer);
|
||||
}
|
||||
|
||||
private void getContentInputStreamReturns(InputStream inputStream) {
|
||||
org.easymock.EasyMock.expect(impl.getContentInputStream()).andReturn(inputStream);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
replayMocks();
|
||||
|
||||
HttpResponse response = impl.getReconstructedResponse();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void inputStreamReturnsEndOfStream() throws IOException {
|
||||
org.easymock.EasyMock.expect(mockInputStream.read()).andReturn(-1);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue