diff options
author | Marcel Molina <marcel@vernix.org> | 2005-10-15 14:39:29 +0000 |
---|---|---|
committer | Marcel Molina <marcel@vernix.org> | 2005-10-15 14:39:29 +0000 |
commit | 48fd667bda20b899c8c2f0c68a403476f083effc (patch) | |
tree | 7ef50bcc0a06ecac3eb4adfa5ed0c8a9f6aaa88c /actionpack/lib/action_controller/session/active_record_store.rb | |
parent | 6a8b9484a7398f3b500cd1f056cbe46fd7d6301c (diff) | |
download | rails-48fd667bda20b899c8c2f0c68a403476f083effc.tar.gz rails-48fd667bda20b899c8c2f0c68a403476f083effc.tar.bz2 rails-48fd667bda20b899c8c2f0c68a403476f083effc.zip |
Raise an exception if an attempt is made to insert more session data into the ActiveRecordStore data column than the column can hold. Closes #2234.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2612 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_controller/session/active_record_store.rb')
-rw-r--r-- | actionpack/lib/action_controller/session/active_record_store.rb | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/actionpack/lib/action_controller/session/active_record_store.rb b/actionpack/lib/action_controller/session/active_record_store.rb index 130ce12150..90d9f3fbe1 100644 --- a/actionpack/lib/action_controller/session/active_record_store.rb +++ b/actionpack/lib/action_controller/session/active_record_store.rb @@ -33,13 +33,23 @@ class CGI # # The fast SqlBypass class is a generic SQL session store. You may # use it as a basis for high-performance database-specific stores. + # + # If the data you are attempting to write to the +data+ column is larger + # than the column's size limit, ActionController::SessionOverflowError + # will be raised. class ActiveRecordStore # The default Active Record class. class Session < ActiveRecord::Base before_save :marshal_data! + before_save :ensure_data_not_too_big before_update :data_changed? class << self + + def data_column_size_limit + connection.columns(table_name).find {|column| column.name == 'data'}.limit + end + # Hook to set up sessid compatibility. def find_by_session_id(session_id) setup_sessid_compatibility! @@ -55,7 +65,7 @@ class CGI CREATE TABLE #{table_name} ( id INTEGER PRIMARY KEY, #{connection.quote_column_name('session_id')} TEXT UNIQUE, - #{connection.quote_column_name('data')} TEXT + #{connection.quote_column_name('data')} TEXT(255) ) end_sql end @@ -109,6 +119,15 @@ class CGI old_fingerprint, @fingerprint = @fingerprint, self.class.fingerprint(read_attribute('data')) old_fingerprint != @fingerprint end + + # Ensures that the data about to be stored in the database is not + # larger than the data storage column. Raises + # ActionController::SessionOverflowError. + def ensure_data_not_too_big + return unless limit = self.class.data_column_size_limit + raise ActionController::SessionOverflowError, ActionController::SessionOverflowError::DEFAULT_MESSAGE if read_attribute('data').size > limit + end + end # A barebones session store which duck-types with the default session @@ -126,9 +145,6 @@ class CGI class SqlBypass # Use the ActiveRecord::Base.connection by default. cattr_accessor :connection - def self.connection - @@connection ||= ActiveRecord::Base.connection - end # The table name defaults to 'sessions'. cattr_accessor :table_name @@ -143,6 +159,11 @@ class CGI @@data_column = 'data' class << self + + def connection + @@connection ||= ActiveRecord::Base.connection + end + # Look up a session by id and unmarshal its data if found. def find_by_session_id(session_id) if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}") @@ -201,6 +222,7 @@ class CGI def save marshaled_data = self.class.marshal(data) + if @new_record @new_record = false @@connection.update <<-end_sql, 'Create session' @@ -231,6 +253,7 @@ class CGI end_sql end end + end # The class used for session storage. Defaults to @@ -278,6 +301,7 @@ class CGI @session = nil end end + end end end |