< prev index next >

test/jdk/java/net/httpclient/ProxyServer.java

Print this page

        

@@ -23,10 +23,11 @@
 
 import java.net.*;
 import java.io.*;
 import java.util.*;
 import java.security.*;
+import java.util.concurrent.CopyOnWriteArrayList;
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Arrays.asList;
 import static java.util.stream.Collectors.toList;
 
 /**

@@ -88,11 +89,11 @@
         listener.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), port));
         this.port = listener.getLocalPort();
         this.credentials = credentials;
         setName("ProxyListener");
         setDaemon(true);
-        connections = new LinkedList<>();
+        connections = new CopyOnWriteArrayList<Connection>();
         start();
     }
 
     public ProxyServer(String s) {
         credentials = null;

@@ -108,19 +109,20 @@
     /**
      * Shuts down the proxy, probably aborting any connections
      * currently open
      */
     public void close() throws IOException {
-        if (debug) System.out.println("Proxy: closing");
+        if (debug) System.out.println("Proxy: closing server");
         done = true;
         listener.close();
         for (Connection c : connections) {
             c.close();
+            c.awaitCompletion();
         }
     }
 
-    List<Connection> connections;
+    CopyOnWriteArrayList<Connection> connections;
 
     volatile boolean done;
 
     public void run() {
         if (System.getSecurityManager() == null) {

@@ -135,46 +137,48 @@
             });
         }
     }
 
     public void execute() {
+        int id = 0;
         try {
-            while(!done) {
+            while (!done) {
                 Socket s = listener.accept();
+                id++;
+                Connection c = new Connection(s, id);
                 if (debug)
-                    System.out.println("Client: " + s);
-                Connection c = new Connection(s);
+                    System.out.println("Proxy: accepted new connection: " + s);
                 connections.add(c);
+                c.init();
             }
         } catch(Throwable e) {
             if (debug && !done) {
-                System.out.println("Fatal error: Listener: " + e);
+                System.out.println("Proxy: Fatal error, listener got " + e);
                 e.printStackTrace();
             }
         }
     }
 
     /**
      * Transparently forward everything, once we know what the destination is
      */
     class Connection {
 
+        private final int id;
         Socket clientSocket, serverSocket;
         Thread out, in;
         volatile InputStream clientIn, serverIn;
         volatile OutputStream clientOut, serverOut;
 
-        boolean forwarding = false;
-
         final static int CR = 13;
         final static int LF = 10;
 
-        Connection(Socket s) throws IOException {
+        Connection(Socket s, int id) throws IOException {
+            this.id = id;
             this.clientSocket= s;
             this.clientIn = new BufferedInputStream(s.getInputStream());
             this.clientOut = s.getOutputStream();
-            init();
         }
 
         byte[] readHeaders(InputStream is) throws IOException {
             byte[] outbuffer = new byte[8000];
             int crlfcount = 0;

@@ -216,13 +220,25 @@
         }
 
         private volatile boolean closing;
         public synchronized void close() throws IOException {
             closing = true;
-            if (debug) System.out.println("Closing connection (proxy)");
-            if (serverSocket != null) serverSocket.close();
-            if (clientSocket != null) clientSocket.close();
+            if (debug)
+                System.out.println("Proxy: closing connection {" + this + "}");
+            if (serverSocket != null)
+                serverSocket.close();
+            if (clientSocket != null)
+                clientSocket.close();
+        }
+
+        public void awaitCompletion() {
+            try {
+                if (in != null)
+                    in.join();
+                if (out!= null)
+                    out.join();
+            } catch (InterruptedException e) { }
         }
 
         int findCRLF(byte[] b) {
             for (int i=0; i<b.length-1; i++) {
                 if (b[i] == CR && b[i+1] == LF) {

@@ -272,10 +288,13 @@
             try {
                 byte[] buf;
                 while (true) {
                     buf = readHeaders(clientIn);
                     if (findCRLF(buf) == -1) {
+                        if (debug)
+                            System.out.println("Proxy: no CRLF closing, buf contains:["
+                                    + new String(buf, UTF_8) + "]" );
                         close();
                         return;
                     }
 
                     List<String> headers = asList(new String(buf, UTF_8).split("\r\n"));

@@ -300,11 +319,12 @@
                 } else {
                     doProxy(params[1], buf, p, cmd);
                 }
             } catch (Throwable e) {
                 if (debug) {
-                    System.out.println (e);
+                    System.out.println("Proxy: " + e);
+                    e.printStackTrace();
                 }
                 try {close(); } catch (IOException e1) {}
             }
         }
 

@@ -350,11 +370,12 @@
             if (hostport.length == 1) {
                 port = defaultPort;
             } else {
                 port = Integer.parseInt(hostport[1]);
             }
-            if (debug) System.out.printf("Server: (%s/%d)\n", hostport[0], port);
+            if (debug)
+                System.out.printf("Proxy: connecting to (%s/%d)\n", hostport[0], port);
             serverSocket = new Socket(hostport[0], port);
             serverOut = serverSocket.getOutputStream();
 
             serverIn = new BufferedInputStream(serverSocket.getInputStream());
         }

@@ -370,12 +391,13 @@
                     }
                     closing = true;
                     serverSocket.close();
                     clientSocket.close();
                 } catch (IOException e) {
-                    if (debug) {
-                        System.out.println (e);
+                    if (!closing && debug) {
+                        System.out.println("Proxy: " + e);
+                        e.printStackTrace();
                     }
                 }
             });
             in = new Thread(() -> {
                 try {

@@ -386,12 +408,12 @@
                     }
                     closing = true;
                     serverSocket.close();
                     clientSocket.close();
                 } catch (IOException e) {
-                    if (debug) {
-                        System.out.println(e);
+                    if (!closing && debug) {
+                        System.out.println("Proxy: " + e);
                         e.printStackTrace();
                     }
                 }
             });
             out.setName("Proxy-outbound");

@@ -407,10 +429,15 @@
             commonInit(dest, 443);
             // might fail if we're closing, but we don't care.
             clientOut.write("HTTP/1.1 200 OK\r\n\r\n".getBytes());
             proxyCommon();
         }
+
+        @Override
+        public String toString() {
+            return "Proxy connection " + id + ", client sock:" + clientSocket;
+        }
     }
 
     public static void main(String[] args) throws Exception {
         int port = Integer.parseInt(args[0]);
         boolean debug = args.length > 1 && args[1].equals("-debug");
< prev index next >