jdk/test/java/net/URLClassLoader/HttpTest.java
changeset 2 90ce3da70b43
child 5165 5693cc1e95c6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLClassLoader/HttpTest.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 4636331
+ * @summary Check that URLClassLoader doesn't create excessive http
+ *          connections
+ */
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+public class HttpTest {
+
+    /*
+     * Simple http server to service http requests. Auto shutdown
+     * if "idle" (no requests) for 10 seconds. Forks worker thread
+     * to service persistent connections. Work threads shutdown if
+     * "idle" for 5 seconds.
+     */
+    static class HttpServer implements Runnable {
+
+        private static HttpServer svr = null;
+        private static Counters cnts = null;
+        private static ServerSocket ss;
+
+        private static Object counterLock = new Object();
+        private static int getCount = 0;
+        private static int headCount = 0;
+
+        class Worker extends Thread {
+            Socket s;
+            Worker(Socket s) {
+                this.s = s;
+            }
+
+            public void run() {
+                try {
+
+                    InputStream in = s.getInputStream();
+                    for (;;) {
+
+                        // read entire request from client
+                        byte b[] = new byte[1024];
+                        int n, total=0;
+
+                        // max 5 seconds to wait for new request
+                        s.setSoTimeout(5000);
+                        try {
+                            do {
+                                n = in.read(b, total, b.length-total);
+                                // max 0.5 seconds between each segment
+                                // of request.
+                                s.setSoTimeout(500);
+                                if (n > 0) total += n;
+                            } while (n > 0);
+                        } catch (SocketTimeoutException e) { }
+
+                        if (total == 0) {
+                            s.close();
+                            return;
+                        }
+
+                        boolean getRequest = false;
+                        if (b[0] == 'G' && b[1] == 'E' && b[2] == 'T')
+                            getRequest = true;
+
+                        synchronized (counterLock) {
+                            if (getRequest)
+                                getCount++;
+                            else
+                                headCount++;
+                        }
+
+                        // response to client
+                        PrintStream out = new PrintStream(
+                                new BufferedOutputStream(
+                                        s.getOutputStream() ));
+                        out.print("HTTP/1.1 200 OK\r\n");
+
+                        out.print("Content-Length: 75000\r\n");
+                        out.print("\r\n");
+                        if (getRequest) {
+                            for (int i=0; i<75*1000; i++) {
+                                out.write( (byte)'.' );
+                            }
+                        }
+                        out.flush();
+
+                    } // for
+
+                } catch (Exception e) {
+                }
+            }
+        }
+
+        HttpServer() throws Exception {
+            ss = new ServerSocket(0);
+        }
+
+        public void run() {
+            try {
+                // shutdown if no request in 10 seconds.
+                ss.setSoTimeout(10000);
+                for (;;) {
+                    Socket s = ss.accept();
+                    (new Worker(s)).start();
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        public static HttpServer create() throws Exception {
+            if (svr != null)
+                return svr;
+            cnts = new Counters();
+            svr = new HttpServer();
+            (new Thread(svr)).start();
+            return svr;
+        }
+
+        public static void shutdown() throws Exception {
+            if (svr != null) {
+                ss.close();
+                svr = null;
+            }
+        }
+
+        public int port() {
+            return ss.getLocalPort();
+        }
+
+        public static class Counters {
+            public void reset() {
+                synchronized (counterLock) {
+                    getCount = 0;
+                    headCount = 0;
+                }
+            }
+
+            public int getCount() {
+                synchronized (counterLock) {
+                    return getCount;
+                }
+            }
+
+            public int headCount() {
+                synchronized (counterLock) {
+                    return headCount;
+                }
+            }
+
+            public String toString() {
+                synchronized (counterLock) {
+                    return "GET count: " + getCount + "; " +
+                       "HEAD count: " + headCount;
+                }
+            }
+        }
+
+        public Counters counters() {
+            return cnts;
+        }
+
+    }
+
+    public static void main(String args[]) throws Exception {
+        boolean failed = false;
+
+        // create http server
+        HttpServer svr = HttpServer.create();
+
+        // create class loader
+        URL urls[] =
+            { new URL("http://localhost:" + svr.port() + "/dir1/"),
+              new URL("http://localhost:" + svr.port() + "/dir2/") };
+        URLClassLoader cl = new URLClassLoader(urls);
+
+        // Test 1 - check that getResource does single HEAD request
+        svr.counters().reset();
+        URL url = cl.getResource("foo.gif");
+        System.out.println(svr.counters());
+
+        if (svr.counters().getCount() > 0 ||
+            svr.counters().headCount() > 1) {
+            failed = true;
+        }
+
+        // Test 2 - check that getResourceAsStream does at most
+        //          one GET request
+        svr.counters().reset();
+        InputStream in = cl.getResourceAsStream("foo2.gif");
+        System.out.println(svr.counters());
+        if (svr.counters().getCount() > 1) {
+            failed = true;
+        }
+
+        // Test 3 - check that getResources only does HEAD requests
+        svr.counters().reset();
+        Enumeration e = cl.getResources("foos.gif");
+        try {
+            for (;;) {
+                e.nextElement();
+            }
+        } catch (NoSuchElementException exc) { }
+        System.out.println(svr.counters());
+        if (svr.counters().getCount() > 1) {
+            failed = true;
+        }
+
+        // shutdown http server
+        svr.shutdown();
+
+        if (failed) {
+            throw new Exception("Excessive http connections established - Test failed");
+        }
+    }
+
+}