Test.java revision 3112
152N/A/*
152N/A * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
152N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
152N/A *
152N/A * This code is free software; you can redistribute it and/or modify it
152N/A * under the terms of the GNU General Public License version 2 only, as
152N/A * published by the Free Software Foundation.
152N/A *
152N/A * This code is distributed in the hope that it will be useful, but WITHOUT
152N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
152N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
152N/A * version 2 for more details (a copy is included in the LICENSE file that
152N/A * accompanied this code).
152N/A *
152N/A * You should have received a copy of the GNU General Public License version
152N/A * 2 along with this work; if not, write to the Free Software Foundation,
152N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
152N/A *
152N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
152N/A * or visit www.oracle.com if you need additional information or have any
727N/A * questions.
152N/A */
152N/A
152N/A/**
152N/A * @test
760N/A * @bug 6725892
618N/A * @run main/othervm -Dsun.net.httpserver.maxReqTime=2 Test
152N/A * @summary
760N/A */
760N/A
760N/Aimport com.sun.net.httpserver.*;
152N/A
152N/Aimport java.util.concurrent.*;
152N/Aimport java.util.logging.*;
760N/Aimport java.io.*;
760N/Aimport java.net.*;
760N/Aimport javax.net.ssl.*;
152N/A
152N/Apublic class Test {
152N/A
152N/A static HttpServer s1;
152N/A static int port;
152N/A static URL url;
152N/A static final String RESPONSE_BODY = "response";
152N/A static boolean failed = false;
277N/A
727N/A static class Handler implements HttpHandler {
152N/A
152N/A public void handle (HttpExchange t)
152N/A throws IOException
277N/A {
683N/A InputStream is = t.getRequestBody();
152N/A InetSocketAddress rem = t.getRemoteAddress();
181N/A System.out.println ("Request from: " + rem);
181N/A while (is.read () != -1) ;
152N/A is.close();
760N/A String requrl = t.getRequestURI().toString();
152N/A OutputStream os = t.getResponseBody();
152N/A t.sendResponseHeaders (200, RESPONSE_BODY.length());
760N/A os.write (RESPONSE_BODY.getBytes());
152N/A t.close();
152N/A }
152N/A }
760N/A
152N/A public static void main (String[] args) throws Exception {
760N/A
181N/A ExecutorService exec = Executors.newCachedThreadPool();
760N/A
181N/A try {
152N/A InetSocketAddress addr = new InetSocketAddress (0);
760N/A s1 = HttpServer.create (addr, 0);
152N/A HttpHandler h = new Handler ();
152N/A HttpContext c1 = s1.createContext ("/", h);
760N/A s1.setExecutor(exec);
760N/A s1.start();
152N/A
760N/A port = s1.getAddress().getPort();
760N/A System.out.println ("Server on port " + port);
760N/A url = new URL ("http://127.0.0.1:"+port+"/foo");
760N/A test1();
152N/A test2();
760N/A test3();
760N/A Thread.sleep (2000);
760N/A } catch (Exception e) {
760N/A e.printStackTrace();
760N/A System.out.println ("FAIL");
760N/A throw new RuntimeException ();
760N/A } finally {
760N/A s1.stop(0);
760N/A System.out.println ("After Shutdown");
760N/A exec.shutdown();
152N/A }
181N/A }
152N/A
152N/A // open TCP connection without sending anything. Check server closes it.
152N/A
152N/A static void test1() throws IOException {
152N/A failed = false;
Socket s = new Socket ("127.0.0.1", port);
InputStream is = s.getInputStream();
// server should close connection after 2 seconds. We wait up to 10
s.setSoTimeout (10000);
try {
is.read();
} catch (SocketTimeoutException e) {
failed = true;
}
s.close();
if (failed) {
System.out.println ("test1: FAIL");
throw new RuntimeException ();
} else {
System.out.println ("test1: OK");
}
}
// send request and don't read response. Check server closes connection
static void test2() throws IOException {
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setReadTimeout (20 * 1000);
InputStream is = urlc.getInputStream();
// we won't read response and check if it times out
// on server. If it timesout at client then there is a problem
try {
Thread.sleep (10 * 1000);
while (is.read() != -1) ;
} catch (InterruptedException e) {
System.out.println (e);
System.out.println ("test2: FAIL");
throw new RuntimeException ("unexpected error");
} catch (SocketTimeoutException e1) {
System.out.println (e1);
System.out.println ("test2: FAIL");
throw new RuntimeException ("client timedout");
} finally {
is.close();
}
System.out.println ("test2: OK");
}
// same as test2, but repeated with multiple connections
// including a number of valid request/responses
// Worker: a thread opens a connection to the server in one of three modes.
// NORMAL - sends a request, waits for response, and checks valid response
// REQUEST - sends a partial request, and blocks, to see if
// server closes the connection.
// RESPONSE - sends a request, partially reads response and blocks,
// to see if server closes the connection.
static class Worker extends Thread {
CountDownLatch latch;
Mode mode;
enum Mode {
REQUEST, // block during sending of request
RESPONSE, // block during reading of response
NORMAL // don't block
};
Worker (CountDownLatch latch, Mode mode) {
this.latch = latch;
this.mode = mode;
}
void fail(String msg) {
System.out.println (msg);
failed = true;
}
public void run () {
HttpURLConnection urlc;
InputStream is = null;
try {
urlc = (HttpURLConnection) url.openConnection();
urlc.setReadTimeout (20 * 1000);
urlc.setDoOutput(true);
} catch (IOException e) {
fail("Worker: failed to connect to server");
latch.countDown();
return;
}
try {
OutputStream os = urlc.getOutputStream();
os.write ("foo".getBytes());
if (mode == Mode.REQUEST) {
Thread.sleep (3000);
}
os.close();
is = urlc.getInputStream();
if (mode == Mode.RESPONSE) {
Thread.sleep (3000);
}
if (!checkResponse (is, RESPONSE_BODY)) {
fail ("Worker: response");
}
is.close();
return;
} catch (InterruptedException e0) {
fail("Worker: timedout");
} catch (SocketTimeoutException e1) {
fail("Worker: timedout");
} catch (IOException e2) {
switch (mode) {
case NORMAL:
fail ("Worker: " + e2.getMessage());
break;
case RESPONSE:
if (is == null) {
fail ("Worker: " + e2.getMessage());
break;
}
// default: is ok
}
} finally {
latch.countDown();
}
}
}
static final int NUM = 20;
static void test3() throws Exception {
failed = false;
CountDownLatch l = new CountDownLatch (NUM*3);
Worker[] workers = new Worker[NUM*3];
for (int i=0; i<NUM; i++) {
workers[i*3] = new Worker (l, Worker.Mode.NORMAL);
workers[i*3+1] = new Worker (l, Worker.Mode.REQUEST);
workers[i*3+2] = new Worker (l, Worker.Mode.RESPONSE);
workers[i*3].start();
workers[i*3+1].start();
workers[i*3+2].start();
}
l.await();
for (int i=0; i<NUM*3; i++) {
workers[i].join();
}
if (failed) {
throw new RuntimeException ("test3: failed");
}
System.out.println ("test3: OK");
}
static boolean checkResponse (InputStream is, String resp) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte [64];
int c;
while ((c=is.read(buf)) != -1) {
bos.write (buf, 0, c);
}
bos.close();
if (!bos.toString().equals(resp)) {
System.out.println ("Wrong response: " + bos.toString());
return false;
}
} catch (IOException e) {
System.out.println (e);
return false;
}
return true;
}
}