Path: blob/master/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java
41161 views
/*1* Copyright (c) 2005, 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*/2223/*24* @test25* @bug 6226610 697303026* @summary HTTP tunnel connections send user headers to proxy27* @modules java.base/sun.net.www28* @run main/othervm B622661029*/3031/* This class includes a proxy server that processes the HTTP CONNECT request,32* and validates that the request does not have the user defined header in it.33* The proxy server always returns 400 Bad Request so that the Http client34* will not try to proceed with the connection as there is no back end http server.35*/3637import java.io.*;38import java.net.*;39import sun.net.www.MessageHeader;4041public class B6226610 {42static HeaderCheckerProxyTunnelServer proxy;4344public static void main(String[] args) throws Exception45{46proxy = new HeaderCheckerProxyTunnelServer();47proxy.start();4849InetAddress localHost = InetAddress.getLocalHost();50String hostname = localHost.getHostName();51String hostAddress = localHost.getHostAddress();5253try {54URL u = new URL("https://" + hostname + "/");55System.out.println("Connecting to " + u);56InetSocketAddress proxyAddr = InetSocketAddress.createUnresolved(hostAddress, proxy.getLocalPort());57java.net.URLConnection c = u.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddr));5859/* I want this header to go to the destination server only, protected60* by SSL61*/62c.setRequestProperty("X-TestHeader", "value");63c.connect();6465} catch (IOException e) {66if ( e.getMessage().equals("Unable to tunnel through proxy. Proxy returns \"HTTP/1.1 400 Bad Request\"") )67{68// OK. Proxy will always return 400 so that the main thread can terminate correctly.69}70else71System.out.println(e);72} finally {73if (proxy != null) proxy.shutdown();74}7576if (HeaderCheckerProxyTunnelServer.failed)77throw new RuntimeException("Test failed; see output");78}79}8081class HeaderCheckerProxyTunnelServer extends Thread82{83public static boolean failed = false;8485private static ServerSocket ss = null;8687// client requesting for a tunnel88private Socket clientSocket = null;8990/*91* Origin server's address and port that the client92* wants to establish the tunnel for communication.93*/94private InetAddress serverInetAddr;95private int serverPort;9697public HeaderCheckerProxyTunnelServer() throws IOException98{99if (ss == null) {100ss = new ServerSocket();101ss.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));102}103}104105void shutdown() {106try { ss.close(); } catch (IOException e) {}107}108109public void run()110{111try {112clientSocket = ss.accept();113processRequests();114} catch (IOException e) {115System.out.println("Proxy Failed: " + e);116e.printStackTrace();117try {118ss.close();119}120catch (IOException excep) {121System.out.println("ProxyServer close error: " + excep);122excep.printStackTrace();123}124}125}126127/**128* Returns the port on which the proxy is accepting connections.129*/130public int getLocalPort() {131return ss.getLocalPort();132}133134/*135* Processes the CONNECT request136*/137private void processRequests() throws IOException138{139InputStream in = clientSocket.getInputStream();140MessageHeader mheader = new MessageHeader(in);141String statusLine = mheader.getValue(0);142143if (statusLine.startsWith("CONNECT")) {144// retrieve the host and port info from the status-line145retrieveConnectInfo(statusLine);146147if (mheader.findValue("X-TestHeader") != null) {148System.out.println("Proxy should not receive user defined headers for tunneled requests");149failed = true;150}151152// 6973030153String value;154if ((value = mheader.findValue("Proxy-Connection")) == null ||155!value.equals("keep-alive")) {156System.out.println("Proxy-Connection:keep-alive not being sent");157failed = true;158}159160//This will allow the main thread to terminate without trying to perform the SSL handshake.161send400();162163in.close();164clientSocket.close();165ss.close();166}167else {168System.out.println("proxy server: processes only "169+ "CONNECT method requests, recieved: "170+ statusLine);171}172}173174private void send400() throws IOException175{176OutputStream out = clientSocket.getOutputStream();177PrintWriter pout = new PrintWriter(out);178179pout.println("HTTP/1.1 400 Bad Request");180pout.println();181pout.flush();182}183184private void restart() throws IOException {185(new Thread(this)).start();186}187188/*189* This method retrieves the hostname and port of the destination190* that the connect request wants to establish a tunnel for191* communication.192* The input, connectStr is of the form:193* CONNECT server-name:server-port HTTP/1.x194*/195private void retrieveConnectInfo(String connectStr) throws IOException {196197int starti;198int endi;199String connectInfo;200String serverName = null;201try {202starti = connectStr.indexOf(' ');203endi = connectStr.lastIndexOf(' ');204connectInfo = connectStr.substring(starti+1, endi).trim();205// retrieve server name and port206endi = connectInfo.indexOf(':');207serverName = connectInfo.substring(0, endi);208serverPort = Integer.parseInt(connectInfo.substring(endi+1));209} catch (Exception e) {210throw new IOException("Proxy recieved a request: "211+ connectStr, e);212}213serverInetAddr = InetAddress.getByName(serverName);214}215}216217218