Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java
38889 views
/*1* Copyright (c) 2005, 2010, 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 6226610 697303026* @run main/othervm B622661027* @summary HTTP tunnel connections send user headers to proxy28*/2930/* This class includes a proxy server that processes the HTTP CONNECT request,31* and validates that the request does not have the user defined header in it.32* The proxy server always returns 400 Bad Request so that the Http client33* will not try to proceed with the connection as there is no back end http server.34*/3536import java.io.*;37import java.net.*;38import sun.net.www.MessageHeader;3940public class B6226610 {41static HeaderCheckerProxyTunnelServer proxy;4243public static void main(String[] args) throws Exception44{45proxy = new HeaderCheckerProxyTunnelServer();46proxy.start();4748String hostname = InetAddress.getLocalHost().getHostName();4950try {51URL u = new URL("https://" + hostname + "/");52System.out.println("Connecting to " + u);53InetSocketAddress proxyAddr = new InetSocketAddress(hostname, proxy.getLocalPort());54java.net.URLConnection c = u.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddr));5556/* I want this header to go to the destination server only, protected57* by SSL58*/59c.setRequestProperty("X-TestHeader", "value");60c.connect();6162} catch (IOException e) {63if ( e.getMessage().equals("Unable to tunnel through proxy. Proxy returns \"HTTP/1.1 400 Bad Request\"") )64{65// OK. Proxy will always return 400 so that the main thread can terminate correctly.66}67else68System.out.println(e);69} finally {70if (proxy != null) proxy.shutdown();71}7273if (HeaderCheckerProxyTunnelServer.failed)74throw new RuntimeException("Test failed; see output");75}76}7778class HeaderCheckerProxyTunnelServer extends Thread79{80public static boolean failed = false;8182private static ServerSocket ss = null;8384// client requesting for a tunnel85private Socket clientSocket = null;8687/*88* Origin server's address and port that the client89* wants to establish the tunnel for communication.90*/91private InetAddress serverInetAddr;92private int serverPort;9394public HeaderCheckerProxyTunnelServer() throws IOException95{96if (ss == null) {97ss = new ServerSocket(0);98}99}100101void shutdown() {102try { ss.close(); } catch (IOException e) {}103}104105public void run()106{107try {108clientSocket = ss.accept();109processRequests();110} catch (IOException e) {111System.out.println("Proxy Failed: " + e);112e.printStackTrace();113try {114ss.close();115}116catch (IOException excep) {117System.out.println("ProxyServer close error: " + excep);118excep.printStackTrace();119}120}121}122123/**124* Returns the port on which the proxy is accepting connections.125*/126public int getLocalPort() {127return ss.getLocalPort();128}129130/*131* Processes the CONNECT request132*/133private void processRequests() throws IOException134{135InputStream in = clientSocket.getInputStream();136MessageHeader mheader = new MessageHeader(in);137String statusLine = mheader.getValue(0);138139if (statusLine.startsWith("CONNECT")) {140// retrieve the host and port info from the status-line141retrieveConnectInfo(statusLine);142143if (mheader.findValue("X-TestHeader") != null) {144System.out.println("Proxy should not receive user defined headers for tunneled requests");145failed = true;146}147148// 6973030149String value;150if ((value = mheader.findValue("Proxy-Connection")) == null ||151!value.equals("keep-alive")) {152System.out.println("Proxy-Connection:keep-alive not being sent");153failed = true;154}155156//This will allow the main thread to terminate without trying to perform the SSL handshake.157send400();158159in.close();160clientSocket.close();161ss.close();162}163else {164System.out.println("proxy server: processes only "165+ "CONNECT method requests, recieved: "166+ statusLine);167}168}169170private void send400() throws IOException171{172OutputStream out = clientSocket.getOutputStream();173PrintWriter pout = new PrintWriter(out);174175pout.println("HTTP/1.1 400 Bad Request");176pout.println();177pout.flush();178}179180private void restart() throws IOException {181(new Thread(this)).start();182}183184/*185* This method retrieves the hostname and port of the destination186* that the connect request wants to establish a tunnel for187* communication.188* The input, connectStr is of the form:189* CONNECT server-name:server-port HTTP/1.x190*/191private void retrieveConnectInfo(String connectStr) throws IOException {192193int starti;194int endi;195String connectInfo;196String serverName = null;197try {198starti = connectStr.indexOf(' ');199endi = connectStr.lastIndexOf(' ');200connectInfo = connectStr.substring(starti+1, endi).trim();201// retrieve server name and port202endi = connectInfo.indexOf(':');203serverName = connectInfo.substring(0, endi);204serverPort = Integer.parseInt(connectInfo.substring(endi+1));205} catch (Exception e) {206throw new IOException("Proxy recieved a request: "207+ connectStr);208}209serverInetAddr = InetAddress.getByName(serverName);210}211}212213214