Upgrade to Rails 2.0.2
Upgraded to Rails 2.0.2, except that we maintain vendor/rails/actionpack/lib/action_controller/routing.rb from Rail 1.2.6 (at least for now), so that Routes don't change. We still get to enjoy Rails's many new features. Also fixed a bug in Chunk-handling: disable WikiWord processing in tags (for real this time).
This commit is contained in:
parent
0f6889e09f
commit
6873fc8026
1083 changed files with 52810 additions and 41058 deletions
|
@ -122,13 +122,14 @@ class CGI
|
|||
@data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {}
|
||||
end
|
||||
|
||||
attr_writer :data
|
||||
|
||||
# Has the session been loaded yet?
|
||||
def loaded?
|
||||
!! @data
|
||||
end
|
||||
|
||||
private
|
||||
attr_writer :data
|
||||
|
||||
def marshal_data!
|
||||
return false if !loaded?
|
||||
|
@ -332,4 +333,4 @@ class CGI
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
164
vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb
vendored
Normal file
164
vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
require 'cgi'
|
||||
require 'cgi/session'
|
||||
require 'base64' # to convert Marshal.dump to ASCII
|
||||
require 'openssl' # to generate the HMAC message digest
|
||||
|
||||
# This cookie-based session store is the Rails default. Sessions typically
|
||||
# contain at most a user_id and flash message; both fit within the 4K cookie
|
||||
# size limit. Cookie-based sessions are dramatically faster than the
|
||||
# alternatives.
|
||||
#
|
||||
# If you have more than 4K of session data or don't want your data to be
|
||||
# visible to the user, pick another session store.
|
||||
#
|
||||
# CookieOverflow is raised if you attempt to store more than 4K of data.
|
||||
# TamperedWithCookie is raised if the data integrity check fails.
|
||||
#
|
||||
# A message digest is included with the cookie to ensure data integrity:
|
||||
# a user cannot alter his user_id without knowing the secret key included in
|
||||
# the hash. New apps are generated with a pregenerated secret in
|
||||
# config/environment.rb. Set your own for old apps you're upgrading.
|
||||
#
|
||||
# Session options:
|
||||
# :secret An application-wide key string or block returning a string
|
||||
# called per generated digest. The block is called with the
|
||||
# CGI::Session instance as an argument. It's important that the
|
||||
# secret is not vulnerable to a dictionary attack. Therefore,
|
||||
# you should choose a secret consisting of random numbers and
|
||||
# letters and more than 30 characters.
|
||||
#
|
||||
# Example: :secret => '449fe2e7daee471bffae2fd8dc02313d'
|
||||
# :secret => Proc.new { User.current_user.secret_key }
|
||||
#
|
||||
# :digest The message digest algorithm used to verify session integrity
|
||||
# defaults to 'SHA1' but may be any digest provided by OpenSSL,
|
||||
# such as 'MD5', 'RIPEMD160', 'SHA256', etc.
|
||||
#
|
||||
# To generate a secret key for an existing application, run
|
||||
# `rake secret` and set the key in config/environment.rb
|
||||
#
|
||||
# Note that changing digest or secret invalidates all existing sessions!
|
||||
class CGI::Session::CookieStore
|
||||
# Cookies can typically store 4096 bytes.
|
||||
MAX = 4096
|
||||
SECRET_MIN_LENGTH = 30 # characters
|
||||
|
||||
# Raised when storing more than 4K of session data.
|
||||
class CookieOverflow < StandardError; end
|
||||
|
||||
# Raised when the cookie fails its integrity check.
|
||||
class TamperedWithCookie < StandardError; end
|
||||
|
||||
# Called from CGI::Session only.
|
||||
def initialize(session, options = {})
|
||||
# The session_key option is required.
|
||||
if options['session_key'].blank?
|
||||
raise ArgumentError, 'A session_key is required to write a cookie containing the session data. Use config.action_controller.session = { :session_key => "_myapp_session", :secret => "some secret phrase" } in config/environment.rb'
|
||||
end
|
||||
|
||||
# The secret option is required.
|
||||
ensure_secret_secure(options['secret'])
|
||||
|
||||
# Keep the session and its secret on hand so we can read and write cookies.
|
||||
@session, @secret = session, options['secret']
|
||||
|
||||
# Message digest defaults to SHA1.
|
||||
@digest = options['digest'] || 'SHA1'
|
||||
|
||||
# Default cookie options derived from session settings.
|
||||
@cookie_options = {
|
||||
'name' => options['session_key'],
|
||||
'path' => options['session_path'],
|
||||
'domain' => options['session_domain'],
|
||||
'expires' => options['session_expires'],
|
||||
'secure' => options['session_secure']
|
||||
}
|
||||
|
||||
# Set no_hidden and no_cookies since the session id is unused and we
|
||||
# set our own data cookie.
|
||||
options['no_hidden'] = true
|
||||
options['no_cookies'] = true
|
||||
end
|
||||
|
||||
# To prevent users from using something insecure like "Password" we make sure that the
|
||||
# secret they've provided is at least 30 characters in length.
|
||||
def ensure_secret_secure(secret)
|
||||
# There's no way we can do this check if they've provided a proc for the
|
||||
# secret.
|
||||
return true if secret.is_a?(Proc)
|
||||
|
||||
if secret.blank?
|
||||
raise ArgumentError, %Q{A secret is required to generate an integrity hash for cookie session data. Use config.action_controller.session = { :session_key => "_myapp_session", :secret => "some secret phrase of at least #{SECRET_MIN_LENGTH} characters" } in config/environment.rb}
|
||||
end
|
||||
|
||||
if secret.length < SECRET_MIN_LENGTH
|
||||
raise ArgumentError, %Q{Secret should be something secure, like "#{CGI::Session.generate_unique_id}". The value you provided, "#{secret}", is shorter than the minimum length of #{SECRET_MIN_LENGTH} characters}
|
||||
end
|
||||
end
|
||||
|
||||
# Restore session data from the cookie.
|
||||
def restore
|
||||
@original = read_cookie
|
||||
@data = unmarshal(@original) || {}
|
||||
end
|
||||
|
||||
# Wait until close to write the session data cookie.
|
||||
def update; end
|
||||
|
||||
# Write the session data cookie if it was loaded and has changed.
|
||||
def close
|
||||
if defined?(@data) && !@data.blank?
|
||||
updated = marshal(@data)
|
||||
raise CookieOverflow if updated.size > MAX
|
||||
write_cookie('value' => updated) unless updated == @original
|
||||
end
|
||||
end
|
||||
|
||||
# Delete the session data by setting an expired cookie with no data.
|
||||
def delete
|
||||
@data = nil
|
||||
clear_old_cookie_value
|
||||
write_cookie('value' => '', 'expires' => 1.year.ago)
|
||||
end
|
||||
|
||||
# Generate the HMAC keyed message digest. Uses SHA1 by default.
|
||||
def generate_digest(data)
|
||||
key = @secret.respond_to?(:call) ? @secret.call(@session) : @secret
|
||||
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), key, data)
|
||||
end
|
||||
|
||||
private
|
||||
# Marshal a session hash into safe cookie data. Include an integrity hash.
|
||||
def marshal(session)
|
||||
data = Base64.encode64(Marshal.dump(session)).chop
|
||||
CGI.escape "#{data}--#{generate_digest(data)}"
|
||||
end
|
||||
|
||||
# Unmarshal cookie data to a hash and verify its integrity.
|
||||
def unmarshal(cookie)
|
||||
if cookie
|
||||
data, digest = CGI.unescape(cookie).split('--')
|
||||
unless digest == generate_digest(data)
|
||||
delete
|
||||
raise TamperedWithCookie
|
||||
end
|
||||
Marshal.load(Base64.decode64(data))
|
||||
end
|
||||
end
|
||||
|
||||
# Read the session data cookie.
|
||||
def read_cookie
|
||||
@session.cgi.cookies[@cookie_options['name']].first
|
||||
end
|
||||
|
||||
# CGI likes to make you hack.
|
||||
def write_cookie(options)
|
||||
cookie = CGI::Cookie.new(@cookie_options.merge(options))
|
||||
@session.cgi.send :instance_variable_set, '@output_cookies', [cookie]
|
||||
end
|
||||
|
||||
# Clear cookie value so subsequent new_session doesn't reload old data.
|
||||
def clear_old_cookie_value
|
||||
@session.cgi.cookies[@cookie_options['name']].clear
|
||||
end
|
||||
end
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
begin
|
||||
require 'cgi/session'
|
||||
require 'memcache'
|
||||
require_library_or_gem 'memcache'
|
||||
|
||||
class CGI
|
||||
class Session
|
||||
|
@ -57,26 +57,22 @@ begin
|
|||
@expires = options['expires'] || 0
|
||||
@session_key = "session:#{id}"
|
||||
@session_data = {}
|
||||
# Add this key to the store if haven't done so yet
|
||||
unless @cache.get(@session_key)
|
||||
@cache.add(@session_key, @session_data, @expires)
|
||||
end
|
||||
end
|
||||
|
||||
# Restore session state from the session's memcache entry.
|
||||
#
|
||||
# Returns the session state as a hash.
|
||||
def restore
|
||||
begin
|
||||
@session_data = @cache[@session_key] || {}
|
||||
rescue
|
||||
@session_data = {}
|
||||
end
|
||||
@session_data = @cache[@session_key] || {}
|
||||
end
|
||||
|
||||
# Save session state to the session's memcache entry.
|
||||
def update
|
||||
begin
|
||||
@cache.set(@session_key, @session_data, @expires)
|
||||
rescue
|
||||
# Ignore session update failures.
|
||||
end
|
||||
@cache.set(@session_key, @session_data, @expires)
|
||||
end
|
||||
|
||||
# Update and close the session's memcache entry.
|
||||
|
@ -86,17 +82,14 @@ begin
|
|||
|
||||
# Delete the session's memcache entry.
|
||||
def delete
|
||||
begin
|
||||
@cache.delete(@session_key)
|
||||
rescue
|
||||
# Ignore session delete failures.
|
||||
end
|
||||
@cache.delete(@session_key)
|
||||
@session_data = {}
|
||||
end
|
||||
|
||||
def data
|
||||
@session_data
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue