blob: e04331f0123e492b2d02a7002ec115a66ebaa350 [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
2 * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/**
25 * @test
26 * @bug 4636331
27 * @summary Check that URLClassLoader doesn't create excessive http
28 * connections
29 */
30import java.net.*;
31import java.io.*;
32import java.util.*;
33
34public class HttpTest {
35
36 /*
37 * Simple http server to service http requests. Auto shutdown
38 * if "idle" (no requests) for 10 seconds. Forks worker thread
39 * to service persistent connections. Work threads shutdown if
40 * "idle" for 5 seconds.
41 */
42 static class HttpServer implements Runnable {
43
44 private static HttpServer svr = null;
45 private static Counters cnts = null;
46 private static ServerSocket ss;
47
48 private static Object counterLock = new Object();
49 private static int getCount = 0;
50 private static int headCount = 0;
51
52 class Worker extends Thread {
53 Socket s;
54 Worker(Socket s) {
55 this.s = s;
56 }
57
58 public void run() {
59 try {
60
61 InputStream in = s.getInputStream();
62 for (;;) {
63
64 // read entire request from client
65 byte b[] = new byte[1024];
66 int n, total=0;
67
68 // max 5 seconds to wait for new request
69 s.setSoTimeout(5000);
70 try {
71 do {
72 n = in.read(b, total, b.length-total);
73 // max 0.5 seconds between each segment
74 // of request.
75 s.setSoTimeout(500);
76 if (n > 0) total += n;
77 } while (n > 0);
78 } catch (SocketTimeoutException e) { }
79
80 if (total == 0) {
81 s.close();
82 return;
83 }
84
85 boolean getRequest = false;
86 if (b[0] == 'G' && b[1] == 'E' && b[2] == 'T')
87 getRequest = true;
88
89 synchronized (counterLock) {
90 if (getRequest)
91 getCount++;
92 else
93 headCount++;
94 }
95
96 // response to client
97 PrintStream out = new PrintStream(
98 new BufferedOutputStream(
99 s.getOutputStream() ));
100 out.print("HTTP/1.1 200 OK\r\n");
101
102 out.print("Content-Length: 75000\r\n");
103 out.print("\r\n");
104 if (getRequest) {
105 for (int i=0; i<75*1000; i++) {
106 out.write( (byte)'.' );
107 }
108 }
109 out.flush();
110
111 } // for
112
113 } catch (Exception e) {
114 }
115 }
116 }
117
118 HttpServer() throws Exception {
119 ss = new ServerSocket(0);
120 }
121
122 public void run() {
123 try {
124 // shutdown if no request in 10 seconds.
125 ss.setSoTimeout(10000);
126 for (;;) {
127 Socket s = ss.accept();
128 (new Worker(s)).start();
129 }
130 } catch (Exception e) {
131 }
132 }
133
134 public static HttpServer create() throws Exception {
135 if (svr != null)
136 return svr;
137 cnts = new Counters();
138 svr = new HttpServer();
139 (new Thread(svr)).start();
140 return svr;
141 }
142
143 public static void shutdown() throws Exception {
144 if (svr != null) {
145 ss.close();
146 svr = null;
147 }
148 }
149
150 public int port() {
151 return ss.getLocalPort();
152 }
153
154 public static class Counters {
155 public void reset() {
156 synchronized (counterLock) {
157 getCount = 0;
158 headCount = 0;
159 }
160 }
161
162 public int getCount() {
163 synchronized (counterLock) {
164 return getCount;
165 }
166 }
167
168 public int headCount() {
169 synchronized (counterLock) {
170 return headCount;
171 }
172 }
173
174 public String toString() {
175 synchronized (counterLock) {
176 return "GET count: " + getCount + "; " +
177 "HEAD count: " + headCount;
178 }
179 }
180 }
181
182 public Counters counters() {
183 return cnts;
184 }
185
186 }
187
188 public static void main(String args[]) throws Exception {
189 boolean failed = false;
190
191 // create http server
192 HttpServer svr = HttpServer.create();
193
194 // create class loader
195 URL urls[] =
196 { new URL("http://localhost:" + svr.port() + "/dir1/"),
197 new URL("http://localhost:" + svr.port() + "/dir2/") };
198 URLClassLoader cl = new URLClassLoader(urls);
199
200 // Test 1 - check that getResource does single HEAD request
201 svr.counters().reset();
202 URL url = cl.getResource("foo.gif");
203 System.out.println(svr.counters());
204
205 if (svr.counters().getCount() > 0 ||
206 svr.counters().headCount() > 1) {
207 failed = true;
208 }
209
210 // Test 2 - check that getResourceAsStream does at most
211 // one GET request
212 svr.counters().reset();
213 InputStream in = cl.getResourceAsStream("foo2.gif");
214 System.out.println(svr.counters());
215 if (svr.counters().getCount() > 1) {
216 failed = true;
217 }
218
219 // Test 3 - check that getResources only does HEAD requests
220 svr.counters().reset();
221 Enumeration e = cl.getResources("foos.gif");
222 try {
223 for (;;) {
224 e.nextElement();
225 }
226 } catch (NoSuchElementException exc) { }
227 System.out.println(svr.counters());
228 if (svr.counters().getCount() > 1) {
229 failed = true;
230 }
231
232 // shutdown http server
233 svr.shutdown();
234
235 if (failed) {
236 throw new Exception("Excessive http connections established - Test failed");
237 }
238 }
239
240}