Path: blob/master/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java
41161 views
/*1* Copyright (c) 2008, 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* @test25* @bug 661838726* @summary SSL client sessions do not close cleanly. A TCP reset occurs27* instead of a close_notify alert.28* @run main/othervm CloseKeepAliveCached29*30* SunJSSE does not support dynamic system properties, no way to re-use31* system properties in samevm/agentvm mode.32*33* @ignore34* After run the test manually, at the end of the debug output,35* if "MainThread, called close()" found, the test passed. Otherwise,36* if "Keep-Alive-Timer: called close()", the test failed.37*/3839import java.net.*;40import java.util.*;41import java.io.*;42import javax.net.ssl.*;4344public class CloseKeepAliveCached {45static Map cookies;46ServerSocket ss;4748/*49* =============================================================50* Set the various variables needed for the tests, then51* specify what tests to run on each side.52*/5354/*55* Should we run the client or server in a separate thread?56* Both sides can throw exceptions, but do you have a preference57* as to which side should be the main thread.58*/59static boolean separateServerThread = true;6061/*62* Where do we find the keystores?63*/64static String pathToStores = "../../../../../../javax/net/ssl/etc";65static String keyStoreFile = "keystore";66static String trustStoreFile = "truststore";67static String passwd = "passphrase";6869/*70* Is the server ready to serve?71*/72volatile static boolean serverReady = false;7374/*75* Turn on SSL debugging?76*/77static boolean debug = false;7879private SSLServerSocket sslServerSocket = null;8081/*82* Define the server side of the test.83*84* If the server prematurely exits, serverReady will be set to true85* to avoid infinite hangs.86*/87void doServerSide() throws Exception {88SSLServerSocketFactory sslssf =89(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();90sslServerSocket =91(SSLServerSocket) sslssf.createServerSocket(serverPort);92serverPort = sslServerSocket.getLocalPort();9394/*95* Signal Client, we're ready for his connect.96*/97serverReady = true;98SSLSocket sslSocket = null;99try {100sslSocket = (SSLSocket) sslServerSocket.accept();101for (int i = 0; i < 3 && !sslSocket.isClosed(); i++) {102// read request103InputStream is = sslSocket.getInputStream ();104105BufferedReader r = new BufferedReader(106new InputStreamReader(is));107String x;108while ((x=r.readLine()) != null) {109if (x.length() ==0) {110break;111}112}113114115PrintStream out = new PrintStream(116new BufferedOutputStream(117sslSocket.getOutputStream() ));118119/* send the header */120out.print("HTTP/1.1 200 OK\r\n");121out.print("Keep-Alive: timeout=15, max=100\r\n");122out.print("Connection: Keep-Alive\r\n");123out.print("Content-Type: text/html; charset=iso-8859-1\r\n");124out.print("Content-Length: 9\r\n");125out.print("\r\n");126out.print("Testing\r\n");127out.flush();128129Thread.sleep(50);130}131sslSocket.close();132sslServerSocket.close();133} catch (Exception e) {134e.printStackTrace();135}136}137138/*139* Define the client side of the test.140*141* If the server prematurely exits, serverReady will be set to true142* to avoid infinite hangs.143*/144void doClientSide() throws Exception {145/*146* Wait for server to get started.147*/148while (!serverReady) {149Thread.sleep(50);150}151152HostnameVerifier reservedHV =153HttpsURLConnection.getDefaultHostnameVerifier();154try {155HttpsURLConnection http = null;156157/* establish http connection to server */158URL url = new URL("https://localhost:" + serverPort+"/");159HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());160http = (HttpsURLConnection)url.openConnection();161InputStream is = http.getInputStream ();162while (is.read() != -1);163is.close();164165url = new URL("https://localhost:" + serverPort+"/");166http = (HttpsURLConnection)url.openConnection();167is = http.getInputStream ();168while (is.read() != -1);169170// if inputstream.close() called, the http.disconnect() will171// not able to close the cached connection. If application172// wanna close the keep-alive cached connection immediately173// with httpURLConnection.disconnect(), they should not call174// inputstream.close() explicitly, the175// httpURLConnection.disconnect() will do it internally.176// is.close();177178// close the connection, sending close_notify to peer.179// otherwise, the connection will be closed by Finalizer or180// Keep-Alive-Timer if timeout.181http.disconnect();182// Thread.sleep(5000);183} catch (IOException ioex) {184if (sslServerSocket != null)185sslServerSocket.close();186throw ioex;187} finally {188HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);189}190}191192static class NameVerifier implements HostnameVerifier {193public boolean verify(String hostname, SSLSession session) {194return true;195}196}197198/*199* =============================================================200* The remainder is just support stuff201*/202203// use any free port by default204volatile int serverPort = 0;205206volatile Exception serverException = null;207volatile Exception clientException = null;208209public static void main(String args[]) throws Exception {210String keyFilename =211System.getProperty("test.src", "./") + "/" + pathToStores +212"/" + keyStoreFile;213String trustFilename =214System.getProperty("test.src", "./") + "/" + pathToStores +215"/" + trustStoreFile;216217System.setProperty("javax.net.ssl.keyStore", keyFilename);218System.setProperty("javax.net.ssl.keyStorePassword", passwd);219System.setProperty("javax.net.ssl.trustStore", trustFilename);220System.setProperty("javax.net.ssl.trustStorePassword", passwd);221222if (debug)223System.setProperty("javax.net.debug", "all");224225/*226* Start the tests.227*/228new CloseKeepAliveCached();229}230231Thread clientThread = null;232Thread serverThread = null;233/*234* Primary constructor, used to drive remainder of the test.235*236* Fork off the other side, then do your work.237*/238CloseKeepAliveCached() throws Exception {239if (separateServerThread) {240startServer(true);241startClient(false);242} else {243startClient(true);244startServer(false);245}246247/*248* Wait for other side to close down.249*/250if (separateServerThread) {251serverThread.join();252} else {253clientThread.join();254}255256/*257* When we get here, the test is pretty much over.258*259* If the main thread excepted, that propagates back260* immediately. If the other thread threw an exception, we261* should report back.262*/263if (serverException != null)264throw serverException;265if (clientException != null)266throw clientException;267}268269void startServer(boolean newThread) throws Exception {270if (newThread) {271serverThread = new Thread() {272public void run() {273try {274doServerSide();275} catch (Exception e) {276/*277* Our server thread just died.278*279* Release the client, if not active already...280*/281System.err.println("Server died...");282serverReady = true;283serverException = e;284}285}286};287serverThread.start();288} else {289doServerSide();290}291}292293void startClient(boolean newThread) throws Exception {294if (newThread) {295clientThread = new Thread() {296public void run() {297try {298doClientSide();299} catch (Exception e) {300/*301* Our client thread just died.302*/303System.err.println("Client died...");304clientException = e;305}306}307};308clientThread.start();309} else {310doClientSide();311}312}313}314315316