8 opt_parser = OptionParser.new("", 24, ' ') do |opts|
9 opts.banner = "Usage: rackup [ruby options] [rack options] [rackup config]"
12 opts.separator "Ruby options:"
15 opts.on("-e", "--eval LINE", "evaluate a LINE of code") { |line|
16 eval line, TOPLEVEL_BINDING, "-e", lineno
20 opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
21 options[:debug] = true
23 opts.on("-w", "--warn", "turn warnings on for your script") {
27 opts.on("-I", "--include PATH",
28 "specify $LOAD_PATH (may be used more than once)") { |path|
29 options[:include] = path.split(":")
32 opts.on("-r", "--require LIBRARY",
33 "require the library, before executing your script") { |library|
34 options[:require] = library
38 opts.separator "Rack options:"
39 opts.on("-s", "--server SERVER", "serve using SERVER (webrick/mongrel)") { |s|
43 opts.on("-o", "--host HOST", "listen on HOST (default: 0.0.0.0)") { |host|
47 opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
51 opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
52 options[:environment] = e
55 opts.on("-D", "--daemonize", "run daemonized in the background") { |d|
56 options[:daemonize] = d ? true : false
59 opts.on("-P", "--pid FILE", "file to store PID (default: rack.pid)") { |f|
60 options[:pid] = ::File.expand_path(f, Dir.pwd)
64 opts.separator "Common options:"
66 opts.on_tail("-h", "--help", "Show this message") do
71 opts.on_tail("--version", "Show version") do
72 puts "Rack #{Rack.version}"
76 opt_parser.parse! args
77 options[:config] = args.last if args.last
86 attr_accessor :options
88 def initialize(options = nil)
93 @options ||= parse_options(ARGV)
98 :environment => "development",
103 :config => ::File.expand_path("config.ru", Dir.pwd)
109 if !::File.exist? options[:config]
110 abort "configuration #{options[:config]} not found"
113 app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
114 self.options.merge! options
120 @middleware ||= begin
121 m = Hash.new {|h,k| h[k] = []}
122 m["deployment"].concat [lambda {|server| server.server =~ /CGI/ ? nil : [Rack::CommonLogger, $stderr] }]
123 m["development"].concat m["deployment"] + [[Rack::ShowExceptions], [Rack::Lint]]
129 self.class.middleware
145 if includes = options[:include]
146 $LOAD_PATH.unshift *includes
149 if library = options[:require]
153 daemonize_app if options[:daemonize]
154 write_pid if options[:pid]
155 server.run wrapped_app, options
159 @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default
163 def parse_options(args)
164 options = default_options
166 # Don't evaluate CGI ISINDEX parameters.
167 # http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
168 args.clear if ENV.include?("REQUEST_METHOD")
170 options.merge! opt_parser.parse! args
179 middleware[options[:environment]].reverse_each do |middleware|
180 middleware = middleware.call(self) if middleware.respond_to?(:call)
181 next unless middleware
182 klass = middleware.shift
183 app = klass.new(app, *middleware)
189 @wrapped_app ||= build_app app
193 if RUBY_VERSION < "1.9"
199 STDIN.reopen "/dev/null"
200 STDOUT.reopen "/dev/null", "a"
201 STDERR.reopen "/dev/null", "a"
208 ::File.open(options[:pid], 'w'){ |f| f.write("#{Process.pid}") }
209 at_exit { ::File.delete(options[:pid]) if ::File.exist?(options[:pid]) }