Path: blob/master/test/jdk/sun/security/ssl/AppInputStream/ReadBlocksClose.java
41152 views
/*1* Copyright (c) 2003, 2011, 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// SunJSSE does not support dynamic system properties, no way to re-use25// system properties in samevm/agentvm mode.26//2728/*29* @test30* @bug 481414031* @summary AppInputStream: read can block a close32* @run main/othervm -Djdk.tls.acknowledgeCloseNotify=true ReadBlocksClose33* @author Brad Wetmore34*/3536import java.io.*;37import java.net.*;38import javax.net.ssl.*;3940public class ReadBlocksClose {4142/*43* =============================================================44* Set the various variables needed for the tests, then45* specify what tests to run on each side.46*/4748/*49* Should we run the client or server in a separate thread?50* Both sides can throw exceptions, but do you have a preference51* as to which side should be the main thread.52*/53static boolean separateServerThread = false;5455/*56* Where do we find the keystores?57*/58static String pathToStores = "../../../../javax/net/ssl/etc";59static String keyStoreFile = "keystore";60static String trustStoreFile = "truststore";61static String passwd = "passphrase";6263/*64* Is the server ready to serve?65*/66volatile static boolean serverReady = false;6768/*69* Turn on SSL debugging?70*/71static boolean debug = false;7273/*74* If the client or server is doing some kind of object creation75* that the other side depends on, and that thread prematurely76* exits, you may experience a hang. The test harness will77* terminate all hung threads after its timeout has expired,78* currently 3 minutes by default, but you might try to be79* smart about it....80*/8182/*83* Define the server side of the test.84*85* If the server prematurely exits, serverReady will be set to true86* to avoid infinite hangs.87*/88void doServerSide() throws Exception {89SSLServerSocketFactory sslssf =90(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();91SSLServerSocket sslServerSocket =92(SSLServerSocket) sslssf.createServerSocket(serverPort);9394serverPort = sslServerSocket.getLocalPort();9596/*97* Signal Client, we're ready for his connect.98*/99serverReady = true;100101SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();102InputStream sslIS = sslSocket.getInputStream();103OutputStream sslOS = sslSocket.getOutputStream();104105try {106sslIS.read();107} catch (IOException e) {108// this is ok, we expect this to time out anyway if the bug109// is not fixed. This is just to make sure that we110// don't inadvertantly fail.111}112113sslSocket.close();114}115116/*117* Define the client side of the test.118*119* If the server prematurely exits, serverReady will be set to true120* to avoid infinite hangs.121*/122void doClientSide() throws Exception {123124/*125* Wait for server to get started.126*/127while (!serverReady) {128Thread.sleep(50);129}130131SSLSocketFactory sslsf =132(SSLSocketFactory) SSLSocketFactory.getDefault();133SSLSocket sslSocket = (SSLSocket)134sslsf.createSocket("localhost", serverPort);135136final InputStream sslIS = sslSocket.getInputStream();137final OutputStream sslOS = sslSocket.getOutputStream();138139new Thread(new Runnable() {140public void run() {141try {142System.out.println("Closing Thread started");143Thread.sleep(3000);144System.out.println("Closing Thread closing");145sslOS.close();146System.out.println("Closing Thread closed");147} catch (Exception e) {148RuntimeException rte =149new RuntimeException("Check this out");150rte.initCause(e);151throw rte;152}153}154}).start();155156try {157/*158* This should timeout and fail the test159*/160System.out.println("Client starting read");161sslIS.read();162} catch (IOException e) {163// this is ok, we expect this to time out anyway if the bug164// is not fixed. This is just to make sure that we165// don't inadvertantly fail.166}167168sslSocket.close();169}170171/*172* =============================================================173* The remainder is just support stuff174*/175176// use any free port by default177volatile int serverPort = 0;178179volatile Exception serverException = null;180volatile Exception clientException = null;181182public static void main(String[] args) throws Exception {183String keyFilename =184System.getProperty("test.src", "./") + "/" + pathToStores +185"/" + keyStoreFile;186String trustFilename =187System.getProperty("test.src", "./") + "/" + pathToStores +188"/" + trustStoreFile;189190System.setProperty("javax.net.ssl.keyStore", keyFilename);191System.setProperty("javax.net.ssl.keyStorePassword", passwd);192System.setProperty("javax.net.ssl.trustStore", trustFilename);193System.setProperty("javax.net.ssl.trustStorePassword", passwd);194195if (debug)196System.setProperty("javax.net.debug", "all");197198/*199* Start the tests.200*/201new ReadBlocksClose();202}203204Thread clientThread = null;205Thread serverThread = null;206207/*208* Primary constructor, used to drive remainder of the test.209*210* Fork off the other side, then do your work.211*/212ReadBlocksClose() throws Exception {213try {214if (separateServerThread) {215startServer(true);216startClient(false);217} else {218startClient(true);219startServer(false);220}221} catch (Exception e) {222// swallow for now. Show later223}224225/*226* Wait for other side to close down.227*/228if (separateServerThread) {229serverThread.join();230} else {231clientThread.join();232}233234/*235* When we get here, the test is pretty much over.236* Which side threw the error?237*/238Exception local;239Exception remote;240String whichRemote;241242if (separateServerThread) {243remote = serverException;244local = clientException;245whichRemote = "server";246} else {247remote = clientException;248local = serverException;249whichRemote = "client";250}251252/*253* If both failed, return the curthread's exception, but also254* print the remote side Exception255*/256if ((local != null) && (remote != null)) {257System.out.println(whichRemote + " also threw:");258remote.printStackTrace();259System.out.println();260throw local;261}262263if (remote != null) {264throw remote;265}266267if (local != null) {268throw local;269}270}271272void startServer(boolean newThread) throws Exception {273if (newThread) {274serverThread = new Thread() {275public void run() {276try {277doServerSide();278} catch (Exception e) {279/*280* Our server thread just died.281*282* Release the client, if not active already...283*/284System.err.println("Server died...");285serverReady = true;286serverException = e;287}288}289};290serverThread.start();291} else {292try {293doServerSide();294} catch (Exception e) {295serverException = e;296} finally {297serverReady = true;298}299}300}301302void startClient(boolean newThread) throws Exception {303if (newThread) {304clientThread = new Thread() {305public void run() {306try {307doClientSide();308} catch (Exception e) {309/*310* Our client thread just died.311*/312System.err.println("Client died...");313clientException = e;314}315}316};317clientThread.start();318} else {319try {320doClientSide();321} catch (Exception e) {322clientException = e;323}324}325}326}327328329