View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.impl.cache;
28  
29  import static org.junit.Assert.assertEquals;
30  import static org.junit.Assert.assertFalse;
31  import static org.junit.Assert.assertThat;
32  import static org.junit.Assert.assertTrue;
33  
34  import java.io.ByteArrayOutputStream;
35  import java.io.IOException;
36  import java.io.ObjectOutputStream;
37  import java.math.BigDecimal;
38  import java.nio.charset.StandardCharsets;
39  import java.util.Date;
40  import java.util.HashMap;
41  import java.util.Map;
42  
43  import org.apache.hc.client5.http.cache.HttpCacheEntry;
44  import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
45  import org.apache.hc.client5.http.cache.Resource;
46  import org.apache.hc.core5.http.Header;
47  import org.apache.hc.core5.http.HttpStatus;
48  import org.apache.hc.core5.http.message.BasicHeader;
49  import org.apache.hc.core5.http.message.StatusLine;
50  import org.junit.Before;
51  import org.junit.Test;
52  
53  public class TestByteArrayCacheEntrySerializer {
54  
55      private ByteArrayCacheEntrySerializer impl;
56  
57      @Before
58      public void setUp() {
59          impl = new ByteArrayCacheEntrySerializer();
60      }
61  
62      @Test
63      public void canSerializeEntriesWithVariantMaps() throws Exception {
64          readWriteVerify(makeCacheEntryWithVariantMap("somekey"));
65      }
66  
67      @Test
68      public void isAllowedClassNameStringTrue() {
69          assertIsAllowedClassNameTrue(String.class.getName());
70      }
71  
72      @Test
73      public void isAllowedClassNameStringArrayTrue() {
74          assertIsAllowedClassNameTrue("[L" + String.class.getName());
75      }
76  
77      @Test
78      public void isAllowedClassNameStringArrayArrayTrue() {
79          assertIsAllowedClassNameTrue("[[L" + String.class.getName());
80      }
81  
82      @Test
83      public void isAllowedClassNameDataTrue() {
84          assertIsAllowedClassNameTrue(Date.class.getName());
85      }
86  
87      @Test
88      public void isAllowedClassNameStatusLineTrue() {
89          assertIsAllowedClassNameTrue(StatusLine.class.getName());
90      }
91  
92      @Test
93      public void isAllowedClassNameResourceTrue() {
94          assertIsAllowedClassNameTrue(Resource.class.getName());
95      }
96  
97      @Test
98      public void isAllowedClassNameByteArrayTrue() {
99          assertIsAllowedClassNameTrue("[B");
100     }
101 
102     @Test
103     public void isAllowedClassNameByteArrayArrayTrue() {
104         assertIsAllowedClassNameTrue("[[B");
105     }
106 
107     @Test
108     public void isAllowedClassNameCharArrayTrue() {
109         assertIsAllowedClassNameTrue("[C");
110     }
111 
112     @Test
113     public void isAllowedClassNameCharArrayArrayTrue() {
114         assertIsAllowedClassNameTrue("[[C");
115     }
116 
117     @Test
118     public void isAllowedClassNameDoubleArrayTrue() {
119         assertIsAllowedClassNameTrue("[D");
120     }
121 
122     @Test
123     public void isAllowedClassNameDoubleArrayArrayTrue() {
124         assertIsAllowedClassNameTrue("[[D");
125     }
126 
127     @Test
128     public void isAllowedClassNameFloatArrayTrue() {
129         assertIsAllowedClassNameTrue("[F");
130     }
131 
132     @Test
133     public void isAllowedClassNameFloatArrayArrayTrue() {
134         assertIsAllowedClassNameTrue("[[F");
135     }
136 
137     @Test
138     public void isAllowedClassNameIntArrayTrue() {
139         assertIsAllowedClassNameTrue("[I");
140     }
141 
142     @Test
143     public void isAllowedClassNameIntArrayArrayTrue() {
144         assertIsAllowedClassNameTrue("[[I");
145     }
146 
147     @Test
148     public void isAllowedClassNameLongArrayTrue() {
149         assertIsAllowedClassNameTrue("[J");
150     }
151 
152     @Test
153     public void isAllowedClassNameLongArrayArrayTrue() {
154         assertIsAllowedClassNameTrue("[[J");
155     }
156 
157     @Test
158     public void isAllowedClassNameShortArrayTrue() {
159         assertIsAllowedClassNameTrue("[S");
160     }
161 
162     @Test
163     public void isAllowedClassNameShortArrayArrayTrue() {
164         assertIsAllowedClassNameTrue("[[S");
165     }
166 
167     @Test
168     public void isAllowedClassNameCollectionsInvokerTransformerFalse() {
169         assertIsAllowedClassNameFalse("org.apache.commons.collections.functors.InvokerTransformer");
170     }
171 
172     @Test
173     public void isAllowedClassNameCollections4InvokerTransformerFalse() {
174         assertIsAllowedClassNameFalse("org.apache.commons.collections4.functors.InvokerTransformer");
175     }
176 
177     @Test
178     public void isAllowedClassNameCollectionsInstantiateTransformerFalse() {
179         assertIsAllowedClassNameFalse("org.apache.commons.collections.functors.InstantiateTransformer");
180     }
181 
182     @Test
183     public void isAllowedClassNameCollections4InstantiateTransformerFalse() {
184         assertIsAllowedClassNameFalse("org.apache.commons.collections4.functors.InstantiateTransformer");
185     }
186 
187     @Test
188     public void isAllowedClassNameGroovyConvertedClosureFalse() {
189         assertIsAllowedClassNameFalse("org.codehaus.groovy.runtime.ConvertedClosure");
190     }
191 
192     @Test
193     public void isAllowedClassNameGroovyMethodClosureFalse() {
194         assertIsAllowedClassNameFalse("org.codehaus.groovy.runtime.MethodClosure");
195     }
196 
197     @Test
198     public void isAllowedClassNameSpringObjectFactoryFalse() {
199         assertIsAllowedClassNameFalse("org.springframework.beans.factory.ObjectFactory");
200     }
201 
202     @Test
203     public void isAllowedClassNameCalanTemplatesImplFalse() {
204         assertIsAllowedClassNameFalse("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
205     }
206 
207     @Test
208     public void isAllowedClassNameCalanTemplatesImplArrayFalse() {
209         assertIsAllowedClassNameFalse("[Lcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
210     }
211 
212     @Test
213     public void isAllowedClassNameJavaRmiRegistryFalse() {
214         assertIsAllowedClassNameFalse("java.rmi.registry.Registry");
215     }
216 
217     @Test
218     public void isAllowedClassNameJavaRmiServerRemoteObjectInvocationHandlerFalse() {
219         assertIsAllowedClassNameFalse("java.rmi.server.RemoteObjectInvocationHandler");
220     }
221 
222     @Test
223     public void isAllowedClassNameJavaxXmlTransformTemplatesFalse() {
224         assertIsAllowedClassNameFalse("javax.xml.transform.Templates");
225     }
226 
227     @Test
228     public void isAllowedClassNameJavaxManagementMBeanServerInvocationHandlerFalse() {
229         assertIsAllowedClassNameFalse("javax.management.MBeanServerInvocationHandler");
230     }
231 
232     private static void assertIsAllowedClassNameTrue(final String className) {
233         assertTrue(ByteArrayCacheEntrySerializer.RestrictedObjectInputStream.isAllowedClassName(className));
234     }
235 
236     private static void assertIsAllowedClassNameFalse(final String className) {
237         assertFalse(ByteArrayCacheEntrySerializer.RestrictedObjectInputStream.isAllowedClassName(className));
238     }
239 
240     private byte[] serializeProhibitedObject() throws IOException {
241         final BigDecimal bigDecimal = new BigDecimal("1000.00");
242         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
243         try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
244             oos.writeObject(bigDecimal);
245         }
246         return baos.toByteArray();
247     }
248 
249     public void readWriteVerify(final HttpCacheStorageEntry writeEntry) throws Exception {
250         // write the entry
251         final byte[] bytes = impl.serialize(writeEntry);
252         // read the entry
253         final HttpCacheStorageEntry readEntry = impl.deserialize(bytes);
254         // compare
255         assertEquals(readEntry.getKey(), writeEntry.getKey());
256         assertThat(readEntry.getContent(), HttpCacheEntryMatcher.equivalent(writeEntry.getContent()));
257     }
258 
259     private HttpCacheStorageEntry makeCacheEntryWithVariantMap(final String key) {
260         final Header[] headers = new Header[5];
261         for (int i = 0; i < headers.length; i++) {
262             headers[i] = new BasicHeader("header" + i, "value" + i);
263         }
264         final String body = "Lorem ipsum dolor sit amet";
265 
266         final Map<String,String> variantMap = new HashMap<>();
267         variantMap.put("test variant 1","true");
268         variantMap.put("test variant 2","true");
269         final HttpCacheEntry cacheEntry = new HttpCacheEntry(
270                 new Date(),
271                 new Date(),
272                 HttpStatus.SC_OK,
273                 headers,
274                 new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap);
275 
276         return new HttpCacheStorageEntry(key, cacheEntry);
277     }
278 
279 }