Path: blob/master/test/jdk/com/sun/net/httpserver/bugs/6725892/Test.java
41161 views
/*1* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 672589226* @library /test/lib27* @run main/othervm -Dsun.net.httpserver.maxReqTime=2 Test28* @run main/othervm -Djava.net.preferIPv6Addresses=true -Dsun.net.httpserver.maxReqTime=2 Test29* @summary30*/3132import com.sun.net.httpserver.*;3334import java.util.concurrent.*;35import java.util.logging.*;36import java.io.*;37import java.net.*;38import javax.net.ssl.*;3940import jdk.test.lib.net.URIBuilder;4142public class Test {4344static HttpServer s1;45static int port;46static URL url;47static final String RESPONSE_BODY = "response";48static boolean failed = false;4950static class Handler implements HttpHandler {5152public void handle(HttpExchange t)53throws IOException54{55InputStream is = t.getRequestBody();56InetSocketAddress rem = t.getRemoteAddress();57System.out.println("Request from: " + rem);58while (is.read () != -1) ;59is.close();60String requrl = t.getRequestURI().toString();61OutputStream os = t.getResponseBody();62t.sendResponseHeaders(200, RESPONSE_BODY.length());63os.write(RESPONSE_BODY.getBytes());64t.close();65}66}6768public static void main(String[] args) throws Exception {6970ExecutorService exec = Executors.newCachedThreadPool();7172InetAddress loopback = InetAddress.getLoopbackAddress();73try {74InetSocketAddress addr = new InetSocketAddress(loopback, 0);75s1 = HttpServer.create(addr, 100);76HttpHandler h = new Handler();77HttpContext c1 = s1.createContext("/", h);78s1.setExecutor(exec);79s1.start();8081port = s1.getAddress().getPort();82System.out.println("Server on port " + port);83url = URIBuilder.newBuilder()84.scheme("http")85.loopback()86.port(port)87.path("/foo")88.toURLUnchecked();89System.out.println("URL: " + url);90test1();91test2();92test3();93Thread.sleep(2000);94} catch (Exception e) {95e.printStackTrace();96System.out.println("FAIL");97throw new RuntimeException();98} finally {99s1.stop(0);100System.out.println("After Shutdown");101exec.shutdown();102}103}104105// open TCP connection without sending anything. Check server closes it.106107static void test1() throws IOException {108failed = false;109Socket s = new Socket(InetAddress.getLoopbackAddress(), port);110InputStream is = s.getInputStream();111// server should close connection after 2 seconds. We wait up to 10112s.setSoTimeout(10000);113try {114is.read();115} catch (SocketTimeoutException e) {116failed = true;117}118s.close();119if (failed) {120System.out.println("test1: FAIL");121throw new RuntimeException();122} else {123System.out.println("test1: OK");124}125}126127// send request and don't read response. Check server closes connection128129static void test2() throws IOException {130HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);131urlc.setReadTimeout(20 * 1000);132InputStream is = urlc.getInputStream();133// we won't read response and check if it times out134// on server. If it timesout at client then there is a problem135try {136Thread.sleep(10 * 1000);137while (is.read() != -1) ;138} catch (InterruptedException e) {139System.out.println(e);140System.out.println("test2: FAIL");141throw new RuntimeException("unexpected error");142} catch (SocketTimeoutException e1) {143System.out.println(e1);144System.out.println("test2: FAIL");145throw new RuntimeException("client timedout");146} finally {147is.close();148}149System.out.println("test2: OK");150}151152// same as test2, but repeated with multiple connections153// including a number of valid request/responses154155// Worker: a thread opens a connection to the server in one of three modes.156// NORMAL - sends a request, waits for response, and checks valid response157// REQUEST - sends a partial request, and blocks, to see if158// server closes the connection.159// RESPONSE - sends a request, partially reads response and blocks,160// to see if server closes the connection.161162static class Worker extends Thread {163CountDownLatch latch;164Mode mode;165166enum Mode {167REQUEST, // block during sending of request168RESPONSE, // block during reading of response169NORMAL // don't block170};171172Worker (CountDownLatch latch, Mode mode) {173this.latch = latch;174this.mode = mode;175}176177void fail(String msg) {178System.out.println(msg);179failed = true;180}181182public void run() {183HttpURLConnection urlc;184InputStream is = null;185186try {187urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);188urlc.setReadTimeout(20 * 1000);189urlc.setDoOutput(true);190} catch (IOException e) {191fail("Worker: failed to connect to server");192latch.countDown();193return;194}195try {196OutputStream os = urlc.getOutputStream();197os.write("foo".getBytes());198if (mode == Mode.REQUEST) {199Thread.sleep(3000);200}201os.close();202is = urlc.getInputStream();203if (mode == Mode.RESPONSE) {204Thread.sleep(3000);205}206if (!checkResponse(is, RESPONSE_BODY)) {207fail("Worker: response");208}209is.close();210return;211} catch (InterruptedException e0) {212fail("Worker: timedout");213} catch (SocketTimeoutException e1) {214fail("Worker: timedout");215} catch (IOException e2) {216switch (mode) {217case NORMAL:218fail("Worker: " + e2.getMessage());219break;220case RESPONSE:221if (is == null) {222fail("Worker: " + e2.getMessage());223break;224}225// default: is ok226}227} finally {228latch.countDown();229}230}231}232233static final int NUM = 20;234235static void test3() throws Exception {236failed = false;237CountDownLatch l = new CountDownLatch(NUM*3);238Worker[] workers = new Worker[NUM*3];239for (int i=0; i<NUM; i++) {240workers[i*3] = new Worker(l, Worker.Mode.NORMAL);241workers[i*3+1] = new Worker(l, Worker.Mode.REQUEST);242workers[i*3+2] = new Worker(l, Worker.Mode.RESPONSE);243workers[i*3].start();244workers[i*3+1].start();245workers[i*3+2].start();246}247l.await();248for (int i=0; i<NUM*3; i++) {249workers[i].join();250}251if (failed) {252throw new RuntimeException("test3: failed");253}254System.out.println("test3: OK");255}256257static boolean checkResponse(InputStream is, String resp) {258try {259ByteArrayOutputStream bos = new ByteArrayOutputStream();260byte[] buf = new byte[64];261int c;262while ((c=is.read(buf)) != -1) {263bos.write(buf, 0, c);264}265bos.close();266if (!bos.toString().equals(resp)) {267System.out.println("Wrong response: " + bos.toString());268return false;269}270} catch (IOException e) {271System.out.println(e);272return false;273}274return true;275}276}277278279