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

bucket.gitbucket_2.13.4.41.0.source-code.JettyLauncher Maven / Gradle / Ivy

The newest version!
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.session.DefaultSessionCache;
import org.eclipse.jetty.server.session.FileSessionDataStore;
import org.eclipse.jetty.server.session.SessionCache;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;

import java.io.File;
import java.net.InetAddress;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toSet;

public class JettyLauncher {

    private interface Defaults {

        String CONNECTORS = "http";
        String HOST = "0.0.0.0";

        int HTTP_PORT = 8080;
        int HTTPS_PORT = 8443;

        boolean REDIRECT_HTTPS = false;
    }

    private interface Connectors {

        String HTTP = "http";
        String HTTPS = "https";
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("java.awt.headless", "true");

        String connectors = getEnvironmentVariable("gitbucket.connectors");
        String host = getEnvironmentVariable("gitbucket.host");
        String port = getEnvironmentVariable("gitbucket.port");
        String securePort = getEnvironmentVariable("gitbucket.securePort");
        String keyStorePath = getEnvironmentVariable("gitbucket.keyStorePath");
        String keyStorePassword = getEnvironmentVariable("gitbucket.keyStorePassword");
        String keyManagerPassword = getEnvironmentVariable("gitbucket.keyManagerPassword");
        String redirectHttps = getEnvironmentVariable("gitbucket.redirectHttps");
        String contextPath = getEnvironmentVariable("gitbucket.prefix");
        String tmpDirPath = getEnvironmentVariable("gitbucket.tempDir");
        String jettyIdleTimeout = getEnvironmentVariable("gitbucket.jettyIdleTimeout");
        boolean saveSessions = false;

        for(String arg: args) {
            if (arg.equals("--save_sessions")) {
                saveSessions = true;
            }
            if (arg.equals("--disable_news_feed")) {
                System.setProperty("gitbucket.disableNewsFeed", "true");
            }
            if (arg.equals("--disable_cache")) {
                System.setProperty("gitbucket.disableCache", "true");
            }
            if(arg.startsWith("--") && arg.contains("=")) {
                String[] dim = arg.split("=", 2);
                if(dim.length == 2) {
                    switch (dim[0]) {
                        case "--connectors":
                            connectors = dim[1];
                            break;
                        case "--host":
                            host = dim[1];
                            break;
                        case "--port":
                            port = dim[1];
                            break;
                        case "--secure_port":
                            securePort = dim[1];
                            break;
                        case "--key_store_path":
                            keyStorePath = dim[1];
                            break;
                        case "--key_store_password":
                            keyStorePassword = dim[1];
                            break;
                        case "--key_manager_password":
                            keyManagerPassword = dim[1];
                            break;
                        case "--redirect_https":
                            redirectHttps = dim[1];
                            break;
                        case "--prefix":
                            contextPath = dim[1];
                            break;
                        case "--gitbucket.home":
                            System.setProperty("gitbucket.home", dim[1]);
                            break;
                        case "--temp_dir":
                            tmpDirPath = dim[1];
                            break;
                        case "--plugin_dir":
                            System.setProperty("gitbucket.pluginDir", dim[1]);
                            break;
                        case "--jetty_idle_timeout":
                            jettyIdleTimeout = dim[1];
                            break;
                    }
                }
            }
        }

        if (contextPath != null && !contextPath.startsWith("/")) {
            contextPath = "/" + contextPath;
        }

        final String hostName = InetAddress.getByName(fallback(host, Defaults.HOST)).getHostName();

        final Server server = new Server();

        final Set connectorsSet = Stream.of(fallback(connectors, Defaults.CONNECTORS)
            .toLowerCase().split(",")).map(String::trim).collect(toSet());

        final List connectorInstances = new ArrayList<>();

        final HttpConfiguration httpConfig = new HttpConfiguration();
        httpConfig.setSendServerVersion(false);
        if (connectorsSet.contains(Connectors.HTTPS)) {
            httpConfig.setSecurePort(fallback(securePort, Defaults.HTTPS_PORT, Integer::parseInt));
        }
        if (jettyIdleTimeout != null && jettyIdleTimeout.trim().length() != 0) {
            httpConfig.setIdleTimeout(Long.parseLong(jettyIdleTimeout.trim()));
        } else {
            httpConfig.setIdleTimeout(300000L); // default is 5min
        }

        if (connectorsSet.contains(Connectors.HTTP)) {
            final ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
            connector.setHost(hostName);
            connector.setPort(fallback(port, Defaults.HTTP_PORT, Integer::parseInt));

            connectorInstances.add(connector);
        }

        if (connectorsSet.contains(Connectors.HTTPS)) {
            final SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();

            sslContextFactory.setKeyStorePath(requireNonNull(keyStorePath,
                "You must specify a path to an SSL keystore via the --key_store_path command line argument" +
                    " or GITBUCKET_KEYSTOREPATH environment variable."));

            sslContextFactory.setKeyStorePassword(requireNonNull(keyStorePassword,
                "You must specify a an SSL keystore password via the --key_store_password argument" +
                    " or GITBUCKET_KEYSTOREPASSWORD environment variable."));

            sslContextFactory.setKeyManagerPassword(requireNonNull(keyManagerPassword,
                "You must specify a key manager password via the --key_manager_password' argument" +
                    " or GITBUCKET_KEYMANAGERPASSWORD environment variable."));

            final HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
            httpsConfig.addCustomizer(new SecureRequestCustomizer());

            final ServerConnector connector = new ServerConnector(server,
                new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                new HttpConnectionFactory(httpsConfig));

            connector.setHost(hostName);
            connector.setPort(fallback(securePort, Defaults.HTTPS_PORT, Integer::parseInt));

            connectorInstances.add(connector);
        }

        require(!connectorInstances.isEmpty(),
            "No server connectors could be configured, please check your --connectors command line argument" +
                " or GITBUCKET_CONNECTORS environment variable.");

        server.setConnectors(connectorInstances.toArray(new ServerConnector[0]));

        WebAppContext context = new WebAppContext();

        if(saveSessions) {
            File sessDir = new File(getGitBucketHome(), "sessions");
            if(!sessDir.exists()){
                mkdir(sessDir);
            }
            SessionHandler sessions = context.getSessionHandler();
            SessionCache cache = new DefaultSessionCache(sessions);
            FileSessionDataStore fsds = new FileSessionDataStore();
            fsds.setStoreDir(sessDir);
            cache.setSessionDataStore(fsds);
            sessions.setSessionCache(cache);
        }

        File tmpDir;
        if(tmpDirPath == null || tmpDirPath.equals("")){
            tmpDir = new File(getGitBucketHome(), "tmp");
            if(!tmpDir.exists()){
                mkdir(tmpDir);
            }
        } else {
            tmpDir = new File(tmpDirPath);
            if(!tmpDir.exists()){
                throw new java.io.FileNotFoundException(
                    String.format("temp_dir \"%s\" not found", tmpDirPath));
            } else if(!tmpDir.isDirectory()) {
                throw new IllegalArgumentException(
                    String.format("temp_dir \"%s\" is not a directory", tmpDirPath));
            }
        }
        context.setTempDirectory(tmpDir);

        // Disabling the directory listing feature.
        context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

        ProtectionDomain domain = JettyLauncher.class.getProtectionDomain();
        URL location = domain.getCodeSource().getLocation();

        context.setContextPath(contextPath == null ? "" : contextPath);
        context.setDescriptor(location.toExternalForm() + "/WEB-INF/web.xml");
        context.setServer(server);
        context.setWar(location.toExternalForm());

        final HandlerList handlers = new HandlerList();

        if (fallback(redirectHttps, Defaults.REDIRECT_HTTPS, Boolean::parseBoolean)) {
            handlers.addHandler(new SecuredRedirectHandler());
        }

        handlers.addHandler(addStatisticsHandler(context));

        server.setHandler(handlers);
        server.setStopAtShutdown(true);
        server.setStopTimeout(7_000);
        server.start();
        server.join();
    }

    private static File getGitBucketHome(){
        String home = System.getProperty("gitbucket.home");
        if(home != null && home.length() > 0){
            return new File(home);
        }
        home = System.getenv("GITBUCKET_HOME");
        if(home != null && home.length() > 0){
            return new File(home);
        }
        return new File(System.getProperty("user.home"), ".gitbucket");
    }

    private static String getEnvironmentVariable(String key){
        String value =  System.getenv(key.toUpperCase().replace('.', '_'));
        if (value != null && value.length() == 0){
            return null;
        } else {
            return value;
        }
    }

    private static  T fallback(R value, T defaultValue, Function converter) {
        return value == null ? defaultValue : converter.apply(value);
    }

    private static  T fallback(T value, T defaultValue) {
        return fallback(value, defaultValue, identity());
    }

    private static void require(boolean condition, String message) {
        if (!condition) {
            throw new IllegalArgumentException(message);
        }
    }

    private static  T requireNonNull(T value, String message) {
        require(value != null, message);
        return value;
    }

    private static void mkdir(File dir) {
        if (!dir.mkdirs()) {
            throw new RuntimeException("Unable to create directory: " + dir);
        }
    }

    private static Handler addStatisticsHandler(Handler handler) {
        // The graceful shutdown is implemented via the statistics handler.
        // See the following: https://bugs.eclipse.org/bugs/show_bug.cgi?id=420142
        final StatisticsHandler statisticsHandler = new StatisticsHandler();
        statisticsHandler.setHandler(handler);
        return statisticsHandler;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy