/* * Copyright 2011- Per Wendel * * 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 spark.webserver; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import com.cinchapi.common.reflect.Reflection; import spark.webserver.SparkServer; /** * Spark server implementation * * @author Per Wendel */ class SparkServerImpl implements SparkServer { private Handler handler; private Server server; public SparkServerImpl(Handler handler) { this.handler = handler; System.setProperty("org.mortbay.log.class", "spark.JettyLogger"); } @Override public void ignite(String host, int port, String keystoreFile, String keystorePassword, String truststoreFile, String truststorePassword, String staticFilesFolder, String externalFilesFolder) { ServerConnector connector; if(keystoreFile == null) { connector = createSocketConnector(); } else { connector = createSecureSocketConnector(keystoreFile, keystorePassword, truststoreFile, truststorePassword); } // Set some timeout options to make debugging easier. connector.setIdleTimeout(TimeUnit.HOURS.toMillis(1)); connector.setSoLingerTime(-1); connector.setHost(host); connector.setPort(port); server = connector.getServer(); server.setConnectors(new Connector[] { connector }); // Handle static file routes if(staticFilesFolder == null && externalFilesFolder == null) { server.setHandler(handler); } else { List<Handler> handlersInList = new ArrayList<Handler>(); handlersInList.add(handler); // Set static file location setStaticFileLocationIfPresent(staticFilesFolder, handlersInList); // Set external static file location setExternalStaticFileLocationIfPresent(externalFilesFolder, handlersInList); HandlerList handlers = new HandlerList(); handlers.setHandlers(handlersInList .toArray(new Handler[handlersInList.size()])); server.setHandler(handlers); } try { server.start(); server.join(); } catch (Exception e) { e.printStackTrace(); // NOSONAR System.exit(100); // NOSONAR } } @Override public void stop() { try { if(server != null) { server.stop(); } } catch (Exception e) { e.printStackTrace(); // NOSONAR System.exit(100); // NOSONAR } } /** * Creates a secure jetty socket connector. Keystore required, truststore * optional. If truststore not specifed keystore will be reused. * * @param keystoreFile The keystore file location as string * @param keystorePassword the password for the keystore * @param truststoreFile the truststore file location as string, leave null * to reuse keystore * @param truststorePassword the trust store password * * @return a secure socket connector */ private static ServerConnector createSecureSocketConnector( String keystoreFile, String keystorePassword, String truststoreFile, String truststorePassword) { SslContextFactory sslContextFactory = new SslContextFactory( keystoreFile); if(keystorePassword != null) { sslContextFactory.setKeyStorePassword(keystorePassword); } if(truststoreFile != null) { sslContextFactory.setTrustStorePath(truststoreFile); } if(truststorePassword != null) { sslContextFactory.setTrustStorePassword(truststorePassword); } return new ServerConnector(new Server(), sslContextFactory); } /** * Creates an ordinary, non-secured Jetty server connector. * * @return - a server connector */ private static ServerConnector createSocketConnector() { // NOTE: This code has been modified to change the name of the threads // used in the server's QueuedThreadPool (jnelson) Server server = new Server(); QueuedThreadPool pool = Reflection.get("_threadPool", server); Reflection.set("_name", "HTTP Client Worker", pool); return new ServerConnector(server); } /** * Sets static file location if present */ private static void setStaticFileLocationIfPresent(String staticFilesRoute, List<Handler> handlersInList) { if(staticFilesRoute != null) { ResourceHandler resourceHandler = new ResourceHandler(); Resource staticResources = Resource .newClassPathResource(staticFilesRoute); resourceHandler.setBaseResource(staticResources); resourceHandler.setWelcomeFiles(new String[] { "index.html" }); handlersInList.add(resourceHandler); } } /** * Sets external static file location if present */ private static void setExternalStaticFileLocationIfPresent( String externalFilesRoute, List<Handler> handlersInList) { if(externalFilesRoute != null) { ResourceHandler externalResourceHandler = new ResourceHandler(); Resource externalStaticResources = Resource.newResource(new File( externalFilesRoute)); externalResourceHandler.setBaseResource(externalStaticResources); externalResourceHandler .setWelcomeFiles(new String[] { "index.html" }); handlersInList.add(externalResourceHandler); } } }