1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package tests.api.java.net;
19
20import dalvik.annotation.TestTargetClass;
21import dalvik.annotation.TestTargetNew;
22import dalvik.annotation.TestLevel;
23
24import java.io.BufferedOutputStream;
25import java.io.File;
26import java.io.FileOutputStream;
27import java.io.IOException;
28import java.io.InputStream;
29import java.net.JarURLConnection;
30import java.net.MalformedURLException;
31import java.net.URL;
32import java.net.URLConnection;
33import java.security.cert.Certificate;
34import java.util.Collection;
35import java.util.Map;
36import java.util.Set;
37import java.util.Arrays;
38import java.util.HashSet;
39import java.util.jar.Attributes;
40import java.util.jar.JarEntry;
41import java.util.jar.JarFile;
42import java.util.jar.JarOutputStream;
43import java.util.jar.Manifest;
44import java.util.zip.ZipEntry;
45import java.util.zip.ZipFile;
46
47import tests.support.resource.Support_Resources;
48
49@TestTargetClass(JarURLConnection.class)
50public class JarURLConnectionTest extends junit.framework.TestCase {
51
52    JarURLConnection juc;
53
54    URLConnection uc;
55
56    private static final URL BASE = getBaseURL();
57
58    private static URL getBaseURL() {
59        String clazz = JarURLConnectionTest.class.getName();
60        int p = clazz.lastIndexOf(".");
61        String pack = (p == -1 ? "" : clazz.substring(0, p)).replace('.', File.separatorChar);
62
63        return JarURLConnectionTest.class.getClassLoader().getResource(pack);
64    }
65
66    private URL createContent(String jarFile, String inFile)
67                                                throws MalformedURLException {
68
69        File resources = Support_Resources.createTempFolder();
70
71        Support_Resources.copyFile(resources, "net", jarFile);
72        File file = new File(resources.toString() + "/net/" + jarFile);
73        URL fUrl1 = new URL("jar:file:" + file.getPath() + "!/" + inFile);
74
75        return fUrl1;
76    }
77
78    /**
79     * @tests java.net.JarURLConnection#getAttributes()
80     */
81    @TestTargetNew(
82      level = TestLevel.COMPLETE,
83      notes = "",
84      method = "getAttributes",
85      args = {}
86    )
87    public void test_getAttributes() throws Exception {
88        //URL u = new URL("jar:"
89        //        + BASE.toString()+"/lf.jar!/swt.dll");
90
91        URL u = createContent("lf.jar", "swt.dll");
92        juc = (JarURLConnection) u.openConnection();
93        java.util.jar.Attributes a = juc.getAttributes();
94        assertEquals("Returned incorrect Attributes", "SHA MD5", a
95                .get(new java.util.jar.Attributes.Name("Digest-Algorithms")));
96
97        //URL invURL = new URL("jar:"
98        //        + BASE.toString()+"/InvalidJar.jar!/Test.class");
99
100        URL invURL = createContent("InvalidJar.jar", "Test.class");
101
102        JarURLConnection juConn = (JarURLConnection) invURL.openConnection();
103        try {
104            juConn.getAttributes();
105            fail("IOException was not thrown.");
106        } catch(java.io.IOException io) {
107            //expected
108        }
109    }
110
111    @TestTargetNew(
112      level = TestLevel.COMPLETE,
113      notes = "",
114      method = "getCertificates",
115      args = {}
116    )
117    public void test_getCertificates() throws Exception {
118
119        //URL u = new URL("jar:"
120        //        + BASE.toString()+"/TestCodeSigners.jar!/Test.class");
121
122        URL u = createContent("TestCodeSigners.jar", "Test.class");
123
124        juc = (JarURLConnection) u.openConnection();
125        assertNull(juc.getCertificates());
126
127        JarEntry je = juc.getJarEntry();
128        JarFile jf = juc.getJarFile();
129        InputStream is = jf.getInputStream(je);
130        is.skip(je.getSize());
131
132        Certificate [] certs = juc.getCertificates();
133        assertEquals(3, certs.length);
134
135        //URL invURL = new URL("jar:"
136        //        + BASE.toString()+"/InvalidJar.jar!/Test.class");
137
138        URL invURL = createContent("InvalidJar.jar", "Test.class");
139
140        JarURLConnection juConn = (JarURLConnection) invURL.openConnection();
141        try {
142            juConn.getCertificates();
143            fail("IOException was not thrown.");
144        } catch(java.io.IOException io) {
145            //expected
146        }
147    }
148
149    @TestTargetNew(
150      level = TestLevel.COMPLETE,
151      notes = "",
152      method = "getManifest",
153      args = {}
154    )
155    public void test_getManifest() throws Exception {
156
157        //URL u = new URL("jar:"
158        //        + BASE.toString()+"/lf.jar!/swt.dll");
159
160        URL u = createContent("lf.jar", "swt.dll");
161
162        juc = (JarURLConnection) u.openConnection();
163        Manifest manifest = juc.getManifest();
164        Map<String, Attributes> attr = manifest.getEntries();
165        assertEquals(new HashSet<String>(Arrays.asList("plus.bmp", "swt.dll")),
166                attr.keySet());
167
168        //URL invURL = new URL("jar:"
169        //        + BASE.toString()+"/InvalidJar.jar!/Test.class");
170
171        URL invURL = createContent("InvalidJar.jar", "Test.class");
172
173        JarURLConnection juConn = (JarURLConnection) invURL.openConnection();
174        try {
175            juConn.getManifest();
176            fail("IOException was not thrown.");
177        } catch(java.io.IOException io) {
178            //expected
179        }
180    }
181
182    /**
183     * @throws Exception
184     * @tests java.net.JarURLConnection#getEntryName()
185     */
186    @TestTargetNew(
187      level = TestLevel.COMPLETE,
188      notes = "",
189      method = "getEntryName",
190      args = {}
191    )
192    public void test_getEntryName() throws Exception {
193        //URL u = new URL("jar:"
194        //        + BASE.toString()+"/lf.jar!/plus.bmp");
195
196        URL u = createContent("lf.jar", "plus.bmp");
197
198        juc = (JarURLConnection) u.openConnection();
199        assertEquals("Returned incorrect entryName", "plus.bmp", juc
200                .getEntryName());
201
202        //u = new URL("jar:" + BASE.toString()+"/lf.jar!/");
203
204        u = createContent("lf.jar", "");
205
206        juc = (JarURLConnection) u.openConnection();
207        assertNull("Returned incorrect entryName", juc.getEntryName());
208//      Regression test for harmony-3053
209
210        URL url = new URL("jar:file:///bar.jar!/foo.jar!/Bugs/HelloWorld.class");
211        assertEquals("foo.jar!/Bugs/HelloWorld.class",((JarURLConnection)url.openConnection()).getEntryName());
212    }
213
214    /**
215     * @tests java.net.JarURLConnection#getJarEntry()
216     */
217    @TestTargetNew(
218      level = TestLevel.COMPLETE,
219      notes = "",
220      method = "getJarEntry",
221      args = {}
222    )
223    public void test_getJarEntry() throws Exception {
224        //URL u = new URL("jar:"
225        //        + BASE.toString()+"/lf.jar!/plus.bmp");
226
227        URL u = createContent("lf.jar", "plus.bmp");
228
229        juc = (JarURLConnection) u.openConnection();
230        assertEquals("Returned incorrect JarEntry", "plus.bmp", juc
231                .getJarEntry().getName());
232
233        //u = new URL("jar:" + BASE.toString()+"/lf.jar!/");
234        u = createContent("lf.jar", "");
235
236        juc = (JarURLConnection) u.openConnection();
237        assertNull("Returned incorrect JarEntry", juc.getJarEntry());
238
239        //URL invURL = new URL("jar:"
240        //        + BASE.toString()+"/InvalidJar.jar!/Test.class");
241
242        URL invURL = createContent("InvalidJar.jar", "Test.class");
243
244        JarURLConnection juConn = (JarURLConnection) invURL.openConnection();
245        try {
246            juConn.getJarEntry();
247            fail("IOException was not thrown.");
248        } catch(java.io.IOException io) {
249            //expected
250        }
251    }
252
253    /**
254     * @tests java.net.JarURLConnection#getJarFile()
255     */
256    @TestTargetNew(
257      level = TestLevel.COMPLETE,
258      notes = "",
259      method = "getJarFile",
260      args = {}
261    )
262    public void test_getJarFile() throws MalformedURLException, IOException {
263        URL url = null;
264        //url = new URL("jar:"
265        //        + BASE.toString()+"/lf.jar!/missing");
266
267        url = createContent("lf.jar", "missing");
268
269        JarURLConnection connection = null;
270        connection = (JarURLConnection) url.openConnection();
271        try {
272            connection.connect();
273            fail("Did not throw exception on connect");
274        } catch (IOException e) {
275            // expected
276        }
277
278        try {
279            connection.getJarFile();
280            fail("Did not throw exception after connect");
281        } catch (IOException e) {
282            // expected
283        }
284
285        //URL invURL = new URL("jar:"
286        //        + BASE.toString()+"/InvalidJar.jar!/Test.class");
287
288        URL invURL = createContent("InvalidJar.jar", "Test.class");
289
290        JarURLConnection juConn = (JarURLConnection) invURL.openConnection();
291        try {
292            juConn.getJarFile();
293            fail("IOException was not thrown.");
294        } catch(java.io.IOException io) {
295            //expected
296        }
297
298        File resources = Support_Resources.createTempFolder();
299
300        Support_Resources.copyFile(resources, null, "hyts_att.jar");
301        File file = new File(resources.toString() + "/hyts_att.jar");
302        URL fUrl1 = new URL("jar:file:" + file.getPath() + "!/");
303        JarURLConnection con1 = (JarURLConnection) fUrl1.openConnection();
304        ZipFile jf1 = con1.getJarFile();
305        JarURLConnection con2 = (JarURLConnection) fUrl1.openConnection();
306        ZipFile jf2 = con2.getJarFile();
307        assertTrue("file: JarFiles not the same", jf1 == jf2);
308        jf1.close();
309        assertTrue("File should exist", file.exists());
310
311        fUrl1 = createContent("lf.jar", "");
312        //new URL("jar:" + BASE.toString()+"/lf.jar!/");
313
314        con1 = (JarURLConnection) fUrl1.openConnection();
315        jf1 = con1.getJarFile();
316        con2 = (JarURLConnection) fUrl1.openConnection();
317        jf2 = con2.getJarFile();
318        assertTrue("http: JarFiles not the same", jf1 == jf2);
319        jf1.close();
320    }
321
322    /**
323     * @tests java.net.JarURLConnection.getJarFile()
324     *
325     * Regression test for HARMONY-29
326     */
327    @TestTargetNew(
328      level = TestLevel.PARTIAL_COMPLETE,
329      notes = "Regression test.",
330      method = "getJarFile",
331      args = {}
332    )
333    public void test_getJarFile29() throws Exception {
334        File jarFile = File.createTempFile("1+2 3", "test.jar");
335        jarFile.deleteOnExit();
336        JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile));
337        out.putNextEntry(new ZipEntry("test"));
338        out.closeEntry();
339        out.close();
340
341        JarURLConnection conn = (JarURLConnection) new URL("jar:file:"
342                + jarFile.getAbsolutePath().replaceAll(" ", "%20") + "!/")
343                .openConnection();
344        conn.getJarFile().entries();
345    }
346
347    //Regression for HARMONY-3436
348    @TestTargetNew(
349        level = TestLevel.PARTIAL,
350        notes = "Exceptions checking missed.",
351        method = "setUseCaches",
352        args = {boolean.class}
353    )
354    public void test_setUseCaches() throws Exception {
355        File resources = Support_Resources.createTempFolder();
356        Support_Resources.copyFile(resources, null, "hyts_att.jar");
357        File file = new File(resources.toString() + "/hyts_att.jar");
358        URL url = new URL("jar:file:" + file.getPath() + "!/HasAttributes.txt");
359
360        JarURLConnection connection = (JarURLConnection) url.openConnection();
361        connection.setUseCaches(false);
362        InputStream in = connection.getInputStream();
363        in = connection.getInputStream();
364        JarFile jarFile1 = connection.getJarFile();
365        JarEntry jarEntry1 = connection.getJarEntry();
366        in.read();
367        in.close();
368        JarFile jarFile2 = connection.getJarFile();
369        JarEntry jarEntry2 = connection.getJarEntry();
370        assertSame(jarFile1, jarFile2);
371        assertSame(jarEntry1, jarEntry2);
372
373        try {
374            connection.getInputStream();
375            fail("should throw IllegalStateException");
376        } catch (IllegalStateException e) {
377            // expected
378        }
379    }
380
381    /**
382     * @tests java.net.JarURLConnection#getJarFileURL()
383     */
384    @TestTargetNew(
385      level = TestLevel.COMPLETE,
386      notes = "",
387      method = "getJarFileURL",
388      args = {}
389    )
390    public void test_getJarFileURL() throws Exception {
391        //URL fileURL = new URL(BASE.toString()+"/lf.jar");
392        //URL u = new URL("jar:"
393        //        + BASE.toString()+"/lf.jar!/plus.bmp");
394
395        URL u = createContent("lf.jar", "plus.bmp");
396
397        URL fileURL = new URL(u.getPath().substring(0, u.getPath().indexOf("!")));
398
399        juc = (JarURLConnection) u.openConnection();
400        assertTrue("Returned incorrect file URL", juc.getJarFileURL().equals(
401                fileURL));
402        // Regression test for harmony-3053
403        URL url = new URL("jar:file:///bar.jar!/foo.jar!/Bugs/HelloWorld.class");
404        assertEquals("file:/bar.jar",((JarURLConnection)url.openConnection()).getJarFileURL().toString());
405    }
406
407    /**
408     * @tests java.net.JarURLConnection#getMainAttributes()
409     */
410    @TestTargetNew(
411      level = TestLevel.COMPLETE,
412      notes = "",
413      method = "getMainAttributes",
414      args = {}
415    )
416    public void test_getMainAttributes() throws Exception {
417        //URL u = new URL("jar:"
418        //        + BASE.toString()+"/lf.jar!/swt.dll");
419        URL u = createContent("lf.jar", "swt.dll");
420
421        juc = (JarURLConnection) u.openConnection();
422        java.util.jar.Attributes a = juc.getMainAttributes();
423        assertEquals("Returned incorrect Attributes", "1.0", a
424                .get(java.util.jar.Attributes.Name.MANIFEST_VERSION));
425
426        //URL invURL = new URL("jar:"
427        //        + BASE.toString()+"/InvalidJar.jar!/Test.class");
428        URL invURL = createContent("InvalidJar.jar", "Test.class");
429
430        JarURLConnection juConn = (JarURLConnection) invURL.openConnection();
431        try {
432            juConn.getMainAttributes();
433            fail("IOException was not thrown.");
434        } catch(java.io.IOException io) {
435            //expected
436        }
437    }
438
439    /**
440     * @tests java.net.JarURLConnection#getInputStream()
441     */
442    @TestTargetNew(
443      level = TestLevel.COMPLETE,
444      notes = "Test fails: IOException expected but IllegalStateException is thrown: ticket 128",
445      method = "getInputStream",
446      args = {}
447    )
448    public void test_getInputStream_DeleteJarFileUsingURLConnection()
449            throws Exception {
450        String jarFileName = "";
451        String entry = "text.txt";
452        String cts = System.getProperty("java.io.tmpdir");
453        File tmpDir = new File(cts);
454        File jarFile = tmpDir.createTempFile("file", ".jar", tmpDir);
455        jarFileName = jarFile.getPath();
456        FileOutputStream jarFileOutputStream = new FileOutputStream(jarFileName);
457        JarOutputStream out = new JarOutputStream(new BufferedOutputStream(
458                jarFileOutputStream));
459        JarEntry jarEntry = new JarEntry(entry);
460        out.putNextEntry(jarEntry);
461        out.write(new byte[] { 'a', 'b', 'c' });
462        out.close();
463
464        URL url = new URL("jar:file:" + jarFileName + "!/" + entry);
465        URLConnection conn = url.openConnection();
466        conn.setUseCaches(false);
467        InputStream is = conn.getInputStream();
468        is.close();
469
470        assertTrue(jarFile.delete());
471
472        /*
473        try {
474            conn.getInputStream();
475            fail("Exception was not thrown.");
476        } catch (IOException e) {
477            //ok
478        }
479
480        */
481
482    }
483
484    @TestTargetNew(
485      level = TestLevel.COMPLETE,
486      notes = "",
487      method = "JarURLConnection",
488      args = {java.net.URL.class}
489    )
490    public void test_Constructor() {
491        try {
492            String jarFileName = "file.jar";
493            String entry = "text.txt";
494            URL url = new URL("jar:file:" + jarFileName + "!/" + entry);
495            TestJarURLConnection jarConn = new TestJarURLConnection(url);
496            assertEquals(new URL("file:file.jar"), jarConn.getJarFileURL());
497        } catch(MalformedURLException me) {
498            fail("MalformedURLException was thrown.");
499        }
500
501        try {
502        URL [] urls = {new URL("file:file.jar"),
503                       new URL("http://foo.com/foo/foo.jar")};
504
505        for(URL url:urls) {
506            try {
507                new TestJarURLConnection(url);
508                fail("MalformedURLException was not thrown.");
509            } catch(MalformedURLException me) {
510                //expected
511            }
512        }
513        } catch(MalformedURLException me) {
514            fail("MalformedURLException was thrown.");
515        }
516    }
517
518
519    protected void setUp() {
520    }
521
522    protected void tearDown() {
523    }
524
525    class TestJarURLConnection extends JarURLConnection {
526
527        protected TestJarURLConnection(URL arg0) throws MalformedURLException {
528            super(arg0);
529        }
530
531        @Override
532        public JarFile getJarFile() throws IOException {
533            return null;
534        }
535
536        @Override
537        public void connect() throws IOException {
538
539        }
540
541    }
542}
543
544