1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.impl.client.cache;
28
29 import java.io.IOException;
30 import java.lang.reflect.Proxy;
31 import java.util.concurrent.atomic.AtomicBoolean;
32
33 import org.apache.http.HttpEntity;
34 import org.apache.http.HttpRequest;
35 import org.apache.http.HttpResponse;
36 import org.apache.http.HttpStatus;
37 import org.apache.http.HttpVersion;
38 import org.apache.http.client.methods.CloseableHttpResponse;
39 import org.apache.http.client.methods.HttpGet;
40 import org.apache.http.entity.ByteArrayEntity;
41 import org.apache.http.entity.StringEntity;
42 import org.apache.http.message.BasicHttpResponse;
43 import org.apache.http.util.EntityUtils;
44 import org.junit.Assert;
45 import org.junit.Before;
46 import org.junit.Test;
47
48 public class TestSizeLimitedResponseReader {
49
50 private static final long MAX_SIZE = 4;
51
52 private HttpRequest request;
53 private SizeLimitedResponseReader impl;
54
55 @Before
56 public void setUp() {
57 request = new HttpGet("http://foo.example.com/bar");
58 }
59
60 @Test
61 public void testLargeResponseIsTooLarge() throws Exception {
62 final byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
63 final CloseableHttpResponse response = make200Response(buf);
64
65 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
66
67 impl.readResponse();
68 final boolean tooLarge = impl.isLimitReached();
69 final HttpResponse result = impl.getReconstructedResponse();
70 final byte[] body = EntityUtils.toByteArray(result.getEntity());
71
72 Assert.assertTrue(tooLarge);
73 Assert.assertArrayEquals(buf, body);
74 }
75
76 @Test
77 public void testExactSizeResponseIsNotTooLarge() throws Exception {
78 final byte[] buf = new byte[] { 1, 2, 3, 4 };
79 final CloseableHttpResponse response = make200Response(buf);
80
81 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
82
83 impl.readResponse();
84 final boolean tooLarge = impl.isLimitReached();
85 final HttpResponse reconstructed = impl.getReconstructedResponse();
86 final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity());
87
88 Assert.assertFalse(tooLarge);
89 Assert.assertArrayEquals(buf, result);
90 }
91
92 @Test
93 public void testSmallResponseIsNotTooLarge() throws Exception {
94 final byte[] buf = new byte[] { 1, 2, 3 };
95 final CloseableHttpResponse response = make200Response(buf);
96
97 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
98
99 impl.readResponse();
100 final boolean tooLarge = impl.isLimitReached();
101 final HttpResponse reconstructed = impl.getReconstructedResponse();
102 final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity());
103
104 Assert.assertFalse(tooLarge);
105 Assert.assertArrayEquals(buf, result);
106 }
107
108 @Test
109 public void testResponseWithNoEntityIsNotTooLarge() throws Exception {
110 final CloseableHttpResponse response = make200Response();
111
112 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
113
114 impl.readResponse();
115 final boolean tooLarge = impl.isLimitReached();
116
117 Assert.assertFalse(tooLarge);
118 }
119
120 @Test
121 public void testTooLargeEntityHasOriginalContentTypes() throws Exception {
122 final CloseableHttpResponse response = make200Response();
123 final StringEntity entity = new StringEntity("large entity content");
124 response.setEntity(entity);
125
126 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
127
128 impl.readResponse();
129 final boolean tooLarge = impl.isLimitReached();
130 final HttpResponse result = impl.getReconstructedResponse();
131 final HttpEntity reconstructedEntity = result.getEntity();
132 Assert.assertEquals(entity.getContentEncoding(), reconstructedEntity.getContentEncoding());
133 Assert.assertEquals(entity.getContentType(), reconstructedEntity.getContentType());
134
135 final String content = EntityUtils.toString(reconstructedEntity);
136
137 Assert.assertTrue(tooLarge);
138 Assert.assertEquals("large entity content", content);
139 }
140
141 @Test
142 public void testTooLargeResponseCombinedClosed() throws Exception {
143 final AtomicBoolean closed = new AtomicBoolean(false);
144 final CloseableHttpResponse response = (CloseableHttpResponse) Proxy
145 .newProxyInstance(ResponseProxyHandler.class.getClassLoader(),
146 new Class<?>[] { CloseableHttpResponse.class },
147 new ResponseProxyHandler(new BasicHttpResponse(
148 HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")) {
149 @Override
150 public void close() throws IOException {
151 closed.set(true);
152 }
153 });
154 final StringEntity entity = new StringEntity("large entity content");
155 response.setEntity(entity);
156
157 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
158
159 impl.readResponse();
160 final boolean tooLarge = impl.isLimitReached();
161 final CloseableHttpResponse result = impl.getReconstructedResponse();
162 try {
163 final HttpEntity reconstructedEntity = result.getEntity();
164 Assert.assertEquals(entity.getContentEncoding(), reconstructedEntity.getContentEncoding());
165 Assert.assertEquals(entity.getContentType(), reconstructedEntity.getContentType());
166
167 Assert.assertFalse(closed.get());
168 final String content = EntityUtils.toString(reconstructedEntity);
169
170 Assert.assertTrue(tooLarge);
171 Assert.assertEquals("large entity content", content);
172 } finally {
173 result.close();
174 }
175 Assert.assertTrue(closed.get());
176 }
177
178 @Test
179 public void testResponseCopiesAllOriginalHeaders() throws Exception {
180 final byte[] buf = new byte[] { 1, 2, 3 };
181 final CloseableHttpResponse response = make200Response(buf);
182 response.setHeader("Content-Encoding", "gzip");
183
184 impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response);
185
186 impl.readResponse();
187 final boolean tooLarge = impl.isLimitReached();
188 final HttpResponse reconstructed = impl.getReconstructedResponse();
189 final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity());
190
191 Assert.assertFalse(tooLarge);
192 Assert.assertArrayEquals(buf, result);
193 Assert.assertEquals("gzip", reconstructed.getFirstHeader("Content-Encoding").getValue());
194 }
195
196 private CloseableHttpResponse make200Response() {
197 return Proxies.enhanceResponse(new BasicHttpResponse(
198 HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"));
199 }
200
201 private CloseableHttpResponse make200Response(final byte[] buf) {
202 final HttpResponse response = new BasicHttpResponse(
203 HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
204 response.setEntity(new ByteArrayEntity(buf));
205 return Proxies.enhanceResponse(response);
206 }
207
208 }