/* * Copyright (c) 2011 PonySDK * Owners: * Luciano Broussal <luciano.broussal AT gmail.com> * Mathieu Barbier <mathieu.barbier AT gmail.com> * Nicolas Ciaravola <nicolas.ciaravola.pro AT gmail.com> * * WebSite: * http://code.google.com/p/pony-sdk/ * * 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.ponysdk.impl.main; import java.net.InetAddress; import java.net.URL; import java.util.EnumSet; import javax.servlet.DispatcherType; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ponysdk.core.model.MappingPath; import com.ponysdk.core.server.application.ApplicationManagerOption; import com.ponysdk.core.server.servlet.ApplicationLoader; import com.ponysdk.core.server.servlet.BootstrapServlet; import com.ponysdk.core.server.servlet.ServletContextFilter; import com.ponysdk.core.server.servlet.StreamServiceServlet; import com.ponysdk.core.server.servlet.WebSocketServlet; public class PonySDKServer { public static final String MAPPING_BOOTSTRAP = "/*"; public static final String MAPPING_WS = "/" + MappingPath.WEBSOCKET + "/*"; public static final String MAPPING_STREAM = "/" + MappingPath.STREAM; private static final Logger log = LoggerFactory.getLogger(PonySDKServer.class); protected final Server server; protected ApplicationLoader applicationLoader; protected String host = "0.0.0.0"; protected int port = 80; private boolean useSSL = true; private int sslPort = 443; private String sslKeyStoreFile; private String sslKeyStorePassphrase; private String sslKeyStoreType = "JKS"; private String sslTrustStoreFile; private String sslTrustStorePassphrase; private String sslTrustStoreType = "JKS"; private boolean needClientAuth = false; private String[] enabledProtocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }; private String enabledCipherSuites; public PonySDKServer() { server = new Server(); } public void start() throws Exception { server.addConnector(createHttpConnector()); if (useSSL) server.addConnector(createHttpsConnector()); final ServletContextHandler context = createWebApp(); final GzipHandler gzip = new GzipHandler(); gzip.setHandler(context); server.setHandler(gzip); context.addEventListener(applicationLoader); applicationLoader.start(); server.start(); server.join(); log.info("Webserver started on: " + InetAddress.getLocalHost().getHostAddress() + ":" + port); } protected ServletContextHandler createWebApp() { final ApplicationManagerOption applicationManagerOption = applicationLoader.getApplicationManagerOption(); log.info("Adding application #" + applicationManagerOption.getApplicationContextName()); final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/" + applicationManagerOption.getApplicationContextName()); context.addServlet(new ServletHolder(createBootstrapServlet()), MAPPING_BOOTSTRAP); context.addServlet(new ServletHolder(createStreamServiceServlet()), MAPPING_STREAM); context.addServlet(new ServletHolder(createWebSocketServlet()), MAPPING_WS); final ServletContextFilter servletContextFilter = new ServletContextFilter(); context.addFilter(new FilterHolder(servletContextFilter), MAPPING_BOOTSTRAP, EnumSet.of(DispatcherType.REQUEST)); final SessionHandler sessionHandler = context.getSessionHandler(); sessionHandler.setMaxInactiveInterval(60 * applicationManagerOption.getSessionTimeout()); sessionHandler.addEventListener(applicationLoader); return context; } protected ServerConnector createHttpConnector() { final ServerConnector serverConnector; if (useSSL) { final HttpConfiguration httpConfiguration = new HttpConfiguration(); httpConfiguration.setSecurePort(sslPort); serverConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration)); } else { serverConnector = new ServerConnector(server); } serverConnector.setPort(port); serverConnector.setHost(host); serverConnector.setReuseAddress(true); return serverConnector; } protected ServerConnector createHttpsConnector() { final ServerConnector serverConnector; // HTTPS URL keyStore = getClass().getResource(sslKeyStoreFile); if (keyStore == null) { keyStore = getClass().getClassLoader().getResource(sslKeyStoreFile); } if (keyStore == null) throw new RuntimeException("KeyStore not found #" + sslKeyStoreFile); final SslContextFactory sslContextFactory = new SslContextFactory(keyStore.toExternalForm()); sslContextFactory.setKeyStorePassword(sslKeyStorePassphrase); sslContextFactory.setKeyStoreType(sslKeyStoreType); sslContextFactory.setIncludeProtocols(enabledProtocols); if (enabledCipherSuites != null) sslContextFactory.setIncludeCipherSuites(enabledCipherSuites); if (needClientAuth) { sslContextFactory.setNeedClientAuth(needClientAuth); if (sslTrustStoreFile != null) { sslContextFactory.setTrustStorePath(sslTrustStoreFile); sslContextFactory.setTrustStorePassword(sslTrustStorePassphrase); sslContextFactory.setTrustStoreType(sslTrustStoreType); } } serverConnector = new ServerConnector(server, sslContextFactory); serverConnector.setPort(sslPort); serverConnector.setHost(host); serverConnector.setReuseAddress(true); return serverConnector; } protected BootstrapServlet createBootstrapServlet() { final BootstrapServlet bootstrapServlet = new BootstrapServlet(); bootstrapServlet.setApplication(applicationLoader.getApplicationManagerOption()); return bootstrapServlet; } protected StreamServiceServlet createStreamServiceServlet() { return new StreamServiceServlet(); } protected WebSocketServlet createWebSocketServlet() { return new WebSocketServlet(); } public void stop() throws Exception { server.stop(); } public void setApplicationLoader(final ApplicationLoader applicationLoader) { this.applicationLoader = applicationLoader; } public ApplicationManagerOption getApplicationOption() { return applicationLoader.getApplicationManagerOption(); } public void setHost(final String host) { this.host = host; } public void setPort(final int port) { this.port = port; } public void setUseSSL(final boolean useSSL) { this.useSSL = useSSL; } public boolean isUseSSL() { return useSSL; } public void setSslKeyStoreFile(final String sslKeyStoreFile) { this.sslKeyStoreFile = sslKeyStoreFile; } public void setSslKeyStorePassphrase(final String sslKeyStorePassphrase) { this.sslKeyStorePassphrase = sslKeyStorePassphrase; } public void setSslPort(final int sslPort) { this.sslPort = sslPort; } public void setSslKeyStoreType(final String sslKeyStoreType) { this.sslKeyStoreType = sslKeyStoreType; } public void setSslTrustStoreFile(final String sslTrustStoreFile) { this.sslTrustStoreFile = sslTrustStoreFile; } public void setSslTrustStorePassphrase(final String sslTrustStorePassphrase) { this.sslTrustStorePassphrase = sslTrustStorePassphrase; } public void setSslTrustStoreType(final String sslTrustStoreType) { this.sslTrustStoreType = sslTrustStoreType; } public void setNeedClientAuth(final boolean needClientAuth) { this.needClientAuth = needClientAuth; } public void setEnabledProtocols(final String[] enabledProtocols) { this.enabledProtocols = enabledProtocols; } public void setEnabledCipherSuites(final String enabledCipherSuites) { this.enabledCipherSuites = enabledCipherSuites; } }