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.hc.client5.http.impl.cache;
28
29
30 import static org.hamcrest.MatcherAssert.assertThat;
31 import static org.junit.jupiter.api.Assertions.assertEquals;
32 import static org.junit.jupiter.api.Assertions.assertFalse;
33 import static org.junit.jupiter.api.Assertions.assertTrue;
34
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.io.ObjectOutputStream;
38 import java.math.BigDecimal;
39 import java.nio.charset.StandardCharsets;
40 import java.time.Instant;
41 import java.util.Date;
42 import java.util.HashMap;
43 import java.util.Map;
44
45 import org.apache.hc.client5.http.cache.HttpCacheEntry;
46 import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
47 import org.apache.hc.client5.http.cache.Resource;
48 import org.apache.hc.core5.http.Header;
49 import org.apache.hc.core5.http.HttpStatus;
50 import org.apache.hc.core5.http.message.BasicHeader;
51 import org.apache.hc.core5.http.message.StatusLine;
52 import org.junit.jupiter.api.BeforeEach;
53 import org.junit.jupiter.api.Test;
54
55 @SuppressWarnings("deprecation")
56 public class TestByteArrayCacheEntrySerializer {
57
58 private ByteArrayCacheEntrySerializer impl;
59
60 @BeforeEach
61 public void setUp() {
62 impl = new ByteArrayCacheEntrySerializer();
63 }
64
65 @Test
66 public void canSerializeEntriesWithVariantMapsDeprecatedConstructor() throws Exception {
67 readWriteVerify(makeCacheEntryDeprecatedConstructorWithVariantMap("somekey"));
68 }
69
70 @Test
71 public void canSerializeEntriesWithVariantMapsAndInstant() throws Exception {
72 readWriteVerify(makeCacheEntryWithVariantMap("somekey"));
73 }
74
75 @Test
76 public void isAllowedClassNameStringTrue() {
77 assertIsAllowedClassNameTrue(String.class.getName());
78 }
79
80 @Test
81 public void isAllowedClassNameStringArrayTrue() {
82 assertIsAllowedClassNameTrue("[L" + String.class.getName());
83 }
84
85 @Test
86 public void isAllowedClassNameStringArrayArrayTrue() {
87 assertIsAllowedClassNameTrue("[[L" + String.class.getName());
88 }
89
90 @Test
91 public void isAllowedClassNameDataTrue() {
92 assertIsAllowedClassNameTrue(Date.class.getName());
93 }
94
95 @Test
96 public void isAllowedClassNameInstantTrue() {
97 assertIsAllowedClassNameTrue(Instant.class.getName());
98 }
99
100 @Test
101 public void isAllowedClassNameStatusLineTrue() {
102 assertIsAllowedClassNameTrue(StatusLine.class.getName());
103 }
104
105 @Test
106 public void isAllowedClassNameResourceTrue() {
107 assertIsAllowedClassNameTrue(Resource.class.getName());
108 }
109
110 @Test
111 public void isAllowedClassNameByteArrayTrue() {
112 assertIsAllowedClassNameTrue("[B");
113 }
114
115 @Test
116 public void isAllowedClassNameByteArrayArrayTrue() {
117 assertIsAllowedClassNameTrue("[[B");
118 }
119
120 @Test
121 public void isAllowedClassNameCharArrayTrue() {
122 assertIsAllowedClassNameTrue("[C");
123 }
124
125 @Test
126 public void isAllowedClassNameCharArrayArrayTrue() {
127 assertIsAllowedClassNameTrue("[[C");
128 }
129
130 @Test
131 public void isAllowedClassNameDoubleArrayTrue() {
132 assertIsAllowedClassNameTrue("[D");
133 }
134
135 @Test
136 public void isAllowedClassNameDoubleArrayArrayTrue() {
137 assertIsAllowedClassNameTrue("[[D");
138 }
139
140 @Test
141 public void isAllowedClassNameFloatArrayTrue() {
142 assertIsAllowedClassNameTrue("[F");
143 }
144
145 @Test
146 public void isAllowedClassNameFloatArrayArrayTrue() {
147 assertIsAllowedClassNameTrue("[[F");
148 }
149
150 @Test
151 public void isAllowedClassNameIntArrayTrue() {
152 assertIsAllowedClassNameTrue("[I");
153 }
154
155 @Test
156 public void isAllowedClassNameIntArrayArrayTrue() {
157 assertIsAllowedClassNameTrue("[[I");
158 }
159
160 @Test
161 public void isAllowedClassNameLongArrayTrue() {
162 assertIsAllowedClassNameTrue("[J");
163 }
164
165 @Test
166 public void isAllowedClassNameLongArrayArrayTrue() {
167 assertIsAllowedClassNameTrue("[[J");
168 }
169
170 @Test
171 public void isAllowedClassNameShortArrayTrue() {
172 assertIsAllowedClassNameTrue("[S");
173 }
174
175 @Test
176 public void isAllowedClassNameShortArrayArrayTrue() {
177 assertIsAllowedClassNameTrue("[[S");
178 }
179
180 @Test
181 public void isAllowedClassNameCollectionsInvokerTransformerFalse() {
182 assertIsAllowedClassNameFalse("org.apache.commons.collections.functors.InvokerTransformer");
183 }
184
185 @Test
186 public void isAllowedClassNameCollections4InvokerTransformerFalse() {
187 assertIsAllowedClassNameFalse("org.apache.commons.collections4.functors.InvokerTransformer");
188 }
189
190 @Test
191 public void isAllowedClassNameCollectionsInstantiateTransformerFalse() {
192 assertIsAllowedClassNameFalse("org.apache.commons.collections.functors.InstantiateTransformer");
193 }
194
195 @Test
196 public void isAllowedClassNameCollections4InstantiateTransformerFalse() {
197 assertIsAllowedClassNameFalse("org.apache.commons.collections4.functors.InstantiateTransformer");
198 }
199
200 @Test
201 public void isAllowedClassNameGroovyConvertedClosureFalse() {
202 assertIsAllowedClassNameFalse("org.codehaus.groovy.runtime.ConvertedClosure");
203 }
204
205 @Test
206 public void isAllowedClassNameGroovyMethodClosureFalse() {
207 assertIsAllowedClassNameFalse("org.codehaus.groovy.runtime.MethodClosure");
208 }
209
210 @Test
211 public void isAllowedClassNameSpringObjectFactoryFalse() {
212 assertIsAllowedClassNameFalse("org.springframework.beans.factory.ObjectFactory");
213 }
214
215 @Test
216 public void isAllowedClassNameCalanTemplatesImplFalse() {
217 assertIsAllowedClassNameFalse("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
218 }
219
220 @Test
221 public void isAllowedClassNameCalanTemplatesImplArrayFalse() {
222 assertIsAllowedClassNameFalse("[Lcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
223 }
224
225 @Test
226 public void isAllowedClassNameJavaRmiRegistryFalse() {
227 assertIsAllowedClassNameFalse("java.rmi.registry.Registry");
228 }
229
230 @Test
231 public void isAllowedClassNameJavaRmiServerRemoteObjectInvocationHandlerFalse() {
232 assertIsAllowedClassNameFalse("java.rmi.server.RemoteObjectInvocationHandler");
233 }
234
235 @Test
236 public void isAllowedClassNameJavaxXmlTransformTemplatesFalse() {
237 assertIsAllowedClassNameFalse("javax.xml.transform.Templates");
238 }
239
240 @Test
241 public void isAllowedClassNameJavaxManagementMBeanServerInvocationHandlerFalse() {
242 assertIsAllowedClassNameFalse("javax.management.MBeanServerInvocationHandler");
243 }
244
245 private static void assertIsAllowedClassNameTrue(final String className) {
246 assertTrue(ByteArrayCacheEntrySerializer.RestrictedObjectInputStream.isAllowedClassName(className));
247 }
248
249 private static void assertIsAllowedClassNameFalse(final String className) {
250 assertFalse(ByteArrayCacheEntrySerializer.RestrictedObjectInputStream.isAllowedClassName(className));
251 }
252
253 private byte[] serializeProhibitedObject() throws IOException {
254 final BigDecimal bigDecimal = new BigDecimal("1000.00");
255 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
256 try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
257 oos.writeObject(bigDecimal);
258 }
259 return baos.toByteArray();
260 }
261
262 public void readWriteVerify(final HttpCacheStorageEntry writeEntry) throws Exception {
263
264 final byte[] bytes = impl.serialize(writeEntry);
265
266 final HttpCacheStorageEntry readEntry = impl.deserialize(bytes);
267
268 assertEquals(readEntry.getKey(), writeEntry.getKey());
269 assertThat(readEntry.getContent(), HttpCacheEntryMatcher.equivalent(writeEntry.getContent()));
270 }
271
272
273 private HttpCacheStorageEntry makeCacheEntryDeprecatedConstructorWithVariantMap(final String key) {
274 final Header[] headers = new Header[5];
275 for (int i = 0; i < headers.length; i++) {
276 headers[i] = new BasicHeader("header" + i, "value" + i);
277 }
278 final String body = "Lorem ipsum dolor sit amet";
279
280 final Map<String,String> variantMap = new HashMap<>();
281 variantMap.put("test variant 1","true");
282 variantMap.put("test variant 2","true");
283 final HttpCacheEntry cacheEntry = new HttpCacheEntry(
284 Instant.now(),
285 Instant.now(),
286 HttpStatus.SC_OK,
287 headers,
288 new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap);
289
290 return new HttpCacheStorageEntry(key, cacheEntry);
291 }
292
293 private HttpCacheStorageEntry makeCacheEntryWithVariantMap(final String key) {
294 final Header[] headers = new Header[5];
295 for (int i = 0; i < headers.length; i++) {
296 headers[i] = new BasicHeader("header" + i, "value" + i);
297 }
298 final String body = "Lorem ipsum dolor sit amet";
299
300 final Map<String,String> variantMap = new HashMap<>();
301 variantMap.put("test variant 1","true");
302 variantMap.put("test variant 2","true");
303 final HttpCacheEntry cacheEntry = new HttpCacheEntry(
304 Instant.now(),
305 Instant.now(),
306 HttpStatus.SC_OK,
307 headers,
308 new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap);
309
310 return new HttpCacheStorageEntry(key, cacheEntry);
311 }
312
313 }