|
50 | 50 | import java.util.concurrent.Executor; |
51 | 51 | import java.util.concurrent.ExecutorService; |
52 | 52 | import java.util.concurrent.Executors; |
| 53 | +import java.util.concurrent.RejectedExecutionException; |
53 | 54 | import java.util.logging.LogRecord; |
54 | 55 |
|
55 | 56 | import javax.net.ssl.SSLSocket; |
@@ -342,82 +343,92 @@ public void run() { |
342 | 343 | while (true) { |
343 | 344 | try { |
344 | 345 | Socket s = socket.accept(); |
345 | | - if(logger.isLoggable(Level.TRACE)) { |
346 | | - logger.log(Level.TRACE, "accepted connection: " + s.toString()); |
347 | | - } |
348 | | - stats.connectionCount.incrementAndGet(); |
349 | | - if (MAX_CONNECTIONS > 0 && allConnections.size() >= MAX_CONNECTIONS) { |
350 | | - // we've hit max limit of current open connections, so we go |
351 | | - // ahead and close this connection without processing it |
| 346 | + try { |
| 347 | + executor.execute(() -> { |
352 | 348 | try { |
353 | | - stats.maxConnectionsExceededCount.incrementAndGet(); |
354 | | - logger.log(Level.WARNING, "closing accepted connection due to too many connections"); |
355 | | - s.close(); |
356 | | - } catch (IOException ignore) { |
| 349 | + acceptConnection(s); |
| 350 | + } catch (IOException t) { |
| 351 | + logger.log(Level.ERROR, "Dispatcher Exception", t); |
| 352 | + try { |
| 353 | + s.close(); |
| 354 | + } catch (IOException ex) { |
| 355 | + } |
357 | 356 | } |
358 | | - continue; |
| 357 | + }); |
| 358 | + } catch (RejectedExecutionException e) { |
| 359 | + s.close(); |
359 | 360 | } |
360 | | - |
361 | | - if (ServerConfig.noDelay()) { |
362 | | - s.setTcpNoDelay(true); |
| 361 | + } catch (IOException e) { |
| 362 | + if (!isFinishing()) { |
| 363 | + logger.log(Level.ERROR, "Dispatcher Exception, terminating", e); |
363 | 364 | } |
| 365 | + return; |
| 366 | + } |
| 367 | + } |
| 368 | + } |
| 369 | + private void acceptConnection(Socket s) throws IOException { |
| 370 | + if(logger.isLoggable(Level.TRACE)) { |
| 371 | + logger.log(Level.TRACE, "accepted connection: " + s.toString()); |
| 372 | + } |
| 373 | + stats.connectionCount.incrementAndGet(); |
| 374 | + if (MAX_CONNECTIONS > 0 && allConnections.size() >= MAX_CONNECTIONS) { |
| 375 | + // we've hit max limit of current open connections, so we go |
| 376 | + // ahead and close this connection without processing it |
| 377 | + try { |
| 378 | + stats.maxConnectionsExceededCount.incrementAndGet(); |
| 379 | + logger.log(Level.WARNING, "closing accepted connection due to too many connections"); |
| 380 | + s.close(); |
| 381 | + } catch (IOException ignore) { |
| 382 | + } |
| 383 | + return; |
| 384 | + } |
364 | 385 |
|
365 | | - boolean http2 = false; |
| 386 | + if (ServerConfig.noDelay()) { |
| 387 | + s.setTcpNoDelay(true); |
| 388 | + } |
366 | 389 |
|
367 | | - if (https) { |
368 | | - // for some reason, creating an SSLServerSocket and setting the default parameters would |
369 | | - // not work, so upgrade to a SSLSocket after connection |
370 | | - SSLSocketFactory ssf = httpsConfig.getSSLContext().getSocketFactory(); |
371 | | - SSLSocket sslSocket = (SSLSocket) ssf.createSocket(s, null, false); |
372 | | - SSLConfigurator.configure(sslSocket,httpsConfig); |
| 390 | + boolean http2 = false; |
373 | 391 |
|
374 | | - sslSocket.setHandshakeApplicationProtocolSelector((_sslSocket, protocols) -> { |
375 | | - if (protocols.contains("h2") && ServerConfig.http2OverSSL()) { |
376 | | - return "h2"; |
377 | | - } else { |
378 | | - return "http/1.1"; |
379 | | - } |
380 | | - }); |
381 | | - // the following forces the SSL handshake to complete in order to determine the negotiated protocol |
382 | | - var session = sslSocket.getSession(); |
383 | | - if ("h2".equals(sslSocket.getApplicationProtocol())) { |
384 | | - logger.log(Level.DEBUG, () -> "http2 connection "+sslSocket.toString()); |
385 | | - http2 = true; |
386 | | - } else { |
387 | | - logger.log(Level.DEBUG, () -> "http/1.1 connection "+sslSocket.toString()); |
388 | | - } |
389 | | - s = sslSocket; |
| 392 | + if (https) { |
| 393 | + // for some reason, creating an SSLServerSocket and setting the default parameters would |
| 394 | + // not work, so upgrade to a SSLSocket after connection |
| 395 | + SSLSocketFactory ssf = httpsConfig.getSSLContext().getSocketFactory(); |
| 396 | + SSLSocket sslSocket = (SSLSocket) ssf.createSocket(s, null, false); |
| 397 | + SSLConfigurator.configure(sslSocket,httpsConfig); |
| 398 | + |
| 399 | + sslSocket.setHandshakeApplicationProtocolSelector((_sslSocket, protocols) -> { |
| 400 | + if (protocols.contains("h2") && ServerConfig.http2OverSSL()) { |
| 401 | + return "h2"; |
| 402 | + } else { |
| 403 | + return "http/1.1"; |
390 | 404 | } |
| 405 | + }); |
| 406 | + // the following forces the SSL handshake to complete in order to determine the negotiated protocol |
| 407 | + var session = sslSocket.getSession(); |
| 408 | + if ("h2".equals(sslSocket.getApplicationProtocol())) { |
| 409 | + logger.log(Level.DEBUG, () -> "http2 connection "+sslSocket.toString()); |
| 410 | + http2 = true; |
| 411 | + } else { |
| 412 | + logger.log(Level.DEBUG, () -> "http/1.1 connection "+sslSocket.toString()); |
| 413 | + } |
| 414 | + s = sslSocket; |
| 415 | + } |
391 | 416 |
|
392 | | - HttpConnection c; |
393 | | - try { |
394 | | - c = new HttpConnection(s); |
395 | | - } catch (IOException e) { |
396 | | - logger.log(Level.WARNING, "Failed to create HttpConnection", e); |
397 | | - continue; |
398 | | - } |
399 | | - try { |
400 | | - allConnections.add(c); |
401 | | - |
402 | | - if (http2) { |
403 | | - Http2Exchange t = new Http2Exchange(protocol, c); |
404 | | - executor.execute(t); |
405 | | - } else { |
406 | | - Exchange t = new Exchange(protocol, c); |
407 | | - executor.execute(t); |
408 | | - } |
| 417 | + HttpConnection c = new HttpConnection(s); |
| 418 | + try { |
| 419 | + allConnections.add(c); |
409 | 420 |
|
410 | | - } catch (Exception e) { |
411 | | - logger.log(Level.TRACE, "Dispatcher Exception", e); |
412 | | - stats.handleExceptionCount.incrementAndGet(); |
413 | | - closeConnection(c); |
414 | | - } |
415 | | - } catch (IOException e) { |
416 | | - if (!isFinishing()) { |
417 | | - logger.log(Level.ERROR, "Dispatcher Exception, terminating", e); |
418 | | - } |
419 | | - return; |
| 421 | + if (http2) { |
| 422 | + Http2Exchange t = new Http2Exchange(protocol, c); |
| 423 | + executor.execute(t); |
| 424 | + } else { |
| 425 | + Exchange t = new Exchange(protocol, c); |
| 426 | + executor.execute(t); |
420 | 427 | } |
| 428 | + } catch (Exception e) { |
| 429 | + logger.log(Level.TRACE, "Dispatcher Exception", e); |
| 430 | + stats.handleExceptionCount.incrementAndGet(); |
| 431 | + closeConnection(c); |
421 | 432 | } |
422 | 433 | } |
423 | 434 | } |
|
0 commit comments