rack 1.4.7 → 2.1.4
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 +5 -5
- data/CHANGELOG.md +77 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +122 -456
- data/Rakefile +32 -31
- data/SPEC +119 -29
- 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 +7 -5
- data/lib/rack/auth/abstract/request.rb +8 -6
- data/lib/rack/auth/basic.rb +5 -2
- data/lib/rack/auth/digest/md5.rb +10 -8
- 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 +4 -2
- data/lib/rack/body_proxy.rb +11 -9
- data/lib/rack/builder.rb +63 -20
- data/lib/rack/cascade.rb +10 -9
- data/lib/rack/chunked.rb +45 -11
- data/lib/rack/{commonlogger.rb → common_logger.rb} +24 -15
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -6
- data/lib/rack/config.rb +7 -0
- data/lib/rack/content_length.rb +12 -6
- data/lib/rack/content_type.rb +4 -2
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +73 -42
- data/lib/rack/directory.rb +77 -56
- data/lib/rack/etag.rb +25 -13
- data/lib/rack/events.rb +156 -0
- data/lib/rack/file.rb +4 -143
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler/cgi.rb +18 -17
- data/lib/rack/handler/fastcgi.rb +21 -17
- data/lib/rack/handler/lsws.rb +14 -12
- data/lib/rack/handler/scgi.rb +27 -21
- data/lib/rack/handler/thin.rb +19 -5
- data/lib/rack/handler/webrick.rb +66 -24
- data/lib/rack/handler.rb +29 -19
- data/lib/rack/head.rb +21 -14
- data/lib/rack/lint.rb +259 -65
- data/lib/rack/lobster.rb +17 -10
- data/lib/rack/lock.rb +19 -10
- data/lib/rack/logger.rb +4 -2
- data/lib/rack/media_type.rb +43 -0
- data/lib/rack/method_override.rb +52 -0
- data/lib/rack/mime.rb +43 -6
- data/lib/rack/mock.rb +109 -44
- data/lib/rack/multipart/generator.rb +11 -12
- data/lib/rack/multipart/parser.rb +302 -115
- data/lib/rack/multipart/uploaded_file.rb +4 -3
- data/lib/rack/multipart.rb +40 -9
- data/lib/rack/null_logger.rb +39 -0
- data/lib/rack/query_parser.rb +218 -0
- data/lib/rack/recursive.rb +14 -11
- data/lib/rack/reloader.rb +12 -5
- data/lib/rack/request.rb +484 -270
- data/lib/rack/response.rb +196 -77
- data/lib/rack/rewindable_input.rb +5 -14
- data/lib/rack/runtime.rb +13 -6
- data/lib/rack/sendfile.rb +44 -20
- data/lib/rack/server.rb +175 -61
- data/lib/rack/session/abstract/id.rb +276 -133
- data/lib/rack/session/cookie.rb +75 -40
- data/lib/rack/session/memcache.rb +4 -87
- data/lib/rack/session/pool.rb +24 -18
- data/lib/rack/show_exceptions.rb +392 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +11 -9
- data/lib/rack/static.rb +65 -38
- data/lib/rack/tempfile_reaper.rb +24 -0
- data/lib/rack/urlmap.rb +40 -15
- data/lib/rack/utils.rb +316 -285
- data/lib/rack.rb +78 -23
- data/rack.gemspec +26 -19
- metadata +44 -209
- data/KNOWN-ISSUES +0 -30
- 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 -100
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/methodoverride.rb +0 -33
- data/lib/rack/nulllogger.rb +0 -18
- data/lib/rack/showexceptions.rb +0 -378
- 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/lighttpd.errors +0 -1
- 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_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +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/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.rb +0 -57
- data/test/spec_auth_basic.rb +0 -81
- data/test/spec_auth_digest.rb +0 -259
- data/test/spec_body_proxy.rb +0 -69
- data/test/spec_builder.rb +0 -207
- data/test/spec_cascade.rb +0 -61
- data/test/spec_cgi.rb +0 -102
- data/test/spec_chunked.rb +0 -87
- data/test/spec_commonlogger.rb +0 -57
- data/test/spec_conditionalget.rb +0 -102
- data/test/spec_config.rb +0 -22
- data/test/spec_content_length.rb +0 -86
- data/test/spec_content_type.rb +0 -45
- data/test/spec_deflater.rb +0 -187
- data/test/spec_directory.rb +0 -88
- data/test/spec_etag.rb +0 -98
- data/test/spec_fastcgi.rb +0 -107
- data/test/spec_file.rb +0 -200
- data/test/spec_handler.rb +0 -59
- data/test/spec_head.rb +0 -48
- data/test/spec_lint.rb +0 -515
- data/test/spec_lobster.rb +0 -58
- data/test/spec_lock.rb +0 -167
- data/test/spec_logger.rb +0 -23
- data/test/spec_methodoverride.rb +0 -72
- data/test/spec_mock.rb +0 -269
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_multipart.rb +0 -479
- data/test/spec_nulllogger.rb +0 -23
- data/test/spec_recursive.rb +0 -72
- data/test/spec_request.rb +0 -955
- data/test/spec_response.rb +0 -313
- data/test/spec_rewindable_input.rb +0 -118
- data/test/spec_runtime.rb +0 -49
- data/test/spec_sendfile.rb +0 -90
- data/test/spec_server.rb +0 -121
- data/test/spec_session_abstract_id.rb +0 -43
- data/test/spec_session_cookie.rb +0 -361
- data/test/spec_session_memcache.rb +0 -321
- data/test/spec_session_pool.rb +0 -209
- data/test/spec_showexceptions.rb +0 -92
- data/test/spec_showstatus.rb +0 -84
- data/test/spec_static.rb +0 -145
- data/test/spec_thin.rb +0 -86
- data/test/spec_urlmap.rb +0 -213
- data/test/spec_utils.rb +0 -554
- data/test/spec_webrick.rb +0 -143
- 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/session/cookie.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'openssl'
|
4
|
+
require 'zlib'
|
2
5
|
require 'rack/request'
|
3
6
|
require 'rack/response'
|
4
7
|
require 'rack/session/abstract/id'
|
8
|
+
require 'json'
|
9
|
+
require 'base64'
|
5
10
|
|
6
11
|
module Rack
|
7
12
|
|
@@ -43,15 +48,15 @@ module Rack
|
|
43
48
|
# })
|
44
49
|
#
|
45
50
|
|
46
|
-
class Cookie < Abstract::
|
51
|
+
class Cookie < Abstract::PersistedSecure
|
47
52
|
# Encode session cookies as Base64
|
48
53
|
class Base64
|
49
54
|
def encode(str)
|
50
|
-
|
55
|
+
::Base64.strict_encode64(str)
|
51
56
|
end
|
52
57
|
|
53
58
|
def decode(str)
|
54
|
-
|
59
|
+
::Base64.decode64(str)
|
55
60
|
end
|
56
61
|
|
57
62
|
# Encode session cookies as Marshaled Base64 data
|
@@ -61,9 +66,36 @@ module Rack
|
|
61
66
|
end
|
62
67
|
|
63
68
|
def decode(str)
|
69
|
+
return unless str
|
64
70
|
::Marshal.load(super(str)) rescue nil
|
65
71
|
end
|
66
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
|
67
99
|
end
|
68
100
|
|
69
101
|
# Use no encoding for session cookies
|
@@ -72,17 +104,13 @@ module Rack
|
|
72
104
|
def decode(str); str; end
|
73
105
|
end
|
74
106
|
|
75
|
-
# Reverse string encoding. (trollface)
|
76
|
-
class Reverse
|
77
|
-
def encode(str); str.reverse; end
|
78
|
-
def decode(str); str.reverse; end
|
79
|
-
end
|
80
|
-
|
81
107
|
attr_reader :coder
|
82
108
|
|
83
|
-
def initialize(app, options={})
|
109
|
+
def initialize(app, options = {})
|
84
110
|
@secrets = options.values_at(:secret, :old_secret).compact
|
85
|
-
|
111
|
+
@hmac = options.fetch(:hmac, OpenSSL::Digest::SHA1)
|
112
|
+
|
113
|
+
warn <<-MSG unless secure?(options)
|
86
114
|
SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
|
87
115
|
This poses a security threat. It is strongly recommended that you
|
88
116
|
provide a secret to prevent exploits that may be possible from crafted
|
@@ -91,78 +119,85 @@ module Rack
|
|
91
119
|
|
92
120
|
Called from: #{caller[0]}.
|
93
121
|
MSG
|
94
|
-
@coder
|
95
|
-
super(app, options.merge!(:
|
122
|
+
@coder = options[:coder] ||= Base64::Marshal.new
|
123
|
+
super(app, options.merge!(cookie_only: true))
|
96
124
|
end
|
97
125
|
|
98
126
|
private
|
99
127
|
|
100
|
-
def
|
101
|
-
data = unpacked_cookie_data(
|
128
|
+
def find_session(req, sid)
|
129
|
+
data = unpacked_cookie_data(req)
|
102
130
|
data = persistent_session_id!(data)
|
103
131
|
[data["session_id"], data]
|
104
132
|
end
|
105
133
|
|
106
|
-
def extract_session_id(
|
107
|
-
unpacked_cookie_data(
|
134
|
+
def extract_session_id(request)
|
135
|
+
unpacked_cookie_data(request)["session_id"]
|
108
136
|
end
|
109
137
|
|
110
|
-
def unpacked_cookie_data(
|
111
|
-
|
112
|
-
request = Rack::Request.new(env)
|
138
|
+
def unpacked_cookie_data(request)
|
139
|
+
request.fetch_header(RACK_SESSION_UNPACKED_COOKIE_DATA) do |k|
|
113
140
|
session_data = request.cookies[@key]
|
114
141
|
|
115
142
|
if @secrets.size > 0 && session_data
|
116
|
-
session_data, digest = session_data.
|
117
|
-
|
118
|
-
if session_data && digest
|
119
|
-
ok = @secrets.any? do |secret|
|
120
|
-
secret && Rack::Utils.secure_compare(digest, generate_hmac(session_data, secret))
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
session_data = nil unless ok
|
143
|
+
session_data, _, digest = session_data.rpartition('--')
|
144
|
+
session_data = nil unless digest_match?(session_data, digest)
|
125
145
|
end
|
126
146
|
|
127
|
-
coder.decode(session_data) || {}
|
147
|
+
request.set_header(k, coder.decode(session_data) || {})
|
128
148
|
end
|
129
149
|
end
|
130
150
|
|
131
|
-
def persistent_session_id!(data, sid=nil)
|
151
|
+
def persistent_session_id!(data, sid = nil)
|
132
152
|
data ||= {}
|
133
153
|
data["session_id"] ||= sid || generate_sid
|
134
154
|
data
|
135
155
|
end
|
136
156
|
|
137
|
-
|
157
|
+
class SessionId < DelegateClass(Session::SessionId)
|
158
|
+
attr_reader :cookie_value
|
138
159
|
|
139
|
-
|
140
|
-
|
160
|
+
def initialize(session_id, cookie_value)
|
161
|
+
super(session_id)
|
162
|
+
@cookie_value = cookie_value
|
163
|
+
end
|
141
164
|
end
|
142
165
|
|
143
|
-
def
|
166
|
+
def write_session(req, session_id, session, options)
|
144
167
|
session = session.merge("session_id" => session_id)
|
145
168
|
session_data = coder.encode(session)
|
146
169
|
|
147
170
|
if @secrets.first
|
148
|
-
session_data
|
171
|
+
session_data << "--#{generate_hmac(session_data, @secrets.first)}"
|
149
172
|
end
|
150
173
|
|
151
174
|
if session_data.size > (4096 - @key.size)
|
152
|
-
|
175
|
+
req.get_header(RACK_ERRORS).puts("Warning! Rack::Session::Cookie data size exceeds 4K.")
|
153
176
|
nil
|
154
177
|
else
|
155
|
-
session_data
|
178
|
+
SessionId.new(session_id, session_data)
|
156
179
|
end
|
157
180
|
end
|
158
181
|
|
159
|
-
def
|
182
|
+
def delete_session(req, session_id, options)
|
160
183
|
# Nothing to do here, data is in the client
|
161
184
|
generate_sid unless options[:drop]
|
162
185
|
end
|
163
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
|
+
|
164
194
|
def generate_hmac(data, secret)
|
165
|
-
OpenSSL::HMAC.hexdigest(
|
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])
|
166
201
|
end
|
167
202
|
|
168
203
|
end
|
@@ -1,93 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rack/session/
|
4
|
-
require 'memcache'
|
3
|
+
require 'rack/session/dalli'
|
5
4
|
|
6
5
|
module Rack
|
7
6
|
module Session
|
8
|
-
|
9
|
-
|
10
|
-
# maintained in the cookie.
|
11
|
-
# You may treat Session::Memcache as you would Session::Pool with the
|
12
|
-
# following caveats.
|
13
|
-
#
|
14
|
-
# * Setting :expire_after to 0 would note to the Memcache server to hang
|
15
|
-
# onto the session data until it would drop it according to it's own
|
16
|
-
# specifications. However, the cookie sent to the client would expire
|
17
|
-
# immediately.
|
18
|
-
#
|
19
|
-
# Note that memcache does drop data before it may be listed to expire. For
|
20
|
-
# a full description of behaviour, please see memcache's documentation.
|
21
|
-
|
22
|
-
class Memcache < Abstract::ID
|
23
|
-
attr_reader :mutex, :pool
|
24
|
-
|
25
|
-
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \
|
26
|
-
:namespace => 'rack:session',
|
27
|
-
:memcache_server => 'localhost:11211'
|
28
|
-
|
29
|
-
def initialize(app, options={})
|
30
|
-
super
|
31
|
-
|
32
|
-
@mutex = Mutex.new
|
33
|
-
mserv = @default_options[:memcache_server]
|
34
|
-
mopts = @default_options.reject{|k,v| !MemCache::DEFAULT_OPTIONS.include? k }
|
35
|
-
|
36
|
-
@pool = options[:cache] || MemCache.new(mserv, mopts)
|
37
|
-
unless @pool.active? and @pool.servers.any?{|c| c.alive? }
|
38
|
-
raise 'No memcache servers'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def generate_sid
|
43
|
-
loop do
|
44
|
-
sid = super
|
45
|
-
break sid unless @pool.get(sid, true)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_session(env, sid)
|
50
|
-
with_lock(env, [nil, {}]) do
|
51
|
-
unless sid and session = @pool.get(sid)
|
52
|
-
sid, session = generate_sid, {}
|
53
|
-
unless /^STORED/ =~ @pool.add(sid, session)
|
54
|
-
raise "Session collision on '#{sid.inspect}'"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
[sid, session]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def set_session(env, session_id, new_session, options)
|
62
|
-
expiry = options[:expire_after]
|
63
|
-
expiry = expiry.nil? ? 0 : expiry + 1
|
64
|
-
|
65
|
-
with_lock(env, false) do
|
66
|
-
@pool.set session_id, new_session, expiry
|
67
|
-
session_id
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def destroy_session(env, session_id, options)
|
72
|
-
with_lock(env) do
|
73
|
-
@pool.delete(session_id)
|
74
|
-
generate_sid unless options[:drop]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def with_lock(env, default=nil)
|
79
|
-
@mutex.lock if env['rack.multithread']
|
80
|
-
yield
|
81
|
-
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
82
|
-
if $VERBOSE
|
83
|
-
warn "#{self} is unable to find memcached server."
|
84
|
-
warn $!.inspect
|
85
|
-
end
|
86
|
-
default
|
87
|
-
ensure
|
88
|
-
@mutex.unlock if @mutex.locked?
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
7
|
+
warn "Rack::Session::Memcache is deprecated, please use Rack::Session::Dalli from 'dalli' gem instead."
|
8
|
+
Memcache = Dalli
|
92
9
|
end
|
93
10
|
end
|
data/lib/rack/session/pool.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
|
2
4
|
# THANKS:
|
3
5
|
# apeiros, for session id generation, expiry setup, and threadiness
|
@@ -24,11 +26,11 @@ module Rack
|
|
24
26
|
# )
|
25
27
|
# Rack::Handler::WEBrick.run sessioned
|
26
28
|
|
27
|
-
class Pool < Abstract::
|
29
|
+
class Pool < Abstract::PersistedSecure
|
28
30
|
attr_reader :mutex, :pool
|
29
|
-
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :
|
31
|
+
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge drop: false
|
30
32
|
|
31
|
-
def initialize(app, options={})
|
33
|
+
def initialize(app, options = {})
|
32
34
|
super
|
33
35
|
@pool = Hash.new
|
34
36
|
@mutex = Mutex.new
|
@@ -37,43 +39,47 @@ module Rack
|
|
37
39
|
def generate_sid
|
38
40
|
loop do
|
39
41
|
sid = super
|
40
|
-
break sid unless @pool.key? sid
|
42
|
+
break sid unless @pool.key? sid.private_id
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
def
|
45
|
-
with_lock(
|
46
|
-
unless sid and session =
|
46
|
+
def find_session(req, sid)
|
47
|
+
with_lock(req) do
|
48
|
+
unless sid and session = get_session_with_fallback(sid)
|
47
49
|
sid, session = generate_sid, {}
|
48
|
-
@pool.store sid, session
|
50
|
+
@pool.store sid.private_id, session
|
49
51
|
end
|
50
52
|
[sid, session]
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
|
-
def
|
55
|
-
with_lock(
|
56
|
-
@pool.store session_id, new_session
|
56
|
+
def write_session(req, session_id, new_session, options)
|
57
|
+
with_lock(req) do
|
58
|
+
@pool.store session_id.private_id, new_session
|
57
59
|
session_id
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
def
|
62
|
-
with_lock(
|
63
|
-
@pool.delete(session_id)
|
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)
|
64
67
|
generate_sid unless options[:drop]
|
65
68
|
end
|
66
69
|
end
|
67
70
|
|
68
|
-
def with_lock(
|
69
|
-
@mutex.lock if
|
71
|
+
def with_lock(req)
|
72
|
+
@mutex.lock if req.multithread?
|
70
73
|
yield
|
71
|
-
rescue
|
72
|
-
default
|
73
74
|
ensure
|
74
75
|
@mutex.unlock if @mutex.locked?
|
75
76
|
end
|
76
77
|
|
78
|
+
private
|
79
|
+
|
80
|
+
def get_session_with_fallback(sid)
|
81
|
+
@pool[sid.private_id] || @pool[sid.public_id]
|
82
|
+
end
|
77
83
|
end
|
78
84
|
end
|
79
85
|
end
|