1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Avoid deserializing cookies too early, which causes session objects to not be available yet. Unfortunately, could not reproduce this in a test case.

This commit is contained in:
José Valim 2010-06-24 20:02:23 +02:00
parent b549d93d2f
commit d69ebb849a
3 changed files with 25 additions and 21 deletions

View file

@ -18,15 +18,13 @@ module ActionDispatch
def initialize(by, env, default_options) def initialize(by, env, default_options)
@by = by @by = by
@env = env @env = env
merge!(default_options)
@session_id_loaded = false @session_id_loaded = false
merge!(default_options)
end end
alias_method :get_without_session_load, :[]
def [](key) def [](key)
if key == :id if key == :id
load_session_id! unless has_session_id? load_session_id! unless key?(:id) || has_session_id?
end end
super(key) super(key)
end end
@ -34,11 +32,12 @@ module ActionDispatch
private private
def has_session_id? def has_session_id?
get_without_session_load(:id).present? || @session_id_loaded @session_id_loaded
end end
def load_session_id! def load_session_id!
self[:id] = @by.send(:extract_session_id, @env) self[:id] = @by.send(:extract_session_id, @env)
ensure
@session_id_loaded = true @session_id_loaded = true
end end
end end
@ -99,7 +98,7 @@ module ActionDispatch
def destroy def destroy
clear clear
@by.send(:destroy, @env) if @by @by.send(:destroy, @env) if @by
@env[ENV_SESSION_OPTIONS_KEY].delete(:id) if @env && @env[ENV_SESSION_OPTIONS_KEY] @env[ENV_SESSION_OPTIONS_KEY][:id] = nil if @env && @env[ENV_SESSION_OPTIONS_KEY]
@loaded = false @loaded = false
end end
@ -164,8 +163,8 @@ module ActionDispatch
session_data = env[ENV_SESSION_KEY] session_data = env[ENV_SESSION_KEY]
options = env[ENV_SESSION_OPTIONS_KEY] options = env[ENV_SESSION_OPTIONS_KEY]
if !session_data.is_a?(AbstractStore::SessionHash) || session_data.send(:loaded?) || options[:expire_after] if !session_data.is_a?(AbstractStore::SessionHash) || session_data.loaded? || options[:expire_after]
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.send(:loaded?) session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.loaded?
sid = options[:id] || generate_sid sid = options[:id] || generate_sid
session_data = session_data.to_hash session_data = session_data.to_hash
@ -189,7 +188,7 @@ module ActionDispatch
def prepare!(env) def prepare!(env)
env[ENV_SESSION_KEY] = SessionHash.new(self, env) env[ENV_SESSION_KEY] = SessionHash.new(self, env)
env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options.dup) env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options)
end end
def generate_sid def generate_sid
@ -207,7 +206,7 @@ module ActionDispatch
end end
def extract_session_id(env) def extract_session_id(env)
request = Rack::Request.new(env) request = ActionDispatch::Request.new(env)
sid = request.cookies[@key] sid = request.cookies[@key]
sid ||= request.params[@key] unless @cookie_only sid ||= request.params[@key] unless @cookie_only
sid sid

View file

@ -65,8 +65,9 @@ module ActionDispatch
request = ActionDispatch::Request.new(env) request = ActionDispatch::Request.new(env)
if data = request.cookie_jar.signed[@key] if data = request.cookie_jar.signed[@key]
data.stringify_keys! data.stringify_keys!
else
{}
end end
data
end end
def set_cookie(request, options) def set_cookie(request, options)
@ -77,6 +78,10 @@ module ActionDispatch
persistent_session_id!(session_data, sid) persistent_session_id!(session_data, sid)
end end
def exists?(env)
ActionDispatch::Request.new(env).cookie_jar.key?(@key)
end
def destroy(env) def destroy(env)
# session data is stored on client; nothing to do here # session data is stored on client; nothing to do here
end end

View file

@ -205,21 +205,21 @@ class CookieStoreTest < ActionController::IntegrationTest
def test_session_store_without_domain def test_session_store_without_domain
with_test_route_set do with_test_route_set do
get '/set_session_value' get '/set_session_value'
assert_no_match /domain\=/, headers['Set-Cookie'] assert_no_match(/domain\=/, headers['Set-Cookie'])
end end
end end
def test_session_store_with_nil_domain def test_session_store_with_nil_domain
with_test_route_set(:domain => nil) do with_test_route_set(:domain => nil) do
get '/set_session_value' get '/set_session_value'
assert_no_match /domain\=/, headers['Set-Cookie'] assert_no_match(/domain\=/, headers['Set-Cookie'])
end end
end end
def test_session_store_with_all_domains def test_session_store_with_all_domains
with_test_route_set(:domain => :all) do with_test_route_set(:domain => :all) do
get '/set_session_value' get '/set_session_value'
assert_match /domain=\.example\.com/, headers['Set-Cookie'] assert_match(/domain=\.example\.com/, headers['Set-Cookie'])
end end
end end