< prev index next >

test/jdk/java/net/Socket/HttpProxy.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -21,15 +21,16 @@
  * questions.
  */
 
 /*
  * @test
- * @bug 6370908
+ * @bug 6370908 8220663
  * @summary Add support for HTTP_CONNECT proxy in Socket class
  * @modules java.base/sun.net.www
  * @run main HttpProxy
  * @run main/othervm -Djava.net.preferIPv4Stack=true HttpProxy
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true HttpProxy
  */
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;

@@ -38,23 +39,27 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.List;
 import sun.net.www.MessageHeader;
 
 public class HttpProxy {
     final String proxyHost;
     final int proxyPort;
     static final int SO_TIMEOUT = 15000;
 
     public static void main(String[] args) throws Exception {
         String host;
         int port;
+        ConnectProxyTunnelServer proxy = null;
         if (args.length == 0) {
             // Start internal proxy
-            ConnectProxyTunnelServer proxy = new ConnectProxyTunnelServer();
+            proxy = new ConnectProxyTunnelServer();
             proxy.start();
             host = "localhost";
             port = proxy.getLocalPort();
             out.println("Running with internal proxy: " + host + ":" + port);
         } else if (args.length == 2) {

@@ -64,12 +69,17 @@
         } else {
             System.err.println("Usage: java HttpProxy [<proxy host> <proxy port>]");
             return;
         }
 
+        try {
         HttpProxy p = new HttpProxy(host, port);
         p.test();
+        } finally {
+            if (proxy != null)
+                proxy.close();
+        }
     }
 
     public HttpProxy(String proxyHost, int proxyPort) {
         this.proxyHost = proxyHost;
         this.proxyPort = proxyPort;

@@ -77,18 +87,27 @@
 
     void test() throws Exception {
         InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
         Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
 
-        try (ServerSocket ss = new ServerSocket(0);
-             Socket sock = new Socket(httpProxy)) {
+        try (ServerSocket ss = new ServerSocket(0)) {
+            List<InetSocketAddress> externalAddresses = new ArrayList<>();
+            externalAddresses.add(
+                new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort()));
+
+            if (!"true".equals(System.getProperty("java.net.preferIPv4Stack"))) {
+                byte[] bytes = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+                var address = InetAddress.getByAddress(bytes);
+                externalAddresses.add(
+                        new InetSocketAddress(address, ss.getLocalPort()));
+            }
+
+            for (SocketAddress externalAddress : externalAddresses) {
+                try (Socket sock = new Socket(httpProxy)) {
             sock.setSoTimeout(SO_TIMEOUT);
             sock.setTcpNoDelay(false);
 
-            InetSocketAddress externalAddress =
-                new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort());
-
             out.println("Trying to connect to server socket on " + externalAddress);
             sock.connect(externalAddress);
             try (Socket externalSock = ss.accept()) {
                 // perform some simple checks
                 check(sock.isBound(), "Socket is not bound");

@@ -100,17 +119,19 @@
 
                 simpleDataExchange(sock, externalSock);
             }
         }
     }
+        }
+    }
 
     static void check(boolean condition, String message) {
         if (!condition) out.println(message);
     }
 
     static Exception unexpected(Exception e) {
-        out.println("Unexcepted Exception: " + e);
+        out.println("Unexpected Exception: " + e);
         e.printStackTrace();
         return e;
     }
 
     // performs a simple exchange of data between the two sockets

@@ -162,26 +183,34 @@
         int i1 = (int)b1 & 0xFF;
         int i2 = (int)b2 & 0xFF;
         return i1 * 256 + i2;
     }
 
-    static class ConnectProxyTunnelServer extends Thread {
+    static class ConnectProxyTunnelServer extends Thread implements AutoCloseable {
 
         private final ServerSocket ss;
+        private volatile boolean closed;
 
         public ConnectProxyTunnelServer() throws IOException {
             ss = new ServerSocket(0);
         }
 
         @Override
         public void run() {
+            try {
+                while (!closed) {
             try (Socket clientSocket = ss.accept()) {
                 processRequest(clientSocket);
+                    }
+                }
             } catch (Exception e) {
+                if (!closed) {
                 out.println("Proxy Failed: " + e);
                 e.printStackTrace();
+                }
             } finally {
+                if (!closed)
                 try { ss.close(); } catch (IOException x) { unexpected(x); }
             }
         }
 
         /**

@@ -189,20 +218,26 @@
          */
         public int getLocalPort() {
             return ss.getLocalPort();
         }
 
+        @Override
+        public void close() throws Exception {
+            closed = true;
+            ss.close();
+        }
+
         /*
          * Processes the CONNECT request
          */
         private void processRequest(Socket clientSocket) throws Exception {
             MessageHeader mheader = new MessageHeader(clientSocket.getInputStream());
             String statusLine = mheader.getValue(0);
 
             if (!statusLine.startsWith("CONNECT")) {
                 out.println("proxy server: processes only "
-                                  + "CONNECT method requests, recieved: "
+                                  + "CONNECT method requests, received: "
                                   + statusLine);
                 return;
             }
 
             // retrieve the host and port info from the status-line

@@ -244,16 +279,21 @@
             try {
                 int starti = connectStr.indexOf(' ');
                 int endi = connectStr.lastIndexOf(' ');
                 String connectInfo = connectStr.substring(starti+1, endi).trim();
                 // retrieve server name and port
-                endi = connectInfo.indexOf(':');
+                endi = connectInfo.lastIndexOf(':');
                 String name = connectInfo.substring(0, endi);
+                if (name.startsWith("[")) {
+                    assert name.endsWith("]") : "name:" + name;
+                    assert name.contains(":") : "name:" + name;
+                    name = name.substring(1, name.length() - 1);
+                }
                 int port = Integer.parseInt(connectInfo.substring(endi+1));
                 return new InetSocketAddress(name, port);
             } catch (Exception e) {
-                out.println("Proxy recieved a request: " + connectStr);
+                out.println("Proxy received a request: " + connectStr);
                 throw unexpected(e);
             }
         }
     }
 
< prev index next >