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