Class: Rack::Session::Abstract::Persisted

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/session/abstract/id.rb

Overview

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 #find_session and #write_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#set_cookie

  • :skip will not a set a cookie in the response nor update the session state

  • :defer will not set a cookie in the response but still update the session state if it is used with a backend

  • :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.

Not included by default; you must require ‘rack/session/abstract/id’ to use.

Direct Known Subclasses

ID, PersistedSecure

Constant Summary collapse

DEFAULT_OPTIONS =
{
  :key =>           RACK_SESSION,
  :path =>          '/',
  :domain =>        nil,
  :expire_after =>  nil,
  :secure =>        false,
  :httponly =>      true,
  :defer =>         false,
  :renew =>         false,
  :sidbits =>       128,
  :cookie_only =>   true,
  :secure_random => ::SecureRandom
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Persisted

Returns a new instance of Persisted.



244
245
246
247
248
249
250
# File 'lib/rack/session/abstract/id.rb', line 244

def initialize(app, options={})
  @app = app
  @default_options = self.class::DEFAULT_OPTIONS.merge(options)
  @key = @default_options.delete(:key)
  @cookie_only = @default_options.delete(:cookie_only)
  initialize_sid
end

Instance Attribute Details

#default_optionsObject (readonly)

Returns the value of attribute default_options.



242
243
244
# File 'lib/rack/session/abstract/id.rb', line 242

def default_options
  @default_options
end

#keyObject (readonly)

Returns the value of attribute key.



242
243
244
# File 'lib/rack/session/abstract/id.rb', line 242

def key
  @key
end

#sid_secureObject (readonly)

Returns the value of attribute sid_secure.



242
243
244
# File 'lib/rack/session/abstract/id.rb', line 242

def sid_secure
  @sid_secure
end

Instance Method Details

#call(env) ⇒ Object



252
253
254
# File 'lib/rack/session/abstract/id.rb', line 252

def call(env)
  context(env)
end

#commit_session(req, res) ⇒ Object

Acquires the session from the environment and the session id from the session options and passes them to #write_session. If successful and the :defer option is not true, a cookie will be added to the response with the session’s id.



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/rack/session/abstract/id.rb', line 366

def commit_session(req, res)
  session = req.get_header RACK_SESSION
  options = session.options

  if options[:drop] || options[:renew]
    session_id = delete_session(req, session.id || generate_sid, options)
    return unless session_id
  end

  return unless commit_session?(req, session, options)

  session.send(:load!) unless loaded_session?(session)
  session_id ||= session.id
  session_data = session.to_hash.delete_if { |k,v| v.nil? }

  if not data = write_session(req, session_id, session_data, options)
    req.get_header(RACK_ERRORS).puts("Warning! #{self.class.name} failed to save session. Content dropped.")
  elsif options[:defer] and not options[:renew]
    req.get_header(RACK_ERRORS).puts("Deferring cookie for #{session_id}") if $VERBOSE
  else
    cookie = Hash.new
    cookie[:value] = cookie_value(data)
    cookie[:expires] = Time.now + options[:expire_after] if options[:expire_after]
    cookie[:expires] = Time.now + options[:max_age] if options[:max_age]
    set_cookie(req, res, cookie.merge!(options))
  end
end

#context(env, app = @app) ⇒ Object



256
257
258
259
260
261
262
263
# File 'lib/rack/session/abstract/id.rb', line 256

def context(env, app=@app)
  req = make_request env
  prepare_session(req)
  status, headers, body = app.call(req.env)
  res = Rack::Response::Raw.new status, headers
  commit_session(req, res)
  [status, headers, body]
end