| /* | |
| * Copyright 2011 gitblit.com. | |
| * | |
| * Licensed 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 | |
| * | |
| * http://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.gitblit; | |
| import java.io.BufferedReader; | |
| import java.io.BufferedWriter; | |
| import java.io.File; | |
| import java.io.FileWriter; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.io.InputStreamReader; | |
| import java.io.OutputStream; | |
| import java.net.InetAddress; | |
| import java.net.ServerSocket; | |
| import java.net.Socket; | |
| import java.net.URI; | |
| import java.net.URL; | |
| import java.net.UnknownHostException; | |
| import java.security.ProtectionDomain; | |
| import java.text.MessageFormat; | |
| import java.util.ArrayList; | |
| import java.util.Date; | |
| import java.util.List; | |
| import java.util.Properties; | |
| import java.util.Scanner; | |
| import org.apache.log4j.PropertyConfigurator; | |
| import org.eclipse.jetty.ajp.Ajp13SocketConnector; | |
| import org.eclipse.jetty.security.ConstraintMapping; | |
| import org.eclipse.jetty.security.ConstraintSecurityHandler; | |
| import org.eclipse.jetty.server.Connector; | |
| import org.eclipse.jetty.server.Server; | |
| import org.eclipse.jetty.server.bio.SocketConnector; | |
| import org.eclipse.jetty.server.nio.SelectChannelConnector; | |
| import org.eclipse.jetty.server.session.HashSessionManager; | |
| import org.eclipse.jetty.server.ssl.SslConnector; | |
| import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; | |
| import org.eclipse.jetty.server.ssl.SslSocketConnector; | |
| import org.eclipse.jetty.util.security.Constraint; | |
| import org.eclipse.jetty.util.thread.QueuedThreadPool; | |
| import org.eclipse.jetty.webapp.WebAppContext; | |
| import org.eclipse.jgit.storage.file.FileBasedConfig; | |
| import org.eclipse.jgit.util.FS; | |
| import org.eclipse.jgit.util.FileUtils; | |
| import org.kohsuke.args4j.CmdLineException; | |
| import org.kohsuke.args4j.CmdLineParser; | |
| import org.kohsuke.args4j.Option; | |
| import org.slf4j.Logger; | |
| import org.slf4j.LoggerFactory; | |
| import com.gitblit.authority.GitblitAuthority; | |
| import com.gitblit.authority.NewCertificateConfig; | |
| import com.gitblit.servlet.GitblitContext; | |
| import com.gitblit.utils.StringUtils; | |
| import com.gitblit.utils.TimeUtils; | |
| import com.gitblit.utils.X509Utils; | |
| import com.gitblit.utils.X509Utils.X509Log; | |
| import com.gitblit.utils.X509Utils.X509Metadata; | |
| import com.unboundid.ldap.listener.InMemoryDirectoryServer; | |
| import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; | |
| import com.unboundid.ldap.listener.InMemoryListenerConfig; | |
| import com.unboundid.ldif.LDIFReader; | |
| /** | |
| * GitBlitServer is the embedded Jetty server for Gitblit GO. This class starts | |
| * and stops an instance of Jetty that is configured from a combination of the | |
| * gitblit.properties file and command line parameters. JCommander is used to | |
| * simplify command line parameter processing. This class also automatically | |
| * generates a self-signed certificate for localhost, if the keystore does not | |
| * already exist. | |
| * | |
| * @author James Moger | |
| * | |
| */ | |
| public class GitBlitServer { | |
| private static Logger logger; | |
| public static void main(String... args) { | |
| GitBlitServer server = new GitBlitServer(); | |
| // filter out the baseFolder parameter | |
| List<String> filtered = new ArrayList<String>(); | |
| String folder = "data"; | |
| for (int i = 0; i < args.length; i++) { | |
| String arg = args[i]; | |
| if (arg.equals("--baseFolder")) { | |
| if (i + 1 == args.length) { | |
| System.out.println("Invalid --baseFolder parameter!"); | |
| System.exit(-1); | |
| } else if (!".".equals(args[i + 1])) { | |
| folder = args[i + 1]; | |
| } | |
| i = i + 1; | |
| } else { | |
| filtered.add(arg); | |
| } | |
| } | |
| Params.baseFolder = folder; | |
| Params params = new Params(); | |
| CmdLineParser parser = new CmdLineParser(params); | |
| try { | |
| parser.parseArgument(filtered); | |
| if (params.help) { | |
| server.usage(parser, null); | |
| } | |
| } catch (CmdLineException t) { | |
| server.usage(parser, t); | |
| } | |
| if (params.stop) { | |
| server.stop(params); | |
| } else { | |
| server.start(params); | |
| } | |
| } | |
| /** | |
| * Display the command line usage of Gitblit GO. | |
| * | |
| * @param parser | |
| * @param t | |
| */ | |
| protected final void usage(CmdLineParser parser, CmdLineException t) { | |
| System.out.println(Constants.BORDER); | |
| System.out.println(Constants.getGitBlitVersion()); | |
| System.out.println(Constants.BORDER); | |
| System.out.println(); | |
| if (t != null) { | |
| System.out.println(t.getMessage()); | |
| System.out.println(); | |
| } | |
| if (parser != null) { | |
| parser.printUsage(System.out); | |
| System.out | |
| .println("\nExample:\n java -server -Xmx1024M -jar gitblit.jar --repositoriesFolder c:\\git --httpPort 80 --httpsPort 443"); | |
| } | |
| System.exit(0); | |
| } | |
| /** | |
| * Stop Gitblt GO. | |
| */ | |
| public void stop(Params params) { | |
| try { | |
| Socket s = new Socket(InetAddress.getByName("127.0.0.1"), params.shutdownPort); | |
| OutputStream out = s.getOutputStream(); | |
| System.out.println("Sending Shutdown Request to " + Constants.NAME); | |
| out.write("\r\n".getBytes()); | |
| out.flush(); | |
| s.close(); | |
| } catch (UnknownHostException e) { | |
| e.printStackTrace(); | |
| } catch (IOException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| /** | |
| * Start Gitblit GO. | |
| */ | |
| protected final void start(Params params) { | |
| final File baseFolder = new File(Params.baseFolder).getAbsoluteFile(); | |
| FileSettings settings = params.FILESETTINGS; | |
| if (!StringUtils.isEmpty(params.settingsfile)) { | |
| if (new File(params.settingsfile).exists()) { | |
| settings = new FileSettings(params.settingsfile); | |
| } | |
| } | |
| if (params.dailyLogFile) { | |
| // Configure log4j for daily log file generation | |
| InputStream is = null; | |
| try { | |
| is = getClass().getResourceAsStream("/log4j.properties"); | |
| Properties loggingProperties = new Properties(); | |
| loggingProperties.load(is); | |
| loggingProperties.put("log4j.appender.R.File", new File(baseFolder, "logs/gitblit.log").getAbsolutePath()); | |
| loggingProperties.put("log4j.rootCategory", "INFO, R"); | |
| if (settings.getBoolean(Keys.web.debugMode, false)) { | |
| loggingProperties.put("log4j.logger.com.gitblit", "DEBUG"); | |
| } | |
| PropertyConfigurator.configure(loggingProperties); | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } finally { | |
| try { | |
| is.close(); | |
| } catch (IOException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } | |
| logger = LoggerFactory.getLogger(GitBlitServer.class); | |
| logger.info(Constants.BORDER); | |
| logger.info(" _____ _ _ _ _ _ _"); | |
| logger.info(" | __ \\(_)| | | | | |(_)| |"); | |
| logger.info(" | | \\/ _ | |_ | |__ | | _ | |_"); | |
| logger.info(" | | __ | || __|| '_ \\ | || || __|"); | |
| logger.info(" | |_\\ \\| || |_ | |_) || || || |_"); | |
| logger.info(" \\____/|_| \\__||_.__/ |_||_| \\__|"); | |
| int spacing = (Constants.BORDER.length() - Constants.getGitBlitVersion().length()) / 2; | |
| StringBuilder sb = new StringBuilder(); | |
| while (spacing > 0) { | |
| spacing--; | |
| sb.append(' '); | |
| } | |
| logger.info(sb.toString() + Constants.getGitBlitVersion()); | |
| logger.info(""); | |
| logger.info(Constants.BORDER); | |
| System.setProperty("java.awt.headless", "true"); | |
| String osname = System.getProperty("os.name"); | |
| String osversion = System.getProperty("os.version"); | |
| logger.info("Running on " + osname + " (" + osversion + ")"); | |
| List<Connector> connectors = new ArrayList<Connector>(); | |
| // conditionally configure the http connector | |
| if (params.port > 0) { | |
| Connector httpConnector = createConnector(params.useNIO, params.port, settings.getInteger(Keys.server.threadPoolSize, 50)); | |
| String bindInterface = settings.getString(Keys.server.httpBindInterface, null); | |
| if (!StringUtils.isEmpty(bindInterface)) { | |
| logger.warn(MessageFormat.format("Binding connector on port {0,number,0} to {1}", | |
| params.port, bindInterface)); | |
| httpConnector.setHost(bindInterface); | |
| } | |
| if (params.port < 1024 && !isWindows()) { | |
| logger.warn("Gitblit needs to run with ROOT permissions for ports < 1024!"); | |
| } | |
| if (params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)) { | |
| // redirect HTTP requests to HTTPS | |
| if (httpConnector instanceof SelectChannelConnector) { | |
| ((SelectChannelConnector) httpConnector).setConfidentialPort(params.securePort); | |
| } else { | |
| ((SocketConnector) httpConnector).setConfidentialPort(params.securePort); | |
| } | |
| } | |
| connectors.add(httpConnector); | |
| } | |
| // conditionally configure the https connector | |
| if (params.securePort > 0) { | |
| File certificatesConf = new File(baseFolder, X509Utils.CA_CONFIG); | |
| File serverKeyStore = new File(baseFolder, X509Utils.SERVER_KEY_STORE); | |
| File serverTrustStore = new File(baseFolder, X509Utils.SERVER_TRUST_STORE); | |
| File caRevocationList = new File(baseFolder, X509Utils.CA_REVOCATION_LIST); | |
| // generate CA & web certificates, create certificate stores | |
| X509Metadata metadata = new X509Metadata("localhost", params.storePassword); | |
| // set default certificate values from config file | |
| if (certificatesConf.exists()) { | |
| FileBasedConfig config = new FileBasedConfig(certificatesConf, FS.detect()); | |
| try { | |
| config.load(); | |
| } catch (Exception e) { | |
| logger.error("Error parsing " + certificatesConf, e); | |
| } | |
| NewCertificateConfig certificateConfig = NewCertificateConfig.KEY.parse(config); | |
| certificateConfig.update(metadata); | |
| } | |
| metadata.notAfter = new Date(System.currentTimeMillis() + 10*TimeUtils.ONEYEAR); | |
| X509Utils.prepareX509Infrastructure(metadata, baseFolder, new X509Log() { | |
| @Override | |
| public void log(String message) { | |
| BufferedWriter writer = null; | |
| try { | |
| writer = new BufferedWriter(new FileWriter(new File(baseFolder, X509Utils.CERTS + File.separator + "log.txt"), true)); | |
| writer.write(MessageFormat.format("{0,date,yyyy-MM-dd HH:mm}: {1}", new Date(), message)); | |
| writer.newLine(); | |
| writer.flush(); | |
| } catch (Exception e) { | |
| LoggerFactory.getLogger(GitblitAuthority.class).error("Failed to append log entry!", e); | |
| } finally { | |
| if (writer != null) { | |
| try { | |
| writer.close(); | |
| } catch (IOException e) { | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| if (serverKeyStore.exists()) { | |
| Connector secureConnector = createSSLConnector(params.alias, serverKeyStore, serverTrustStore, params.storePassword, | |
| caRevocationList, params.useNIO, params.securePort, settings.getInteger(Keys.server.threadPoolSize, 50), params.requireClientCertificates); | |
| String bindInterface = settings.getString(Keys.server.httpsBindInterface, null); | |
| if (!StringUtils.isEmpty(bindInterface)) { | |
| logger.warn(MessageFormat.format( | |
| "Binding ssl connector on port {0,number,0} to {1}", params.securePort, | |
| bindInterface)); | |
| secureConnector.setHost(bindInterface); | |
| } | |
| if (params.securePort < 1024 && !isWindows()) { | |
| logger.warn("Gitblit needs to run with ROOT permissions for ports < 1024!"); | |
| } | |
| connectors.add(secureConnector); | |
| } else { | |
| logger.warn("Failed to find or load Keystore?"); | |
| logger.warn("SSL connector DISABLED."); | |
| } | |
| } | |
| // conditionally configure the ajp connector | |
| if (params.ajpPort > 0) { | |
| Connector ajpConnector = createAJPConnector(params.ajpPort); | |
| String bindInterface = settings.getString(Keys.server.ajpBindInterface, null); | |
| if (!StringUtils.isEmpty(bindInterface)) { | |
| logger.warn(MessageFormat.format("Binding connector on port {0,number,0} to {1}", | |
| params.ajpPort, bindInterface)); | |
| ajpConnector.setHost(bindInterface); | |
| } | |
| if (params.ajpPort < 1024 && !isWindows()) { | |
| logger.warn("Gitblit needs to run with ROOT permissions for ports < 1024!"); | |
| } | |
| connectors.add(ajpConnector); | |
| } | |
| // tempDir is where the embedded Gitblit web application is expanded and | |
| // where Jetty creates any necessary temporary files | |
| File tempDir = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.temp); | |
| if (tempDir.exists()) { | |
| try { | |
| FileUtils.delete(tempDir, FileUtils.RECURSIVE | FileUtils.RETRY); | |
| } catch (IOException x) { | |
| logger.warn("Failed to delete temp dir " + tempDir.getAbsolutePath(), x); | |
| } | |
| } | |
| if (!tempDir.mkdirs()) { | |
| logger.warn("Failed to create temp dir " + tempDir.getAbsolutePath()); | |
| } | |
| Server server = new Server(); | |
| server.setStopAtShutdown(true); | |
| server.setConnectors(connectors.toArray(new Connector[connectors.size()])); | |
| // Get the execution path of this class | |
| // We use this to set the WAR path. | |
| ProtectionDomain protectionDomain = GitBlitServer.class.getProtectionDomain(); | |
| URL location = protectionDomain.getCodeSource().getLocation(); | |
| // Root WebApp Context | |
| WebAppContext rootContext = new WebAppContext(); | |
| rootContext.setContextPath(settings.getString(Keys.server.contextPath, "/")); | |
| rootContext.setServer(server); | |
| rootContext.setWar(location.toExternalForm()); | |
| rootContext.setTempDirectory(tempDir); | |
| // Set cookies HttpOnly so they are not accessible to JavaScript engines | |
| HashSessionManager sessionManager = new HashSessionManager(); | |
| sessionManager.setHttpOnly(true); | |
| // Use secure cookies if only serving https | |
| sessionManager.setSecureRequestOnly(params.port <= 0 && params.securePort > 0); | |
| rootContext.getSessionHandler().setSessionManager(sessionManager); | |
| // Ensure there is a defined User Service | |
| String realmUsers = params.userService; | |
| if (StringUtils.isEmpty(realmUsers)) { | |
| logger.error(MessageFormat.format("PLEASE SPECIFY {0}!!", Keys.realm.userService)); | |
| return; | |
| } | |
| // Override settings from the command-line | |
| settings.overrideSetting(Keys.realm.userService, params.userService); | |
| settings.overrideSetting(Keys.git.repositoriesFolder, params.repositoriesFolder); | |
| settings.overrideSetting(Keys.git.daemonPort, params.gitPort); | |
| // Start up an in-memory LDAP server, if configured | |
| try { | |
| if (!StringUtils.isEmpty(params.ldapLdifFile)) { | |
| File ldifFile = new File(params.ldapLdifFile); | |
| if (ldifFile != null && ldifFile.exists()) { | |
| URI ldapUrl = new URI(settings.getRequiredString(Keys.realm.ldap.server)); | |
| String firstLine = new Scanner(ldifFile).nextLine(); | |
| String rootDN = firstLine.substring(4); | |
| String bindUserName = settings.getString(Keys.realm.ldap.username, ""); | |
| String bindPassword = settings.getString(Keys.realm.ldap.password, ""); | |
| // Get the port | |
| int port = ldapUrl.getPort(); | |
| if (port == -1) | |
| port = 389; | |
| InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(rootDN); | |
| config.addAdditionalBindCredentials(bindUserName, bindPassword); | |
| config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", port)); | |
| config.setSchema(null); | |
| InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); | |
| ds.importFromLDIF(true, new LDIFReader(ldifFile)); | |
| ds.startListening(); | |
| logger.info("LDAP Server started at ldap://localhost:" + port); | |
| } | |
| } | |
| } catch (Exception e) { | |
| // Completely optional, just show a warning | |
| logger.warn("Unable to start LDAP server", e); | |
| } | |
| // Set the server's contexts | |
| server.setHandler(rootContext); | |
| // redirect HTTP requests to HTTPS | |
| if (params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)) { | |
| logger.info(String.format("Configuring automatic http(%1$s) -> https(%2$s) redirects", params.port, params.securePort)); | |
| // Create the internal mechanisms to handle secure connections and redirects | |
| Constraint constraint = new Constraint(); | |
| constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL); | |
| ConstraintMapping cm = new ConstraintMapping(); | |
| cm.setConstraint(constraint); | |
| cm.setPathSpec("/*"); | |
| ConstraintSecurityHandler sh = new ConstraintSecurityHandler(); | |
| sh.setConstraintMappings(new ConstraintMapping[] { cm }); | |
| // Configure this context to use the Security Handler defined before | |
| rootContext.setHandler(sh); | |
| } | |
| // Setup the Gitblit context | |
| GitblitContext gitblit = newGitblit(settings, baseFolder); | |
| rootContext.addEventListener(gitblit); | |
| try { | |
| // start the shutdown monitor | |
| if (params.shutdownPort > 0) { | |
| Thread shutdownMonitor = new ShutdownMonitorThread(server, params); | |
| shutdownMonitor.start(); | |
| } | |
| // start Jetty | |
| server.start(); | |
| server.join(); | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| System.exit(100); | |
| } | |
| } | |
| protected GitblitContext newGitblit(IStoredSettings settings, File baseFolder) { | |
| return new GitblitContext(settings, baseFolder); | |
| } | |
| /** | |
| * Creates an http connector. | |
| * | |
| * @param useNIO | |
| * @param port | |
| * @param threadPoolSize | |
| * @return an http connector | |
| */ | |
| private Connector createConnector(boolean useNIO, int port, int threadPoolSize) { | |
| Connector connector; | |
| if (useNIO) { | |
| logger.info("Setting up NIO SelectChannelConnector on port " + port); | |
| SelectChannelConnector nioconn = new SelectChannelConnector(); | |
| nioconn.setSoLingerTime(-1); | |
| if (threadPoolSize > 0) { | |
| nioconn.setThreadPool(new QueuedThreadPool(threadPoolSize)); | |
| } | |
| connector = nioconn; | |
| } else { | |
| logger.info("Setting up SocketConnector on port " + port); | |
| SocketConnector sockconn = new SocketConnector(); | |
| if (threadPoolSize > 0) { | |
| sockconn.setThreadPool(new QueuedThreadPool(threadPoolSize)); | |
| } | |
| connector = sockconn; | |
| } | |
| connector.setPort(port); | |
| connector.setMaxIdleTime(30000); | |
| return connector; | |
| } | |
| /** | |
| * Creates an https connector. | |
| * | |
| * SSL renegotiation will be enabled if the JVM is 1.6.0_22 or later. | |
| * oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html | |
| * | |
| * @param certAlias | |
| * @param keyStore | |
| * @param clientTrustStore | |
| * @param storePassword | |
| * @param caRevocationList | |
| * @param useNIO | |
| * @param port | |
| * @param threadPoolSize | |
| * @param requireClientCertificates | |
| * @return an https connector | |
| */ | |
| private Connector createSSLConnector(String certAlias, File keyStore, File clientTrustStore, | |
| String storePassword, File caRevocationList, boolean useNIO, int port, int threadPoolSize, | |
| boolean requireClientCertificates) { | |
| GitblitSslContextFactory factory = new GitblitSslContextFactory(certAlias, | |
| keyStore, clientTrustStore, storePassword, caRevocationList); | |
| SslConnector connector; | |
| if (useNIO) { | |
| logger.info("Setting up NIO SslSelectChannelConnector on port " + port); | |
| SslSelectChannelConnector ssl = new SslSelectChannelConnector(factory); | |
| ssl.setSoLingerTime(-1); | |
| if (requireClientCertificates) { | |
| factory.setNeedClientAuth(true); | |
| } else { | |
| factory.setWantClientAuth(true); | |
| } | |
| if (threadPoolSize > 0) { | |
| ssl.setThreadPool(new QueuedThreadPool(threadPoolSize)); | |
| } | |
| connector = ssl; | |
| } else { | |
| logger.info("Setting up NIO SslSocketConnector on port " + port); | |
| SslSocketConnector ssl = new SslSocketConnector(factory); | |
| if (threadPoolSize > 0) { | |
| ssl.setThreadPool(new QueuedThreadPool(threadPoolSize)); | |
| } | |
| connector = ssl; | |
| } | |
| connector.setPort(port); | |
| connector.setMaxIdleTime(30000); | |
| return connector; | |
| } | |
| /** | |
| * Creates an ajp connector. | |
| * | |
| * @param port | |
| * @return an ajp connector | |
| */ | |
| private Connector createAJPConnector(int port) { | |
| logger.info("Setting up AJP Connector on port " + port); | |
| Ajp13SocketConnector ajp = new Ajp13SocketConnector(); | |
| ajp.setPort(port); | |
| if (port < 1024 && !isWindows()) { | |
| logger.warn("Gitblit needs to run with ROOT permissions for ports < 1024!"); | |
| } | |
| return ajp; | |
| } | |
| /** | |
| * Tests to see if the operating system is Windows. | |
| * | |
| * @return true if this is a windows machine | |
| */ | |
| private boolean isWindows() { | |
| return System.getProperty("os.name").toLowerCase().indexOf("windows") > -1; | |
| } | |
| /** | |
| * The ShutdownMonitorThread opens a socket on a specified port and waits | |
| * for an incoming connection. When that connection is accepted a shutdown | |
| * message is issued to the running Jetty server. | |
| * | |
| * @author James Moger | |
| * | |
| */ | |
| private static class ShutdownMonitorThread extends Thread { | |
| private final ServerSocket socket; | |
| private final Server server; | |
| private final Logger logger = LoggerFactory.getLogger(ShutdownMonitorThread.class); | |
| public ShutdownMonitorThread(Server server, Params params) { | |
| this.server = server; | |
| setDaemon(true); | |
| setName(Constants.NAME + " Shutdown Monitor"); | |
| ServerSocket skt = null; | |
| try { | |
| skt = new ServerSocket(params.shutdownPort, 1, InetAddress.getByName("127.0.0.1")); | |
| } catch (Exception e) { | |
| logger.warn("Could not open shutdown monitor on port " + params.shutdownPort, e); | |
| } | |
| socket = skt; | |
| } | |
| @Override | |
| public void run() { | |
| logger.info("Shutdown Monitor listening on port " + socket.getLocalPort()); | |
| Socket accept; | |
| try { | |
| accept = socket.accept(); | |
| BufferedReader reader = new BufferedReader(new InputStreamReader( | |
| accept.getInputStream())); | |
| reader.readLine(); | |
| logger.info(Constants.BORDER); | |
| logger.info("Stopping " + Constants.NAME); | |
| logger.info(Constants.BORDER); | |
| server.stop(); | |
| server.setStopAtShutdown(false); | |
| accept.close(); | |
| socket.close(); | |
| } catch (Exception e) { | |
| logger.warn("Failed to shutdown Jetty", e); | |
| } | |
| } | |
| } | |
| /** | |
| * Parameters class for GitBlitServer. | |
| */ | |
| public static class Params { | |
| public static String baseFolder; | |
| private final FileSettings FILESETTINGS = new FileSettings(new File(baseFolder, Constants.PROPERTIES_FILE).getAbsolutePath()); | |
| /* | |
| * Server parameters | |
| */ | |
| @Option(name = "--help", aliases = { "-h"}, usage = "Show this help") | |
| public Boolean help = false; | |
| @Option(name = "--stop", usage = "Stop Server") | |
| public Boolean stop = false; | |
| @Option(name = "--tempFolder", usage = "Folder for server to extract built-in webapp", metaVar="PATH") | |
| public String temp = FILESETTINGS.getString(Keys.server.tempFolder, "temp"); | |
| @Option(name = "--dailyLogFile", usage = "Log to a rolling daily log file INSTEAD of stdout.") | |
| public Boolean dailyLogFile = false; | |
| /* | |
| * GIT Servlet Parameters | |
| */ | |
| @Option(name = "--repositoriesFolder", usage = "Git Repositories Folder", metaVar="PATH") | |
| public String repositoriesFolder = FILESETTINGS.getString(Keys.git.repositoriesFolder, | |
| "git"); | |
| /* | |
| * Authentication Parameters | |
| */ | |
| @Option(name = "--userService", usage = "Authentication and Authorization Service (filename or fully qualified classname)") | |
| public String userService = FILESETTINGS.getString(Keys.realm.userService, | |
| "users.conf"); | |
| /* | |
| * JETTY Parameters | |
| */ | |
| @Option(name = "--useNio", usage = "Use NIO Connector else use Socket Connector.") | |
| public Boolean useNIO = FILESETTINGS.getBoolean(Keys.server.useNio, true); | |
| @Option(name = "--httpPort", usage = "HTTP port for to serve. (port <= 0 will disable this connector)", metaVar="PORT") | |
| public Integer port = FILESETTINGS.getInteger(Keys.server.httpPort, 0); | |
| @Option(name = "--httpsPort", usage = "HTTPS port to serve. (port <= 0 will disable this connector)", metaVar="PORT") | |
| public Integer securePort = FILESETTINGS.getInteger(Keys.server.httpsPort, 8443); | |
| @Option(name = "--ajpPort", usage = "AJP port to serve. (port <= 0 will disable this connector)", metaVar="PORT") | |
| public Integer ajpPort = FILESETTINGS.getInteger(Keys.server.ajpPort, 0); | |
| @Option(name = "--gitPort", usage = "Git Daemon port to serve. (port <= 0 will disable this connector)", metaVar="PORT") | |
| public Integer gitPort = FILESETTINGS.getInteger(Keys.git.daemonPort, 9418); | |
| @Option(name = "--alias", usage = "Alias of SSL certificate in keystore for serving https.", metaVar="ALIAS") | |
| public String alias = FILESETTINGS.getString(Keys.server.certificateAlias, ""); | |
| @Option(name = "--storePassword", usage = "Password for SSL (https) keystore.", metaVar="PASSWORD") | |
| public String storePassword = FILESETTINGS.getString(Keys.server.storePassword, ""); | |
| @Option(name = "--shutdownPort", usage = "Port for Shutdown Monitor to listen on. (port <= 0 will disable this monitor)", metaVar="PORT") | |
| public Integer shutdownPort = FILESETTINGS.getInteger(Keys.server.shutdownPort, 8081); | |
| @Option(name = "--requireClientCertificates", usage = "Require client X509 certificates for https connections.") | |
| public Boolean requireClientCertificates = FILESETTINGS.getBoolean(Keys.server.requireClientCertificates, false); | |
| /* | |
| * Setting overrides | |
| */ | |
| @Option(name = "--settings", usage = "Path to alternative settings", metaVar="FILE") | |
| public String settingsfile; | |
| @Option(name = "--ldapLdifFile", usage = "Path to LDIF file. This will cause an in-memory LDAP server to be started according to gitblit settings", metaVar="FILE") | |
| public String ldapLdifFile; | |
| } | |
| } |