SSLSocketTemplate.java revision 13924:a025c940d090
1/* 2 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24// SunJSSE does not support dynamic system properties, no way to re-use 25// system properties in samevm/agentvm mode. 26 27/* 28 * @test 29 * @bug 1234567 30 * @summary Use this template to help speed your client/server tests. 31 * @run main/othervm SSLSocketTemplate 32 * @author Brad Wetmore 33 */ 34 35import java.io.*; 36import javax.net.ssl.*; 37 38public class SSLSocketTemplate { 39 40 /* 41 * ============================================================= 42 * Set the various variables needed for the tests, then 43 * specify what tests to run on each side. 44 */ 45 46 /* 47 * Should we run the client or server in a separate thread? 48 * Both sides can throw exceptions, but do you have a preference 49 * as to which side should be the main thread. 50 */ 51 static boolean separateServerThread = false; 52 53 /* 54 * Where do we find the keystores? 55 */ 56 static String pathToStores = "../etc"; 57 static String keyStoreFile = "keystore"; 58 static String trustStoreFile = "truststore"; 59 static String passwd = "passphrase"; 60 61 /* 62 * Is the server ready to serve? 63 */ 64 volatile static boolean serverReady = false; 65 66 /* 67 * Turn on SSL debugging? 68 */ 69 static boolean debug = false; 70 71 /* 72 * If the client or server is doing some kind of object creation 73 * that the other side depends on, and that thread prematurely 74 * exits, you may experience a hang. The test harness will 75 * terminate all hung threads after its timeout has expired, 76 * currently 3 minutes by default, but you might try to be 77 * smart about it.... 78 */ 79 80 /* 81 * Define the server side of the test. 82 * 83 * If the server prematurely exits, serverReady will be set to true 84 * to avoid infinite hangs. 85 */ 86 void doServerSide() throws Exception { 87 SSLServerSocketFactory sslssf = 88 (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); 89 try (SSLServerSocket sslServerSocket = 90 (SSLServerSocket)sslssf.createServerSocket(serverPort)) { 91 92 serverPort = sslServerSocket.getLocalPort(); 93 94 /* 95 * Signal Client, we're ready for his connect. 96 */ 97 serverReady = true; 98 99 try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) { 100 InputStream sslIS = sslSocket.getInputStream(); 101 OutputStream sslOS = sslSocket.getOutputStream(); 102 103 sslIS.read(); 104 sslOS.write(85); 105 sslOS.flush(); 106 } 107 } 108 } 109 110 /* 111 * Define the client side of the test. 112 * 113 * If the server prematurely exits, serverReady will be set to true 114 * to avoid infinite hangs. 115 */ 116 void doClientSide() throws Exception { 117 118 /* 119 * Wait for server to get started. 120 */ 121 while (!serverReady) { 122 Thread.sleep(50); 123 } 124 125 SSLSocketFactory sslsf = 126 (SSLSocketFactory)SSLSocketFactory.getDefault(); 127 try (SSLSocket sslSocket = 128 (SSLSocket)sslsf.createSocket("localhost", serverPort)) { 129 130 InputStream sslIS = sslSocket.getInputStream(); 131 OutputStream sslOS = sslSocket.getOutputStream(); 132 133 sslOS.write(280); 134 sslOS.flush(); 135 sslIS.read(); 136 } 137 } 138 139 /* 140 * ============================================================= 141 * The remainder is just support stuff 142 */ 143 144 // use any free port by default 145 volatile int serverPort = 0; 146 147 volatile Exception serverException = null; 148 volatile Exception clientException = null; 149 150 public static void main(String[] args) throws Exception { 151 String keyFilename = 152 System.getProperty("test.src", ".") + "/" + pathToStores + 153 "/" + keyStoreFile; 154 String trustFilename = 155 System.getProperty("test.src", ".") + "/" + pathToStores + 156 "/" + trustStoreFile; 157 158 System.setProperty("javax.net.ssl.keyStore", keyFilename); 159 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 160 System.setProperty("javax.net.ssl.trustStore", trustFilename); 161 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 162 163 if (debug) { 164 System.setProperty("javax.net.debug", "all"); 165 } 166 167 /* 168 * Start the tests. 169 */ 170 new SSLSocketTemplate(); 171 } 172 173 Thread clientThread = null; 174 Thread serverThread = null; 175 176 /* 177 * Primary constructor, used to drive remainder of the test. 178 * 179 * Fork off the other side, then do your work. 180 */ 181 SSLSocketTemplate() throws Exception { 182 Exception startException = null; 183 try { 184 if (separateServerThread) { 185 startServer(true); 186 startClient(false); 187 } else { 188 startClient(true); 189 startServer(false); 190 } 191 } catch (Exception e) { 192 startException = e; 193 } 194 195 /* 196 * Wait for other side to close down. 197 */ 198 if (separateServerThread) { 199 if (serverThread != null) { 200 serverThread.join(); 201 } 202 } else { 203 if (clientThread != null) { 204 clientThread.join(); 205 } 206 } 207 208 /* 209 * When we get here, the test is pretty much over. 210 * Which side threw the error? 211 */ 212 Exception local; 213 Exception remote; 214 215 if (separateServerThread) { 216 remote = serverException; 217 local = clientException; 218 } else { 219 remote = clientException; 220 local = serverException; 221 } 222 223 Exception exception = null; 224 225 /* 226 * Check various exception conditions. 227 */ 228 if ((local != null) && (remote != null)) { 229 // If both failed, return the curthread's exception. 230 local.initCause(remote); 231 exception = local; 232 } else if (local != null) { 233 exception = local; 234 } else if (remote != null) { 235 exception = remote; 236 } else if (startException != null) { 237 exception = startException; 238 } 239 240 /* 241 * If there was an exception *AND* a startException, 242 * output it. 243 */ 244 if (exception != null) { 245 if (exception != startException && startException != null) { 246 exception.addSuppressed(startException); 247 } 248 throw exception; 249 } 250 251 // Fall-through: no exception to throw! 252 } 253 254 void startServer(boolean newThread) throws Exception { 255 if (newThread) { 256 serverThread = new Thread() { 257 @Override 258 public void run() { 259 try { 260 doServerSide(); 261 } catch (Exception e) { 262 /* 263 * Our server thread just died. 264 * 265 * Release the client, if not active already... 266 */ 267 System.err.println("Server died..."); 268 serverReady = true; 269 serverException = e; 270 } 271 } 272 }; 273 serverThread.start(); 274 } else { 275 try { 276 doServerSide(); 277 } catch (Exception e) { 278 serverException = e; 279 } finally { 280 serverReady = true; 281 } 282 } 283 } 284 285 void startClient(boolean newThread) throws Exception { 286 if (newThread) { 287 clientThread = new Thread() { 288 @Override 289 public void run() { 290 try { 291 doClientSide(); 292 } catch (Exception e) { 293 /* 294 * Our client thread just died. 295 */ 296 System.err.println("Client died..."); 297 clientException = e; 298 } 299 } 300 }; 301 clientThread.start(); 302 } else { 303 try { 304 doClientSide(); 305 } catch (Exception e) { 306 clientException = e; 307 } 308 } 309 } 310} 311