aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2005-11-09 06:00:46 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2005-11-09 06:00:46 +0000
commitbb4c32e2b5858b25524191ee4868e616fa5bd9be (patch)
tree510545bd430a8d8905e0b84cf8da0b25f38e35b2 /actionpack/lib/action_controller
parent98ae24b9676fb4c28d25c13ace8d08ec741aad04 (diff)
downloadrails-bb4c32e2b5858b25524191ee4868e616fa5bd9be.tar.gz
rails-bb4c32e2b5858b25524191ee4868e616fa5bd9be.tar.bz2
rails-bb4c32e2b5858b25524191ee4868e616fa5bd9be.zip
Delete existing sessions with the same session id before creating a new session. Prevents duplication and hijacking.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2946 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/cgi_process.rb69
1 files changed, 42 insertions, 27 deletions
diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb
index 7f05e21cb8..62bbd02e32 100644
--- a/actionpack/lib/action_controller/cgi_process.rb
+++ b/actionpack/lib/action_controller/cgi_process.rb
@@ -89,37 +89,26 @@ module ActionController #:nodoc:
def port_from_http_host
$1.to_i if env['HTTP_HOST'] && /:(\d+)$/ =~ env['HTTP_HOST']
end
-
- def session
- return @session unless @session.nil?
- begin
- @session = (@session_options == false ? {} : CGI::Session.new(@cgi, session_options_with_string_keys))
- @session["__valid_session"]
- return @session
- rescue ArgumentError => e
- if e.message =~ %r{undefined class/module (\w+)}
- begin
- Module.const_missing($1)
- rescue LoadError, NameError => e
- raise(
- ActionController::SessionRestoreError,
- "Session contained objects where the class definition wasn't available. " +
- "Remember to require classes for all objects kept in the session. " +
- "(Original exception: #{e.message} [#{e.class}])"
- )
- end
-
- retry
+ def session
+ unless @session
+ if @session_options == false
+ @session = Hash.new
else
- raise
+ if session_options_with_string_keys['new_session'] == true
+ @session = new_session
+ else
+ @session = CGI::Session.new(@cgi, session_options_with_string_keys)
+ end
+ stale_session_check!
end
end
+ @session
end
-
+
def reset_session
@session.delete if CGI::Session === @session
- @session = (@session_options == false ? {} : new_session)
+ @session = new_session
end
def method_missing(method_id, *arguments)
@@ -127,12 +116,38 @@ module ActionController #:nodoc:
end
private
+ # Delete an old session if it exists then create a new one.
def new_session
- CGI::Session.new(@cgi, session_options_with_string_keys.update("new_session" => true))
+ if @session_options == false
+ Hash.new
+ else
+ CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => false)).delete rescue nil
+ CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => true))
+ end
end
-
+
+ def stale_session_check!
+ @session['__valid_session']
+ rescue ArgumentError => argument_error
+ if argument_error.message =~ %r{undefined class/module (\w+)}
+ begin
+ Module.const_missing($1)
+ rescue LoadError, NameError => const_error
+ raise ActionController::SessionRestoreError, <<end_msg
+Session contains objects whose class definition isn't available.
+Remember to require the classes for all objects kept in the session.
+(Original exception: #{const_error.message} [#{const_error.class}])
+end_msg
+ end
+
+ retry
+ else
+ raise
+ end
+ end
+
def session_options_with_string_keys
- DEFAULT_SESSION_OPTIONS.merge(@session_options).inject({}) { |options, (k,v)| options[k.to_s] = v; options }
+ @session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).inject({}) { |options, (k,v)| options[k.to_s] = v; options }
end
end