aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-04-30 13:29:33 +0100
committerPratik Naik <pratiknaik@gmail.com>2009-04-30 13:29:33 +0100
commit5f24ed718f92abe97fc3f50a36c9fb09499d0173 (patch)
treed097bb0e59c4a31c262fe83081e396219e7186bd /actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session
parent35ca877abc889d863747726e3da6e359ba928506 (diff)
parent79420e71e0e75d6f81e5284184bac4e7d0b02c30 (diff)
downloadrails-5f24ed718f92abe97fc3f50a36c9fb09499d0173.tar.gz
rails-5f24ed718f92abe97fc3f50a36c9fb09499d0173.tar.bz2
rails-5f24ed718f92abe97fc3f50a36c9fb09499d0173.zip
Merge commit 'mainstream/master'
Diffstat (limited to 'actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session')
-rw-r--r--actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/abstract/id.rb142
-rw-r--r--actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/cookie.rb91
-rw-r--r--actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/memcache.rb109
-rw-r--r--actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/pool.rb100
4 files changed, 0 insertions, 442 deletions
diff --git a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/abstract/id.rb b/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/abstract/id.rb
deleted file mode 100644
index 218144c17f..0000000000
--- a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/abstract/id.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-# AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
-# bugrep: Andreas Zehnder
-
-require 'time'
-require 'rack/request'
-require 'rack/response'
-
-module Rack
-
- module Session
-
- module Abstract
-
- # ID sets up a basic framework for implementing an id based sessioning
- # service. Cookies sent to the client for maintaining sessions will only
- # contain an id reference. Only #get_session and #set_session are
- # required to be overwritten.
- #
- # All parameters are optional.
- # * :key determines the name of the cookie, by default it is
- # 'rack.session'
- # * :path, :domain, :expire_after, :secure, and :httponly set the related
- # cookie options as by Rack::Response#add_cookie
- # * :defer will not set a cookie in the response.
- # * :renew (implementation dependent) will prompt the generation of a new
- # session id, and migration of data to be referenced at the new id. If
- # :defer is set, it will be overridden and the cookie will be set.
- # * :sidbits sets the number of bits in length that a generated session
- # id will be.
- #
- # These options can be set on a per request basis, at the location of
- # env['rack.session.options']. Additionally the id of the session can be
- # found within the options hash at the key :id. It is highly not
- # recommended to change its value.
- #
- # Is Rack::Utils::Context compatible.
-
- class ID
- DEFAULT_OPTIONS = {
- :path => '/',
- :domain => nil,
- :expire_after => nil,
- :secure => false,
- :httponly => true,
- :defer => false,
- :renew => false,
- :sidbits => 128
- }
-
- attr_reader :key, :default_options
- def initialize(app, options={})
- @app = app
- @key = options[:key] || "rack.session"
- @default_options = self.class::DEFAULT_OPTIONS.merge(options)
- end
-
- def call(env)
- context(env)
- end
-
- def context(env, app=@app)
- load_session(env)
- status, headers, body = app.call(env)
- commit_session(env, status, headers, body)
- end
-
- private
-
- # Generate a new session id using Ruby #rand. The size of the
- # session id is controlled by the :sidbits option.
- # Monkey patch this to use custom methods for session id generation.
-
- def generate_sid
- "%0#{@default_options[:sidbits] / 4}x" %
- rand(2**@default_options[:sidbits] - 1)
- end
-
- # Extracts the session id from provided cookies and passes it and the
- # environment to #get_session. It then sets the resulting session into
- # 'rack.session', and places options and session metadata into
- # 'rack.session.options'.
-
- def load_session(env)
- request = Rack::Request.new(env)
- session_id = request.cookies[@key]
-
- begin
- session_id, session = get_session(env, session_id)
- env['rack.session'] = session
- rescue
- env['rack.session'] = Hash.new
- end
-
- env['rack.session.options'] = @default_options.
- merge(:id => session_id)
- end
-
- # Acquires the session from the environment and the session id from
- # the session options and passes them to #set_session. If successful
- # and the :defer option is not true, a cookie will be added to the
- # response with the session's id.
-
- def commit_session(env, status, headers, body)
- session = env['rack.session']
- options = env['rack.session.options']
- session_id = options[:id]
-
- if not session_id = set_session(env, session_id, session, options)
- env["rack.errors"].puts("Warning! #{self.class.name} failed to save session. Content dropped.")
- [status, headers, body]
- elsif options[:defer] and not options[:renew]
- env["rack.errors"].puts("Defering cookie for #{session_id}") if $VERBOSE
- [status, headers, body]
- else
- cookie = Hash.new
- cookie[:value] = session_id
- cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
- response = Rack::Response.new(body, status, headers)
- response.set_cookie(@key, cookie.merge(options))
- response.to_a
- end
- end
-
- # All thread safety and session retrival proceedures should occur here.
- # Should return [session_id, session].
- # If nil is provided as the session id, generation of a new valid id
- # should occur within.
-
- def get_session(env, sid)
- raise '#get_session not implemented.'
- end
-
- # All thread safety and session storage proceedures should occur here.
- # Should return true or false dependant on whether or not the session
- # was saved or not.
- def set_session(env, sid, session, options)
- raise '#set_session not implemented.'
- end
- end
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/cookie.rb b/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/cookie.rb
deleted file mode 100644
index eace9bd0c6..0000000000
--- a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/cookie.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-require 'openssl'
-require 'rack/request'
-require 'rack/response'
-
-module Rack
-
- module Session
-
- # Rack::Session::Cookie provides simple cookie based session management.
- # The session is a Ruby Hash stored as base64 encoded marshalled data
- # set to :key (default: rack.session).
- # When the secret key is set, cookie data is checked for data integrity.
- #
- # Example:
- #
- # use Rack::Session::Cookie, :key => 'rack.session',
- # :domain => 'foo.com',
- # :path => '/',
- # :expire_after => 2592000,
- # :secret => 'change_me'
- #
- # All parameters are optional.
-
- class Cookie
-
- def initialize(app, options={})
- @app = app
- @key = options[:key] || "rack.session"
- @secret = options[:secret]
- @default_options = {:domain => nil,
- :path => "/",
- :expire_after => nil}.merge(options)
- end
-
- def call(env)
- load_session(env)
- status, headers, body = @app.call(env)
- commit_session(env, status, headers, body)
- end
-
- private
-
- def load_session(env)
- request = Rack::Request.new(env)
- session_data = request.cookies[@key]
-
- if @secret && session_data
- session_data, digest = session_data.split("--")
- session_data = nil unless digest == generate_hmac(session_data)
- end
-
- begin
- session_data = session_data.unpack("m*").first
- session_data = Marshal.load(session_data)
- env["rack.session"] = session_data
- rescue
- env["rack.session"] = Hash.new
- end
-
- env["rack.session.options"] = @default_options.dup
- end
-
- def commit_session(env, status, headers, body)
- session_data = Marshal.dump(env["rack.session"])
- session_data = [session_data].pack("m*")
-
- if @secret
- session_data = "#{session_data}--#{generate_hmac(session_data)}"
- end
-
- if session_data.size > (4096 - @key.size)
- env["rack.errors"].puts("Warning! Rack::Session::Cookie data size exceeds 4K. Content dropped.")
- [status, headers, body]
- else
- options = env["rack.session.options"]
- cookie = Hash.new
- cookie[:value] = session_data
- cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
- response = Rack::Response.new(body, status, headers)
- response.set_cookie(@key, cookie.merge(options))
- response.to_a
- end
- end
-
- def generate_hmac(data)
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @secret, data)
- end
-
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/memcache.rb b/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/memcache.rb
deleted file mode 100644
index 4a65cbf35d..0000000000
--- a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/memcache.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-# AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
-
-require 'rack/session/abstract/id'
-require 'memcache'
-
-module Rack
- module Session
- # Rack::Session::Memcache provides simple cookie based session management.
- # Session data is stored in memcached. The corresponding session key is
- # maintained in the cookie.
- # You may treat Session::Memcache as you would Session::Pool with the
- # following caveats.
- #
- # * Setting :expire_after to 0 would note to the Memcache server to hang
- # onto the session data until it would drop it according to it's own
- # specifications. However, the cookie sent to the client would expire
- # immediately.
- #
- # Note that memcache does drop data before it may be listed to expire. For
- # a full description of behaviour, please see memcache's documentation.
-
- class Memcache < Abstract::ID
- attr_reader :mutex, :pool
- DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \
- :namespace => 'rack:session',
- :memcache_server => 'localhost:11211'
-
- def initialize(app, options={})
- super
-
- @mutex = Mutex.new
- @pool = MemCache.
- new @default_options[:memcache_server], @default_options
- raise 'No memcache servers' unless @pool.servers.any?{|s|s.alive?}
- end
-
- def generate_sid
- loop do
- sid = super
- break sid unless @pool.get(sid, true)
- end
- end
-
- def get_session(env, sid)
- session = @pool.get(sid) if sid
- @mutex.lock if env['rack.multithread']
- unless sid and session
- env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
- session = {}
- sid = generate_sid
- ret = @pool.add sid, session
- raise "Session collision on '#{sid.inspect}'" unless /^STORED/ =~ ret
- end
- session.instance_variable_set('@old', {}.merge(session))
- return [sid, session]
- rescue MemCache::MemCacheError, Errno::ECONNREFUSED # MemCache server cannot be contacted
- warn "#{self} is unable to find server."
- warn $!.inspect
- return [ nil, {} ]
- ensure
- @mutex.unlock if env['rack.multithread']
- end
-
- def set_session(env, session_id, new_session, options)
- expiry = options[:expire_after]
- expiry = expiry.nil? ? 0 : expiry + 1
-
- @mutex.lock if env['rack.multithread']
- session = @pool.get(session_id) || {}
- if options[:renew] or options[:drop]
- @pool.delete session_id
- return false if options[:drop]
- session_id = generate_sid
- @pool.add session_id, 0 # so we don't worry about cache miss on #set
- end
- old_session = new_session.instance_variable_get('@old') || {}
- session = merge_sessions session_id, old_session, new_session, session
- @pool.set session_id, session, expiry
- return session_id
- rescue MemCache::MemCacheError, Errno::ECONNREFUSED # MemCache server cannot be contacted
- warn "#{self} is unable to find server."
- warn $!.inspect
- return false
- ensure
- @mutex.unlock if env['rack.multithread']
- end
-
- private
-
- def merge_sessions sid, old, new, cur=nil
- cur ||= {}
- unless Hash === old and Hash === new
- warn 'Bad old or new sessions provided.'
- return cur
- end
-
- delete = old.keys - new.keys
- warn "//@#{sid}: delete #{delete*','}" if $VERBOSE and not delete.empty?
- delete.each{|k| cur.delete k }
-
- update = new.keys.select{|k| new[k] != old[k] }
- warn "//@#{sid}: update #{update*','}" if $VERBOSE and not update.empty?
- update.each{|k| cur[k] = new[k] }
-
- cur
- end
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/pool.rb b/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/pool.rb
deleted file mode 100644
index f6f87408bb..0000000000
--- a/actionpack/lib/action_dispatch/vendor/rack-1.0/rack/session/pool.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
-# THANKS:
-# apeiros, for session id generation, expiry setup, and threadiness
-# sergio, threadiness and bugreps
-
-require 'rack/session/abstract/id'
-require 'thread'
-
-module Rack
- module Session
- # Rack::Session::Pool provides simple cookie based session management.
- # Session data is stored in a hash held by @pool.
- # In the context of a multithreaded environment, sessions being
- # committed to the pool is done in a merging manner.
- #
- # The :drop option is available in rack.session.options if you with to
- # explicitly remove the session from the session cache.
- #
- # Example:
- # myapp = MyRackApp.new
- # sessioned = Rack::Session::Pool.new(myapp,
- # :domain => 'foo.com',
- # :expire_after => 2592000
- # )
- # Rack::Handler::WEBrick.run sessioned
-
- class Pool < Abstract::ID
- attr_reader :mutex, :pool
- DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :drop => false
-
- def initialize(app, options={})
- super
- @pool = Hash.new
- @mutex = Mutex.new
- end
-
- def generate_sid
- loop do
- sid = super
- break sid unless @pool.key? sid
- end
- end
-
- def get_session(env, sid)
- session = @pool[sid] if sid
- @mutex.lock if env['rack.multithread']
- unless sid and session
- env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
- session = {}
- sid = generate_sid
- @pool.store sid, session
- end
- session.instance_variable_set('@old', {}.merge(session))
- return [sid, session]
- ensure
- @mutex.unlock if env['rack.multithread']
- end
-
- def set_session(env, session_id, new_session, options)
- @mutex.lock if env['rack.multithread']
- session = @pool[session_id]
- if options[:renew] or options[:drop]
- @pool.delete session_id
- return false if options[:drop]
- session_id = generate_sid
- @pool.store session_id, 0
- end
- old_session = new_session.instance_variable_get('@old') || {}
- session = merge_sessions session_id, old_session, new_session, session
- @pool.store session_id, session
- return session_id
- rescue
- warn "#{new_session.inspect} has been lost."
- warn $!.inspect
- ensure
- @mutex.unlock if env['rack.multithread']
- end
-
- private
-
- def merge_sessions sid, old, new, cur=nil
- cur ||= {}
- unless Hash === old and Hash === new
- warn 'Bad old or new sessions provided.'
- return cur
- end
-
- delete = old.keys - new.keys
- warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
- delete.each{|k| cur.delete k }
-
- update = new.keys.select{|k| new[k] != old[k] }
- warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
- update.each{|k| cur[k] = new[k] }
-
- cur
- end
- end
- end
-end