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