Skip to content

Commit e6a07b6

Browse files
committed
Implemented handler-specific options in a way that allows them to be retrieved and used from rackup or any other user of Rack::Server.
- Rack handlers that can accept options can now provide a valid_options method that returns a hash of options that can be passed to the handler. - If the hash contains Host or Port, they will be ignored for display by Rack::Server. - Options can be passed in with -O or --option followed by optname=value, or just optname if the option is binary. - rackup -h will display options for the default handler, and rackup -s SERVERNAME -h will display the options for SERVERNAME.
1 parent 996e8cb commit e6a07b6

File tree

6 files changed

+76
-2
lines changed

6 files changed

+76
-2
lines changed

lib/rack/handler/fastcgi.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ def self.run(app, options={})
2828
serve request, app
2929
}
3030
end
31+
32+
def self.valid_options
33+
{
34+
"Host=HOST" => "Hostname to listen on (default: localhost)",
35+
"Port=PORT" => "Port to listen on (default: 8080)",
36+
"File=PATH" => "Creates a Domain socket at PATH instead of a TCP socket. Ignores Host and Port if set.",
37+
}
38+
end
3139

3240
def self.serve(request, app)
3341
env = request.env

lib/rack/handler/mongrel.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,20 @@ def self.run(app, options={})
3838
server.run.join
3939
end
4040

41+
def self.valid_options
42+
{
43+
"Host=HOST" => "Hostname to listen on (default: localhost)",
44+
"Port=PORT" => "Port to listen on (default: 8080)",
45+
"Processors=N" => "Number of concurrent processors to accept (default: 950)",
46+
"Timeout=N" => "Time before a request is dropped for inactivity (default: 60)",
47+
"Throttle=N" => "Throttle time between socket.accept calls in hundredths of a second (default: 0)",
48+
}
49+
end
50+
4151
def initialize(app)
4252
@app = app
4353
end
44-
54+
4555
def process(request, response)
4656
env = {}.replace(request.params)
4757
env.delete "HTTP_CONTENT_TYPE"

lib/rack/handler/scgi.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,19 @@ class SCGI < ::SCGI::Processor
99
attr_accessor :app
1010

1111
def self.run(app, options=nil)
12+
options[:Socket] = UNIXServer.new(options[:File]) if options[:File]
1213
new(options.merge(:app=>app,
1314
:host=>options[:Host],
1415
:port=>options[:Port],
1516
:socket=>options[:Socket])).listen
1617
end
18+
19+
def self.valid_options
20+
{
21+
"Host=HOST" => "Hostname to listen on (default: localhost)",
22+
"Port=PORT" => "Port to listen on (default: 8080)",
23+
}
24+
end
1725

1826
def initialize(settings = {})
1927
@app = settings[:app]

lib/rack/handler/thin.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ def self.run(app, options={})
1212
yield server if block_given?
1313
server.start
1414
end
15+
16+
def self.valid_options
17+
{
18+
"Host=HOST" => "Hostname to listen on (default: localhost)",
19+
"Port=PORT" => "Port to listen on (default: 8080)",
20+
}
21+
end
1522
end
1623
end
1724
end

lib/rack/handler/webrick.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ def self.run(app, options={})
1212
yield @server if block_given?
1313
@server.start
1414
end
15+
16+
def self.valid_options
17+
{
18+
"Host=HOST" => "Hostname to listen on (default: localhost)",
19+
"Port=PORT" => "Port to listen on (default: 8080)",
20+
}
21+
end
1522

1623
def self.shutdown
1724
@server.shutdown

lib/rack/server.rb

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
module Rack
44
class Server
55
class Options
6+
def initialize(server)
7+
@server = server
8+
end
9+
610
def parse!(args)
711
options = {}
812
opt_parser = OptionParser.new("", 24, ' ') do |opts|
@@ -47,6 +51,12 @@ def parse!(args)
4751
opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
4852
options[:Port] = port
4953
}
54+
55+
opts.on("-O", "--option NAME[=VALUE]", "pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '#{$0} -s SERVER -h' to get a list of options for SERVER") { |name|
56+
name, value = name.split('=', 2)
57+
value = true if value.nil?
58+
options[name.to_sym] = value
59+
}
5060

5161
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
5262
options[:environment] = e
@@ -65,6 +75,8 @@ def parse!(args)
6575

6676
opts.on_tail("-h", "--help", "Show this message") do
6777
puts opts
78+
puts handler_opts(options)
79+
6880
exit
6981
end
7082

@@ -77,6 +89,28 @@ def parse!(args)
7789
options[:config] = args.last if args.last
7890
options
7991
end
92+
93+
def handler_opts(options)
94+
begin
95+
info = []
96+
server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
97+
if server && server.respond_to?(:valid_options)
98+
info << ""
99+
info << "Server-specific options for #{server.name}:"
100+
101+
has_options = false
102+
server.valid_options.each do |name, description|
103+
next if name.to_s.match(/^(Host|Port)[^a-zA-Z]/) # ignore handler's host and port options, we do our own.
104+
info << " -O %-21s %s" % [name, description]
105+
has_options = true
106+
end
107+
return "" if !has_options
108+
end
109+
info.join("\n")
110+
rescue NameError
111+
return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
112+
end
113+
end
80114
end
81115

82116
# Start a new rack server (like running rackup). This will parse ARGV and
@@ -242,7 +276,7 @@ def parse_options(args)
242276
end
243277

244278
def opt_parser
245-
Options.new
279+
Options.new(self)
246280
end
247281

248282
def build_app(app)

0 commit comments

Comments
 (0)