Path: blob/master/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java
41161 views
/*1* Copyright (c) 2001, 2019, 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*/2223import java.io.*;24import java.net.*;25import java.security.KeyStore;26import javax.net.*;27import javax.net.ssl.*;2829import jdk.test.lib.process.OutputAnalyzer;30import jdk.test.lib.process.ProcessTools;31import jdk.test.lib.net.URIBuilder;3233/*34* @test35* @bug 442307436* @modules java.base/sun.net.www37* @summary This test case is written to test the https POST through a proxy38* with proxy authentication. It includes a simple server that serves39* http POST method requests in secure channel, and a client that40* makes https POST request through a proxy.41* @library /test/lib42* @build jdk.test.lib.Utils43* jdk.test.lib.Asserts44* jdk.test.lib.JDKToolFinder45* jdk.test.lib.JDKToolLauncher46* jdk.test.lib.Platform47* jdk.test.lib.process.*48* @compile OriginServer.java ProxyTunnelServer.java49* @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth50* @run main/othervm -Djava.net.preferIPv6Addresses=true51-Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth52*/53public class PostThruProxyWithAuth {5455private static final String TEST_SRC = System.getProperty("test.src", ".");56private static final int TIMEOUT = 30000;5758/*59* Where do we find the keystores?60*/61static String pathToStores = "../../../../../../javax/net/ssl/etc";62static String keyStoreFile = "keystore";63static String trustStoreFile = "truststore";64static String passwd = "passphrase";6566volatile private static int serverPort = 0;67private static ProxyTunnelServer pserver;68private static TestServer server;6970static final String RESPONSE_MSG =71"Https POST thru proxy is successful with proxy authentication";7273/*74* The TestServer implements a OriginServer that75* processes HTTP requests and responses.76*/77static class TestServer extends OriginServer {78public TestServer(ServerSocket ss) throws Exception {79super(ss);80}8182/*83* Returns an array of bytes containing the bytes for84* the data sent in the response.85*86* @return bytes for the data in the response87*/88public byte[] getBytes() {89return RESPONSE_MSG.getBytes();90}91}9293/*94* Main method to create the server and client95*/96public static void main(String args[]) throws Exception {97String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;98String trustFilename = TEST_SRC + "/" + pathToStores + "/"99+ trustStoreFile;100101System.setProperty("javax.net.ssl.keyStore", keyFilename);102System.setProperty("javax.net.ssl.keyStorePassword", passwd);103System.setProperty("javax.net.ssl.trustStore", trustFilename);104System.setProperty("javax.net.ssl.trustStorePassword", passwd);105106boolean useSSL = true;107/*108* setup the server109*/110try {111InetAddress localhost = InetAddress.getLocalHost();112ServerSocketFactory ssf = getServerSocketFactory(useSSL);113ServerSocket ss = ssf.createServerSocket(serverPort, 0, localhost);114ss.setSoTimeout(TIMEOUT); // 30 seconds115serverPort = ss.getLocalPort();116server = new TestServer(ss);117System.out.println("Server started at: " + ss);118} catch (Exception e) {119System.out.println("Server side failed:" +120e.getMessage());121throw e;122}123// trigger the client124try {125doClientSide();126} catch (Exception e) {127System.out.println("Client side failed: " +128e.getMessage());129throw e;130}131long connectCount = pserver.getConnectCount();132if (connectCount == 0) {133throw new AssertionError("Proxy was not used!");134} else {135System.out.println("Proxy CONNECT count: " + connectCount);136}137}138139private static ServerSocketFactory getServerSocketFactory140(boolean useSSL) throws Exception {141if (useSSL) {142// set up key manager to do server authentication143SSLContext ctx = SSLContext.getInstance("TLS");144KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");145KeyStore ks = KeyStore.getInstance("JKS");146char[] passphrase = passwd.toCharArray();147148ks.load(new FileInputStream(System.getProperty(149"javax.net.ssl.keyStore")), passphrase);150kmf.init(ks, passphrase);151ctx.init(kmf.getKeyManagers(), null, null);152153return ctx.getServerSocketFactory();154} else {155return ServerSocketFactory.getDefault();156}157}158159/*160* Message to be posted161*/162static String postMsg = "Testing HTTP post on a https server";163164static void doClientSide() throws Exception {165/*166* setup up a proxy167*/168SocketAddress pAddr = setupProxy();169170/*171* we want to avoid URLspoofCheck failures in cases where the cert172* DN name does not match the hostname in the URL.173*/174HttpsURLConnection.setDefaultHostnameVerifier(175new NameVerifier());176177URL url = URIBuilder.newBuilder()178.scheme("https")179.host(getHostname())180.port(serverPort)181.toURL();182183Proxy p = new Proxy(Proxy.Type.HTTP, pAddr);184System.out.println("Client connecting to: " + url);185System.out.println("Through proxy: " + pAddr);186HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p);187https.setConnectTimeout(TIMEOUT);188https.setReadTimeout(TIMEOUT);189https.setDoOutput(true);190https.setRequestMethod("POST");191PrintStream ps = null;192try {193ps = new PrintStream(https.getOutputStream());194ps.println(postMsg);195ps.flush();196if (https.getResponseCode() != 200) {197throw new RuntimeException("test Failed");198}199ps.close();200// clear the pipe201BufferedReader in = new BufferedReader(202new InputStreamReader(203https.getInputStream()));204String inputLine;205boolean msgFound = false;206while ((inputLine = in.readLine()) != null) {207System.out.println("Client received: " + inputLine);208if (inputLine.contains(RESPONSE_MSG)) msgFound = true;209}210in.close();211if (!msgFound) {212throw new RuntimeException("POST message not found.");213}214} catch (SSLException e) {215if (ps != null)216ps.close();217throw e;218} catch (SocketTimeoutException e) {219System.out.println("Client can not get response in time: "220+ e.getMessage());221}222}223224static class NameVerifier implements HostnameVerifier {225public boolean verify(String hostname, SSLSession session) {226return true;227}228}229230static SocketAddress setupProxy() throws IOException {231232InetAddress localhost = InetAddress.getLocalHost();233pserver = new ProxyTunnelServer(localhost);234235/*236* register a system wide authenticator and setup the proxy for237* authentication238*/239Authenticator.setDefault(new TestAuthenticator());240241// register with the username and password242pserver.needUserAuth(true);243pserver.setUserAuth("Test", "test123");244245pserver.start();246247return new InetSocketAddress(localhost, pserver.getPort());248}249250public static class TestAuthenticator extends Authenticator {251public PasswordAuthentication getPasswordAuthentication() {252return new PasswordAuthentication("Test",253"test123".toCharArray());254}255}256257private static String getHostname() {258try {259OutputAnalyzer oa = ProcessTools.executeCommand("hostname");260return oa.getOutput().trim();261} catch (Throwable e) {262throw new RuntimeException("Get hostname failed.", e);263}264}265}266267268