Class: Rack::Session::Redic

Inherits:
Abstract::Persisted
  • Object
show all
Defined in:
lib/rack/session/redic.rb

Overview

Rack::Session::Redic provides simple cookie based session management. Session data is stored in Redis via the Redic gem. The corresponding session key is maintained in the cookie.

Options include:

  • :marshaller - You may optionally supply the class/module you would like to use when marshalling objects in and out of Redis. All that is required is that this class respond to the ‘load` and `dump` methods, returning the session hash and a string respectively.

  • :url - Addtionally, you may pass in the URL for your Redis server. The default URL is fetched from the ENV as ‘REDIS_URL’ in keeping with Heroku and others’ practices.

  • :expire_after - Finally, expiration will be passed to the Redis server via the ‘EX’ option on ‘SET’. Expiration should be in seconds, just like Rack’s default handling of the :expire_after option. This option will refresh the expiration set in Redis with each request.

Any other options will get passed to Rack::Session::Abstract::Persisted.

Constant Summary collapse

HASH =
{}.freeze
DELETE =

Redis commands.

'DEL'
EX =
'EX'
EXISTS =
'EXISTS'
GET =
'GET'
SET =
'SET'
REDIS_URL =

Assorted.

'REDIS_URL'
ZERO =
0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = HASH) ⇒ Redic

Returns a new instance of Redic.



46
47
48
49
50
51
52
# File 'lib/rack/session/redic.rb', line 46

def initialize(app, options = HASH)
  super(app, options)

  @expires = options[:expire_after]
  @marshaller = options.fetch(:marshaller) { Marshal }
  @storage = ::Redic.new(options.fetch(:url) { ENV.fetch(REDIS_URL) })
end

Instance Attribute Details

#storageRedic (readonly)

Access the storage interface directly. Needed for testing.

Returns:



44
45
46
# File 'lib/rack/session/redic.rb', line 44

def storage
  @storage
end

Instance Method Details

#delete_session(_req, session_id, options) ⇒ Object

Kill the session.



88
89
90
91
92
# File 'lib/rack/session/redic.rb', line 88

def delete_session(_req, session_id, options)
  @storage.call(DELETE, session_id)

  generate_sid unless options[:drop]
end

#find_session(_req, session_id) ⇒ Object

Find the session (or generate a blank one).



69
70
71
72
73
74
75
# File 'lib/rack/session/redic.rb', line 69

def find_session(_req, session_id)
  unless session_id && (session = deserialize(@storage.call(GET, session_id)))
    session_id, session = generate_sid, {} # rubocop:disable Style/ParallelAssignment
  end

  [session_id, session]
end

#generate_sidString

Generate a session ID that doesn’t already exist.

Based on Rack::Session::Abstract::Persisted#generate_sid and Rack::Session::Memcache#generate_sid but without the conditional check. We always generate the session ID from SecureRandom#hex.

Returns:

  • (String)


61
62
63
64
65
66
# File 'lib/rack/session/redic.rb', line 61

def generate_sid
  loop do
    session_id = SecureRandom.hex(@sid_length)
    break session_id unless @storage.call(EXISTS, session_id) != ZERO
  end
end

#write_session(_req, session_id, session_data, _options) ⇒ Object

Write the session.



78
79
80
81
82
83
84
85
# File 'lib/rack/session/redic.rb', line 78

def write_session(_req, session_id, session_data, _options)
  arguments = [SET, session_id, serialize(session_data)]
  arguments.push(EX, @expires) if @expires

  @storage.call(*arguments)

  session_id
end