blob: 8a1998fd89da1a98dc333fa6cbd0ee5c568a3ebd [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
ohair2283b9d2010-05-25 15:58:33 -07002 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
duke6e45e102007-12-01 00:00:00 +00003 * 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 *
ohair2283b9d2010-05-25 15:58:33 -070019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
duke6e45e102007-12-01 00:00:00 +000022 */
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() {
chegarf514c562010-03-25 09:38:56 +000059 InputStream in = null;
duke6e45e102007-12-01 00:00:00 +000060 try {
chegarf514c562010-03-25 09:38:56 +000061 in = s.getInputStream();
duke6e45e102007-12-01 00:00:00 +000062 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) {
chegarf514c562010-03-25 09:38:56 +0000114 unexpected(e);
115 } finally {
116 if (in != null) { try {in.close(); } catch(IOException e) {unexpected(e);} }
duke6e45e102007-12-01 00:00:00 +0000117 }
118 }
119 }
120
121 HttpServer() throws Exception {
122 ss = new ServerSocket(0);
123 }
124
125 public void run() {
126 try {
127 // shutdown if no request in 10 seconds.
128 ss.setSoTimeout(10000);
129 for (;;) {
130 Socket s = ss.accept();
131 (new Worker(s)).start();
132 }
133 } catch (Exception e) {
134 }
135 }
136
chegarf514c562010-03-25 09:38:56 +0000137 void unexpected(Exception e) {
138 System.out.println(e);
139 e.printStackTrace();
140 }
141
duke6e45e102007-12-01 00:00:00 +0000142 public static HttpServer create() throws Exception {
143 if (svr != null)
144 return svr;
145 cnts = new Counters();
146 svr = new HttpServer();
147 (new Thread(svr)).start();
148 return svr;
149 }
150
151 public static void shutdown() throws Exception {
152 if (svr != null) {
153 ss.close();
154 svr = null;
155 }
156 }
157
158 public int port() {
159 return ss.getLocalPort();
160 }
161
162 public static class Counters {
163 public void reset() {
164 synchronized (counterLock) {
165 getCount = 0;
166 headCount = 0;
167 }
168 }
169
170 public int getCount() {
171 synchronized (counterLock) {
172 return getCount;
173 }
174 }
175
176 public int headCount() {
177 synchronized (counterLock) {
178 return headCount;
179 }
180 }
181
182 public String toString() {
183 synchronized (counterLock) {
184 return "GET count: " + getCount + "; " +
185 "HEAD count: " + headCount;
186 }
187 }
188 }
189
190 public Counters counters() {
191 return cnts;
192 }
193
194 }
195
196 public static void main(String args[]) throws Exception {
197 boolean failed = false;
198
199 // create http server
200 HttpServer svr = HttpServer.create();
201
202 // create class loader
203 URL urls[] =
204 { new URL("http://localhost:" + svr.port() + "/dir1/"),
205 new URL("http://localhost:" + svr.port() + "/dir2/") };
206 URLClassLoader cl = new URLClassLoader(urls);
207
208 // Test 1 - check that getResource does single HEAD request
209 svr.counters().reset();
210 URL url = cl.getResource("foo.gif");
211 System.out.println(svr.counters());
212
213 if (svr.counters().getCount() > 0 ||
214 svr.counters().headCount() > 1) {
215 failed = true;
216 }
217
218 // Test 2 - check that getResourceAsStream does at most
219 // one GET request
220 svr.counters().reset();
221 InputStream in = cl.getResourceAsStream("foo2.gif");
chegarf514c562010-03-25 09:38:56 +0000222 in.close();
duke6e45e102007-12-01 00:00:00 +0000223 System.out.println(svr.counters());
224 if (svr.counters().getCount() > 1) {
225 failed = true;
226 }
227
228 // Test 3 - check that getResources only does HEAD requests
229 svr.counters().reset();
230 Enumeration e = cl.getResources("foos.gif");
231 try {
232 for (;;) {
233 e.nextElement();
234 }
235 } catch (NoSuchElementException exc) { }
236 System.out.println(svr.counters());
237 if (svr.counters().getCount() > 1) {
238 failed = true;
239 }
240
241 // shutdown http server
242 svr.shutdown();
243
244 if (failed) {
245 throw new Exception("Excessive http connections established - Test failed");
246 }
247 }
248
249}