lib/mizuno/http_server.rb in mizuno-0.4.1 vs lib/mizuno/http_server.rb in mizuno-0.5.0

- old
+ new

@@ -1,17 +1,22 @@ -# Have Jetty log to stdout for the time being. -java.lang.System.setProperty("org.eclipse.jetty.util.log.class", - "org.eclipse.jetty.util.log.StdErrLog") +require 'mizuno/version' +require 'mizuno/java_logger' module Mizuno class HttpServer + include_class 'java.util.Properties' + include_class 'java.io.ByteArrayInputStream' + include_class 'org.apache.log4j.PropertyConfigurator' include_class 'org.eclipse.jetty.server.Server' include_class 'org.eclipse.jetty.servlet.ServletContextHandler' include_class 'org.eclipse.jetty.servlet.ServletHolder' include_class 'org.eclipse.jetty.server.nio.SelectChannelConnector' include_class 'org.eclipse.jetty.util.thread.QueuedThreadPool' - include_class 'org.eclipse.jetty.servlet.DefaultServlet' +# include_class 'org.eclipse.jetty.servlet.DefaultServlet' +# include_class 'org.eclipse.jetty.server.handler.HandlerCollection' +# include_class 'org.eclipse.jetty.server.handler.RequestLogHandler' +# include_class 'org.eclipse.jetty.server.NCSARequestLog' # # Provide accessors so we can set a custom logger and a location # for static assets. # @@ -30,45 +35,68 @@ # # :port:: # String or integer with the port to bind to; defaults # to 9292. # - # FIXME: Clean up options hash (all downcase, all symbols) + # http://wiki.eclipse.org/Jetty/Tutorial/RequestLog # - def self.run(app, options = {}) + # FIXME: Add SSL suport. + # + def HttpServer.run(app, options = {}) + # Symbolize and downcase keys. + @options = options = Hash[options.map { |k, v| + [ k.to_s.downcase.to_sym, v ] }] + options[:quiet] ||= true if options[:embedded] + # The Jetty server + configure_logging(options) @server = Server.new + @server.setSendServerVersion(false) - options = Hash[options.map { |o| - [ o[0].to_s.downcase.to_sym, o[1] ] }] - # Thread pool + threads = options[:threads] || 50 thread_pool = QueuedThreadPool.new - thread_pool.min_threads = 5 - thread_pool.max_threads = 50 + thread_pool.min_threads = [ threads.to_i / 10, 5 ].max + thread_pool.max_threads = [ threads.to_i, 10 ].max @server.set_thread_pool(thread_pool) # Connector connector = SelectChannelConnector.new connector.setPort(options[:port].to_i) connector.setHost(options[:host]) @server.addConnector(connector) - # Servlet context. - context = ServletContextHandler.new(nil, "/", + # Switch to a different user or group if we were asked to. + Runner.setgid(options) if options[:group] + Runner.setuid(options) if options[:user] + + # Servlet handler. + app_handler = ServletContextHandler.new(nil, "/", ServletContextHandler::NO_SESSIONS) # The servlet itself. rack_servlet = RackServlet.new rack_servlet.rackup(app) holder = ServletHolder.new(rack_servlet) - context.addServlet(holder, "/") + app_handler.addServlet(holder, "/") +# # Our request log. +# request_log = NCSARequestLog.new +# request_log.setLogTimeZone("GMT") +# request_log_handler = RequestLogHandler.new +# request_log_handler.setRequestLog(request_log) +# +# # Add handlers in order. +# handlers = HandlerCollection.new +# handlers.addHandler(request_log_handler) +# handlers.addHandler(app_handler) + # Add the context to the server and start. - @server.set_handler(context) - puts "Listening on #{connector.getHost}:#{connector.getPort}" + @server.set_handler(app_handler) @server.start + $stderr.printf("%s listening on %s:%s\n", version, + connector.host, connector.port) unless options[:quiet] # If we're embeded, we're done. return if options[:embedded] # Stop the server when we get The Signal. @@ -81,13 +109,69 @@ end # # Shuts down an embedded Jetty instance. # - def self.stop + def HttpServer.stop return unless @server - puts "Stopping Jetty..." + $stderr.print "Stopping Jetty..." unless @options[:quiet] @server.stop + $stderr.puts "done." unless @options[:quiet] + end + + # + # Returns the full version string. + # + def HttpServer.version + "Mizuno #{Mizuno::VERSION} (Jetty #{Server.getVersion})" + end + + # + # Configure Log4J. + # + def HttpServer.configure_logging(options) + return if @logger + + # Default logging threshold. + limit = options[:warn] ? "WARN" : "ERROR" + limit = "DEBUG" if ($DEBUG or options[:debug]) + + # Base logging configuration. + config = <<-END + log4j.rootCategory = #{limit}, default + log4j.logger.org.eclipse.jetty.util.log = #{limit}, default + log4j.logger.ruby = INFO, ruby + log4j.appender.default.Threshold = #{limit} + log4j.appender.default.layout = org.apache.log4j.PatternLayout + log4j.appender.default.layout.ConversionPattern = %d %p %m + log4j.appender.ruby.Threshold = INFO + log4j.appender.ruby.layout = org.apache.log4j.PatternLayout + log4j.appender.ruby.layout.ConversionPattern = %m + END + + # Should we log to the console? + config.concat(<<-END) unless options[:log] + log4j.appender.default = org.apache.log4j.ConsoleAppender + log4j.appender.ruby = org.apache.log4j.ConsoleAppender + END + + # Are we logging to a file? + config.concat(<<-END) if options[:log] + log4j.appender.default = org.apache.log4j.FileAppender + log4j.appender.default.File = #{options[:log]} + log4j.appender.default.Append = true + log4j.appender.ruby = org.apache.log4j.FileAppender + log4j.appender.ruby.File = #{options[:log]} + log4j.appender.ruby.Append = true + END + + # Set up Log4J via Properties. + properties = Properties.new + properties.load(ByteArrayInputStream.new(config.to_java_bytes)) + PropertyConfigurator.configure(properties) + + # Use log4j for our logging as well. + @logger = JavaLogger.new end end end # Register ourselves with Rack when this file gets loaded.