< prev index next >

test/jdk/java/net/httpclient/http2/server/Http2TestServer.java

Print this page


   1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.IOException;
  25 import java.net.*;
  26 import java.util.*;
  27 import java.util.concurrent.ExecutorService;
  28 import java.util.concurrent.Executors;
  29 import java.util.concurrent.ThreadFactory;
  30 import java.util.concurrent.atomic.AtomicReference;

  31 import javax.net.ServerSocketFactory;
  32 import javax.net.ssl.SSLContext;
  33 import javax.net.ssl.SSLParameters;
  34 import javax.net.ssl.SSLServerSocket;
  35 import javax.net.ssl.SSLServerSocketFactory;
  36 import javax.net.ssl.SNIServerName;
  37 
  38 /**
  39  * Waits for incoming TCP connections from a client and establishes
  40  * a HTTP2 connection. Two threads are created per connection. One for reading
  41  * and one for writing. Incoming requests are dispatched to the supplied
  42  * Http2Handler on additional threads. All threads
  43  * obtained from the supplied ExecutorService.
  44  */
  45 public class Http2TestServer implements AutoCloseable {
  46     final ServerSocket server;
  47     volatile boolean secure;
  48     final ExecutorService exec;
  49     volatile boolean stopping = false;
  50     final Map<String,Http2Handler> handlers;


 114         this.serverName = serverName;
 115         if (secure) {
 116             server = initSecure(port);
 117         } else {
 118             server = initPlaintext(port);
 119         }
 120         this.secure = secure;
 121         this.exec = exec == null ? getDefaultExecutor() : exec;
 122         this.handlers = Collections.synchronizedMap(new HashMap<>());
 123         this.sslContext = context;
 124         this.connections = new HashMap<>();
 125     }
 126 
 127     /**
 128      * Adds the given handler for the given path
 129      */
 130     public void addHandler(Http2Handler handler, String path) {
 131         handlers.put(path, handler);
 132     }
 133 












 134     Http2Handler getHandlerFor(String path) {
 135         if (path == null || path.equals(""))
 136             path = "/";
 137 
 138         final String fpath = path;
 139         AtomicReference<String> bestMatch = new AtomicReference<>("");
 140         AtomicReference<Http2Handler> href = new AtomicReference<>();
 141 
 142         handlers.forEach((key, value) -> {
 143             if (fpath.startsWith(key) && key.length() > bestMatch.get().length()) {
 144                 bestMatch.set(key);
 145                 href.set(value);
 146             }
 147         });
 148         Http2Handler handler = href.get();
 149         if (handler == null)
 150             throw new RuntimeException("No handler found for path " + path);
 151         System.err.println("Using handler for: " + bestMatch.get());
 152         return handler;
 153     }


 182         se.setSSLParameters(sslp);
 183         se.setEnabledCipherSuites(se.getSupportedCipherSuites());
 184         se.setEnabledProtocols(se.getSupportedProtocols());
 185         // other initialisation here
 186         return se;
 187     }
 188 
 189     public String serverName() {
 190         return serverName;
 191     }
 192 
 193     /**
 194      * Starts a thread which waits for incoming connections.
 195      */
 196     public void start() {
 197         exec.submit(() -> {
 198             try {
 199                 while (!stopping) {
 200                     Socket socket = server.accept();
 201                     InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress();
 202                     Http2TestServerConnection c = new Http2TestServerConnection(this, socket);

 203                     connections.put(addr, c);
 204                     try {
 205                         c.run();
 206                     } catch(Throwable e) {
 207                         // we should not reach here, but if we do
 208                         // the connection might not have been closed
 209                         // and if so then the client might wait
 210                         // forever.
 211                         connections.remove(addr, c);
 212                         c.close();
 213                         throw e;
 214                     }
 215                 }
 216             } catch (Throwable e) {
 217                 if (!stopping) {
 218                     System.err.println("TestServer: start exception: " + e);
 219                     e.printStackTrace();
 220                 }
 221             }
 222         });
   1 /*
   2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.IOException;
  25 import java.net.*;
  26 import java.util.*;
  27 import java.util.concurrent.ExecutorService;
  28 import java.util.concurrent.Executors;
  29 import java.util.concurrent.ThreadFactory;
  30 import java.util.concurrent.atomic.AtomicReference;
  31 import java.util.function.Consumer;
  32 import javax.net.ServerSocketFactory;
  33 import javax.net.ssl.SSLContext;
  34 import javax.net.ssl.SSLParameters;
  35 import javax.net.ssl.SSLServerSocket;
  36 import javax.net.ssl.SSLServerSocketFactory;
  37 import javax.net.ssl.SNIServerName;
  38 
  39 /**
  40  * Waits for incoming TCP connections from a client and establishes
  41  * a HTTP2 connection. Two threads are created per connection. One for reading
  42  * and one for writing. Incoming requests are dispatched to the supplied
  43  * Http2Handler on additional threads. All threads
  44  * obtained from the supplied ExecutorService.
  45  */
  46 public class Http2TestServer implements AutoCloseable {
  47     final ServerSocket server;
  48     volatile boolean secure;
  49     final ExecutorService exec;
  50     volatile boolean stopping = false;
  51     final Map<String,Http2Handler> handlers;


 115         this.serverName = serverName;
 116         if (secure) {
 117             server = initSecure(port);
 118         } else {
 119             server = initPlaintext(port);
 120         }
 121         this.secure = secure;
 122         this.exec = exec == null ? getDefaultExecutor() : exec;
 123         this.handlers = Collections.synchronizedMap(new HashMap<>());
 124         this.sslContext = context;
 125         this.connections = new HashMap<>();
 126     }
 127 
 128     /**
 129      * Adds the given handler for the given path
 130      */
 131     public void addHandler(Http2Handler handler, String path) {
 132         handlers.put(path, handler);
 133     }
 134 
 135     volatile Http2TestExchangeSupplier exchangeSupplier = Http2TestExchangeSupplier.ofDefault();
 136 
 137     /**
 138      * Sets an explicit exchange handler to be used for all future connections.
 139      * Useful for testing scenarios where non-standard or specific server
 140      * behaviour is required, either direct control over the frames sent, "bad"
 141      * behaviour, or something else.
 142      */
 143     public void setExchangeSupplier(Http2TestExchangeSupplier exchangeSupplier) {
 144         this.exchangeSupplier = exchangeSupplier;
 145     }
 146 
 147     Http2Handler getHandlerFor(String path) {
 148         if (path == null || path.equals(""))
 149             path = "/";
 150 
 151         final String fpath = path;
 152         AtomicReference<String> bestMatch = new AtomicReference<>("");
 153         AtomicReference<Http2Handler> href = new AtomicReference<>();
 154 
 155         handlers.forEach((key, value) -> {
 156             if (fpath.startsWith(key) && key.length() > bestMatch.get().length()) {
 157                 bestMatch.set(key);
 158                 href.set(value);
 159             }
 160         });
 161         Http2Handler handler = href.get();
 162         if (handler == null)
 163             throw new RuntimeException("No handler found for path " + path);
 164         System.err.println("Using handler for: " + bestMatch.get());
 165         return handler;
 166     }


 195         se.setSSLParameters(sslp);
 196         se.setEnabledCipherSuites(se.getSupportedCipherSuites());
 197         se.setEnabledProtocols(se.getSupportedProtocols());
 198         // other initialisation here
 199         return se;
 200     }
 201 
 202     public String serverName() {
 203         return serverName;
 204     }
 205 
 206     /**
 207      * Starts a thread which waits for incoming connections.
 208      */
 209     public void start() {
 210         exec.submit(() -> {
 211             try {
 212                 while (!stopping) {
 213                     Socket socket = server.accept();
 214                     InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress();
 215                     Http2TestServerConnection c =
 216                             new Http2TestServerConnection(this, socket, exchangeSupplier);
 217                     connections.put(addr, c);
 218                     try {
 219                         c.run();
 220                     } catch(Throwable e) {
 221                         // we should not reach here, but if we do
 222                         // the connection might not have been closed
 223                         // and if so then the client might wait
 224                         // forever.
 225                         connections.remove(addr, c);
 226                         c.close();
 227                         throw e;
 228                     }
 229                 }
 230             } catch (Throwable e) {
 231                 if (!stopping) {
 232                     System.err.println("TestServer: start exception: " + e);
 233                     e.printStackTrace();
 234                 }
 235             }
 236         });
< prev index next >