rack 2.1.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +377 -16
  3. data/CONTRIBUTING.md +144 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +328 -0
  6. data/SPEC.rdoc +365 -0
  7. data/lib/rack/auth/abstract/handler.rb +3 -1
  8. data/lib/rack/auth/abstract/request.rb +2 -2
  9. data/lib/rack/auth/basic.rb +4 -7
  10. data/lib/rack/bad_request.rb +8 -0
  11. data/lib/rack/body_proxy.rb +34 -12
  12. data/lib/rack/builder.rb +162 -59
  13. data/lib/rack/cascade.rb +24 -10
  14. data/lib/rack/common_logger.rb +43 -28
  15. data/lib/rack/conditional_get.rb +30 -25
  16. data/lib/rack/constants.rb +66 -0
  17. data/lib/rack/content_length.rb +10 -16
  18. data/lib/rack/content_type.rb +9 -7
  19. data/lib/rack/deflater.rb +78 -50
  20. data/lib/rack/directory.rb +86 -63
  21. data/lib/rack/etag.rb +14 -22
  22. data/lib/rack/events.rb +18 -17
  23. data/lib/rack/files.rb +99 -61
  24. data/lib/rack/head.rb +8 -9
  25. data/lib/rack/headers.rb +238 -0
  26. data/lib/rack/lint.rb +868 -642
  27. data/lib/rack/lock.rb +2 -6
  28. data/lib/rack/logger.rb +3 -0
  29. data/lib/rack/media_type.rb +9 -4
  30. data/lib/rack/method_override.rb +6 -2
  31. data/lib/rack/mime.rb +14 -5
  32. data/lib/rack/mock.rb +1 -253
  33. data/lib/rack/mock_request.rb +171 -0
  34. data/lib/rack/mock_response.rb +124 -0
  35. data/lib/rack/multipart/generator.rb +15 -8
  36. data/lib/rack/multipart/parser.rb +238 -107
  37. data/lib/rack/multipart/uploaded_file.rb +17 -7
  38. data/lib/rack/multipart.rb +54 -42
  39. data/lib/rack/null_logger.rb +9 -0
  40. data/lib/rack/query_parser.rb +87 -105
  41. data/lib/rack/recursive.rb +3 -1
  42. data/lib/rack/reloader.rb +0 -4
  43. data/lib/rack/request.rb +366 -135
  44. data/lib/rack/response.rb +186 -68
  45. data/lib/rack/rewindable_input.rb +24 -6
  46. data/lib/rack/runtime.rb +8 -7
  47. data/lib/rack/sendfile.rb +29 -27
  48. data/lib/rack/show_exceptions.rb +27 -12
  49. data/lib/rack/show_status.rb +21 -13
  50. data/lib/rack/static.rb +19 -12
  51. data/lib/rack/tempfile_reaper.rb +14 -5
  52. data/lib/rack/urlmap.rb +5 -6
  53. data/lib/rack/utils.rb +274 -260
  54. data/lib/rack/version.rb +21 -0
  55. data/lib/rack.rb +18 -103
  56. metadata +25 -52
  57. data/README.rdoc +0 -262
  58. data/Rakefile +0 -123
  59. data/SPEC +0 -263
  60. data/bin/rackup +0 -5
  61. data/contrib/rack.png +0 -0
  62. data/contrib/rack.svg +0 -150
  63. data/contrib/rack_logo.svg +0 -164
  64. data/contrib/rdoc.css +0 -412
  65. data/example/lobster.ru +0 -6
  66. data/example/protectedlobster.rb +0 -16
  67. data/example/protectedlobster.ru +0 -10
  68. data/lib/rack/auth/digest/md5.rb +0 -131
  69. data/lib/rack/auth/digest/nonce.rb +0 -54
  70. data/lib/rack/auth/digest/params.rb +0 -54
  71. data/lib/rack/auth/digest/request.rb +0 -43
  72. data/lib/rack/chunked.rb +0 -92
  73. data/lib/rack/core_ext/regexp.rb +0 -14
  74. data/lib/rack/file.rb +0 -8
  75. data/lib/rack/handler/cgi.rb +0 -62
  76. data/lib/rack/handler/fastcgi.rb +0 -102
  77. data/lib/rack/handler/lsws.rb +0 -63
  78. data/lib/rack/handler/scgi.rb +0 -73
  79. data/lib/rack/handler/thin.rb +0 -38
  80. data/lib/rack/handler/webrick.rb +0 -122
  81. data/lib/rack/handler.rb +0 -104
  82. data/lib/rack/lobster.rb +0 -72
  83. data/lib/rack/server.rb +0 -467
  84. data/lib/rack/session/abstract/id.rb +0 -528
  85. data/lib/rack/session/cookie.rb +0 -205
  86. data/lib/rack/session/memcache.rb +0 -10
  87. data/lib/rack/session/pool.rb +0 -85
  88. data/rack.gemspec +0 -44
data/lib/rack/server.rb DELETED
@@ -1,467 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'optparse'
4
- require 'fileutils'
5
-
6
- require_relative 'core_ext/regexp'
7
-
8
- module Rack
9
-
10
- class Server
11
- using ::Rack::RegexpExtensions
12
-
13
- class Options
14
- def parse!(args)
15
- options = {}
16
- opt_parser = OptionParser.new("", 24, ' ') do |opts|
17
- opts.banner = "Usage: rackup [ruby options] [rack options] [rackup config]"
18
-
19
- opts.separator ""
20
- opts.separator "Ruby options:"
21
-
22
- lineno = 1
23
- opts.on("-e", "--eval LINE", "evaluate a LINE of code") { |line|
24
- eval line, TOPLEVEL_BINDING, "-e", lineno
25
- lineno += 1
26
- }
27
-
28
- opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
29
- options[:debug] = true
30
- }
31
- opts.on("-w", "--warn", "turn warnings on for your script") {
32
- options[:warn] = true
33
- }
34
- opts.on("-q", "--quiet", "turn off logging") {
35
- options[:quiet] = true
36
- }
37
-
38
- opts.on("-I", "--include PATH",
39
- "specify $LOAD_PATH (may be used more than once)") { |path|
40
- (options[:include] ||= []).concat(path.split(":"))
41
- }
42
-
43
- opts.on("-r", "--require LIBRARY",
44
- "require the library, before executing your script") { |library|
45
- options[:require] = library
46
- }
47
-
48
- opts.separator ""
49
- opts.separator "Rack options:"
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|
55
- options[:server] = s
56
- }
57
-
58
- opts.on("-o", "--host HOST", "listen on HOST (default: localhost)") { |host|
59
- options[:Host] = host
60
- }
61
-
62
- opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
63
- options[:Port] = port
64
- }
65
-
66
- 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|
67
- name, value = name.split('=', 2)
68
- value = true if value.nil?
69
- options[name.to_sym] = value
70
- }
71
-
72
- opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
73
- options[:environment] = e
74
- }
75
-
76
- opts.on("-D", "--daemonize", "run daemonized in the background") { |d|
77
- options[:daemonize] = d ? true : false
78
- }
79
-
80
- opts.on("-P", "--pid FILE", "file to store PID") { |f|
81
- options[:pid] = ::File.expand_path(f)
82
- }
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
-
102
- opts.separator ""
103
- opts.separator "Common options:"
104
-
105
- opts.on_tail("-h", "-?", "--help", "Show this message") do
106
- puts opts
107
- puts handler_opts(options)
108
-
109
- exit
110
- end
111
-
112
- opts.on_tail("--version", "Show version") do
113
- puts "Rack #{Rack.version} (Release: #{Rack.release})"
114
- exit
115
- end
116
- end
117
-
118
- begin
119
- opt_parser.parse! args
120
- rescue OptionParser::InvalidOption => e
121
- warn e.message
122
- abort opt_parser.to_s
123
- end
124
-
125
- options[:config] = args.last if args.last && !args.last.empty?
126
- options
127
- end
128
-
129
- def handler_opts(options)
130
- begin
131
- info = []
132
- server = Rack::Handler.get(options[:server]) || Rack::Handler.default
133
- if server && server.respond_to?(:valid_options)
134
- info << ""
135
- info << "Server-specific options for #{server.name}:"
136
-
137
- has_options = false
138
- server.valid_options.each do |name, description|
139
- next if /^(Host|Port)[^a-zA-Z]/.match?(name.to_s) # ignore handler's host and port options, we do our own.
140
- info << " -O %-21s %s" % [name, description]
141
- has_options = true
142
- end
143
- return "" if !has_options
144
- end
145
- info.join("\n")
146
- rescue NameError
147
- return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
148
- end
149
- end
150
- end
151
-
152
- # Start a new rack server (like running rackup). This will parse ARGV and
153
- # provide standard ARGV rackup options, defaulting to load 'config.ru'.
154
- #
155
- # Providing an options hash will prevent ARGV parsing and will not include
156
- # any default options.
157
- #
158
- # This method can be used to very easily launch a CGI application, for
159
- # example:
160
- #
161
- # Rack::Server.start(
162
- # :app => lambda do |e|
163
- # [200, {'Content-Type' => 'text/html'}, ['hello world']]
164
- # end,
165
- # :server => 'cgi'
166
- # )
167
- #
168
- # Further options available here are documented on Rack::Server#initialize
169
- def self.start(options = nil)
170
- new(options).start
171
- end
172
-
173
- attr_writer :options
174
-
175
- # Options may include:
176
- # * :app
177
- # a rack application to run (overrides :config and :builder)
178
- # * :builder
179
- # a string to evaluate a Rack::Builder from
180
- # * :config
181
- # a rackup configuration file path to load (.ru)
182
- # * :environment
183
- # this selects the middleware that will be wrapped around
184
- # your application. Default options available are:
185
- # - development: CommonLogger, ShowExceptions, and Lint
186
- # - deployment: CommonLogger
187
- # - none: no extra middleware
188
- # note: when the server is a cgi server, CommonLogger is not included.
189
- # * :server
190
- # choose a specific Rack::Handler, e.g. cgi, fcgi, webrick
191
- # * :daemonize
192
- # if true, the server will daemonize itself (fork, detach, etc)
193
- # * :pid
194
- # path to write a pid file after daemonize
195
- # * :Host
196
- # the host address to bind to (used by supporting Rack::Handler)
197
- # * :Port
198
- # the port to bind to (used by supporting Rack::Handler)
199
- # * :AccessLog
200
- # webrick access log options (or supporting Rack::Handler)
201
- # * :debug
202
- # turn on debug output ($DEBUG = true)
203
- # * :warn
204
- # turn on warnings ($-w = true)
205
- # * :include
206
- # add given paths to $LOAD_PATH
207
- # * :require
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)
217
- def initialize(options = nil)
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
229
- end
230
-
231
- def options
232
- merged_options = @use_default_options ? default_options.merge(@options) : @options
233
- merged_options.reject { |k, v| @ignore_options.include?(k) }
234
- end
235
-
236
- def default_options
237
- environment = ENV['RACK_ENV'] || 'development'
238
- default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
239
-
240
- {
241
- environment: environment,
242
- pid: nil,
243
- Port: 9292,
244
- Host: default_host,
245
- AccessLog: [],
246
- config: "config.ru"
247
- }
248
- end
249
-
250
- def app
251
- @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
252
- end
253
-
254
- class << self
255
- def logging_middleware
256
- lambda { |server|
257
- /CGI/.match?(server.server.name) || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]
258
- }
259
- end
260
-
261
- def default_middleware_by_environment
262
- m = Hash.new {|h, k| h[k] = []}
263
- m["deployment"] = [
264
- [Rack::ContentLength],
265
- [Rack::Chunked],
266
- logging_middleware,
267
- [Rack::TempfileReaper]
268
- ]
269
- m["development"] = [
270
- [Rack::ContentLength],
271
- [Rack::Chunked],
272
- logging_middleware,
273
- [Rack::ShowExceptions],
274
- [Rack::Lint],
275
- [Rack::TempfileReaper]
276
- ]
277
-
278
- m
279
- end
280
-
281
- def middleware
282
- default_middleware_by_environment
283
- end
284
- end
285
-
286
- def middleware
287
- self.class.middleware
288
- end
289
-
290
- def start &blk
291
- if options[:warn]
292
- $-w = true
293
- end
294
-
295
- if includes = options[:include]
296
- $LOAD_PATH.unshift(*includes)
297
- end
298
-
299
- if library = options[:require]
300
- require library
301
- end
302
-
303
- if options[:debug]
304
- $DEBUG = true
305
- require 'pp'
306
- p options[:server]
307
- pp wrapped_app
308
- pp app
309
- end
310
-
311
- check_pid! if options[:pid]
312
-
313
- # Touch the wrapped app, so that the config.ru is loaded before
314
- # daemonization (i.e. before chdir, etc).
315
- handle_profiling(options[:heapfile], options[:profile_mode], options[:profile_file]) do
316
- wrapped_app
317
- end
318
-
319
- daemonize_app if options[:daemonize]
320
-
321
- write_pid if options[:pid]
322
-
323
- trap(:INT) do
324
- if server.respond_to?(:shutdown)
325
- server.shutdown
326
- else
327
- exit
328
- end
329
- end
330
-
331
- server.run wrapped_app, options, &blk
332
- end
333
-
334
- def server
335
- @_server ||= Rack::Handler.get(options[:server])
336
-
337
- unless @_server
338
- @_server = Rack::Handler.default
339
-
340
- # We already speak FastCGI
341
- @ignore_options = [:File, :Port] if @_server.to_s == 'Rack::Handler::FastCGI'
342
- end
343
-
344
- @_server
345
- end
346
-
347
- private
348
- def build_app_and_options_from_config
349
- if !::File.exist? options[:config]
350
- abort "configuration #{options[:config]} not found"
351
- end
352
-
353
- app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
354
- @options.merge!(options) { |key, old, new| old }
355
- app
356
- end
357
-
358
- def handle_profiling(heapfile, profile_mode, filename)
359
- if heapfile
360
- require "objspace"
361
- ObjectSpace.trace_object_allocations_start
362
- yield
363
- GC.start
364
- ::File.open(heapfile, "w") { |f| ObjectSpace.dump_all(output: f) }
365
- exit
366
- end
367
-
368
- if profile_mode
369
- require "stackprof"
370
- require "tempfile"
371
-
372
- make_profile_name(filename) do |filename|
373
- ::File.open(filename, "w") do |f|
374
- StackProf.run(mode: profile_mode, out: f) do
375
- yield
376
- end
377
- puts "Profile written to: #{filename}"
378
- end
379
- end
380
- exit
381
- end
382
-
383
- yield
384
- end
385
-
386
- def make_profile_name(filename)
387
- if filename
388
- yield filename
389
- else
390
- ::Dir::Tmpname.create("profile.dump") do |tmpname, _, _|
391
- yield tmpname
392
- end
393
- end
394
- end
395
-
396
- def build_app_from_string
397
- Rack::Builder.new_from_string(self.options[:builder])
398
- end
399
-
400
- def parse_options(args)
401
- # Don't evaluate CGI ISINDEX parameters.
402
- # http://www.meb.uni-bonn.de/docs/cgi/cl.html
403
- args.clear if ENV.include?(REQUEST_METHOD)
404
-
405
- @options = opt_parser.parse!(args)
406
- @options[:config] = ::File.expand_path(options[:config])
407
- ENV["RACK_ENV"] = options[:environment]
408
- @options
409
- end
410
-
411
- def opt_parser
412
- Options.new
413
- end
414
-
415
- def build_app(app)
416
- middleware[options[:environment]].reverse_each do |middleware|
417
- middleware = middleware.call(self) if middleware.respond_to?(:call)
418
- next unless middleware
419
- klass, *args = middleware
420
- app = klass.new(app, *args)
421
- end
422
- app
423
- end
424
-
425
- def wrapped_app
426
- @wrapped_app ||= build_app app
427
- end
428
-
429
- def daemonize_app
430
- Process.daemon
431
- end
432
-
433
- def write_pid
434
- ::File.open(options[:pid], ::File::CREAT | ::File::EXCL | ::File::WRONLY ){ |f| f.write("#{Process.pid}") }
435
- at_exit { ::FileUtils.rm_f(options[:pid]) }
436
- rescue Errno::EEXIST
437
- check_pid!
438
- retry
439
- end
440
-
441
- def check_pid!
442
- case pidfile_process_status
443
- when :running, :not_owned
444
- $stderr.puts "A server is already running. Check #{options[:pid]}."
445
- exit(1)
446
- when :dead
447
- ::File.delete(options[:pid])
448
- end
449
- end
450
-
451
- def pidfile_process_status
452
- return :exited unless ::File.exist?(options[:pid])
453
-
454
- pid = ::File.read(options[:pid]).to_i
455
- return :dead if pid == 0
456
-
457
- Process.kill(0, pid)
458
- :running
459
- rescue Errno::ESRCH
460
- :dead
461
- rescue Errno::EPERM
462
- :not_owned
463
- end
464
-
465
- end
466
-
467
- end