All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.javalin.community.ssl.SSLPlugin Maven / Gradle / Ivy

There is a newer version: 6.4.0
Show newest version
package io.javalin.community.ssl;

import io.javalin.Javalin;
import io.javalin.community.ssl.util.ConnectorFactory;
import io.javalin.jetty.JettyUtil;
import io.javalin.plugin.Plugin;
import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.util.SSLFactoryUtils;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.jetbrains.annotations.NotNull;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

import static io.javalin.community.ssl.util.SSLUtils.createSslContextFactory;
import static io.javalin.community.ssl.util.SSLUtils.getSslFactory;

/**
 * A plugin to easily enable SSL on a Javalin server.
 * 

* The intended configuration pattern is to use the {@link SSLPlugin#SSLPlugin(Consumer)} constructor to configure the * plugin, either though a lambda or a Consumer. This allows for a more fluent configuration pattern. *

* Hot reloading of the SSL certificates is supported. This means that the plugin will replace the SSL certificates without restarting the server, allowing for a seamless transition. This is done by using the {@link SSLPlugin#reload(Consumer)} method. * * @author Alberto Zugazagoitia * @see SSLConfig */ public class SSLPlugin implements Plugin { private final SSLConfig config; private SSLFactory sslFactory = null; /** * Creates a new SSLPlugin with the default configuration. */ public SSLPlugin() { config = new SSLConfig(); } /** * Creates a new SSLPlugin with the given configuration. * * @param config The configuration to use. */ public SSLPlugin(SSLConfig config) { this.config = config; } /** * Creates a new SSLPlugin with the given configuration lambda/supplier. * This is useful if you want to use the default configuration and only change a few values. * Recommended way to create a new SSLPlugin with the given configuration. * * @param config The configuration to use. */ public SSLPlugin(Consumer config) { this(); config.accept(this.config); } /** * Method to apply the plugin to a Javalin instance * * @param javalin Javalin instance */ @Override public void apply(@NotNull Javalin javalin) { Consumer patcher = createJettyServerPatcher(config); javalin.cfg.jetty.server(() -> { //Check if the server has been manually configured Server server = Objects.requireNonNullElseGet( javalin.cfg.pvt.server, SSLPlugin::getServer); //parseConfig returns a consumer configuring the server. patcher.accept(server); return server; }); } /** * Method to apply the SSLConfig to a given Jetty Server. * Can be used to patch pre-existing or custom servers. * * @param server The Jetty Server to patch. */ public void patch(@NotNull Server server) { Consumer patcher = createJettyServerPatcher(config); patcher.accept(server); } /** * Method to hot-swap the certificate and key material of the plugin. * Any configuration changes will be ignored, only the certificate and key material will be updated. * * @param newConfig A config containing the new certificate and key material. * @deprecated Use {@link #reload(Consumer)} instead. */ @Deprecated(forRemoval = true,since = "5.3.2") public void reload(SSLConfig newConfig) { if(sslFactory == null) throw new IllegalStateException("Cannot reload before the plugin has been applied to a Javalin instance, a server has been patched or if the ssl connector is disabled."); SSLFactory newFactory = getSslFactory(newConfig,true); SSLFactoryUtils.reload(sslFactory, newFactory); } /** * Method to hot-swap the certificate and key material of the plugin. * Any configuration changes will be ignored, only the certificate and key material will be updated. * * @param newConfig A consumer providing the new certificate and key material. */ public void reload(Consumer newConfig) { SSLConfig conf = new SSLConfig(); newConfig.accept(conf); if(sslFactory == null) throw new IllegalStateException("Cannot reload before the plugin has been applied to a Javalin instance, a server has been patched or if the ssl connector is disabled."); SSLFactory newFactory = getSslFactory(conf,true); SSLFactoryUtils.reload(sslFactory, newFactory); } /** * Method to parse the config and return a consumer that can be used to configure the server. * * @param config The config to parse. * @return A {@link Consumer} that can be used to configure the server. */ private Consumer createJettyServerPatcher(SSLConfig config) { //Created outside the lambda to have exceptions thrown in the current scope SslContextFactory.Server sslContextFactory; if (config.secure || config.enableHttp3) { sslFactory = getSslFactory(config); sslContextFactory = createSslContextFactory(sslFactory, config); } else { sslContextFactory = null; } return (server) -> { List connectorList = new LinkedList<>(); ConnectorFactory connectorFactory = new ConnectorFactory(config, server, sslContextFactory); if (config.insecure) { connectorList.add(connectorFactory.createInsecureConnector()); } if (config.secure) { connectorList.add(connectorFactory.createSecureConnector()); } if (config.enableHttp3) { throw new UnsupportedOperationException("HTTP/3 is not supported yet"); } connectorList.forEach(server::addConnector); if(config.redirect) server.setHandler(new SecuredRedirectHandler()); }; } /** * Method to create a new Jetty Server instance using Javalin's default configuration. * * @return A new Jetty Server instance. */ private static Server getServer() { return JettyUtil.getOrDefault(null); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy