rack 1.6.13 → 2.0.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/COPYING +1 -1
- data/HISTORY.md +138 -8
- data/README.rdoc +18 -28
- data/Rakefile +6 -14
- data/SPEC +3 -3
- data/contrib/rack_logo.svg +164 -111
- data/example/protectedlobster.rb +1 -1
- data/example/protectedlobster.ru +1 -1
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/auth/digest/params.rb +2 -3
- data/lib/rack/auth/digest/request.rb +1 -1
- data/lib/rack/body_proxy.rb +14 -9
- data/lib/rack/builder.rb +3 -3
- data/lib/rack/chunked.rb +5 -5
- data/lib/rack/{commonlogger.rb → common_logger.rb} +3 -3
- data/lib/rack/content_length.rb +2 -2
- data/lib/rack/deflater.rb +4 -39
- data/lib/rack/directory.rb +66 -54
- data/lib/rack/etag.rb +5 -4
- data/lib/rack/events.rb +154 -0
- data/lib/rack/file.rb +64 -40
- data/lib/rack/handler/cgi.rb +15 -16
- data/lib/rack/handler/fastcgi.rb +13 -14
- data/lib/rack/handler/lsws.rb +11 -11
- data/lib/rack/handler/scgi.rb +15 -15
- data/lib/rack/handler/thin.rb +3 -0
- data/lib/rack/handler/webrick.rb +24 -26
- data/lib/rack/handler.rb +3 -25
- data/lib/rack/head.rb +15 -17
- data/lib/rack/lint.rb +40 -40
- data/lib/rack/lobster.rb +1 -1
- data/lib/rack/lock.rb +15 -10
- data/lib/rack/logger.rb +2 -2
- data/lib/rack/media_type.rb +38 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +6 -6
- data/lib/rack/mime.rb +18 -5
- data/lib/rack/mock.rb +36 -54
- data/lib/rack/multipart/generator.rb +5 -5
- data/lib/rack/multipart/parser.rb +270 -157
- data/lib/rack/multipart/uploaded_file.rb +1 -2
- data/lib/rack/multipart.rb +35 -6
- data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
- data/lib/rack/query_parser.rb +192 -0
- data/lib/rack/recursive.rb +8 -8
- data/lib/rack/request.rb +394 -305
- data/lib/rack/response.rb +130 -57
- data/lib/rack/rewindable_input.rb +1 -12
- data/lib/rack/runtime.rb +10 -18
- data/lib/rack/sendfile.rb +5 -7
- data/lib/rack/server.rb +30 -23
- data/lib/rack/session/abstract/id.rb +110 -75
- data/lib/rack/session/cookie.rb +24 -17
- data/lib/rack/session/memcache.rb +9 -9
- data/lib/rack/session/pool.rb +8 -8
- data/lib/rack/show_exceptions.rb +386 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
- data/lib/rack/static.rb +30 -5
- data/lib/rack/tempfile_reaper.rb +2 -2
- data/lib/rack/urlmap.rb +15 -14
- data/lib/rack/utils.rb +138 -211
- data/lib/rack.rb +70 -21
- data/rack.gemspec +10 -9
- data/test/builder/an_underscore_app.rb +5 -0
- data/test/builder/options.ru +1 -1
- data/test/cgi/test.fcgi +1 -0
- data/test/cgi/test.gz +0 -0
- data/test/helper.rb +34 -0
- data/test/multipart/filename_with_encoded_words +7 -0
- data/test/multipart/filename_with_single_quote +7 -0
- data/test/multipart/quoted +15 -0
- data/test/multipart/rack-logo.png +0 -0
- data/test/multipart/unity3d_wwwform +11 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
- data/test/spec_auth_basic.rb +27 -19
- data/test/spec_auth_digest.rb +47 -46
- data/test/spec_body_proxy.rb +27 -27
- data/test/spec_builder.rb +51 -41
- data/test/spec_cascade.rb +24 -22
- data/test/spec_cgi.rb +49 -67
- data/test/spec_chunked.rb +37 -35
- data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
- data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
- data/test/spec_config.rb +3 -2
- data/test/spec_content_length.rb +18 -17
- data/test/spec_content_type.rb +13 -12
- data/test/spec_deflater.rb +85 -49
- data/test/spec_directory.rb +87 -27
- data/test/spec_etag.rb +32 -31
- data/test/spec_events.rb +133 -0
- data/test/spec_fastcgi.rb +50 -72
- data/test/spec_file.rb +120 -77
- data/test/spec_handler.rb +19 -34
- data/test/spec_head.rb +15 -14
- data/test/spec_lint.rb +164 -199
- data/test/spec_lobster.rb +24 -23
- data/test/spec_lock.rb +79 -39
- data/test/spec_logger.rb +4 -3
- data/test/spec_media_type.rb +42 -0
- data/test/{spec_methodoverride.rb → spec_method_override.rb} +34 -35
- data/test/spec_mime.rb +19 -19
- data/test/spec_mock.rb +206 -144
- data/test/spec_multipart.rb +322 -200
- data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
- data/test/spec_recursive.rb +17 -14
- data/test/spec_request.rb +780 -605
- data/test/spec_response.rb +233 -112
- data/test/spec_rewindable_input.rb +50 -40
- data/test/spec_runtime.rb +11 -10
- data/test/spec_sendfile.rb +30 -35
- data/test/spec_server.rb +78 -52
- data/test/spec_session_abstract_id.rb +11 -33
- data/test/spec_session_abstract_session_hash.rb +45 -0
- data/test/spec_session_cookie.rb +99 -67
- data/test/spec_session_memcache.rb +67 -68
- data/test/spec_session_pool.rb +52 -51
- data/test/{spec_showexceptions.rb → spec_show_exceptions.rb} +23 -28
- data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
- data/test/spec_static.rb +71 -32
- data/test/spec_tempfile_reaper.rb +11 -10
- data/test/spec_thin.rb +55 -50
- data/test/spec_urlmap.rb +79 -78
- data/test/spec_utils.rb +441 -346
- data/test/spec_version.rb +2 -8
- data/test/spec_webrick.rb +93 -71
- data/test/static/foo.html +1 -0
- data/test/testrequest.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
- metadata +57 -36
- data/KNOWN-ISSUES +0 -44
- data/lib/rack/backports/uri/common_18.rb +0 -56
- data/lib/rack/backports/uri/common_192.rb +0 -52
- data/lib/rack/backports/uri/common_193.rb +0 -29
- data/lib/rack/handler/evented_mongrel.rb +0 -8
- data/lib/rack/handler/mongrel.rb +0 -106
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/showexceptions.rb +0 -387
- data/lib/rack/utils/okjson.rb +0 -600
- data/test/spec_mongrel.rb +0 -182
- /data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
data/lib/rack/response.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rack/request'
|
2
2
|
require 'rack/utils'
|
3
3
|
require 'rack/body_proxy'
|
4
|
+
require 'rack/media_type'
|
4
5
|
require 'time'
|
5
6
|
|
6
7
|
module Rack
|
@@ -8,7 +9,7 @@ module Rack
|
|
8
9
|
# response.
|
9
10
|
#
|
10
11
|
# It allows setting of headers and cookies, and provides useful
|
11
|
-
# defaults (
|
12
|
+
# defaults (an OK response with empty headers and body).
|
12
13
|
#
|
13
14
|
# You can use Response#write to iteratively generate your response,
|
14
15
|
# but note that this is buffered by Rack::Response until you call
|
@@ -18,15 +19,16 @@ module Rack
|
|
18
19
|
# Your application's +call+ should end returning Response#finish.
|
19
20
|
|
20
21
|
class Response
|
21
|
-
attr_accessor :length
|
22
|
+
attr_accessor :length, :status, :body
|
23
|
+
attr_reader :header
|
24
|
+
alias headers header
|
22
25
|
|
23
26
|
CHUNKED = 'chunked'.freeze
|
24
|
-
|
27
|
+
|
25
28
|
def initialize(body=[], status=200, header={})
|
26
29
|
@status = status.to_i
|
27
30
|
@header = Utils::HeaderHash.new.merge(header)
|
28
31
|
|
29
|
-
@chunked = CHUNKED == @header[TRANSFER_ENCODING]
|
30
32
|
@writer = lambda { |x| @body << x }
|
31
33
|
@block = nil
|
32
34
|
@length = 0
|
@@ -46,36 +48,21 @@ module Rack
|
|
46
48
|
yield self if block_given?
|
47
49
|
end
|
48
50
|
|
49
|
-
attr_reader :header
|
50
|
-
attr_accessor :status, :body
|
51
|
-
|
52
|
-
def [](key)
|
53
|
-
header[key]
|
54
|
-
end
|
55
|
-
|
56
|
-
def []=(key, value)
|
57
|
-
header[key] = value
|
58
|
-
end
|
59
|
-
|
60
|
-
def set_cookie(key, value)
|
61
|
-
Utils.set_cookie_header!(header, key, value)
|
62
|
-
end
|
63
|
-
|
64
|
-
def delete_cookie(key, value={})
|
65
|
-
Utils.delete_cookie_header!(header, key, value)
|
66
|
-
end
|
67
|
-
|
68
51
|
def redirect(target, status=302)
|
69
52
|
self.status = status
|
70
|
-
self
|
53
|
+
self.location = target
|
54
|
+
end
|
55
|
+
|
56
|
+
def chunked?
|
57
|
+
CHUNKED == get_header(TRANSFER_ENCODING)
|
71
58
|
end
|
72
59
|
|
73
60
|
def finish(&block)
|
74
61
|
@block = block
|
75
62
|
|
76
|
-
if [204,
|
77
|
-
|
78
|
-
|
63
|
+
if [204, 304].include?(status.to_i)
|
64
|
+
delete_header CONTENT_TYPE
|
65
|
+
delete_header CONTENT_LENGTH
|
79
66
|
close
|
80
67
|
[status.to_i, header, []]
|
81
68
|
else
|
@@ -97,10 +84,10 @@ module Rack
|
|
97
84
|
#
|
98
85
|
def write(str)
|
99
86
|
s = str.to_s
|
100
|
-
@length +=
|
87
|
+
@length += s.bytesize unless chunked?
|
101
88
|
@writer.call s
|
102
89
|
|
103
|
-
|
90
|
+
set_header(CONTENT_LENGTH, @length.to_s) unless chunked?
|
104
91
|
str
|
105
92
|
end
|
106
93
|
|
@@ -112,51 +99,137 @@ module Rack
|
|
112
99
|
@block == nil && @body.empty?
|
113
100
|
end
|
114
101
|
|
115
|
-
|
102
|
+
def has_header?(key); headers.key? key; end
|
103
|
+
def get_header(key); headers[key]; end
|
104
|
+
def set_header(key, v); headers[key] = v; end
|
105
|
+
def delete_header(key); headers.delete key; end
|
106
|
+
|
107
|
+
alias :[] :get_header
|
108
|
+
alias :[]= :set_header
|
116
109
|
|
117
110
|
module Helpers
|
118
|
-
def invalid?;
|
119
|
-
|
120
|
-
def informational?;
|
121
|
-
def successful?;
|
122
|
-
def redirection?;
|
123
|
-
def client_error?;
|
124
|
-
def server_error?;
|
125
|
-
|
126
|
-
def ok?;
|
127
|
-
def created?;
|
128
|
-
def accepted?;
|
129
|
-
def
|
130
|
-
def
|
131
|
-
def
|
132
|
-
def
|
133
|
-
def
|
134
|
-
def
|
135
|
-
def
|
136
|
-
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
attr_reader :headers, :original_headers
|
111
|
+
def invalid?; status < 100 || status >= 600; end
|
112
|
+
|
113
|
+
def informational?; status >= 100 && status < 200; end
|
114
|
+
def successful?; status >= 200 && status < 300; end
|
115
|
+
def redirection?; status >= 300 && status < 400; end
|
116
|
+
def client_error?; status >= 400 && status < 500; end
|
117
|
+
def server_error?; status >= 500 && status < 600; end
|
118
|
+
|
119
|
+
def ok?; status == 200; end
|
120
|
+
def created?; status == 201; end
|
121
|
+
def accepted?; status == 202; end
|
122
|
+
def no_content?; status == 204; end
|
123
|
+
def moved_permanently?; status == 301; end
|
124
|
+
def bad_request?; status == 400; end
|
125
|
+
def unauthorized?; status == 401; end
|
126
|
+
def forbidden?; status == 403; end
|
127
|
+
def not_found?; status == 404; end
|
128
|
+
def method_not_allowed?; status == 405; end
|
129
|
+
def precondition_failed?; status == 412; end
|
130
|
+
def unprocessable?; status == 422; end
|
131
|
+
|
132
|
+
def redirect?; [301, 302, 303, 307, 308].include? status; end
|
141
133
|
|
142
134
|
def include?(header)
|
143
|
-
|
135
|
+
has_header? header
|
136
|
+
end
|
137
|
+
|
138
|
+
# Add a header that may have multiple values.
|
139
|
+
#
|
140
|
+
# Example:
|
141
|
+
# response.add_header 'Vary', 'Accept-Encoding'
|
142
|
+
# response.add_header 'Vary', 'Cookie'
|
143
|
+
#
|
144
|
+
# assert_equal 'Accept-Encoding,Cookie', response.get_header('Vary')
|
145
|
+
#
|
146
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
|
147
|
+
def add_header key, v
|
148
|
+
if v.nil?
|
149
|
+
get_header key
|
150
|
+
elsif has_header? key
|
151
|
+
set_header key, "#{get_header key},#{v}"
|
152
|
+
else
|
153
|
+
set_header key, v
|
154
|
+
end
|
144
155
|
end
|
145
156
|
|
146
157
|
def content_type
|
147
|
-
|
158
|
+
get_header CONTENT_TYPE
|
159
|
+
end
|
160
|
+
|
161
|
+
def media_type
|
162
|
+
MediaType.type(content_type)
|
163
|
+
end
|
164
|
+
|
165
|
+
def media_type_params
|
166
|
+
MediaType.params(content_type)
|
148
167
|
end
|
149
168
|
|
150
169
|
def content_length
|
151
|
-
cl =
|
170
|
+
cl = get_header CONTENT_LENGTH
|
152
171
|
cl ? cl.to_i : cl
|
153
172
|
end
|
154
173
|
|
155
174
|
def location
|
156
|
-
|
175
|
+
get_header "Location"
|
176
|
+
end
|
177
|
+
|
178
|
+
def location=(location)
|
179
|
+
set_header "Location", location
|
180
|
+
end
|
181
|
+
|
182
|
+
def set_cookie(key, value)
|
183
|
+
cookie_header = get_header SET_COOKIE
|
184
|
+
set_header SET_COOKIE, ::Rack::Utils.add_cookie_to_header(cookie_header, key, value)
|
185
|
+
end
|
186
|
+
|
187
|
+
def delete_cookie(key, value={})
|
188
|
+
set_header SET_COOKIE, ::Rack::Utils.add_remove_cookie_to_header(get_header(SET_COOKIE), key, value)
|
189
|
+
end
|
190
|
+
|
191
|
+
def set_cookie_header
|
192
|
+
get_header SET_COOKIE
|
193
|
+
end
|
194
|
+
|
195
|
+
def set_cookie_header= v
|
196
|
+
set_header SET_COOKIE, v
|
197
|
+
end
|
198
|
+
|
199
|
+
def cache_control
|
200
|
+
get_header CACHE_CONTROL
|
201
|
+
end
|
202
|
+
|
203
|
+
def cache_control= v
|
204
|
+
set_header CACHE_CONTROL, v
|
205
|
+
end
|
206
|
+
|
207
|
+
def etag
|
208
|
+
get_header ETAG
|
209
|
+
end
|
210
|
+
|
211
|
+
def etag= v
|
212
|
+
set_header ETAG, v
|
157
213
|
end
|
158
214
|
end
|
159
215
|
|
160
216
|
include Helpers
|
217
|
+
|
218
|
+
class Raw
|
219
|
+
include Helpers
|
220
|
+
|
221
|
+
attr_reader :headers
|
222
|
+
attr_accessor :status
|
223
|
+
|
224
|
+
def initialize status, headers
|
225
|
+
@status = status
|
226
|
+
@headers = headers
|
227
|
+
end
|
228
|
+
|
229
|
+
def has_header?(key); headers.key? key; end
|
230
|
+
def get_header(key); headers[key]; end
|
231
|
+
def set_header(key, v); headers[key] = v; end
|
232
|
+
def delete_header(key); headers.delete key; end
|
233
|
+
end
|
161
234
|
end
|
162
235
|
end
|
@@ -57,15 +57,6 @@ module Rack
|
|
57
57
|
|
58
58
|
private
|
59
59
|
|
60
|
-
# Ruby's Tempfile class has a bug. Subclass it and fix it.
|
61
|
-
class Tempfile < ::Tempfile
|
62
|
-
def _close
|
63
|
-
@tmpfile.close if @tmpfile
|
64
|
-
@data[1] = nil if @data
|
65
|
-
@tmpfile = nil
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
60
|
def make_rewindable
|
70
61
|
# Buffer all data into a tempfile. Since this tempfile is private to this
|
71
62
|
# RewindableInput object, we chmod it so that nobody else can read or write
|
@@ -77,8 +68,6 @@ module Rack
|
|
77
68
|
@rewindable_io.set_encoding(Encoding::BINARY) if @rewindable_io.respond_to?(:set_encoding)
|
78
69
|
@rewindable_io.binmode
|
79
70
|
if filesystem_has_posix_semantics?
|
80
|
-
# Use ::File.unlink as 1.9.1 Tempfile has a bug where unlink closes the file!
|
81
|
-
::File.unlink @rewindable_io.path
|
82
71
|
raise 'Unlink failed. IO closed.' if @rewindable_io.closed?
|
83
72
|
@unlinked = true
|
84
73
|
end
|
@@ -88,7 +77,7 @@ module Rack
|
|
88
77
|
entire_buffer_written_out = false
|
89
78
|
while !entire_buffer_written_out
|
90
79
|
written = @rewindable_io.write(buffer)
|
91
|
-
entire_buffer_written_out = written ==
|
80
|
+
entire_buffer_written_out = written == buffer.bytesize
|
92
81
|
if !entire_buffer_written_out
|
93
82
|
buffer.slice!(0 .. written - 1)
|
94
83
|
end
|
data/lib/rack/runtime.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rack/utils'
|
2
|
+
|
1
3
|
module Rack
|
2
4
|
# Sets an "X-Runtime" response header, indicating the response
|
3
5
|
# time of the request, in seconds
|
@@ -6,35 +8,25 @@ module Rack
|
|
6
8
|
# time, or before all the other middlewares to include time for them,
|
7
9
|
# too.
|
8
10
|
class Runtime
|
11
|
+
FORMAT_STRING = "%0.6f".freeze # :nodoc:
|
12
|
+
HEADER_NAME = "X-Runtime".freeze # :nodoc:
|
13
|
+
|
9
14
|
def initialize(app, name = nil)
|
10
15
|
@app = app
|
11
|
-
@header_name =
|
12
|
-
@header_name
|
16
|
+
@header_name = HEADER_NAME
|
17
|
+
@header_name += "-#{name}" if name
|
13
18
|
end
|
14
19
|
|
15
|
-
FORMAT_STRING = "%0.6f"
|
16
20
|
def call(env)
|
17
|
-
start_time = clock_time
|
21
|
+
start_time = Utils.clock_time
|
18
22
|
status, headers, body = @app.call(env)
|
19
|
-
request_time = clock_time - start_time
|
23
|
+
request_time = Utils.clock_time - start_time
|
20
24
|
|
21
|
-
|
25
|
+
unless headers.has_key?(@header_name)
|
22
26
|
headers[@header_name] = FORMAT_STRING % request_time
|
23
27
|
end
|
24
28
|
|
25
29
|
[status, headers, body]
|
26
30
|
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
if defined?(Process::CLOCK_MONOTONIC)
|
31
|
-
def clock_time
|
32
|
-
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
33
|
-
end
|
34
|
-
else
|
35
|
-
def clock_time
|
36
|
-
Time.now.to_f
|
37
|
-
end
|
38
|
-
end
|
39
31
|
end
|
40
32
|
end
|
data/lib/rack/sendfile.rb
CHANGED
@@ -99,8 +99,6 @@ module Rack
|
|
99
99
|
# will be matched with case indifference.
|
100
100
|
|
101
101
|
class Sendfile
|
102
|
-
F = ::File
|
103
|
-
|
104
102
|
def initialize(app, variation=nil, mappings=[])
|
105
103
|
@app = app
|
106
104
|
@variation = variation
|
@@ -114,7 +112,7 @@ module Rack
|
|
114
112
|
if body.respond_to?(:to_path)
|
115
113
|
case type = variation(env)
|
116
114
|
when 'X-Accel-Redirect'
|
117
|
-
path =
|
115
|
+
path = ::File.expand_path(body.to_path)
|
118
116
|
if url = map_accel_path(env, path)
|
119
117
|
headers[CONTENT_LENGTH] = '0'
|
120
118
|
headers[type] = url
|
@@ -123,10 +121,10 @@ module Rack
|
|
123
121
|
obody.close if obody.respond_to?(:close)
|
124
122
|
end
|
125
123
|
else
|
126
|
-
env[
|
124
|
+
env[RACK_ERRORS].puts "X-Accel-Mapping header missing"
|
127
125
|
end
|
128
126
|
when 'X-Sendfile', 'X-Lighttpd-Send-File'
|
129
|
-
path =
|
127
|
+
path = ::File.expand_path(body.to_path)
|
130
128
|
headers[CONTENT_LENGTH] = '0'
|
131
129
|
headers[type] = path
|
132
130
|
obody = body
|
@@ -135,7 +133,7 @@ module Rack
|
|
135
133
|
end
|
136
134
|
when '', nil
|
137
135
|
else
|
138
|
-
env[
|
136
|
+
env[RACK_ERRORS].puts "Unknown x-sendfile variation: '#{type}'.\n"
|
139
137
|
end
|
140
138
|
end
|
141
139
|
[status, headers, body]
|
@@ -152,7 +150,7 @@ module Rack
|
|
152
150
|
if mapping = @mappings.find { |internal,_| internal =~ path }
|
153
151
|
path.sub(*mapping)
|
154
152
|
elsif mapping = env['HTTP_X_ACCEL_MAPPING']
|
155
|
-
internal, external = mapping.split('=', 2).map
|
153
|
+
internal, external = mapping.split('=', 2).map(&:strip)
|
156
154
|
path.sub(/^#{internal}/i, external)
|
157
155
|
end
|
158
156
|
end
|
data/lib/rack/server.rb
CHANGED
@@ -100,14 +100,14 @@ module Rack
|
|
100
100
|
abort opt_parser.to_s
|
101
101
|
end
|
102
102
|
|
103
|
-
options[:config] = args.last if args.last
|
103
|
+
options[:config] = args.last if args.last && !args.last.empty?
|
104
104
|
options
|
105
105
|
end
|
106
106
|
|
107
107
|
def handler_opts(options)
|
108
108
|
begin
|
109
109
|
info = []
|
110
|
-
server = Rack::Handler.get(options[:server]) || Rack::Handler.default
|
110
|
+
server = Rack::Handler.get(options[:server]) || Rack::Handler.default
|
111
111
|
if server && server.respond_to?(:valid_options)
|
112
112
|
info << ""
|
113
113
|
info << "Server-specific options for #{server.name}:"
|
@@ -183,12 +183,22 @@ module Rack
|
|
183
183
|
# * :require
|
184
184
|
# require the given libraries
|
185
185
|
def initialize(options = nil)
|
186
|
-
@
|
187
|
-
|
186
|
+
@ignore_options = []
|
187
|
+
|
188
|
+
if options
|
189
|
+
@use_default_options = false
|
190
|
+
@options = options
|
191
|
+
@app = options[:app] if options[:app]
|
192
|
+
else
|
193
|
+
argv = defined?(SPEC_ARGV) ? SPEC_ARGV : ARGV
|
194
|
+
@use_default_options = true
|
195
|
+
@options = parse_options(argv)
|
196
|
+
end
|
188
197
|
end
|
189
198
|
|
190
199
|
def options
|
191
|
-
@
|
200
|
+
merged_options = @use_default_options ? default_options.merge(@options) : @options
|
201
|
+
merged_options.reject { |k, v| @ignore_options.include?(k) }
|
192
202
|
end
|
193
203
|
|
194
204
|
def default_options
|
@@ -288,7 +298,16 @@ module Rack
|
|
288
298
|
end
|
289
299
|
|
290
300
|
def server
|
291
|
-
@_server ||= Rack::Handler.get(options[:server])
|
301
|
+
@_server ||= Rack::Handler.get(options[:server])
|
302
|
+
|
303
|
+
unless @_server
|
304
|
+
@_server = Rack::Handler.default
|
305
|
+
|
306
|
+
# We already speak FastCGI
|
307
|
+
@ignore_options = [:File, :Port] if @_server.to_s == 'Rack::Handler::FastCGI'
|
308
|
+
end
|
309
|
+
|
310
|
+
@_server
|
292
311
|
end
|
293
312
|
|
294
313
|
private
|
@@ -298,7 +317,7 @@ module Rack
|
|
298
317
|
end
|
299
318
|
|
300
319
|
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
301
|
-
|
320
|
+
@options.merge!(options) { |key, old, new| old }
|
302
321
|
app
|
303
322
|
end
|
304
323
|
|
@@ -307,16 +326,14 @@ module Rack
|
|
307
326
|
end
|
308
327
|
|
309
328
|
def parse_options(args)
|
310
|
-
options = default_options
|
311
|
-
|
312
329
|
# Don't evaluate CGI ISINDEX parameters.
|
313
330
|
# http://www.meb.uni-bonn.de/docs/cgi/cl.html
|
314
331
|
args.clear if ENV.include?(REQUEST_METHOD)
|
315
332
|
|
316
|
-
options
|
317
|
-
options[:config] = ::File.expand_path(options[:config])
|
333
|
+
@options = opt_parser.parse!(args)
|
334
|
+
@options[:config] = ::File.expand_path(options[:config])
|
318
335
|
ENV["RACK_ENV"] = options[:environment]
|
319
|
-
options
|
336
|
+
@options
|
320
337
|
end
|
321
338
|
|
322
339
|
def opt_parser
|
@@ -338,17 +355,7 @@ module Rack
|
|
338
355
|
end
|
339
356
|
|
340
357
|
def daemonize_app
|
341
|
-
|
342
|
-
exit if fork
|
343
|
-
Process.setsid
|
344
|
-
exit if fork
|
345
|
-
Dir.chdir "/"
|
346
|
-
STDIN.reopen "/dev/null"
|
347
|
-
STDOUT.reopen "/dev/null", "a"
|
348
|
-
STDERR.reopen "/dev/null", "a"
|
349
|
-
else
|
350
|
-
Process.daemon
|
351
|
-
end
|
358
|
+
Process.daemon
|
352
359
|
end
|
353
360
|
|
354
361
|
def write_pid
|