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
@@ -1,205 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'openssl'
4
- require 'zlib'
5
- require 'rack/request'
6
- require 'rack/response'
7
- require 'rack/session/abstract/id'
8
- require 'json'
9
- require 'base64'
10
-
11
- module Rack
12
-
13
- module Session
14
-
15
- # Rack::Session::Cookie provides simple cookie based session management.
16
- # By default, the session is a Ruby Hash stored as base64 encoded marshalled
17
- # data set to :key (default: rack.session). The object that encodes the
18
- # session data is configurable and must respond to +encode+ and +decode+.
19
- # Both methods must take a string and return a string.
20
- #
21
- # When the secret key is set, cookie data is checked for data integrity.
22
- # The old secret key is also accepted and allows graceful secret rotation.
23
- #
24
- # Example:
25
- #
26
- # use Rack::Session::Cookie, :key => 'rack.session',
27
- # :domain => 'foo.com',
28
- # :path => '/',
29
- # :expire_after => 2592000,
30
- # :secret => 'change_me',
31
- # :old_secret => 'also_change_me'
32
- #
33
- # All parameters are optional.
34
- #
35
- # Example of a cookie with no encoding:
36
- #
37
- # Rack::Session::Cookie.new(application, {
38
- # :coder => Rack::Session::Cookie::Identity.new
39
- # })
40
- #
41
- # Example of a cookie with custom encoding:
42
- #
43
- # Rack::Session::Cookie.new(application, {
44
- # :coder => Class.new {
45
- # def encode(str); str.reverse; end
46
- # def decode(str); str.reverse; end
47
- # }.new
48
- # })
49
- #
50
-
51
- class Cookie < Abstract::PersistedSecure
52
- # Encode session cookies as Base64
53
- class Base64
54
- def encode(str)
55
- ::Base64.strict_encode64(str)
56
- end
57
-
58
- def decode(str)
59
- ::Base64.decode64(str)
60
- end
61
-
62
- # Encode session cookies as Marshaled Base64 data
63
- class Marshal < Base64
64
- def encode(str)
65
- super(::Marshal.dump(str))
66
- end
67
-
68
- def decode(str)
69
- return unless str
70
- ::Marshal.load(super(str)) rescue nil
71
- end
72
- end
73
-
74
- # N.B. Unlike other encoding methods, the contained objects must be a
75
- # valid JSON composite type, either a Hash or an Array.
76
- class JSON < Base64
77
- def encode(obj)
78
- super(::JSON.dump(obj))
79
- end
80
-
81
- def decode(str)
82
- return unless str
83
- ::JSON.parse(super(str)) rescue nil
84
- end
85
- end
86
-
87
- class ZipJSON < Base64
88
- def encode(obj)
89
- super(Zlib::Deflate.deflate(::JSON.dump(obj)))
90
- end
91
-
92
- def decode(str)
93
- return unless str
94
- ::JSON.parse(Zlib::Inflate.inflate(super(str)))
95
- rescue
96
- nil
97
- end
98
- end
99
- end
100
-
101
- # Use no encoding for session cookies
102
- class Identity
103
- def encode(str); str; end
104
- def decode(str); str; end
105
- end
106
-
107
- attr_reader :coder
108
-
109
- def initialize(app, options = {})
110
- @secrets = options.values_at(:secret, :old_secret).compact
111
- @hmac = options.fetch(:hmac, OpenSSL::Digest::SHA1)
112
-
113
- warn <<-MSG unless secure?(options)
114
- SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
115
- This poses a security threat. It is strongly recommended that you
116
- provide a secret to prevent exploits that may be possible from crafted
117
- cookies. This will not be supported in future versions of Rack, and
118
- future versions will even invalidate your existing user cookies.
119
-
120
- Called from: #{caller[0]}.
121
- MSG
122
- @coder = options[:coder] ||= Base64::Marshal.new
123
- super(app, options.merge!(cookie_only: true))
124
- end
125
-
126
- private
127
-
128
- def find_session(req, sid)
129
- data = unpacked_cookie_data(req)
130
- data = persistent_session_id!(data)
131
- [data["session_id"], data]
132
- end
133
-
134
- def extract_session_id(request)
135
- unpacked_cookie_data(request)["session_id"]
136
- end
137
-
138
- def unpacked_cookie_data(request)
139
- request.fetch_header(RACK_SESSION_UNPACKED_COOKIE_DATA) do |k|
140
- session_data = request.cookies[@key]
141
-
142
- if @secrets.size > 0 && session_data
143
- session_data, _, digest = session_data.rpartition('--')
144
- session_data = nil unless digest_match?(session_data, digest)
145
- end
146
-
147
- request.set_header(k, coder.decode(session_data) || {})
148
- end
149
- end
150
-
151
- def persistent_session_id!(data, sid = nil)
152
- data ||= {}
153
- data["session_id"] ||= sid || generate_sid
154
- data
155
- end
156
-
157
- class SessionId < DelegateClass(Session::SessionId)
158
- attr_reader :cookie_value
159
-
160
- def initialize(session_id, cookie_value)
161
- super(session_id)
162
- @cookie_value = cookie_value
163
- end
164
- end
165
-
166
- def write_session(req, session_id, session, options)
167
- session = session.merge("session_id" => session_id)
168
- session_data = coder.encode(session)
169
-
170
- if @secrets.first
171
- session_data << "--#{generate_hmac(session_data, @secrets.first)}"
172
- end
173
-
174
- if session_data.size > (4096 - @key.size)
175
- req.get_header(RACK_ERRORS).puts("Warning! Rack::Session::Cookie data size exceeds 4K.")
176
- nil
177
- else
178
- SessionId.new(session_id, session_data)
179
- end
180
- end
181
-
182
- def delete_session(req, session_id, options)
183
- # Nothing to do here, data is in the client
184
- generate_sid unless options[:drop]
185
- end
186
-
187
- def digest_match?(data, digest)
188
- return unless data && digest
189
- @secrets.any? do |secret|
190
- Rack::Utils.secure_compare(digest, generate_hmac(data, secret))
191
- end
192
- end
193
-
194
- def generate_hmac(data, secret)
195
- OpenSSL::HMAC.hexdigest(@hmac.new, secret, data)
196
- end
197
-
198
- def secure?(options)
199
- @secrets.size >= 1 ||
200
- (options[:coder] && options[:let_coder_handle_secure_encoding])
201
- end
202
-
203
- end
204
- end
205
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rack/session/dalli'
4
-
5
- module Rack
6
- module Session
7
- warn "Rack::Session::Memcache is deprecated, please use Rack::Session::Dalli from 'dalli' gem instead."
8
- Memcache = Dalli
9
- end
10
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
4
- # THANKS:
5
- # apeiros, for session id generation, expiry setup, and threadiness
6
- # sergio, threadiness and bugreps
7
-
8
- require 'rack/session/abstract/id'
9
- require 'thread'
10
-
11
- module Rack
12
- module Session
13
- # Rack::Session::Pool provides simple cookie based session management.
14
- # Session data is stored in a hash held by @pool.
15
- # In the context of a multithreaded environment, sessions being
16
- # committed to the pool is done in a merging manner.
17
- #
18
- # The :drop option is available in rack.session.options if you wish to
19
- # explicitly remove the session from the session cache.
20
- #
21
- # Example:
22
- # myapp = MyRackApp.new
23
- # sessioned = Rack::Session::Pool.new(myapp,
24
- # :domain => 'foo.com',
25
- # :expire_after => 2592000
26
- # )
27
- # Rack::Handler::WEBrick.run sessioned
28
-
29
- class Pool < Abstract::PersistedSecure
30
- attr_reader :mutex, :pool
31
- DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge drop: false
32
-
33
- def initialize(app, options = {})
34
- super
35
- @pool = Hash.new
36
- @mutex = Mutex.new
37
- end
38
-
39
- def generate_sid
40
- loop do
41
- sid = super
42
- break sid unless @pool.key? sid.private_id
43
- end
44
- end
45
-
46
- def find_session(req, sid)
47
- with_lock(req) do
48
- unless sid and session = get_session_with_fallback(sid)
49
- sid, session = generate_sid, {}
50
- @pool.store sid.private_id, session
51
- end
52
- [sid, session]
53
- end
54
- end
55
-
56
- def write_session(req, session_id, new_session, options)
57
- with_lock(req) do
58
- @pool.store session_id.private_id, new_session
59
- session_id
60
- end
61
- end
62
-
63
- def delete_session(req, session_id, options)
64
- with_lock(req) do
65
- @pool.delete(session_id.public_id)
66
- @pool.delete(session_id.private_id)
67
- generate_sid unless options[:drop]
68
- end
69
- end
70
-
71
- def with_lock(req)
72
- @mutex.lock if req.multithread?
73
- yield
74
- ensure
75
- @mutex.unlock if @mutex.locked?
76
- end
77
-
78
- private
79
-
80
- def get_session_with_fallback(sid)
81
- @pool[sid.private_id] || @pool[sid.public_id]
82
- end
83
- end
84
- end
85
- end
data/rack.gemspec DELETED
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Gem::Specification.new do |s|
4
- s.name = "rack"
5
- s.version = File.read('lib/rack.rb')[/RELEASE += +([\"\'])([\d][\w\.]+)\1/, 2]
6
- s.platform = Gem::Platform::RUBY
7
- s.summary = "a modular Ruby webserver interface"
8
- s.license = "MIT"
9
-
10
- s.description = <<-EOF
11
- Rack provides a minimal, modular and adaptable interface for developing
12
- web applications in Ruby. By wrapping HTTP requests and responses in
13
- the simplest way possible, it unifies and distills the API for web
14
- servers, web frameworks, and software in between (the so-called
15
- middleware) into a single method call.
16
-
17
- Also see https://rack.github.io/.
18
- EOF
19
-
20
- s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] +
21
- %w(MIT-LICENSE rack.gemspec Rakefile README.rdoc SPEC)
22
- s.bindir = 'bin'
23
- s.executables << 'rackup'
24
- s.require_path = 'lib'
25
- s.extra_rdoc_files = ['README.rdoc', 'CHANGELOG.md']
26
-
27
- s.author = 'Leah Neukirchen'
28
- s.email = 'leah@vuxu.org'
29
- s.homepage = 'https://rack.github.io/'
30
- s.required_ruby_version = '>= 2.2.2'
31
- s.metadata = {
32
- "bug_tracker_uri" => "https://github.com/rack/rack/issues",
33
- "changelog_uri" => "https://github.com/rack/rack/blob/master/CHANGELOG.md",
34
- "documentation_uri" => "https://rubydoc.info/github/rack/rack",
35
- "homepage_uri" => "https://rack.github.io",
36
- "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rack-devel",
37
- "source_code_uri" => "https://github.com/rack/rack"
38
- }
39
-
40
- s.add_development_dependency 'minitest', "~> 5.0"
41
- s.add_development_dependency 'minitest-sprint'
42
- s.add_development_dependency 'minitest-global_expectations'
43
- s.add_development_dependency 'rake'
44
- end