package play.server; import java.io.File; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.Properties; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelException; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import play.Logger; import play.Play; import play.Play.Mode; import play.libs.IO; import play.server.ssl.SslHttpServerPipelineFactory; import play.vfs.VirtualFile; public class Server { public static int httpPort; public static int httpsPort; public final static String PID_FILE = "server.pid"; public Server(String[] args) { System.setProperty("file.encoding", "utf-8"); final Properties p = Play.configuration; httpPort = Integer.parseInt(getOpt(args, "http.port", p.getProperty("http.port", "-1"))); httpsPort = Integer.parseInt(getOpt(args, "https.port", p.getProperty("https.port", "-1"))); if (httpPort == -1 && httpsPort == -1) { httpPort = 9000; } if (httpPort == httpsPort) { Logger.error("Could not bind on https and http on the same port " + httpPort); Play.fatalServerErrorOccurred(); } InetAddress address = null; InetAddress secureAddress = null; try { if (p.getProperty("http.address") != null) { address = InetAddress.getByName(p.getProperty("http.address")); } else if (System.getProperties().containsKey("http.address")) { address = InetAddress.getByName(System.getProperty("http.address")); } } catch (Exception e) { Logger.error(e, "Could not understand http.address"); Play.fatalServerErrorOccurred(); } try { if (p.getProperty("https.address") != null) { secureAddress = InetAddress.getByName(p.getProperty("https.address")); } else if (System.getProperties().containsKey("https.address")) { secureAddress = InetAddress.getByName(System.getProperty("https.address")); } } catch (Exception e) { Logger.error(e, "Could not understand https.address"); Play.fatalServerErrorOccurred(); } ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()) ); try { if (httpPort != -1) { bootstrap.setPipelineFactory(new HttpServerPipelineFactory()); bootstrap.bind(new InetSocketAddress(address, httpPort)); bootstrap.setOption("child.tcpNoDelay", true); if (Play.mode == Mode.DEV) { if (address == null) { Logger.info("Listening for HTTP on port %s (Waiting a first request to start) ...", httpPort); } else { Logger.info("Listening for HTTP at %2$s:%1$s (Waiting a first request to start) ...", httpPort, address); } } else { if (address == null) { Logger.info("Listening for HTTP on port %s ...", httpPort); } else { Logger.info("Listening for HTTP at %2$s:%1$s ...", httpPort, address); } } } } catch (ChannelException e) { Logger.error("Could not bind on port " + httpPort, e); Play.fatalServerErrorOccurred(); } bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()) ); try { if (httpsPort != -1) { bootstrap.setPipelineFactory(new SslHttpServerPipelineFactory()); bootstrap.bind(new InetSocketAddress(secureAddress, httpsPort)); bootstrap.setOption("child.tcpNoDelay", true); if (Play.mode == Mode.DEV) { if (secureAddress == null) { Logger.info("Listening for HTTPS on port %s (Waiting a first request to start) ...", httpsPort); } else { Logger.info("Listening for HTTPS at %2$s:%1$s (Waiting a first request to start) ...", httpsPort, secureAddress); } } else { if (secureAddress == null) { Logger.info("Listening for HTTPS on port %s ...", httpsPort); } else { Logger.info("Listening for HTTPS at %2$s:%1$s ...", httpsPort, secureAddress); } } } } catch (ChannelException e) { Logger.error("Could not bind on port " + httpsPort, e); Play.fatalServerErrorOccurred(); } } private String getOpt(String[] args, String arg, String defaultValue) { String s = "--" + arg + "="; for (String a : args) { if (a.startsWith(s)) { return a.substring(s.length()); } } return defaultValue; } private static void writePID(File root) { String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; File pidfile = new File(root, PID_FILE); if (pidfile.exists()) { throw new RuntimeException("The " + PID_FILE + " already exists. Is the server already running?"); } IO.write(pid.getBytes(), pidfile); } public static void main(String[] args) throws Exception { File root = new File(System.getProperty("application.path")); if (System.getProperty("precompiled", "false").equals("true")) { Play.usePrecompiled = true; } if (System.getProperty("writepid", "false").equals("true")) { writePID(root); } Play.init(root, System.getProperty("play.id", "")); if (System.getProperty("precompile") == null) { new Server(args); } else { Logger.info("Done."); } } }