51 volatile boolean stopping = false; |
51 volatile boolean stopping = false; |
52 final Map<String,Http2Handler> handlers; |
52 final Map<String,Http2Handler> handlers; |
53 final SSLContext sslContext; |
53 final SSLContext sslContext; |
54 final String serverName; |
54 final String serverName; |
55 final HashMap<InetSocketAddress,Http2TestServerConnection> connections; |
55 final HashMap<InetSocketAddress,Http2TestServerConnection> connections; |
|
56 final Properties properties; |
56 |
57 |
57 private static ThreadFactory defaultThreadFac = |
58 private static ThreadFactory defaultThreadFac = |
58 (Runnable r) -> { |
59 (Runnable r) -> { |
59 Thread t = new Thread(r); |
60 Thread t = new Thread(r); |
60 t.setName("Test-server-pool"); |
61 t.setName("Test-server-pool"); |
65 private static ExecutorService getDefaultExecutor() { |
66 private static ExecutorService getDefaultExecutor() { |
66 return Executors.newCachedThreadPool(defaultThreadFac); |
67 return Executors.newCachedThreadPool(defaultThreadFac); |
67 } |
68 } |
68 |
69 |
69 public Http2TestServer(String serverName, boolean secure, int port) throws Exception { |
70 public Http2TestServer(String serverName, boolean secure, int port) throws Exception { |
70 this(serverName, secure, port, getDefaultExecutor(), 50, null); |
71 this(serverName, secure, port, getDefaultExecutor(), 50, null, null); |
71 } |
72 } |
72 |
73 |
73 public Http2TestServer(boolean secure, int port) throws Exception { |
74 public Http2TestServer(boolean secure, int port) throws Exception { |
74 this(null, secure, port, getDefaultExecutor(), 50, null); |
75 this(null, secure, port, getDefaultExecutor(), 50, null, null); |
75 } |
76 } |
76 |
77 |
77 public InetSocketAddress getAddress() { |
78 public InetSocketAddress getAddress() { |
78 return (InetSocketAddress)server.getLocalSocketAddress(); |
79 return (InetSocketAddress)server.getLocalSocketAddress(); |
79 } |
80 } |
83 + getAddress().getPort(); |
84 + getAddress().getPort(); |
84 } |
85 } |
85 |
86 |
86 public Http2TestServer(boolean secure, |
87 public Http2TestServer(boolean secure, |
87 SSLContext context) throws Exception { |
88 SSLContext context) throws Exception { |
88 this(null, secure, 0, null, 50, context); |
89 this(null, secure, 0, null, 50, null, context); |
89 } |
90 } |
90 |
91 |
91 public Http2TestServer(String serverName, boolean secure, |
92 public Http2TestServer(String serverName, boolean secure, |
92 SSLContext context) throws Exception { |
93 SSLContext context) throws Exception { |
93 this(serverName, secure, 0, null, 50, context); |
94 this(serverName, secure, 0, null, 50, null, context); |
94 } |
95 } |
95 |
96 |
96 public Http2TestServer(boolean secure, |
97 public Http2TestServer(boolean secure, |
97 int port, |
98 int port, |
98 ExecutorService exec, |
99 ExecutorService exec, |
99 SSLContext context) throws Exception { |
100 SSLContext context) throws Exception { |
100 this(null, secure, port, exec, 50, context); |
101 this(null, secure, port, exec, 50, null, context); |
101 } |
102 } |
102 |
103 |
103 public Http2TestServer(String serverName, |
104 public Http2TestServer(String serverName, |
104 boolean secure, |
105 boolean secure, |
105 int port, |
106 int port, |
106 ExecutorService exec, |
107 ExecutorService exec, |
107 SSLContext context) |
108 SSLContext context) |
108 throws Exception |
109 throws Exception |
109 { |
110 { |
110 this(serverName, secure, port, exec, 50, context); |
111 this(serverName, secure, port, exec, 50, null, context); |
111 } |
112 } |
112 |
113 |
113 /** |
114 /** |
114 * Create a Http2Server listening on the given port. Currently needs |
115 * Create a Http2Server listening on the given port. Currently needs |
115 * to know in advance whether incoming connections are plain TCP "h2c" |
116 * to know in advance whether incoming connections are plain TCP "h2c" |
118 * @param serverName SNI servername |
119 * @param serverName SNI servername |
119 * @param secure https or http |
120 * @param secure https or http |
120 * @param port listen port |
121 * @param port listen port |
121 * @param exec executor service (cached thread pool is used if null) |
122 * @param exec executor service (cached thread pool is used if null) |
122 * @param backlog the server socket backlog |
123 * @param backlog the server socket backlog |
|
124 * @param properties additional configuration properties |
123 * @param context the SSLContext used when secure is true |
125 * @param context the SSLContext used when secure is true |
124 */ |
126 */ |
125 public Http2TestServer(String serverName, |
127 public Http2TestServer(String serverName, |
126 boolean secure, |
128 boolean secure, |
127 int port, |
129 int port, |
128 ExecutorService exec, |
130 ExecutorService exec, |
129 int backlog, |
131 int backlog, |
|
132 Properties properties, |
130 SSLContext context) |
133 SSLContext context) |
131 throws Exception |
134 throws Exception |
132 { |
135 { |
133 this.serverName = serverName; |
136 this.serverName = serverName; |
134 if (secure) { |
137 if (secure) { |
|
138 if (context != null) |
|
139 this.sslContext = context; |
|
140 else |
|
141 this.sslContext = SSLContext.getDefault(); |
135 server = initSecure(port, backlog); |
142 server = initSecure(port, backlog); |
136 } else { |
143 } else { |
|
144 this.sslContext = context; |
137 server = initPlaintext(port, backlog); |
145 server = initPlaintext(port, backlog); |
138 } |
146 } |
139 this.secure = secure; |
147 this.secure = secure; |
140 this.exec = exec == null ? getDefaultExecutor() : exec; |
148 this.exec = exec == null ? getDefaultExecutor() : exec; |
141 this.handlers = Collections.synchronizedMap(new HashMap<>()); |
149 this.handlers = Collections.synchronizedMap(new HashMap<>()); |
142 this.sslContext = context; |
150 this.properties = properties; |
143 this.connections = new HashMap<>(); |
151 this.connections = new HashMap<>(); |
144 } |
152 } |
145 |
153 |
146 /** |
154 /** |
147 * Adds the given handler for the given path |
155 * Adds the given handler for the given path |
204 } |
212 } |
205 |
213 |
206 |
214 |
207 final ServerSocket initSecure(int port, int backlog) throws Exception { |
215 final ServerSocket initSecure(int port, int backlog) throws Exception { |
208 ServerSocketFactory fac; |
216 ServerSocketFactory fac; |
209 if (sslContext != null) { |
217 SSLParameters sslp = null; |
210 fac = sslContext.getServerSocketFactory(); |
218 fac = sslContext.getServerSocketFactory(); |
211 } else { |
219 sslp = sslContext.getSupportedSSLParameters(); |
212 fac = SSLServerSocketFactory.getDefault(); |
|
213 } |
|
214 SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(); |
220 SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(); |
215 se.setReuseAddress(false); |
221 se.setReuseAddress(false); |
216 se.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), backlog); |
222 se.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), backlog); |
217 SSLParameters sslp = se.getSSLParameters(); |
|
218 sslp.setApplicationProtocols(new String[]{"h2"}); |
223 sslp.setApplicationProtocols(new String[]{"h2"}); |
219 sslp.setEndpointIdentificationAlgorithm("HTTPS"); |
224 sslp.setEndpointIdentificationAlgorithm("HTTPS"); |
220 se.setSSLParameters(sslp); |
225 se.setSSLParameters(sslp); |
221 se.setEnabledCipherSuites(se.getSupportedCipherSuites()); |
226 se.setEnabledCipherSuites(se.getSupportedCipherSuites()); |
222 se.setEnabledProtocols(se.getSupportedProtocols()); |
227 se.setEnabledProtocols(se.getSupportedProtocols()); |
283 |
287 |
284 protected Http2TestServerConnection createConnection(Http2TestServer http2TestServer, |
288 protected Http2TestServerConnection createConnection(Http2TestServer http2TestServer, |
285 Socket socket, |
289 Socket socket, |
286 Http2TestExchangeSupplier exchangeSupplier) |
290 Http2TestExchangeSupplier exchangeSupplier) |
287 throws IOException { |
291 throws IOException { |
288 return new Http2TestServerConnection(http2TestServer, socket, exchangeSupplier); |
292 return new Http2TestServerConnection(http2TestServer, socket, exchangeSupplier, properties); |
289 } |
293 } |
290 |
294 |
291 @Override |
295 @Override |
292 public void close() throws Exception { |
296 public void close() throws Exception { |
293 stop(); |
297 stop(); |