rack 2.2.9 → 3.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +330 -88
- data/CONTRIBUTING.md +63 -55
- data/MIT-LICENSE +1 -1
- data/README.md +328 -0
- data/SPEC.rdoc +204 -131
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +3 -1
- data/lib/rack/auth/basic.rb +1 -4
- data/lib/rack/bad_request.rb +8 -0
- data/lib/rack/body_proxy.rb +21 -3
- data/lib/rack/builder.rb +102 -69
- data/lib/rack/cascade.rb +2 -3
- data/lib/rack/common_logger.rb +23 -18
- data/lib/rack/conditional_get.rb +18 -15
- data/lib/rack/constants.rb +67 -0
- data/lib/rack/content_length.rb +12 -16
- data/lib/rack/content_type.rb +8 -5
- data/lib/rack/deflater.rb +40 -26
- data/lib/rack/directory.rb +9 -3
- data/lib/rack/etag.rb +14 -23
- data/lib/rack/events.rb +4 -0
- data/lib/rack/files.rb +15 -17
- data/lib/rack/head.rb +9 -8
- data/lib/rack/headers.rb +238 -0
- data/lib/rack/lint.rb +840 -644
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/logger.rb +3 -0
- data/lib/rack/method_override.rb +5 -1
- data/lib/rack/mime.rb +14 -5
- data/lib/rack/mock.rb +1 -271
- data/lib/rack/mock_request.rb +161 -0
- data/lib/rack/mock_response.rb +124 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +213 -95
- data/lib/rack/multipart/uploaded_file.rb +4 -0
- data/lib/rack/multipart.rb +53 -40
- data/lib/rack/null_logger.rb +9 -0
- data/lib/rack/query_parser.rb +81 -102
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +260 -123
- data/lib/rack/response.rb +151 -66
- data/lib/rack/rewindable_input.rb +24 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +30 -25
- data/lib/rack/show_exceptions.rb +21 -4
- data/lib/rack/show_status.rb +17 -7
- data/lib/rack/static.rb +8 -8
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +3 -1
- data/lib/rack/utils.rb +232 -233
- data/lib/rack/version.rb +1 -9
- data/lib/rack.rb +13 -89
- metadata +15 -41
- data/README.rdoc +0 -320
- data/Rakefile +0 -130
- data/bin/rackup +0 -5
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +0 -150
- data/contrib/rack_logo.svg +0 -164
- data/contrib/rdoc.css +0 -412
- data/example/lobster.ru +0 -6
- data/example/protectedlobster.rb +0 -16
- data/example/protectedlobster.ru +0 -10
- data/lib/rack/auth/digest/md5.rb +0 -131
- data/lib/rack/auth/digest/nonce.rb +0 -54
- data/lib/rack/auth/digest/params.rb +0 -54
- data/lib/rack/auth/digest/request.rb +0 -43
- data/lib/rack/chunked.rb +0 -117
- data/lib/rack/core_ext/regexp.rb +0 -14
- data/lib/rack/file.rb +0 -7
- data/lib/rack/handler/cgi.rb +0 -59
- data/lib/rack/handler/fastcgi.rb +0 -100
- data/lib/rack/handler/lsws.rb +0 -61
- data/lib/rack/handler/scgi.rb +0 -71
- data/lib/rack/handler/thin.rb +0 -36
- data/lib/rack/handler/webrick.rb +0 -129
- data/lib/rack/handler.rb +0 -104
- data/lib/rack/lobster.rb +0 -70
- data/lib/rack/server.rb +0 -466
- data/lib/rack/session/abstract/id.rb +0 -523
- data/lib/rack/session/cookie.rb +0 -204
- data/lib/rack/session/memcache.rb +0 -10
- data/lib/rack/session/pool.rb +0 -85
- data/rack.gemspec +0 -46
data/lib/rack/session/cookie.rb
DELETED
@@ -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
|
data/lib/rack/session/pool.rb
DELETED
@@ -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
|
data/rack.gemspec
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'lib/rack/version'
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
s.name = "rack"
|
7
|
-
s.version = Rack::RELEASE
|
8
|
-
s.platform = Gem::Platform::RUBY
|
9
|
-
s.summary = "A modular Ruby webserver interface."
|
10
|
-
s.license = "MIT"
|
11
|
-
|
12
|
-
s.description = <<~EOF
|
13
|
-
Rack provides a minimal, modular and adaptable interface for developing
|
14
|
-
web applications in Ruby. By wrapping HTTP requests and responses in
|
15
|
-
the simplest way possible, it unifies and distills the API for web
|
16
|
-
servers, web frameworks, and software in between (the so-called
|
17
|
-
middleware) into a single method call.
|
18
|
-
EOF
|
19
|
-
|
20
|
-
s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] +
|
21
|
-
%w(MIT-LICENSE rack.gemspec Rakefile README.rdoc SPEC.rdoc)
|
22
|
-
|
23
|
-
s.bindir = 'bin'
|
24
|
-
s.executables << 'rackup'
|
25
|
-
s.require_path = 'lib'
|
26
|
-
s.extra_rdoc_files = ['README.rdoc', 'CHANGELOG.md', 'CONTRIBUTING.md']
|
27
|
-
|
28
|
-
s.author = 'Leah Neukirchen'
|
29
|
-
s.email = 'leah@vuxu.org'
|
30
|
-
|
31
|
-
s.homepage = 'https://github.com/rack/rack'
|
32
|
-
|
33
|
-
s.required_ruby_version = '>= 2.3.0'
|
34
|
-
|
35
|
-
s.metadata = {
|
36
|
-
"bug_tracker_uri" => "https://github.com/rack/rack/issues",
|
37
|
-
"changelog_uri" => "https://github.com/rack/rack/blob/master/CHANGELOG.md",
|
38
|
-
"documentation_uri" => "https://rubydoc.info/github/rack/rack",
|
39
|
-
"source_code_uri" => "https://github.com/rack/rack"
|
40
|
-
}
|
41
|
-
|
42
|
-
s.add_development_dependency 'minitest', "~> 5.0"
|
43
|
-
s.add_development_dependency 'minitest-sprint'
|
44
|
-
s.add_development_dependency 'minitest-global_expectations'
|
45
|
-
s.add_development_dependency 'rake'
|
46
|
-
end
|