Skip to content

Commit 183d830

Browse files
committed
1 parent ff8c087 commit 183d830

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

rack/lib/rack/session/pool.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def get_session(env, sid)
5353

5454
def set_session(env, session_id, new_session, options)
5555
with_lock(env, false) do
56+
return false unless @pool.key?(session_id)
5657
@pool.store session_id, new_session
5758
session_id
5859
end
@@ -61,7 +62,11 @@ def set_session(env, session_id, new_session, options)
6162
def destroy_session(env, session_id, options)
6263
with_lock(env) do
6364
@pool.delete(session_id)
64-
generate_sid unless options[:drop]
65+
unless options[:drop]
66+
sid = generate_sid
67+
@pool.store sid, {}
68+
sid
69+
end
6570
end
6671
end
6772

rack/test/spec_session_pool.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,59 @@
206206
res = Rack::MockRequest.new(app).get("/")
207207
res["Set-Cookie"].should.be.nil
208208
end
209+
210+
user_id_session = Rack::Lint.new(lambda do |env|
211+
session = env["rack.session"]
212+
213+
case env["PATH_INFO"]
214+
when "/login"
215+
session[:user_id] = 1
216+
when "/logout"
217+
if session[:user_id].nil?
218+
raise "User not logged in"
219+
end
220+
221+
session.delete(:user_id)
222+
env['rack.session.options'][:renew] = true
223+
when "/slow"
224+
session[:user_id]
225+
@ready_queue.push(:ready)
226+
@pause_queue.pop
227+
end
228+
229+
Rack::Response.new(session.to_hash.inspect).to_a
230+
end)
231+
232+
it "doesn't allow session id to be reused" do
233+
app = Rack::Session::Pool.new(user_id_session)
234+
@ready_queue = Queue.new
235+
@pause_queue = Queue.new
236+
237+
login_response = Rack::MockRequest.new(app).get("/login")
238+
login_cookie = login_response["Set-Cookie"]
239+
240+
slow_request_thread = Thread.new do
241+
Rack::MockRequest.new(app).get("/slow", "HTTP_COOKIE" => login_cookie)
242+
end
243+
244+
@ready_queue.pop
245+
# Request is now idling in '/slow'
246+
247+
# Check that the session is valid:
248+
response = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => login_cookie)
249+
response.body.should.equal({"user_id" => 1}.inspect)
250+
251+
logout_response = Rack::MockRequest.new(app).get("/logout", "HTTP_COOKIE" => login_cookie)
252+
logout_cookie = logout_response["Set-Cookie"]
253+
254+
# Check that the session id is different after logout:
255+
login_cookie[session_match].should.not.equal logout_cookie[session_match]
256+
257+
@pause_queue.push(:continue)
258+
slow_response = slow_request_thread.value
259+
260+
# Check that the cookie can't be reused:
261+
response = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => login_cookie)
262+
response.body.should.equal "{}"
263+
end
209264
end

0 commit comments

Comments
 (0)