class Rackup::Server

def self.start(options = nil)

Further options available here are documented on Rack::Server#initialize

)
:server => 'cgi'
end,
[200, {'content-type' => 'text/html'}, ['hello world']]
:app => lambda do |e|
Rack::Server.start(

example:
This method can be used to very easily launch a CGI application, for

any default options.
Providing an options hash will prevent ARGV parsing and will not include

provide standard ARGV rackup options, defaulting to load 'config.ru'.
Start a new rack server (like running rackup). This will parse ARGV and
def self.start(options = nil)
  new(options).start
end

def app

def app
  @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
end

def build_app(app)

def build_app(app)
  middleware[options[:environment]].reverse_each do |middleware|
    middleware = middleware.call(self) if middleware.respond_to?(:call)
    next unless middleware
    klass, *args = middleware
    app = klass.new(app, *args)
  end
  app
end

def build_app_and_options_from_config

def build_app_and_options_from_config
  if !::File.exist? options[:config]
    abort "configuration #{options[:config]} not found"
  end
  return Rack::Builder.parse_file(self.options[:config])
end

def build_app_from_string

def build_app_from_string
  Rack::Builder.new_from_string(self.options[:builder])
end

def check_pid!

def check_pid!
  return unless ::File.exist?(options[:pid])
  pid = ::File.read(options[:pid]).to_i
  raise Errno::ESRCH if pid == 0
  Process.kill(0, pid)
  exit_with_pid(pid)
rescue Errno::ESRCH
  ::File.delete(options[:pid])
rescue Errno::EPERM
  exit_with_pid(pid)
end

def daemonize_app

def daemonize_app
  # Cannot be covered as it forks
  # :nocov:
  Process.daemon(true, options[:daemonize] == :noclose)
  # :nocov:
end

def default_middleware_by_environment

def default_middleware_by_environment
  m = Hash.new {|h, k| h[k] = []}
  m["deployment"] = [
    [Rack::ContentLength],
    logging_middleware,
    [Rack::TempfileReaper]
  ]
  m["development"] = [
    [Rack::ContentLength],
    logging_middleware,
    [Rack::ShowExceptions],
    [Rack::Lint],
    [Rack::TempfileReaper]
  ]
  m
end

def default_options

def default_options
  environment  = ENV['RACK_ENV'] || 'development'
  default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
  {
    environment: environment,
    pid: nil,
    Port: 9292,
    Host: default_host,
    AccessLog: [],
    config: "config.ru"
  }
end

def exit_with_pid(pid)

def exit_with_pid(pid)
  $stderr.puts "A server is already running (pid: #{pid}, file: #{options[:pid]})."
  exit(1)
end

def handle_profiling(heapfile, profile_mode, filename)

def handle_profiling(heapfile, profile_mode, filename)
  if heapfile
    require "objspace"
    ObjectSpace.trace_object_allocations_start
    yield
    GC.start
    ::File.open(heapfile, "w") { |f| ObjectSpace.dump_all(output: f) }
    exit
  end
  if profile_mode
    require "stackprof"
    require "tempfile"
    make_profile_name(filename) do |filename|
      ::File.open(filename, "w") do |f|
        StackProf.run(mode: profile_mode, out: f) do
          yield
        end
        puts "Profile written to: #{filename}"
      end
    end
    exit
  end
  yield
end

def initialize(options = nil)

StackProf profile mode (cpu|wall|object)
* :profile_mode
location for CPU/Memory (StackProf) profile output (defaults to a tempfile)
* :profile_file
location for ObjectSpace.dump_all to write the output to
* :heapfile
Additional options for profiling app initialization include:

require the given libraries
* :require
add given paths to $LOAD_PATH
* :include
turn on warnings ($-w = true)
* :warn
turn on debug output ($DEBUG = true)
* :debug
webrick access log options (or supporting Rackup::Handler)
* :AccessLog
the port to bind to (used by supporting Rackup::Handler)
* :Port
the host address to bind to (used by supporting Rackup::Handler)
* :Host
path to write a pid file after daemonize
* :pid
if :noclose, the server will not close STDOUT/STDERR
if truthy, the server will daemonize itself (fork, detach, etc)
* :daemonize
choose a specific Rackup::Handler, e.g. cgi, fcgi, webrick
* :server
note: when the server is a cgi server, CommonLogger is not included.
- none: no extra middleware
- deployment: CommonLogger
- development: CommonLogger, ShowExceptions, and Lint
your application. Default options available are:
this selects the middleware that will be wrapped around
* :environment
a rackup configuration file path to load (.ru)
* :config
a string to evaluate a Rack::Builder from
* :builder
a rack application to run (overrides :config and :builder)
* :app
Options may include:
def initialize(options = nil)
  @ignore_options = []
  if options
    @use_default_options = false
    @options = options
    @app = options[:app] if options[:app]
  else
    @use_default_options = true
    @options = parse_options(ARGV)
  end
end

def logging_middleware

def logging_middleware
  lambda { |server|
    /CGI/.match?(server.server.name) || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]
  }
end

def make_profile_name(filename)

def make_profile_name(filename)
  if filename
    yield filename
  else
    ::Dir::Tmpname.create("profile.dump") do |tmpname, _, _|
      yield tmpname
    end
  end
end

def middleware

def middleware
  default_middleware_by_environment
end

def middleware

def middleware
  self.class.middleware
end

def opt_parser

def opt_parser
  Options.new
end

def options

def options
  merged_options = @use_default_options ? default_options.merge(@options) : @options
  merged_options.reject { |k, v| @ignore_options.include?(k) }
end

def parse_options(args)

def parse_options(args)
  # Don't evaluate CGI ISINDEX parameters.
  args.clear if ENV.include?(Rack::REQUEST_METHOD)
  @options = opt_parser.parse!(args)
  @options[:config] = ::File.expand_path(options[:config])
  ENV["RACK_ENV"] = options[:environment]
  @options
end

def server

def server
  @_server ||= Handler.get(options[:server]) || Handler.default
end

def start(&block)

def start(&block)
  if options[:warn]
    $-w = true
  end
  if includes = options[:include]
    $LOAD_PATH.unshift(*includes)
  end
  Array(options[:require]).each do |library|
    require library
  end
  if options[:debug]
    $DEBUG = true
    require 'pp'
    p options[:server]
    pp wrapped_app
    pp app
  end
  check_pid! if options[:pid]
  # Touch the wrapped app, so that the config.ru is loaded before
  # daemonization (i.e. before chdir, etc).
  handle_profiling(options[:heapfile], options[:profile_mode], options[:profile_file]) do
    wrapped_app
  end
  daemonize_app if options[:daemonize]
  write_pid if options[:pid]
  trap(:INT) do
    if server.respond_to?(:shutdown)
      server.shutdown
    else
      exit
    end
  end
  server.run(wrapped_app, **options, &block)
end

def wrapped_app

def wrapped_app
  @wrapped_app ||= build_app app
end

def write_pid

def write_pid
  ::File.open(options[:pid], ::File::CREAT | ::File::EXCL | ::File::WRONLY ){ |f| f.write("#{Process.pid}") }
  at_exit { ::FileUtils.rm_f(options[:pid]) }
rescue Errno::EEXIST
  check_pid!
  retry
end