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:
parent
b549d93d2f
commit
d69ebb849a
3 changed files with 25 additions and 21 deletions
|
@ -18,29 +18,28 @@ 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
|
||||||
|
|
||||||
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)
|
||||||
@session_id_loaded = true
|
ensure
|
||||||
end
|
@session_id_loaded = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class SessionHash < Hash
|
class SessionHash < Hash
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue