# HG changeset patch # User michaelm # Date 1567436324 -3600 # Node ID c4ec55644b4b40bb79556da310eac17716fc9a39 # Parent 47ce198d5cf116f4b9bd0dc6018e2981fddc9c3d 8229235: com.sun.net.httpserver.HttpExchange should implement AutoCloseable Reviewed-by: dfuchs, michaelm Contributed-by: patrick.concannon@oracle.com diff -r 47ce198d5cf1 -r c4ec55644b4b src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java Mon Sep 02 11:31:12 2019 +0200 +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java Mon Sep 02 15:58:44 2019 +0100 @@ -64,7 +64,7 @@ * @since 1.6 */ -public abstract class HttpExchange { +public abstract class HttpExchange implements AutoCloseable { protected HttpExchange () { } diff -r 47ce198d5cf1 -r c4ec55644b4b test/jdk/com/sun/net/httpserver/bugs/HttpExchange/AutoCloseableHttpExchange.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/net/httpserver/bugs/HttpExchange/AutoCloseableHttpExchange.java Mon Sep 02 15:58:44 2019 +0100 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.net.httpserver.*; + +import java.io.IOException; +import java.io.InputStream; +import java.net.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; + +import jdk.test.lib.net.URIBuilder; +import sun.net.httpserver.HttpExchangeAccess; + + +/** + * @test + * @bug 8203036 + * @library /test/lib + * @modules jdk.httpserver/sun.net.httpserver + * @build jdk.httpserver/sun.net.httpserver.HttpExchangeAccess AutoCloseableHttpExchange + * @run main/othervm AutoCloseableHttpExchange + * @summary Ensure that HttpExchange closes correctly when utilising the + * AutoCloseable interface e.g. both request InputStream and response OutputStream + * are closed, if not already. + */ + +public class AutoCloseableHttpExchange { + + static HttpServer testHttpServer; + static AtomicBoolean exchangeCloseFail = new AtomicBoolean(false); + + static class Handler implements HttpHandler { + private CountDownLatch latch; + + Handler(CountDownLatch latch) { + this.latch = latch; + } + + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + try (HttpExchange e = t) { + while (is.read() != -1) ; + t.sendResponseHeaders(200, -1); + } + if (!HttpExchangeAccess.isClosed(t)) { + exchangeCloseFail.set(true); + } + latch.countDown(); + } + } + + static void connectAndCheck(String realm) throws Exception { + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(testHttpServer.getAddress().getPort()) + .path(realm) + .toURL(); + HttpURLConnection testConnection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); + InputStream is = testConnection.getInputStream(); + while (is.read() != -1) ; + is.close(); + } + + public static void main(String[] args) throws Exception { + int CONNECTION_COUNT = 5; + CountDownLatch latch = new CountDownLatch(CONNECTION_COUNT); + + InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + testHttpServer = HttpServer.create(addr, 0); + testHttpServer.createContext("/test", new Handler(latch)); + + ExecutorService executor = Executors.newFixedThreadPool(CONNECTION_COUNT); + testHttpServer.setExecutor(executor); + testHttpServer.start(); + + while (CONNECTION_COUNT-- != 0) { + connectAndCheck("/test"); + } + latch.await(); + testHttpServer.stop(2); + executor.shutdown(); + + if (exchangeCloseFail.get()) + throw new RuntimeException("The exchange was not closed properly"); + } +} diff -r 47ce198d5cf1 -r c4ec55644b4b test/jdk/com/sun/net/httpserver/bugs/HttpExchange/jdk.httpserver/sun/net/httpserver/HttpExchangeAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/net/httpserver/bugs/HttpExchange/jdk.httpserver/sun/net/httpserver/HttpExchangeAccess.java Mon Sep 02 15:58:44 2019 +0100 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.net.httpserver; + +public class HttpExchangeAccess { + public static boolean isClosed(com.sun.net.httpserver.HttpExchange exch) { + synchronized (exch) { + return ((HttpExchangeImpl) exch).getExchangeImpl().closed; + } + } +}