Path: blob/master/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
66649 views
/*1* Copyright (c) 2005, 2021, 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 621608231* @summary Redirect problem with HttpsURLConnection using a proxy32* @modules java.base/sun.net.www33* @library .. /test/lib34* @build jdk.test.lib.NetworkConfiguration35* jdk.test.lib.Platform36* ClosedChannelList37* TunnelProxy38* @key intermittent39* @run main/othervm B621608240*/4142import java.io.FileInputStream;43import java.net.HttpURLConnection;44import java.net.InetAddress;45import java.net.InetSocketAddress;46import java.net.NetworkInterface;47import java.net.ProxySelector;48import java.net.URL;49import java.security.KeyStore;50import java.util.Optional;51import java.util.concurrent.Executors;5253import javax.net.ssl.HostnameVerifier;54import javax.net.ssl.HttpsURLConnection;55import javax.net.ssl.KeyManagerFactory;56import javax.net.ssl.SSLContext;57import javax.net.ssl.SSLSession;58import javax.net.ssl.TrustManagerFactory;5960import com.sun.net.httpserver.HttpExchange;61import com.sun.net.httpserver.HttpHandler;62import com.sun.net.httpserver.HttpsConfigurator;63import com.sun.net.httpserver.HttpsServer;64import jdk.test.lib.NetworkConfiguration;6566public class B6216082 {67static SimpleHttpTransaction httpTrans;68static HttpsServer server;69static TunnelProxy proxy;7071// it seems there's no proxy ever if a url points to 'localhost',72// even if proxy related properties are set. so we need to bind73// our simple http proxy and http server to a non-loopback address74static InetAddress firstNonLoAddress = null;7576public static void main(String[] args) throws Exception {77HostnameVerifier reservedHV =78HttpsURLConnection.getDefaultHostnameVerifier();79try {80// XXX workaround for CNFE81Class.forName("java.nio.channels.ClosedByInterruptException");82if (!setupEnv()) {83return;84}85startHttpServer();86// https.proxyPort can only be set after the TunnelProxy has been87// created as it will use an ephemeral port.88ProxySelector.setDefault(ProxySelector.of(new InetSocketAddress(firstNonLoAddress, proxy.getLocalPort())));89makeHttpCall();90} finally {91if (proxy != null) {92proxy.terminate();93}94if (server != null) {95server.stop(1);96}97HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);98}99}100101/*102* Where do we find the keystores for ssl?103*/104static String pathToStores = "../../../../../../javax/net/ssl/etc";105static String keyStoreFile = "keystore";106static String trustStoreFile = "truststore";107static String passwd = "passphrase";108public static boolean setupEnv() throws Exception {109firstNonLoAddress = getNonLoAddress();110if (firstNonLoAddress == null) {111System.err.println("The test needs at least one non-loopback address to run. Quit now.");112return false;113}114System.out.println(firstNonLoAddress.getHostAddress());115// will use proxy116System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress());117118// setup properties to do ssl119String keyFilename = System.getProperty("test.src", "./") + "/" +120pathToStores + "/" + keyStoreFile;121String trustFilename = System.getProperty("test.src", "./") + "/" +122pathToStores + "/" + trustStoreFile;123124System.setProperty("javax.net.ssl.keyStore", keyFilename);125System.setProperty("javax.net.ssl.keyStorePassword", passwd);126System.setProperty("javax.net.ssl.trustStore", trustFilename);127System.setProperty("javax.net.ssl.trustStorePassword", passwd);128HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());129return true;130}131132public static InetAddress getNonLoAddress() throws Exception {133InetAddress lh = InetAddress.getByName("localhost");134NetworkInterface loNIC = NetworkInterface.getByInetAddress(lh);135136NetworkConfiguration nc = NetworkConfiguration.probe();137Optional<InetAddress> oaddr = nc.interfaces()138.filter(nif -> !nif.getName().equalsIgnoreCase(loNIC.getName()))139.flatMap(nif -> nc.addresses(nif))140.filter(a -> !a.isLoopbackAddress())141.findFirst();142143return oaddr.orElseGet(() -> null);144}145146public static void startHttpServer() throws Exception {147// Both the https server and the proxy let the148// system pick up an ephemeral port.149httpTrans = new SimpleHttpTransaction();150// create and initialize a SSLContext151KeyStore ks = KeyStore.getInstance("JKS");152KeyStore ts = KeyStore.getInstance("JKS");153char[] passphrase = "passphrase".toCharArray();154155ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")), passphrase);156ts.load(new FileInputStream(System.getProperty("javax.net.ssl.trustStore")), passphrase);157158KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");159kmf.init(ks, passphrase);160161TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");162tmf.init(ts);163164SSLContext sslCtx = SSLContext.getInstance("TLS");165166sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);167168server = HttpsServer.create(new InetSocketAddress(firstNonLoAddress, 0), 10);169server.setHttpsConfigurator(new HttpsConfigurator(sslCtx));170server.createContext("/", httpTrans);171server.setExecutor(Executors.newSingleThreadExecutor());172server.start();173proxy = new TunnelProxy(1, 10, firstNonLoAddress, 0);174}175176public static void makeHttpCall() throws Exception {177System.out.println("https server listen on: " + server.getAddress().getPort());178System.out.println("https proxy listen on: " + proxy.getLocalPort());179URL url = new URL("https" , firstNonLoAddress.getHostAddress(),180server.getAddress().getPort(), "/");181HttpURLConnection uc = (HttpURLConnection)url.openConnection();182System.out.println(uc.getResponseCode());183if(uc.getResponseCode() != 200) {184uc.disconnect();185throw new RuntimeException("Test failed : bad http request with response code : "+ uc.getResponseCode());186}187uc.disconnect();188}189190static class NameVerifier implements HostnameVerifier {191public boolean verify(String hostname, SSLSession session) {192return true;193}194}195}196197class SimpleHttpTransaction implements HttpHandler {198199/*200* Our http server which simply redirect first call201*/202public void handle(HttpExchange trans) {203try {204String path = trans.getRequestURI().getPath();205if (path.equals("/")) {206// the first call, redirect it207String location = "/redirect";208trans.getResponseHeaders().set("Location", location);209trans.sendResponseHeaders(302, -1);210} else {211trans.sendResponseHeaders(200, -1);212}213} catch (Exception e) {214throw new RuntimeException(e);215}216}217}218219220