Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor TLS and network handling #693

Merged
merged 1 commit into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.jboss.logging.Logger;

import io.quarkiverse.quinoa.QuinoaDevProxyHandlerConfig;
import io.quarkiverse.quinoa.QuinoaNetworkConfiguration;
import io.quarkiverse.quinoa.QuinoaRecorder;
import io.quarkiverse.quinoa.deployment.config.DevServerConfig;
import io.quarkiverse.quinoa.deployment.config.QuinoaConfig;
Expand All @@ -42,7 +43,6 @@
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.CuratedApplicationShutdownBuildItem;
import io.quarkus.deployment.builditem.DevServicesResultBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.LiveReloadBuildItem;
import io.quarkus.deployment.console.ConsoleInstalledBuildItem;
import io.quarkus.deployment.logging.LoggingSetupBuildItem;
Expand All @@ -62,7 +62,6 @@ public class ForwardedDevProcessor {

@BuildStep(onlyIf = IsDevelopment.class)
public ForwardedDevServerBuildItem prepareDevService(
LaunchModeBuildItem launchMode,
ConfiguredQuinoaBuildItem configuredQuinoa,
InstalledPackageManagerBuildItem installedPackageManager,
QuinoaConfig userConfig,
Expand All @@ -78,9 +77,8 @@ public ForwardedDevServerBuildItem prepareDevService(
final QuinoaConfig resolvedConfig = configuredQuinoa.resolvedConfig();
final DevServerConfig devServerConfig = resolvedConfig.devServer();
liveReload.setContextObject(QuinoaConfig.class, resolvedConfig);
final String configuredDevServerHost = devServerConfig.host();
final boolean configuredTls = devServerConfig.tls();
final boolean configuredTlsAllowInsecure = devServerConfig.tlsAllowInsecure();
final QuinoaNetworkConfiguration networkConfiguration = new QuinoaNetworkConfiguration(devServerConfig.tls(),
devServerConfig.tlsAllowInsecure(), devServerConfig.host(), devServerConfig.port().orElse(0), false);
final PackageManagerRunner packageManagerRunner = installedPackageManager.getPackageManager();
final String checkPath = resolvedConfig.devServer().checkPath().orElse(null);
if (devService != null) {
Expand All @@ -94,13 +92,11 @@ public ForwardedDevServerBuildItem prepareDevService(
}
LOG.debug("Quinoa config did not change; no need to restart.");
devServices.produce(devService.toBuildItem());
final String resolvedDevServerHost = PackageManagerRunner.isDevServerUp(devServerConfig.tls(),
devServerConfig.tlsAllowInsecure(),
devServerConfig.host(),
devServerConfig.port().get(),
checkPath);
return new ForwardedDevServerBuildItem(devServerConfig.tls(), devServerConfig.tlsAllowInsecure(),
resolvedDevServerHost, devServerConfig.port().get());
networkConfiguration.setHost(devServerConfig.host());
networkConfiguration.setPort(devServerConfig.port().get());
final String resolvedDevServerHost = PackageManagerRunner.isDevServerUp(networkConfiguration, checkPath);
networkConfiguration.setHost(resolvedDevServerHost);
return new ForwardedDevServerBuildItem(networkConfiguration);
}
shutdownDevService();
}
Expand All @@ -119,14 +115,15 @@ public ForwardedDevServerBuildItem prepareDevService(
return null;
}
final Integer port = devServerConfig.port().get();
networkConfiguration.setPort(port);

if (!devServerConfig.managed()) {
// No need to start the dev-service it is not managed by Quinoa
// We just check that it is up
final String resolvedHostIPAddress = PackageManagerRunner.isDevServerUp(configuredTls, configuredTlsAllowInsecure,
configuredDevServerHost, port, checkPath);
final String resolvedHostIPAddress = PackageManagerRunner.isDevServerUp(networkConfiguration, checkPath);
if (resolvedHostIPAddress != null) {
return new ForwardedDevServerBuildItem(configuredTls, configuredTlsAllowInsecure, resolvedHostIPAddress, port);
networkConfiguration.setHost(resolvedHostIPAddress);
return new ForwardedDevServerBuildItem(networkConfiguration);
} else {
throw new IllegalStateException(
"The Web UI dev server (configured as not managed by Quinoa) is not started on port: " + port);
Expand All @@ -141,11 +138,8 @@ public ForwardedDevServerBuildItem prepareDevService(
final AtomicReference<Process> dev = new AtomicReference<>();
PackageManagerRunner.DevServer devServer = null;
try {
devServer = packageManagerRunner.dev(consoleInstalled, loggingSetup, configuredTls, configuredTlsAllowInsecure,
configuredDevServerHost,
port,
checkPath,
checkTimeout);
devServer = packageManagerRunner.dev(consoleInstalled, loggingSetup, networkConfiguration,
checkPath, checkTimeout);
dev.set(devServer.process());
devServer.logCompressor().close();
final LiveCodingLogOutputFilter logOutputFilter = new LiveCodingLogOutputFilter(
Expand All @@ -162,7 +156,8 @@ public ForwardedDevServerBuildItem prepareDevService(
devService = new DevServicesResultBuildItem.RunningDevService(
DEV_SERVICE_NAME, null, onClose, devServerConfigMap);
devServices.produce(devService.toBuildItem());
return new ForwardedDevServerBuildItem(configuredTls, configuredTlsAllowInsecure, devServer.hostIPAddress(), port);
networkConfiguration.setHost(devServer.hostIPAddress());
return new ForwardedDevServerBuildItem(networkConfiguration);
} catch (Throwable t) {
packageManagerRunner.stopDev(dev.get());
if (devServer != null) {
Expand All @@ -176,7 +171,7 @@ private static Map<String, String> createDevServiceMapForDevUI(QuinoaConfig quin
Map<String, String> devServerConfigMap = new LinkedHashMap<>();
devServerConfigMap.put("quarkus.quinoa.dev-server.host", quinoaConfig.devServer().host());
devServerConfigMap.put("quarkus.quinoa.dev-server.port",
quinoaConfig.devServer().port().map(p -> p.toString()).orElse(""));
quinoaConfig.devServer().port().map(Object::toString).orElse(""));
devServerConfigMap.put("quarkus.quinoa.dev-server.check-timeout",
Integer.toString(quinoaConfig.devServer().checkTimeout()));
devServerConfigMap.put("quarkus.quinoa.dev-server.check-path", quinoaConfig.devServer().checkPath().orElse(""));
Expand Down Expand Up @@ -206,11 +201,12 @@ public void runtimeInit(
}
LOG.infof("Quinoa is forwarding unhandled requests to port: %d", devProxy.get().getPort());
final QuinoaDevProxyHandlerConfig handlerConfig = toDevProxyHandlerConfig(quinoaConfig, httpBuildTimeConfig);
final QuinoaNetworkConfiguration networkConfig = new QuinoaNetworkConfiguration(devProxy.get().isTls(),
devProxy.get().isTlsAllowInsecure(), devProxy.get().getHost(),
devProxy.get().getPort(),
quinoaConfig.devServer().websocket());
routes.produce(RouteBuildItem.builder().orderedRoute("/*", QUINOA_ROUTE_ORDER)
.handler(recorder.quinoaProxyDevHandler(handlerConfig, vertx.getVertx(), devProxy.get().isTls(),
devProxy.get().isTlsAllowInsecure(), devProxy.get().getHost(),
devProxy.get().getPort(),
quinoaConfig.devServer().websocket()))
.handler(recorder.quinoaProxyDevHandler(handlerConfig, vertx.getVertx(), networkConfig))
.build());
if (quinoaConfig.devServer().websocket()) {
websocketSubProtocols.produce(new WebsocketSubProtocolsBuildItem("*"));
Expand Down Expand Up @@ -300,4 +296,4 @@ public Thread newThread(Runnable r) {

}

}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
package io.quarkiverse.quinoa.deployment.items;

import io.quarkiverse.quinoa.QuinoaNetworkConfiguration;
import io.quarkus.builder.item.SimpleBuildItem;

public final class ForwardedDevServerBuildItem extends SimpleBuildItem {

private final boolean tls;
private final boolean tlsAllowInsecure;
private final String host;
private final Integer port;
private final QuinoaNetworkConfiguration networkConfiguration;

public ForwardedDevServerBuildItem(boolean tls, boolean tlsAllowInsecure, String host, Integer port) {
this.tls = tls;
this.tlsAllowInsecure = tlsAllowInsecure;
this.host = host;
this.port = port;
public ForwardedDevServerBuildItem(QuinoaNetworkConfiguration networkConfiguration) {
this.networkConfiguration = networkConfiguration;
}

public QuinoaNetworkConfiguration getNetworkConfiguration() {
return networkConfiguration;
}

public boolean isTls() {
return tls;
return networkConfiguration.isTls();
}

public boolean isTlsAllowInsecure() {
return tlsAllowInsecure;
return networkConfiguration.isTlsAllowInsecure();
}

public String getHost() {
return host;
return networkConfiguration.getHost();
}

public Integer getPort() {
return port;
return networkConfiguration.getPort();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import org.jboss.logging.Logger;

import io.quarkiverse.quinoa.QuinoaNetworkConfiguration;
import io.quarkiverse.quinoa.deployment.SslUtil;
import io.quarkiverse.quinoa.deployment.config.PackageManagerCommandConfig;
import io.quarkiverse.quinoa.deployment.packagemanager.types.PackageManager;
Expand Down Expand Up @@ -139,7 +140,7 @@ private static void killDescendants(ProcessHandle process, boolean force) {
}

public DevServer dev(Optional<ConsoleInstalledBuildItem> consoleInstalled, LoggingSetupBuildItem loggingSetup,
boolean tls, boolean tlsAllowInsecure, String devServerHost, int devServerPort, String checkPath,
QuinoaNetworkConfiguration network, String checkPath,
int checkTimeout) {
final PackageManager.Command dev = packageManager.dev();
LOG.infof("Running Quinoa package manager live coding as a dev service: %s", dev.commandWithArguments);
Expand All @@ -156,16 +157,16 @@ public void run() {
});
if (checkPath == null) {
LOG.infof("Quinoa is configured to continue without check if the live coding server is up");
return new DevServer(p, devServerHost, logCompressor);
return new DevServer(p, network.getHost(), logCompressor);
}
String ipAddress = null;
try {
int i = 0;
while ((ipAddress = isDevServerUp(tls, tlsAllowInsecure, devServerHost, devServerPort, checkPath)) == null) {
while ((ipAddress = isDevServerUp(network, checkPath)) == null) {
if (++i >= checkTimeout / 500) {
stopDev(p);
throw new RuntimeException(
"Quinoa package manager live coding port " + devServerPort
"Quinoa package manager live coding port " + network.getPort()
+ " is still not listening after the checkTimeout.");
}
Thread.sleep(500);
Expand Down Expand Up @@ -275,22 +276,23 @@ public void run() {
}
}

public static String isDevServerUp(boolean tls, boolean tlsAllowInsecure, String host, int port, String path) {
public static String isDevServerUp(QuinoaNetworkConfiguration network, String path) {
if (path == null) {
return host;
return network.getHost();
}
final String normalizedPath = path.indexOf("/") == 0 ? path : "/" + path;
try {
InetAddress[] addresses = InetAddress.getAllByName(host);
InetAddress[] addresses = InetAddress.getAllByName(network.getHost());
for (InetAddress address : addresses) {
try {
final String hostAddress = address.getHostAddress();
final String ipAddress = address instanceof Inet6Address ? "[" + hostAddress + "]" : hostAddress;
URL url = new URL(String.format("%s://%s:%d%s", tls ? "https" : "http", ipAddress, port, normalizedPath));
URL url = new URL(String.format("%s://%s:%d%s", network.isTls() ? "https" : "http", ipAddress,
network.getPort(), normalizedPath));
HttpURLConnection connection;
if (tls) {
if (network.isTls()) {
HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection();
if (tlsAllowInsecure) {
if (network.isTlsAllowInsecure()) {
httpsConnection.setSSLSocketFactory(SslUtil.createNonValidatingSslContext().getSocketFactory());
httpsConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
Expand Down
55 changes: 29 additions & 26 deletions docs/modules/ROOT/pages/includes/quarkus-quinoa.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -519,70 +519,73 @@ endif::add-copy-button-to-env-var[]
--|boolean
|`true`

a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-tls]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-tls[quarkus.quinoa.dev-server.tls]`

a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-port]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-port[quarkus.quinoa.dev-server.port]`


[.description]
--
When set to true, Quinoa requests will be forwarded with tls enabled.
Port of the server to forward requests to. The dev server process (i.e npm start) is managed like a dev service by Quarkus. If the external server responds with a 404, it is ignored by Quinoa and processed like any other backend request.

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_TLS+++[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_PORT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_TLS+++`
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_PORT+++`
endif::add-copy-button-to-env-var[]
--|boolean
|`false`
--|int
|`framework detection or fallback to empty`

a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-tls-allow-insecure]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-tls-allow-insecure[quarkus.quinoa.dev-server.tls.allow-insecure]`

a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-host]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-host[quarkus.quinoa.dev-server.host]`


[.description]
--
When set to true, Quinoa will accept any certificate with any hostname.
Host of the server to forward requests to.

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_TLS_ALLOW_INSECURE+++[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_HOST+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_TLS_ALLOW_INSECURE+++`
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_HOST+++`
endif::add-copy-button-to-env-var[]
--|boolean
|`false`
--|string
|`localhost`

a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-port]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-port[quarkus.quinoa.dev-server.port]`

a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-tls]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-tls[quarkus.quinoa.dev-server.tls]`


[.description]
--
Port of the server to forward requests to. The dev server process (i.e npm start) is managed like a dev service by Quarkus. If the external server responds with a 404, it is ignored by Quinoa and processed like any other backend request.
When set to true, Quinoa requests will be forwarded with tls enabled.

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_PORT+++[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_TLS+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_PORT+++`
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_TLS+++`
endif::add-copy-button-to-env-var[]
--|int
|`framework detection or fallback to empty`
--|boolean
|`false`


a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-host]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-host[quarkus.quinoa.dev-server.host]`
a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-tls-allow-insecure]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-tls-allow-insecure[quarkus.quinoa.dev-server.tls-allow-insecure]`


[.description]
--
Host of the server to forward requests to.
When set to true, Quinoa will accept any certificate with any hostname.

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_HOST+++[]
Environment variable: env_var_with_copy_button:+++QUARKUS_QUINOA_DEV_SERVER_TLS_ALLOW_INSECURE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_HOST+++`
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_TLS_ALLOW_INSECURE+++`
endif::add-copy-button-to-env-var[]
--|string
|`localhost`
--|boolean
|`false`


a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-check-path]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-check-path[quarkus.quinoa.dev-server.check-path]`
Expand Down Expand Up @@ -667,7 +670,7 @@ ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_QUINOA_DEV_SERVER_INDEX_PAGE+++`
endif::add-copy-button-to-env-var[]
--|string
|`auto-detected falling back to the quinoa.index-page`
|`auto-detected falling back to index.html`


a|icon:lock[title=Fixed at build time] [[quarkus-quinoa_quarkus-quinoa-dev-server-direct-forwarding]]`link:#quarkus-quinoa_quarkus-quinoa-dev-server-direct-forwarding[quarkus.quinoa.dev-server.direct-forwarding]`
Expand Down Expand Up @@ -776,4 +779,4 @@ endif::add-copy-button-to-env-var[]

|

|===
|===
Loading