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, Cookie, Pool

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


219
220
221
222
223
224
225
# File 'lib/rack/session/abstract/id.rb', line 219

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


217
218
219
# File 'lib/rack/session/abstract/id.rb', line 217

def default_options
  @default_options
end

#keyObject (readonly)

Returns the value of attribute key


217
218
219
# File 'lib/rack/session/abstract/id.rb', line 217

def key
  @key
end

#sid_secureObject (readonly)

Returns the value of attribute sid_secure


217
218
219
# File 'lib/rack/session/abstract/id.rb', line 217

def sid_secure
  @sid_secure
end

Instance Method Details

#call(env) ⇒ Object


227
228
229
# File 'lib/rack/session/abstract/id.rb', line 227

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.


341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/rack/session/abstract/id.rb', line 341

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] = 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


231
232
233
234
235
236
237
238
# File 'lib/rack/session/abstract/id.rb', line 231

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