lib/global_session/rack.rb in global_session-1.0.0 vs lib/global_session/rack.rb in global_session-1.0.2

- old
+ new

@@ -1,6 +1,6 @@ -basedir = File.dirname(__FILE__) +require File.expand_path(File.join(File.dirname(__FILE__), "..", "global_session")) # Make sure the namespace exists, to satisfy Rails auto-loading module GlobalSession module Rack # Global session middleware. Note: this class relies on @@ -35,20 +35,60 @@ @configuration = Configuration.new(configuration, ENV['RACK_ENV'] || 'development') else @configuration = configuration end + begin + klass_name = @configuration['directory'] || 'GlobalSession::Directory' + + #Constantize the type name that was given as a string + parts = klass_name.split('::') + namespace = Object + namespace = namespace.const_get(parts.shift.to_sym) until parts.empty? + directory_klass = namespace + rescue Exception => e + raise ConfigurationError, "Invalid/unknown directory class name #{@configuration['directory']}" + end + if directory.instance_of?(String) - @directory = Directory.new(@configuration, directory) + @directory = directory_klass.new(@configuration, directory) else @directory = directory end @cookie_retrieval = block @cookie_name = @configuration['cookie']['name'] end + # Rack request chain. Sets up the global session ticket from + # the environment and passes it up the chain. + def call(env) + env['rack.cookies'] = {} unless env['rack.cookies'] + + begin + read_cookie(env) + rescue Exception => e + env['global_session'] = Session.new(@directory) + handle_error('reading session cookie', env, e) + end + + tuple = nil + + begin + tuple = @app.call(env) + rescue Exception => e + handle_error('processing request', env, e) + return tuple + else + renew_cookie(env) + update_cookie(env) + return tuple + end + end + + protected + # Read a cookie from the Rack environment. # # === Parameters # env(Hash): Rack environment. def read_cookie(env) @@ -69,11 +109,11 @@ # === Parameters # env(Hash): Rack environment def renew_cookie(env) return unless env['global_session'].directory.local_authority_name return if env['global_session.req.renew'] == false - + if (renew = @configuration['renew']) && env['global_session'] && env['global_session'].expired_at < Time.at(Time.now.utc + 60 * renew.to_i) env['global_session'].renew! end end @@ -108,10 +148,13 @@ # Delete the global session cookie from the cookie jar. # # === Parameters # env(Hash): Rack environment def wipe_cookie(env) + return unless env['global_session'].directory.local_authority_name + return if env['global_session.req.update'] == false + domain = @configuration['cookie']['domain'] || env['SERVER_NAME'] env['rack.cookies'][@cookie_name] = {:value => nil, :domain => domain, :expires => Time.at(0)} end # Handle exceptions that occur during app invocation. This will either save the error @@ -121,43 +164,18 @@ # === Parameters # activity(String): name of activity in which error happened # env(Hash): Rack environment # e(Exception): error that happened def handle_error(activity, env, e) - if e.is_a? ClientError + env['rack.logger'].error("#{e.class} while #{activity}: #{e} #{e.backtrace}") if env['rack.logger'] + + if e.is_a?(ClientError) || e.is_a?(SecurityError) env['global_session.error'] = e wipe_cookie(env) elsif e.is_a? ConfigurationError - env['rack.logger'].error("#{e.class} while #{activity}: #{e} #{e.backtrace}") if env['rack.logger'] env['global_session.error'] = e else raise e - end - end - - # Rack request chain. Sets up the global session ticket from - # the environment and passes it up the chain. - def call(env) - env['rack.cookies'] = {} unless env['rack.cookies'] - - begin - read_cookie(env) - rescue Exception => e - env['global_session'] = Session.new(@directory) - handle_error('reading session cookie', env, e) - end - - tuple = nil - - begin - tuple = @app.call(env) - rescue Exception => e - handle_error('processing request', env, e) - return tuple - else - renew_cookie(env) - update_cookie(env) - return tuple end end end end end