rack 2.2.9 → 3.0.0.beta1

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.

Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +138 -101
  3. data/CONTRIBUTING.md +53 -47
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +287 -0
  6. data/Rakefile +40 -7
  7. data/SPEC.rdoc +166 -125
  8. data/contrib/LICENSE.md +7 -0
  9. data/contrib/logo.webp +0 -0
  10. data/lib/rack/auth/abstract/handler.rb +3 -1
  11. data/lib/rack/auth/abstract/request.rb +3 -1
  12. data/lib/rack/auth/digest/md5.rb +1 -131
  13. data/lib/rack/auth/digest/nonce.rb +1 -54
  14. data/lib/rack/auth/digest/params.rb +1 -54
  15. data/lib/rack/auth/digest/request.rb +1 -43
  16. data/lib/rack/auth/digest.rb +256 -0
  17. data/lib/rack/body_proxy.rb +3 -1
  18. data/lib/rack/builder.rb +60 -42
  19. data/lib/rack/cascade.rb +2 -0
  20. data/lib/rack/chunked.rb +16 -13
  21. data/lib/rack/common_logger.rb +23 -18
  22. data/lib/rack/conditional_get.rb +18 -15
  23. data/lib/rack/constants.rb +62 -0
  24. data/lib/rack/content_length.rb +12 -16
  25. data/lib/rack/content_type.rb +8 -5
  26. data/lib/rack/deflater.rb +40 -26
  27. data/lib/rack/directory.rb +9 -3
  28. data/lib/rack/etag.rb +14 -23
  29. data/lib/rack/events.rb +4 -0
  30. data/lib/rack/file.rb +2 -0
  31. data/lib/rack/files.rb +15 -17
  32. data/lib/rack/head.rb +9 -8
  33. data/lib/rack/headers.rb +154 -0
  34. data/lib/rack/lint.rb +740 -649
  35. data/lib/rack/lock.rb +2 -5
  36. data/lib/rack/logger.rb +2 -0
  37. data/lib/rack/media_type.rb +4 -9
  38. data/lib/rack/method_override.rb +5 -1
  39. data/lib/rack/mime.rb +8 -0
  40. data/lib/rack/mock.rb +1 -271
  41. data/lib/rack/mock_request.rb +166 -0
  42. data/lib/rack/mock_response.rb +124 -0
  43. data/lib/rack/multipart/generator.rb +7 -5
  44. data/lib/rack/multipart/parser.rb +123 -85
  45. data/lib/rack/multipart/uploaded_file.rb +4 -0
  46. data/lib/rack/multipart.rb +20 -40
  47. data/lib/rack/null_logger.rb +9 -0
  48. data/lib/rack/query_parser.rb +76 -44
  49. data/lib/rack/recursive.rb +2 -0
  50. data/lib/rack/reloader.rb +0 -2
  51. data/lib/rack/request.rb +189 -91
  52. data/lib/rack/response.rb +131 -61
  53. data/lib/rack/rewindable_input.rb +24 -5
  54. data/lib/rack/runtime.rb +7 -6
  55. data/lib/rack/sendfile.rb +30 -25
  56. data/lib/rack/show_exceptions.rb +15 -2
  57. data/lib/rack/show_status.rb +17 -7
  58. data/lib/rack/static.rb +8 -8
  59. data/lib/rack/tempfile_reaper.rb +15 -4
  60. data/lib/rack/urlmap.rb +4 -2
  61. data/lib/rack/utils.rb +210 -199
  62. data/lib/rack/version.rb +9 -4
  63. data/lib/rack.rb +5 -76
  64. data/rack.gemspec +6 -6
  65. metadata +19 -31
  66. data/README.rdoc +0 -320
  67. data/bin/rackup +0 -5
  68. data/contrib/rack.png +0 -0
  69. data/contrib/rack.svg +0 -150
  70. data/contrib/rack_logo.svg +0 -164
  71. data/lib/rack/core_ext/regexp.rb +0 -14
  72. data/lib/rack/handler/cgi.rb +0 -59
  73. data/lib/rack/handler/fastcgi.rb +0 -100
  74. data/lib/rack/handler/lsws.rb +0 -61
  75. data/lib/rack/handler/scgi.rb +0 -71
  76. data/lib/rack/handler/thin.rb +0 -36
  77. data/lib/rack/handler/webrick.rb +0 -129
  78. data/lib/rack/handler.rb +0 -104
  79. data/lib/rack/lobster.rb +0 -70
  80. data/lib/rack/server.rb +0 -466
  81. data/lib/rack/session/abstract/id.rb +0 -523
  82. data/lib/rack/session/cookie.rb +0 -204
  83. data/lib/rack/session/memcache.rb +0 -10
  84. data/lib/rack/session/pool.rb +0 -85
@@ -1,204 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'openssl'
4
- require 'zlib'
5
- require_relative 'abstract/id'
6
- require 'json'
7
- require 'base64'
8
- require 'delegate'
9
-
10
- module Rack
11
-
12
- module Session
13
-
14
- # Rack::Session::Cookie provides simple cookie based session management.
15
- # By default, the session is a Ruby Hash stored as base64 encoded marshalled
16
- # data set to :key (default: rack.session). The object that encodes the
17
- # session data is configurable and must respond to +encode+ and +decode+.
18
- # Both methods must take a string and return a string.
19
- #
20
- # When the secret key is set, cookie data is checked for data integrity.
21
- # The old secret key is also accepted and allows graceful secret rotation.
22
- #
23
- # Example:
24
- #
25
- # use Rack::Session::Cookie, :key => 'rack.session',
26
- # :domain => 'foo.com',
27
- # :path => '/',
28
- # :expire_after => 2592000,
29
- # :secret => 'change_me',
30
- # :old_secret => 'also_change_me'
31
- #
32
- # All parameters are optional.
33
- #
34
- # Example of a cookie with no encoding:
35
- #
36
- # Rack::Session::Cookie.new(application, {
37
- # :coder => Rack::Session::Cookie::Identity.new
38
- # })
39
- #
40
- # Example of a cookie with custom encoding:
41
- #
42
- # Rack::Session::Cookie.new(application, {
43
- # :coder => Class.new {
44
- # def encode(str); str.reverse; end
45
- # def decode(str); str.reverse; end
46
- # }.new
47
- # })
48
- #
49
-
50
- class Cookie < Abstract::PersistedSecure
51
- # Encode session cookies as Base64
52
- class Base64
53
- def encode(str)
54
- ::Base64.strict_encode64(str)
55
- end
56
-
57
- def decode(str)
58
- ::Base64.decode64(str)
59
- end
60
-
61
- # Encode session cookies as Marshaled Base64 data
62
- class Marshal < Base64
63
- def encode(str)
64
- super(::Marshal.dump(str))
65
- end
66
-
67
- def decode(str)
68
- return unless str
69
- ::Marshal.load(super(str)) rescue nil
70
- end
71
- end
72
-
73
- # N.B. Unlike other encoding methods, the contained objects must be a
74
- # valid JSON composite type, either a Hash or an Array.
75
- class JSON < Base64
76
- def encode(obj)
77
- super(::JSON.dump(obj))
78
- end
79
-
80
- def decode(str)
81
- return unless str
82
- ::JSON.parse(super(str)) rescue nil
83
- end
84
- end
85
-
86
- class ZipJSON < Base64
87
- def encode(obj)
88
- super(Zlib::Deflate.deflate(::JSON.dump(obj)))
89
- end
90
-
91
- def decode(str)
92
- return unless str
93
- ::JSON.parse(Zlib::Inflate.inflate(super(str)))
94
- rescue
95
- nil
96
- end
97
- end
98
- end
99
-
100
- # Use no encoding for session cookies
101
- class Identity
102
- def encode(str); str; end
103
- def decode(str); str; end
104
- end
105
-
106
- attr_reader :coder
107
-
108
- def initialize(app, options = {})
109
- @secrets = options.values_at(:secret, :old_secret).compact
110
- @hmac = options.fetch(:hmac, OpenSSL::Digest::SHA1)
111
-
112
- warn <<-MSG unless secure?(options)
113
- SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
114
- This poses a security threat. It is strongly recommended that you
115
- provide a secret to prevent exploits that may be possible from crafted
116
- cookies. This will not be supported in future versions of Rack, and
117
- future versions will even invalidate your existing user cookies.
118
-
119
- Called from: #{caller[0]}.
120
- MSG
121
- @coder = options[:coder] ||= Base64::Marshal.new
122
- super(app, options.merge!(cookie_only: true))
123
- end
124
-
125
- private
126
-
127
- def find_session(req, sid)
128
- data = unpacked_cookie_data(req)
129
- data = persistent_session_id!(data)
130
- [data["session_id"], data]
131
- end
132
-
133
- def extract_session_id(request)
134
- unpacked_cookie_data(request)["session_id"]
135
- end
136
-
137
- def unpacked_cookie_data(request)
138
- request.fetch_header(RACK_SESSION_UNPACKED_COOKIE_DATA) do |k|
139
- session_data = request.cookies[@key]
140
-
141
- if @secrets.size > 0 && session_data
142
- session_data, _, digest = session_data.rpartition('--')
143
- session_data = nil unless digest_match?(session_data, digest)
144
- end
145
-
146
- request.set_header(k, coder.decode(session_data) || {})
147
- end
148
- end
149
-
150
- def persistent_session_id!(data, sid = nil)
151
- data ||= {}
152
- data["session_id"] ||= sid || generate_sid
153
- data
154
- end
155
-
156
- class SessionId < DelegateClass(Session::SessionId)
157
- attr_reader :cookie_value
158
-
159
- def initialize(session_id, cookie_value)
160
- super(session_id)
161
- @cookie_value = cookie_value
162
- end
163
- end
164
-
165
- def write_session(req, session_id, session, options)
166
- session = session.merge("session_id" => session_id)
167
- session_data = coder.encode(session)
168
-
169
- if @secrets.first
170
- session_data << "--#{generate_hmac(session_data, @secrets.first)}"
171
- end
172
-
173
- if session_data.size > (4096 - @key.size)
174
- req.get_header(RACK_ERRORS).puts("Warning! Rack::Session::Cookie data size exceeds 4K.")
175
- nil
176
- else
177
- SessionId.new(session_id, session_data)
178
- end
179
- end
180
-
181
- def delete_session(req, session_id, options)
182
- # Nothing to do here, data is in the client
183
- generate_sid unless options[:drop]
184
- end
185
-
186
- def digest_match?(data, digest)
187
- return unless data && digest
188
- @secrets.any? do |secret|
189
- Rack::Utils.secure_compare(digest, generate_hmac(data, secret))
190
- end
191
- end
192
-
193
- def generate_hmac(data, secret)
194
- OpenSSL::HMAC.hexdigest(@hmac.new, secret, data)
195
- end
196
-
197
- def secure?(options)
198
- @secrets.size >= 1 ||
199
- (options[:coder] && options[:let_coder_handle_secure_encoding])
200
- end
201
-
202
- end
203
- end
204
- 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_relative '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