diff --git a/core/src/main/java/com/linecorp/armeria/common/Flags.java b/core/src/main/java/com/linecorp/armeria/common/Flags.java index ab6cac8421d..70f152a6c38 100644 --- a/core/src/main/java/com/linecorp/armeria/common/Flags.java +++ b/core/src/main/java/com/linecorp/armeria/common/Flags.java @@ -45,6 +45,7 @@ import com.linecorp.armeria.client.retry.RetryingRpcClient; import com.linecorp.armeria.common.util.Exceptions; import com.linecorp.armeria.common.util.Sampler; +import com.linecorp.armeria.common.util.SystemInfo; import com.linecorp.armeria.internal.SslContextUtil; import com.linecorp.armeria.server.RoutingContext; import com.linecorp.armeria.server.ServerBuilder; @@ -117,9 +118,8 @@ public final class Flags { private static final boolean HAS_WSLENV = System.getenv("WSLENV") != null; private static final boolean USE_EPOLL = getBoolean("useEpoll", isEpollAvailable(), value -> isEpollAvailable() || !value); - - private static final boolean USE_OPENSSL = getBoolean("useOpenSsl", OpenSsl.isAvailable(), - value -> OpenSsl.isAvailable() || !value); + @Nullable + private static Boolean useOpenSsl; private static final boolean DUMP_OPENSSL_INFO = getBoolean("dumpOpenSslInfo", false); @@ -312,34 +312,15 @@ public final class Flags { } else if (USE_EPOLL) { logger.info("Using /dev/epoll"); } - - if (!OpenSsl.isAvailable()) { - final Throwable cause = Exceptions.peel(OpenSsl.unavailabilityCause()); - logger.info("OpenSSL not available: {}", cause.toString()); - } else if (USE_OPENSSL) { - logger.info("Using OpenSSL: {}, 0x{}", - OpenSsl.versionString(), - Long.toHexString(OpenSsl.version() & 0xFFFFFFFFL)); - - if (dumpOpenSslInfo()) { - final SSLEngine engine = SslContextUtil.createSslContext( - SslContextBuilder::forClient, - false, - unused -> {}).newEngine(ByteBufAllocator.DEFAULT); - logger.info("All available SSL protocols: {}", - ImmutableList.copyOf(engine.getSupportedProtocols())); - logger.info("Default enabled SSL protocols: {}", SslContextUtil.DEFAULT_PROTOCOLS); - ReferenceCountUtil.release(engine); - logger.info("All available SSL ciphers: {}", OpenSsl.availableJavaCipherSuites()); - logger.info("Default enabled SSL ciphers: {}", SslContextUtil.DEFAULT_CIPHERS); - } - } } private static boolean isEpollAvailable() { - // Netty epoll transport does not work with WSL (Windows Sybsystem for Linux) yet. - // TODO(trustin): Re-enable on WSL if https://github.com/Microsoft/WSL/issues/1982 is resolved. - return Epoll.isAvailable() && !HAS_WSLENV; + if (SystemInfo.isLinux()) { + // Netty epoll transport does not work with WSL (Windows Sybsystem for Linux) yet. + // TODO(trustin): Re-enable on WSL if https://github.com/Microsoft/WSL/issues/1982 is resolved. + return Epoll.isAvailable() && !HAS_WSLENV; + } + return false; } /** @@ -426,7 +407,34 @@ public static boolean useEpoll() { * {@code -Dcom.linecorp.armeria.useOpenSsl=false} JVM option to disable it. */ public static boolean useOpenSsl() { - return USE_OPENSSL; + if (useOpenSsl != null) { + return useOpenSsl; + } + final boolean useOpenSsl = getBoolean("useOpenSsl", true); + if (!useOpenSsl) { + // OpenSSL explicitly disabled + return Flags.useOpenSsl = false; + } + if (!OpenSsl.isAvailable()) { + final Throwable cause = Exceptions.peel(OpenSsl.unavailabilityCause()); + logger.info("OpenSSL not available: {}", cause.toString()); + return Flags.useOpenSsl = false; + } + logger.info("Using OpenSSL: {}, 0x{}", OpenSsl.versionString(), + Long.toHexString(OpenSsl.version() & 0xFFFFFFFFL)); + if (dumpOpenSslInfo()) { + final SSLEngine engine = SslContextUtil.createSslContext( + SslContextBuilder::forClient, + false, + unused -> {}).newEngine(ByteBufAllocator.DEFAULT); + logger.info("All available SSL protocols: {}", + ImmutableList.copyOf(engine.getSupportedProtocols())); + logger.info("Default enabled SSL protocols: {}", SslContextUtil.DEFAULT_PROTOCOLS); + ReferenceCountUtil.release(engine); + logger.info("All available SSL ciphers: {}", OpenSsl.availableJavaCipherSuites()); + logger.info("Default enabled SSL ciphers: {}", SslContextUtil.DEFAULT_CIPHERS); + } + return Flags.useOpenSsl = true; } /** diff --git a/core/src/main/java/com/linecorp/armeria/common/util/OsType.java b/core/src/main/java/com/linecorp/armeria/common/util/OsType.java new file mode 100644 index 00000000000..b23b6fc272f --- /dev/null +++ b/core/src/main/java/com/linecorp/armeria/common/util/OsType.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.linecorp.armeria.common.util; + +/** + * Operating system. + */ +public enum OsType { + WINDOWS, + LINUX, + MAC, + OTHERS +} diff --git a/core/src/main/java/com/linecorp/armeria/common/util/SystemInfo.java b/core/src/main/java/com/linecorp/armeria/common/util/SystemInfo.java index 3638dffb969..286b0a3f0de 100644 --- a/core/src/main/java/com/linecorp/armeria/common/util/SystemInfo.java +++ b/core/src/main/java/com/linecorp/armeria/common/util/SystemInfo.java @@ -51,6 +51,8 @@ public final class SystemInfo { private static boolean JETTY_ALPN_OPTIONAL_OR_AVAILABLE; + private static final OsType osType; + static { int javaVersion = -1; try { @@ -109,6 +111,17 @@ public final class SystemInfo { JETTY_ALPN_OPTIONAL_OR_AVAILABLE = false; } } + + final String osName = Ascii.toUpperCase(System.getProperty("os.name", "")); + if (osName.startsWith("WINDOWS")) { + osType = OsType.WINDOWS; + } else if (osName.startsWith("LINUX")) { + osType = OsType.LINUX; + } else if (osName.startsWith("MAC")) { + osType = OsType.MAC; + } else { + osType = OsType.OTHERS; + } } /** @@ -154,8 +167,18 @@ public static long currentTimeMicros() { return JavaVersionSpecific.get().currentTimeMicros(); } - private static boolean isLinux() { - return Ascii.toLowerCase(System.getProperty("os.name", "")).startsWith("linux"); + /** + * Returns the operating system for the currently running process. + */ + public static OsType osType() { + return osType; + } + + /** + * Returns {@code true} if the operating system is Linux. + */ + public static boolean isLinux() { + return osType == OsType.LINUX; } private SystemInfo() {} diff --git a/core/src/main/java/com/linecorp/armeria/server/ServerBuilder.java b/core/src/main/java/com/linecorp/armeria/server/ServerBuilder.java index a7efa285d26..a9bd098f7bc 100644 --- a/core/src/main/java/com/linecorp/armeria/server/ServerBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/ServerBuilder.java @@ -81,7 +81,6 @@ import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.epoll.EpollChannelOption; -import io.netty.handler.ssl.OpenSsl; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.util.DomainNameMapping; @@ -1576,7 +1575,7 @@ public Server build() { ports = ImmutableList.of(new ServerPort(0, HTTP)); } } else { - if ((!OpenSsl.isAvailable() || !Flags.useOpenSsl()) && !SystemInfo.jettyAlpnOptionalOrAvailable()) { + if (!Flags.useOpenSsl() && !SystemInfo.jettyAlpnOptionalOrAvailable()) { throw new IllegalStateException( "TLS configured but this is Java 8 and neither OpenSSL nor Jetty ALPN could be " + "detected. To use TLS with Armeria, you must either use Java 9+, enable OpenSSL, " +