rack 1.6.13 → 2.1.4.3
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 +92 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +105 -141
- data/Rakefile +27 -28
- data/SPEC +6 -7
- 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 +7 -1
- data/lib/rack/auth/basic.rb +4 -1
- data/lib/rack/auth/digest/md5.rb +9 -7
- 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 +3 -1
- data/lib/rack/body_proxy.rb +11 -9
- data/lib/rack/builder.rb +42 -18
- data/lib/rack/cascade.rb +6 -5
- data/lib/rack/chunked.rb +33 -10
- data/lib/rack/{commonlogger.rb → common_logger.rb} +14 -10
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +3 -1
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +5 -3
- data/lib/rack/content_type.rb +3 -1
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +33 -53
- data/lib/rack/directory.rb +75 -60
- data/lib/rack/etag.rb +8 -5
- data/lib/rack/events.rb +156 -0
- data/lib/rack/file.rb +4 -149
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler/cgi.rb +18 -17
- data/lib/rack/handler/fastcgi.rb +17 -16
- data/lib/rack/handler/lsws.rb +14 -12
- data/lib/rack/handler/scgi.rb +22 -19
- data/lib/rack/handler/thin.rb +6 -1
- data/lib/rack/handler/webrick.rb +28 -28
- data/lib/rack/handler.rb +9 -26
- data/lib/rack/head.rb +17 -17
- data/lib/rack/lint.rb +55 -52
- data/lib/rack/lobster.rb +8 -6
- data/lib/rack/lock.rb +17 -10
- 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 +101 -60
- data/lib/rack/multipart/generator.rb +11 -12
- data/lib/rack/multipart/parser.rb +292 -161
- data/lib/rack/multipart/uploaded_file.rb +3 -2
- data/lib/rack/multipart.rb +38 -8
- data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
- data/lib/rack/query_parser.rb +218 -0
- data/lib/rack/recursive.rb +11 -9
- data/lib/rack/reloader.rb +10 -4
- data/lib/rack/request.rb +447 -305
- data/lib/rack/response.rb +196 -83
- data/lib/rack/rewindable_input.rb +5 -14
- data/lib/rack/runtime.rb +12 -18
- data/lib/rack/sendfile.rb +19 -14
- data/lib/rack/server.rb +118 -41
- data/lib/rack/session/abstract/id.rb +139 -94
- data/lib/rack/session/cookie.rb +34 -26
- data/lib/rack/session/memcache.rb +4 -93
- data/lib/rack/session/pool.rb +12 -10
- data/lib/rack/show_exceptions.rb +392 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +7 -5
- data/lib/rack/static.rb +41 -11
- data/lib/rack/tempfile_reaper.rb +4 -2
- data/lib/rack/urlmap.rb +25 -15
- data/lib/rack/utils.rb +203 -277
- data/lib/rack.rb +76 -24
- data/rack.gemspec +25 -14
- 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/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 -358
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_session_pool.rb +0 -246
- 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,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
4
|
require 'fileutils'
|
3
5
|
|
6
|
+
require_relative 'core_ext/regexp'
|
4
7
|
|
5
8
|
module Rack
|
6
9
|
|
7
10
|
class Server
|
11
|
+
using ::Rack::RegexpExtensions
|
8
12
|
|
9
13
|
class Options
|
10
14
|
def parse!(args)
|
@@ -21,10 +25,6 @@ module Rack
|
|
21
25
|
lineno += 1
|
22
26
|
}
|
23
27
|
|
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
28
|
opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
|
29
29
|
options[:debug] = true
|
30
30
|
}
|
@@ -47,7 +47,11 @@ module Rack
|
|
47
47
|
|
48
48
|
opts.separator ""
|
49
49
|
opts.separator "Rack options:"
|
50
|
-
opts.on("-
|
50
|
+
opts.on("-b", "--builder BUILDER_LINE", "evaluate a BUILDER_LINE of code as a builder script") { |line|
|
51
|
+
options[:builder] = line
|
52
|
+
}
|
53
|
+
|
54
|
+
opts.on("-s", "--server SERVER", "serve using SERVER (thin/puma/webrick)") { |s|
|
51
55
|
options[:server] = s
|
52
56
|
}
|
53
57
|
|
@@ -77,6 +81,24 @@ module Rack
|
|
77
81
|
options[:pid] = ::File.expand_path(f)
|
78
82
|
}
|
79
83
|
|
84
|
+
opts.separator ""
|
85
|
+
opts.separator "Profiling options:"
|
86
|
+
|
87
|
+
opts.on("--heap HEAPFILE", "Build the application, then dump the heap to HEAPFILE") do |e|
|
88
|
+
options[:heapfile] = e
|
89
|
+
end
|
90
|
+
|
91
|
+
opts.on("--profile PROFILE", "Dump CPU or Memory profile to PROFILE (defaults to a tempfile)") do |e|
|
92
|
+
options[:profile_file] = e
|
93
|
+
end
|
94
|
+
|
95
|
+
opts.on("--profile-mode MODE", "Profile mode (cpu|wall|object)") do |e|
|
96
|
+
{ cpu: true, wall: true, object: true }.fetch(e.to_sym) do
|
97
|
+
raise OptionParser::InvalidOption, "unknown profile mode: #{e}"
|
98
|
+
end
|
99
|
+
options[:profile_mode] = e.to_sym
|
100
|
+
end
|
101
|
+
|
80
102
|
opts.separator ""
|
81
103
|
opts.separator "Common options:"
|
82
104
|
|
@@ -100,21 +122,21 @@ module Rack
|
|
100
122
|
abort opt_parser.to_s
|
101
123
|
end
|
102
124
|
|
103
|
-
options[:config] = args.last if args.last
|
125
|
+
options[:config] = args.last if args.last && !args.last.empty?
|
104
126
|
options
|
105
127
|
end
|
106
128
|
|
107
129
|
def handler_opts(options)
|
108
130
|
begin
|
109
131
|
info = []
|
110
|
-
server = Rack::Handler.get(options[:server]) || Rack::Handler.default
|
132
|
+
server = Rack::Handler.get(options[:server]) || Rack::Handler.default
|
111
133
|
if server && server.respond_to?(:valid_options)
|
112
134
|
info << ""
|
113
135
|
info << "Server-specific options for #{server.name}:"
|
114
136
|
|
115
137
|
has_options = false
|
116
138
|
server.valid_options.each do |name, description|
|
117
|
-
next if
|
139
|
+
next if /^(Host|Port)[^a-zA-Z]/.match?(name.to_s) # ignore handler's host and port options, we do our own.
|
118
140
|
info << " -O %-21s %s" % [name, description]
|
119
141
|
has_options = true
|
120
142
|
end
|
@@ -152,7 +174,9 @@ module Rack
|
|
152
174
|
|
153
175
|
# Options may include:
|
154
176
|
# * :app
|
155
|
-
# a rack application to run (overrides :config)
|
177
|
+
# a rack application to run (overrides :config and :builder)
|
178
|
+
# * :builder
|
179
|
+
# a string to evaluate a Rack::Builder from
|
156
180
|
# * :config
|
157
181
|
# a rackup configuration file path to load (.ru)
|
158
182
|
# * :environment
|
@@ -182,13 +206,31 @@ module Rack
|
|
182
206
|
# add given paths to $LOAD_PATH
|
183
207
|
# * :require
|
184
208
|
# require the given libraries
|
209
|
+
#
|
210
|
+
# Additional options for profiling app initialization include:
|
211
|
+
# * :heapfile
|
212
|
+
# location for ObjectSpace.dump_all to write the output to
|
213
|
+
# * :profile_file
|
214
|
+
# location for CPU/Memory (StackProf) profile output (defaults to a tempfile)
|
215
|
+
# * :profile_mode
|
216
|
+
# StackProf profile mode (cpu|wall|object)
|
185
217
|
def initialize(options = nil)
|
186
|
-
@
|
187
|
-
|
218
|
+
@ignore_options = []
|
219
|
+
|
220
|
+
if options
|
221
|
+
@use_default_options = false
|
222
|
+
@options = options
|
223
|
+
@app = options[:app] if options[:app]
|
224
|
+
else
|
225
|
+
argv = defined?(SPEC_ARGV) ? SPEC_ARGV : ARGV
|
226
|
+
@use_default_options = true
|
227
|
+
@options = parse_options(argv)
|
228
|
+
end
|
188
229
|
end
|
189
230
|
|
190
231
|
def options
|
191
|
-
@
|
232
|
+
merged_options = @use_default_options ? default_options.merge(@options) : @options
|
233
|
+
merged_options.reject { |k, v| @ignore_options.include?(k) }
|
192
234
|
end
|
193
235
|
|
194
236
|
def default_options
|
@@ -196,12 +238,12 @@ module Rack
|
|
196
238
|
default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
|
197
239
|
|
198
240
|
{
|
199
|
-
:
|
200
|
-
:
|
201
|
-
:
|
202
|
-
:
|
203
|
-
:
|
204
|
-
:
|
241
|
+
environment: environment,
|
242
|
+
pid: nil,
|
243
|
+
Port: 9292,
|
244
|
+
Host: default_host,
|
245
|
+
AccessLog: [],
|
246
|
+
config: "config.ru"
|
205
247
|
}
|
206
248
|
end
|
207
249
|
|
@@ -212,21 +254,19 @@ module Rack
|
|
212
254
|
class << self
|
213
255
|
def logging_middleware
|
214
256
|
lambda { |server|
|
215
|
-
server.server.name
|
257
|
+
/CGI/.match?(server.server.name) || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]
|
216
258
|
}
|
217
259
|
end
|
218
260
|
|
219
261
|
def default_middleware_by_environment
|
220
|
-
m = Hash.new {|h,k| h[k] = []}
|
262
|
+
m = Hash.new {|h, k| h[k] = []}
|
221
263
|
m["deployment"] = [
|
222
264
|
[Rack::ContentLength],
|
223
|
-
[Rack::Chunked],
|
224
265
|
logging_middleware,
|
225
266
|
[Rack::TempfileReaper]
|
226
267
|
]
|
227
268
|
m["development"] = [
|
228
269
|
[Rack::ContentLength],
|
229
|
-
[Rack::Chunked],
|
230
270
|
logging_middleware,
|
231
271
|
[Rack::ShowExceptions],
|
232
272
|
[Rack::Lint],
|
@@ -270,7 +310,9 @@ module Rack
|
|
270
310
|
|
271
311
|
# Touch the wrapped app, so that the config.ru is loaded before
|
272
312
|
# daemonization (i.e. before chdir, etc).
|
273
|
-
|
313
|
+
handle_profiling(options[:heapfile], options[:profile_mode], options[:profile_file]) do
|
314
|
+
wrapped_app
|
315
|
+
end
|
274
316
|
|
275
317
|
daemonize_app if options[:daemonize]
|
276
318
|
|
@@ -288,7 +330,16 @@ module Rack
|
|
288
330
|
end
|
289
331
|
|
290
332
|
def server
|
291
|
-
@_server ||= Rack::Handler.get(options[:server])
|
333
|
+
@_server ||= Rack::Handler.get(options[:server])
|
334
|
+
|
335
|
+
unless @_server
|
336
|
+
@_server = Rack::Handler.default
|
337
|
+
|
338
|
+
# We already speak FastCGI
|
339
|
+
@ignore_options = [:File, :Port] if @_server.to_s == 'Rack::Handler::FastCGI'
|
340
|
+
end
|
341
|
+
|
342
|
+
@_server
|
292
343
|
end
|
293
344
|
|
294
345
|
private
|
@@ -298,25 +349,61 @@ module Rack
|
|
298
349
|
end
|
299
350
|
|
300
351
|
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
301
|
-
|
352
|
+
@options.merge!(options) { |key, old, new| old }
|
302
353
|
app
|
303
354
|
end
|
304
355
|
|
356
|
+
def handle_profiling(heapfile, profile_mode, filename)
|
357
|
+
if heapfile
|
358
|
+
require "objspace"
|
359
|
+
ObjectSpace.trace_object_allocations_start
|
360
|
+
yield
|
361
|
+
GC.start
|
362
|
+
::File.open(heapfile, "w") { |f| ObjectSpace.dump_all(output: f) }
|
363
|
+
exit
|
364
|
+
end
|
365
|
+
|
366
|
+
if profile_mode
|
367
|
+
require "stackprof"
|
368
|
+
require "tempfile"
|
369
|
+
|
370
|
+
make_profile_name(filename) do |filename|
|
371
|
+
::File.open(filename, "w") do |f|
|
372
|
+
StackProf.run(mode: profile_mode, out: f) do
|
373
|
+
yield
|
374
|
+
end
|
375
|
+
puts "Profile written to: #{filename}"
|
376
|
+
end
|
377
|
+
end
|
378
|
+
exit
|
379
|
+
end
|
380
|
+
|
381
|
+
yield
|
382
|
+
end
|
383
|
+
|
384
|
+
def make_profile_name(filename)
|
385
|
+
if filename
|
386
|
+
yield filename
|
387
|
+
else
|
388
|
+
::Dir::Tmpname.create("profile.dump") do |tmpname, _, _|
|
389
|
+
yield tmpname
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
305
394
|
def build_app_from_string
|
306
395
|
Rack::Builder.new_from_string(self.options[:builder])
|
307
396
|
end
|
308
397
|
|
309
398
|
def parse_options(args)
|
310
|
-
options = default_options
|
311
|
-
|
312
399
|
# Don't evaluate CGI ISINDEX parameters.
|
313
400
|
# http://www.meb.uni-bonn.de/docs/cgi/cl.html
|
314
401
|
args.clear if ENV.include?(REQUEST_METHOD)
|
315
402
|
|
316
|
-
options
|
317
|
-
options[:config] = ::File.expand_path(options[:config])
|
403
|
+
@options = opt_parser.parse!(args)
|
404
|
+
@options[:config] = ::File.expand_path(options[:config])
|
318
405
|
ENV["RACK_ENV"] = options[:environment]
|
319
|
-
options
|
406
|
+
@options
|
320
407
|
end
|
321
408
|
|
322
409
|
def opt_parser
|
@@ -338,17 +425,7 @@ module Rack
|
|
338
425
|
end
|
339
426
|
|
340
427
|
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
|
428
|
+
Process.daemon
|
352
429
|
end
|
353
430
|
|
354
431
|
def write_pid
|