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