Permalink
Browse files

Fix reset_session with lazy cookie stores [#1601 state:resolved]

Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information...
1 parent 462c75b commit 7b249b67e9df9f375eaad9e6eb41be73338faaa7 Matt Bauer committed with josh Dec 20, 2008
@@ -53,6 +53,10 @@ def data
end
private
+ def loaded?
+ @loaded
+ end
+
def load!
@id, session = @by.send(:load_session, @env)
replace(session)
@@ -91,19 +95,23 @@ def initialize(app, options = {})
def call(env)
session = SessionHash.new(self, env)
- original_session = session.dup
env[ENV_SESSION_KEY] = session
env[ENV_SESSION_OPTIONS_KEY] = @default_options.dup
response = @app.call(env)
- session = env[ENV_SESSION_KEY]
- unless session == original_session
+ session_data = env[ENV_SESSION_KEY]
+ if !session_data.is_a?(AbstractStore::SessionHash) || session_data.send(:loaded?)
options = env[ENV_SESSION_OPTIONS_KEY]
- sid = session.id
- unless set_session(env, sid, session.to_hash)
+ if session_data.is_a?(AbstractStore::SessionHash)
+ sid = session_data.id
+ else
+ sid = generate_sid
+ end
+
+ unless set_session(env, sid, session_data.to_hash)
return response
end
@@ -89,16 +89,14 @@ def initialize(app, options = {})
end
def call(env)
- session_data = AbstractStore::SessionHash.new(self, env)
- original_value = session_data.dup
-
- env[ENV_SESSION_KEY] = session_data
+ env[ENV_SESSION_KEY] = AbstractStore::SessionHash.new(self, env)
env[ENV_SESSION_OPTIONS_KEY] = @default_options
status, headers, body = @app.call(env)
- unless env[ENV_SESSION_KEY] == original_value
- session_data = marshal(env[ENV_SESSION_KEY].to_hash)
+ session_data = env[ENV_SESSION_KEY]
+ if !session_data.is_a?(AbstractStore::SessionHash) || session_data.send(:loaded?)
+ session_data = marshal(session_data.to_hash)
raise CookieOverflow if session_data.size > MAX
@@ -153,7 +151,7 @@ def load_session(env)
# Marshal a session hash into safe cookie data. Include an integrity hash.
def marshal(session)
- @verifier.generate( persistent_session_id!(session))
+ @verifier.generate(persistent_session_id!(session))
end
# Unmarshal cookie data to a hash and verify its integrity.
@@ -32,6 +32,11 @@ def get_session_value
render :text => "foo: #{session[:foo].inspect}"
end
+ def call_reset_session
+ reset_session
+ head :ok
+ end
+
def raise_data_overflow
session[:foo] = 'bye!' * 1024
head :ok
@@ -89,7 +94,7 @@ def test_setting_session_value
with_test_route_set do
get '/set_session_value'
assert_response :success
- session_payload = Verifier.generate( Marshal.load(response.body) )
+ session_payload = Verifier.generate(Marshal.load(response.body))
assert_equal ["_myapp_session=#{session_payload}; path=/"],
headers['Set-Cookie']
end
@@ -139,6 +144,25 @@ def test_doesnt_write_session_cookie_if_session_is_unchanged
end
end
+ def test_setting_session_value_after_session_reset
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ session_payload = Verifier.generate(Marshal.load(response.body))
+ assert_equal ["_myapp_session=#{session_payload}; path=/"],
+ headers['Set-Cookie']
+
+ get '/call_reset_session'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+ assert_not_equal session_payload, cookies[SessionKey]
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: nil', response.body
+ end
+ end
+
def test_persistent_session_id
with_test_route_set do
cookies[SessionKey] = SignedBar
@@ -16,6 +16,11 @@ def get_session_value
render :text => "foo: #{session[:foo].inspect}"
end
+ def call_reset_session
+ reset_session
+ head :ok
+ end
+
def rescue_action(e) raise end
end
@@ -63,6 +68,22 @@ def test_prevents_session_fixation
assert_equal nil, cookies['_session_id']
end
end
+
+ def test_setting_session_value_after_session_reset
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/call_reset_session'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: nil', response.body
+ end
+ end
rescue LoadError, RuntimeError
$stderr.puts "Skipping MemCacheStoreTest tests. Start memcached and try again."
end

0 comments on commit 7b249b6

Please sign in to comment.