rack 1.6.11 → 2.2.0
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/CHANGELOG.md +675 -0
- data/CONTRIBUTING.md +136 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +157 -163
- data/Rakefile +38 -32
- data/{SPEC → SPEC.rdoc} +41 -13
- data/bin/rackup +1 -0
- data/contrib/rack_logo.svg +164 -111
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +4 -2
- data/example/protectedlobster.ru +3 -1
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +6 -2
- data/lib/rack/auth/basic.rb +7 -4
- data/lib/rack/auth/digest/md5.rb +13 -11
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +5 -4
- data/lib/rack/auth/digest/request.rb +6 -4
- data/lib/rack/body_proxy.rb +21 -15
- data/lib/rack/builder.rb +119 -26
- data/lib/rack/cascade.rb +28 -12
- data/lib/rack/chunked.rb +70 -22
- data/lib/rack/common_logger.rb +80 -0
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -16
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +9 -8
- data/lib/rack/content_type.rb +5 -4
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +60 -70
- data/lib/rack/directory.rb +117 -85
- data/lib/rack/etag.rb +9 -7
- data/lib/rack/events.rb +153 -0
- data/lib/rack/file.rb +4 -149
- data/lib/rack/files.rb +218 -0
- data/lib/rack/handler/cgi.rb +17 -19
- data/lib/rack/handler/fastcgi.rb +17 -18
- data/lib/rack/handler/lsws.rb +14 -14
- data/lib/rack/handler/scgi.rb +22 -21
- data/lib/rack/handler/thin.rb +20 -11
- data/lib/rack/handler/webrick.rb +39 -32
- data/lib/rack/handler.rb +9 -26
- data/lib/rack/head.rb +16 -18
- data/lib/rack/lint.rb +110 -64
- data/lib/rack/lobster.rb +10 -10
- data/lib/rack/lock.rb +17 -11
- data/lib/rack/logger.rb +4 -2
- data/lib/rack/media_type.rb +43 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
- data/lib/rack/mime.rb +27 -6
- data/lib/rack/mock.rb +124 -65
- data/lib/rack/multipart/generator.rb +20 -16
- data/lib/rack/multipart/parser.rb +273 -162
- data/lib/rack/multipart/uploaded_file.rb +15 -8
- data/lib/rack/multipart.rb +39 -8
- data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
- data/lib/rack/query_parser.rb +217 -0
- data/lib/rack/recursive.rb +11 -9
- data/lib/rack/reloader.rb +8 -4
- data/lib/rack/request.rb +543 -305
- data/lib/rack/response.rb +244 -88
- data/lib/rack/rewindable_input.rb +5 -15
- data/lib/rack/runtime.rb +12 -18
- data/lib/rack/sendfile.rb +17 -15
- data/lib/rack/server.rb +125 -47
- data/lib/rack/session/abstract/id.rb +216 -93
- data/lib/rack/session/cookie.rb +47 -31
- data/lib/rack/session/memcache.rb +4 -87
- data/lib/rack/session/pool.rb +26 -17
- data/lib/rack/show_exceptions.rb +390 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +8 -8
- data/lib/rack/static.rb +48 -11
- data/lib/rack/tempfile_reaper.rb +3 -3
- data/lib/rack/urlmap.rb +26 -19
- data/lib/rack/utils.rb +208 -294
- data/lib/rack/version.rb +29 -0
- data/lib/rack.rb +76 -33
- data/rack.gemspec +43 -30
- metadata +62 -183
- data/HISTORY.md +0 -375
- 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/commonlogger.rb +0 -72
- 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/builder/anything.rb +0 -5
- data/test/builder/comment.ru +0 -4
- data/test/builder/end.ru +0 -5
- data/test/builder/line.ru +0 -1
- data/test/builder/options.ru +0 -2
- data/test/cgi/assets/folder/test.js +0 -1
- data/test/cgi/assets/fonts/font.eot +0 -1
- data/test/cgi/assets/images/image.png +0 -1
- data/test/cgi/assets/index.html +0 -1
- data/test/cgi/assets/javascripts/app.js +0 -1
- data/test/cgi/assets/stylesheets/app.css +0 -1
- data/test/cgi/lighttpd.conf +0 -26
- data/test/cgi/rackup_stub.rb +0 -6
- data/test/cgi/sample_rackup.ru +0 -5
- data/test/cgi/test +0 -9
- data/test/cgi/test+directory/test+file +0 -1
- data/test/cgi/test.fcgi +0 -8
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- data/test/multipart/bad_robots +0 -259
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +0 -6
- data/test/multipart/empty +0 -10
- data/test/multipart/fail_16384_nofile +0 -814
- data/test/multipart/file1.txt +0 -1
- data/test/multipart/filename_and_modification_param +0 -7
- data/test/multipart/filename_and_no_name +0 -6
- data/test/multipart/filename_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
- data/test/multipart/filename_with_null_byte +0 -7
- data/test/multipart/filename_with_percent_escaped_quotes +0 -6
- data/test/multipart/filename_with_unescaped_percentages +0 -6
- data/test/multipart/filename_with_unescaped_percentages2 +0 -6
- data/test/multipart/filename_with_unescaped_percentages3 +0 -6
- data/test/multipart/filename_with_unescaped_quotes +0 -6
- data/test/multipart/ie +0 -6
- data/test/multipart/invalid_character +0 -6
- data/test/multipart/mixed_files +0 -21
- data/test/multipart/nested +0 -10
- data/test/multipart/none +0 -9
- data/test/multipart/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- data/test/multipart/webkit +0 -32
- data/test/rackup/config.ru +0 -31
- data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
- data/test/spec_auth_basic.rb +0 -81
- data/test/spec_auth_digest.rb +0 -259
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -223
- data/test/spec_cascade.rb +0 -61
- data/test/spec_cgi.rb +0 -102
- data/test/spec_chunked.rb +0 -101
- data/test/spec_commonlogger.rb +0 -93
- data/test/spec_conditionalget.rb +0 -102
- data/test/spec_config.rb +0 -22
- data/test/spec_content_length.rb +0 -85
- data/test/spec_content_type.rb +0 -45
- data/test/spec_deflater.rb +0 -339
- data/test/spec_directory.rb +0 -88
- data/test/spec_etag.rb +0 -107
- data/test/spec_fastcgi.rb +0 -107
- data/test/spec_file.rb +0 -221
- data/test/spec_handler.rb +0 -72
- data/test/spec_head.rb +0 -45
- data/test/spec_lint.rb +0 -550
- data/test/spec_lobster.rb +0 -58
- data/test/spec_lock.rb +0 -164
- data/test/spec_logger.rb +0 -23
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -297
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_multipart.rb +0 -600
- data/test/spec_nulllogger.rb +0 -20
- data/test/spec_recursive.rb +0 -72
- data/test/spec_request.rb +0 -1232
- data/test/spec_response.rb +0 -407
- data/test/spec_rewindable_input.rb +0 -118
- data/test/spec_runtime.rb +0 -49
- data/test/spec_sendfile.rb +0 -130
- data/test/spec_server.rb +0 -167
- data/test/spec_session_abstract_id.rb +0 -53
- data/test/spec_session_cookie.rb +0 -410
- data/test/spec_session_memcache.rb +0 -321
- data/test/spec_session_pool.rb +0 -209
- data/test/spec_showexceptions.rb +0 -98
- data/test/spec_showstatus.rb +0 -103
- data/test/spec_static.rb +0 -145
- data/test/spec_tempfile_reaper.rb +0 -63
- data/test/spec_thin.rb +0 -91
- data/test/spec_urlmap.rb +0 -236
- data/test/spec_utils.rb +0 -647
- data/test/spec_version.rb +0 -17
- data/test/spec_webrick.rb +0 -184
- data/test/static/another/index.html +0 -1
- data/test/static/index.html +0 -1
- data/test/testrequest.rb +0 -78
- data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/lib/rack/server.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
4
|
require 'fileutils'
|
3
5
|
|
4
|
-
|
5
6
|
module Rack
|
6
7
|
|
7
8
|
class Server
|
9
|
+
(require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
8
10
|
|
9
11
|
class Options
|
10
12
|
def parse!(args)
|
@@ -21,10 +23,6 @@ module Rack
|
|
21
23
|
lineno += 1
|
22
24
|
}
|
23
25
|
|
24
|
-
opts.on("-b", "--builder BUILDER_LINE", "evaluate a BUILDER_LINE of code as a builder script") { |line|
|
25
|
-
options[:builder] = line
|
26
|
-
}
|
27
|
-
|
28
26
|
opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
|
29
27
|
options[:debug] = true
|
30
28
|
}
|
@@ -42,12 +40,16 @@ module Rack
|
|
42
40
|
|
43
41
|
opts.on("-r", "--require LIBRARY",
|
44
42
|
"require the library, before executing your script") { |library|
|
45
|
-
options[:require]
|
43
|
+
(options[:require] ||= []) << library
|
46
44
|
}
|
47
45
|
|
48
46
|
opts.separator ""
|
49
47
|
opts.separator "Rack options:"
|
50
|
-
opts.on("-
|
48
|
+
opts.on("-b", "--builder BUILDER_LINE", "evaluate a BUILDER_LINE of code as a builder script") { |line|
|
49
|
+
options[:builder] = line
|
50
|
+
}
|
51
|
+
|
52
|
+
opts.on("-s", "--server SERVER", "serve using SERVER (thin/puma/webrick)") { |s|
|
51
53
|
options[:server] = s
|
52
54
|
}
|
53
55
|
|
@@ -77,6 +79,24 @@ module Rack
|
|
77
79
|
options[:pid] = ::File.expand_path(f)
|
78
80
|
}
|
79
81
|
|
82
|
+
opts.separator ""
|
83
|
+
opts.separator "Profiling options:"
|
84
|
+
|
85
|
+
opts.on("--heap HEAPFILE", "Build the application, then dump the heap to HEAPFILE") do |e|
|
86
|
+
options[:heapfile] = e
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on("--profile PROFILE", "Dump CPU or Memory profile to PROFILE (defaults to a tempfile)") do |e|
|
90
|
+
options[:profile_file] = e
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on("--profile-mode MODE", "Profile mode (cpu|wall|object)") do |e|
|
94
|
+
{ cpu: true, wall: true, object: true }.fetch(e.to_sym) do
|
95
|
+
raise OptionParser::InvalidOption, "unknown profile mode: #{e}"
|
96
|
+
end
|
97
|
+
options[:profile_mode] = e.to_sym
|
98
|
+
end
|
99
|
+
|
80
100
|
opts.separator ""
|
81
101
|
opts.separator "Common options:"
|
82
102
|
|
@@ -100,28 +120,28 @@ module Rack
|
|
100
120
|
abort opt_parser.to_s
|
101
121
|
end
|
102
122
|
|
103
|
-
options[:config] = args.last if args.last
|
123
|
+
options[:config] = args.last if args.last && !args.last.empty?
|
104
124
|
options
|
105
125
|
end
|
106
126
|
|
107
127
|
def handler_opts(options)
|
108
128
|
begin
|
109
129
|
info = []
|
110
|
-
server = Rack::Handler.get(options[:server]) || Rack::Handler.default
|
130
|
+
server = Rack::Handler.get(options[:server]) || Rack::Handler.default
|
111
131
|
if server && server.respond_to?(:valid_options)
|
112
132
|
info << ""
|
113
133
|
info << "Server-specific options for #{server.name}:"
|
114
134
|
|
115
135
|
has_options = false
|
116
136
|
server.valid_options.each do |name, description|
|
117
|
-
next if
|
137
|
+
next if /^(Host|Port)[^a-zA-Z]/.match?(name.to_s) # ignore handler's host and port options, we do our own.
|
118
138
|
info << " -O %-21s %s" % [name, description]
|
119
139
|
has_options = true
|
120
140
|
end
|
121
141
|
return "" if !has_options
|
122
142
|
end
|
123
143
|
info.join("\n")
|
124
|
-
rescue NameError
|
144
|
+
rescue NameError, LoadError
|
125
145
|
return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
|
126
146
|
end
|
127
147
|
end
|
@@ -152,7 +172,9 @@ module Rack
|
|
152
172
|
|
153
173
|
# Options may include:
|
154
174
|
# * :app
|
155
|
-
# a rack application to run (overrides :config)
|
175
|
+
# a rack application to run (overrides :config and :builder)
|
176
|
+
# * :builder
|
177
|
+
# a string to evaluate a Rack::Builder from
|
156
178
|
# * :config
|
157
179
|
# a rackup configuration file path to load (.ru)
|
158
180
|
# * :environment
|
@@ -182,13 +204,31 @@ module Rack
|
|
182
204
|
# add given paths to $LOAD_PATH
|
183
205
|
# * :require
|
184
206
|
# require the given libraries
|
207
|
+
#
|
208
|
+
# Additional options for profiling app initialization include:
|
209
|
+
# * :heapfile
|
210
|
+
# location for ObjectSpace.dump_all to write the output to
|
211
|
+
# * :profile_file
|
212
|
+
# location for CPU/Memory (StackProf) profile output (defaults to a tempfile)
|
213
|
+
# * :profile_mode
|
214
|
+
# StackProf profile mode (cpu|wall|object)
|
185
215
|
def initialize(options = nil)
|
186
|
-
@
|
187
|
-
|
216
|
+
@ignore_options = []
|
217
|
+
|
218
|
+
if options
|
219
|
+
@use_default_options = false
|
220
|
+
@options = options
|
221
|
+
@app = options[:app] if options[:app]
|
222
|
+
else
|
223
|
+
argv = defined?(SPEC_ARGV) ? SPEC_ARGV : ARGV
|
224
|
+
@use_default_options = true
|
225
|
+
@options = parse_options(argv)
|
226
|
+
end
|
188
227
|
end
|
189
228
|
|
190
229
|
def options
|
191
|
-
@
|
230
|
+
merged_options = @use_default_options ? default_options.merge(@options) : @options
|
231
|
+
merged_options.reject { |k, v| @ignore_options.include?(k) }
|
192
232
|
end
|
193
233
|
|
194
234
|
def default_options
|
@@ -196,12 +236,12 @@ module Rack
|
|
196
236
|
default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
|
197
237
|
|
198
238
|
{
|
199
|
-
:
|
200
|
-
:
|
201
|
-
:
|
202
|
-
:
|
203
|
-
:
|
204
|
-
:
|
239
|
+
environment: environment,
|
240
|
+
pid: nil,
|
241
|
+
Port: 9292,
|
242
|
+
Host: default_host,
|
243
|
+
AccessLog: [],
|
244
|
+
config: "config.ru"
|
205
245
|
}
|
206
246
|
end
|
207
247
|
|
@@ -212,21 +252,19 @@ module Rack
|
|
212
252
|
class << self
|
213
253
|
def logging_middleware
|
214
254
|
lambda { |server|
|
215
|
-
server.server.name
|
255
|
+
/CGI/.match?(server.server.name) || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]
|
216
256
|
}
|
217
257
|
end
|
218
258
|
|
219
259
|
def default_middleware_by_environment
|
220
|
-
m = Hash.new {|h,k| h[k] = []}
|
260
|
+
m = Hash.new {|h, k| h[k] = []}
|
221
261
|
m["deployment"] = [
|
222
262
|
[Rack::ContentLength],
|
223
|
-
[Rack::Chunked],
|
224
263
|
logging_middleware,
|
225
264
|
[Rack::TempfileReaper]
|
226
265
|
]
|
227
266
|
m["development"] = [
|
228
267
|
[Rack::ContentLength],
|
229
|
-
[Rack::Chunked],
|
230
268
|
logging_middleware,
|
231
269
|
[Rack::ShowExceptions],
|
232
270
|
[Rack::Lint],
|
@@ -245,7 +283,7 @@ module Rack
|
|
245
283
|
self.class.middleware
|
246
284
|
end
|
247
285
|
|
248
|
-
def start
|
286
|
+
def start(&block)
|
249
287
|
if options[:warn]
|
250
288
|
$-w = true
|
251
289
|
end
|
@@ -254,7 +292,7 @@ module Rack
|
|
254
292
|
$LOAD_PATH.unshift(*includes)
|
255
293
|
end
|
256
294
|
|
257
|
-
|
295
|
+
Array(options[:require]).each do |library|
|
258
296
|
require library
|
259
297
|
end
|
260
298
|
|
@@ -270,7 +308,9 @@ module Rack
|
|
270
308
|
|
271
309
|
# Touch the wrapped app, so that the config.ru is loaded before
|
272
310
|
# daemonization (i.e. before chdir, etc).
|
273
|
-
|
311
|
+
handle_profiling(options[:heapfile], options[:profile_mode], options[:profile_file]) do
|
312
|
+
wrapped_app
|
313
|
+
end
|
274
314
|
|
275
315
|
daemonize_app if options[:daemonize]
|
276
316
|
|
@@ -284,11 +324,20 @@ module Rack
|
|
284
324
|
end
|
285
325
|
end
|
286
326
|
|
287
|
-
server.run
|
327
|
+
server.run(wrapped_app, **options, &block)
|
288
328
|
end
|
289
329
|
|
290
330
|
def server
|
291
|
-
@_server ||= Rack::Handler.get(options[:server])
|
331
|
+
@_server ||= Rack::Handler.get(options[:server])
|
332
|
+
|
333
|
+
unless @_server
|
334
|
+
@_server = Rack::Handler.default
|
335
|
+
|
336
|
+
# We already speak FastCGI
|
337
|
+
@ignore_options = [:File, :Port] if @_server.to_s == 'Rack::Handler::FastCGI'
|
338
|
+
end
|
339
|
+
|
340
|
+
@_server
|
292
341
|
end
|
293
342
|
|
294
343
|
private
|
@@ -298,25 +347,61 @@ module Rack
|
|
298
347
|
end
|
299
348
|
|
300
349
|
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
301
|
-
|
350
|
+
@options.merge!(options) { |key, old, new| old }
|
302
351
|
app
|
303
352
|
end
|
304
353
|
|
354
|
+
def handle_profiling(heapfile, profile_mode, filename)
|
355
|
+
if heapfile
|
356
|
+
require "objspace"
|
357
|
+
ObjectSpace.trace_object_allocations_start
|
358
|
+
yield
|
359
|
+
GC.start
|
360
|
+
::File.open(heapfile, "w") { |f| ObjectSpace.dump_all(output: f) }
|
361
|
+
exit
|
362
|
+
end
|
363
|
+
|
364
|
+
if profile_mode
|
365
|
+
require "stackprof"
|
366
|
+
require "tempfile"
|
367
|
+
|
368
|
+
make_profile_name(filename) do |filename|
|
369
|
+
::File.open(filename, "w") do |f|
|
370
|
+
StackProf.run(mode: profile_mode, out: f) do
|
371
|
+
yield
|
372
|
+
end
|
373
|
+
puts "Profile written to: #{filename}"
|
374
|
+
end
|
375
|
+
end
|
376
|
+
exit
|
377
|
+
end
|
378
|
+
|
379
|
+
yield
|
380
|
+
end
|
381
|
+
|
382
|
+
def make_profile_name(filename)
|
383
|
+
if filename
|
384
|
+
yield filename
|
385
|
+
else
|
386
|
+
::Dir::Tmpname.create("profile.dump") do |tmpname, _, _|
|
387
|
+
yield tmpname
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
305
392
|
def build_app_from_string
|
306
393
|
Rack::Builder.new_from_string(self.options[:builder])
|
307
394
|
end
|
308
395
|
|
309
396
|
def parse_options(args)
|
310
|
-
options = default_options
|
311
|
-
|
312
397
|
# Don't evaluate CGI ISINDEX parameters.
|
313
398
|
# http://www.meb.uni-bonn.de/docs/cgi/cl.html
|
314
399
|
args.clear if ENV.include?(REQUEST_METHOD)
|
315
400
|
|
316
|
-
options
|
317
|
-
options[:config] = ::File.expand_path(options[:config])
|
401
|
+
@options = opt_parser.parse!(args)
|
402
|
+
@options[:config] = ::File.expand_path(options[:config])
|
318
403
|
ENV["RACK_ENV"] = options[:environment]
|
319
|
-
options
|
404
|
+
@options
|
320
405
|
end
|
321
406
|
|
322
407
|
def opt_parser
|
@@ -338,17 +423,10 @@ module Rack
|
|
338
423
|
end
|
339
424
|
|
340
425
|
def daemonize_app
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
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
|
426
|
+
# Cannot be covered as it forks
|
427
|
+
# :nocov:
|
428
|
+
Process.daemon
|
429
|
+
# :nocov:
|
352
430
|
end
|
353
431
|
|
354
432
|
def write_pid
|