redis-rack-my-checksub 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 90fb9bfcd8cd361bddd561256f85392471bdba3aaeac993f70bd77c7e277005e
4
+ data.tar.gz: 2ed881dcbe50724d3196ea95a89993a30480db7e56db16e5b7bcbe61fe3052b7
5
+ SHA512:
6
+ metadata.gz: a47a0fbf5642ce628bf32368441f036e7786191162e32d5bb1801b087dfcdc0db04c8d5724d22d58e70665cec1f89c7fb3150fb567719a736c0c00f0403ded13
7
+ data.tar.gz: 38413bf90410051d323792a8b165928b7556f02a12e102c6a58442b8be34b2ad2c725bf77aa51d6b38d73793aecea0a63a559a994f24a2fe2deaf84783babeea
@@ -0,0 +1,2 @@
1
+ assignees:
2
+ - tubbo
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ tmp/
4
+ stdout
5
+ gemfiles/vendor
6
+ gemfiles/*.gemfile.lock
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.1
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+ script: bundle exec rake
3
+ rvm:
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
9
+ - 2.7
10
+ - ruby-head
11
+ - jruby-head
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: jruby-head
15
+ - rvm: ruby-head
16
+ deploy:
17
+ provider: rubygems
18
+ api_key:
19
+ secure: VTosVmCdLWUGK8KyzovYri7ySfd7fACtfL8MClEBBHnI+m2cLCpmtCJ7Z1X7z9BXlj974EDaF8V9iRKzfksXIf8aaPfVQw9AW94fLJZbfSB8YGOGyNbPu9YECoZQB1aZ2lw9s/aEdfwCbmqizO/fYpG3YoPKJdm1ZJpNOFR37Xk=
20
+ gem: redis-rack
21
+ on:
22
+ tags: true
23
+ repo: redis-store/redis-rack
data/CHANGELOG.md ADDED
@@ -0,0 +1,246 @@
1
+ v2.1.0 (2020-01-13)
2
+ --------------------------------------------------------------------------------
3
+
4
+ * Update version to v2.1.0 final
5
+ Tom Scott
6
+
7
+ * Test against most recent versions of Ruby
8
+ Tom Scott
9
+
10
+ * Update gemspec to remove rubyforge_project
11
+
12
+ It is deprecated or removed already
13
+
14
+ Original warning message:
15
+ Gem::Specification#rubyforge_project= is deprecated with no replacement. It will be removed on or after 2019-12-01.
16
+ PikachuEXE
17
+
18
+ * back tests to original state
19
+ Alexey Vasiliev
20
+
21
+ * Fix redis-rack for rack 2.0.8, small improvements
22
+ Alexey Vasiliev
23
+
24
+ * Fix redis-rack for rack 2.0.8, fix generate_unique_sid
25
+ Alexey Vasiliev
26
+
27
+ * Fix redis-rack for rack 2.0.8
28
+ Alexey Vasiliev
29
+
30
+ * v2.1.0.pre: Update Rack Session API, drop support for Rack 1.0
31
+ Tom Scott
32
+
33
+ v2.0.6
34
+ --------------------------------------------------------------------------------
35
+
36
+ * v2.0.6: Prevent Connection Pool from passing nil options
37
+ Tom Scott
38
+
39
+ * Make bundler dependency more permissive to support future ruby versions
40
+ Tom Scott
41
+
42
+ * Drop support for Rack v1
43
+ Tom Scott
44
+
45
+ * Update Rack::Session API Compatibility
46
+
47
+ The latest version of Rack [deprecated subclassing Rack::Session::ID](https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb#L412-L419),
48
+ replacing it instead with `Rack::Session::Persisted`. Update the method
49
+ implementations in this gem to support the new API. Shoutouts to @onk
50
+ for actually writing this code, we're pulling it in from his fork.
51
+ Tom Scott
52
+
53
+ * Automatically assign issues to @tubbo when they are created
54
+ Tom Scott
55
+
56
+ * Automatically release to RubyGems when new tags are pushed to GitHub
57
+ Tom Scott
58
+
59
+ * Raise Error when `:redis_store` is Incorrect Type
60
+
61
+ Passing an object that isn't a `Redis::Store` into the session storage
62
+ configuration can cause errors when methods are called with more
63
+ arguments than the default Redis client can handle. These additional
64
+ arguments are used by `Rack::Session::Redis` to configure the key
65
+ namespace and TTL globally in the main configuration, and pass them down
66
+ to `Redis::Store` to be appended to the key. An `ArgumentError` will now
67
+ be thrown when a `:redis_store` is of a type that isn't a `Redis::Store`
68
+ (or a subclass thereof).
69
+
70
+ Resolves #46
71
+ Tom Scott
72
+
73
+ * Add code owners
74
+ Tom Scott
75
+
76
+ * Do not provide nil values for missing connection pool options
77
+
78
+ Fixes #44
79
+ Jake Goulding
80
+
81
+ v2.0.5
82
+ --------------------------------------------------------------------------------
83
+
84
+ * v2.0.5 release
85
+ Tom Scott
86
+
87
+ * add spec to validate blank sessions are not stored in redis
88
+ mstruve
89
+
90
+ * dont store a blank session in redis
91
+ mstruve
92
+
93
+ * Add documentation for options
94
+ Daniel M Barlow
95
+
96
+ v2.0.4
97
+ --------------------------------------------------------------------------------
98
+
99
+ * Release 2.0.4
100
+ Tom Scott
101
+
102
+ * Remove .ruby-version
103
+ Tom Scott
104
+
105
+ * Remove rake, appraisal from gemspec executables
106
+
107
+ The contents of the bin directory are binstubs to assist development.
108
+ They are not intended to be shipped with the gem itself. This commit
109
+ updates the gemspec to ensure that they are not exposed to rubygems as
110
+ executables for redis-rack, which will fix conflicts with the legitimate
111
+ rake and appraisal executables provided by those other gems.
112
+ Matt Brictson
113
+
114
+ v2.0.3
115
+ --------------------------------------------------------------------------------
116
+
117
+ * v2.0.3: Avoid mutex locking with global option
118
+ Tom Scott
119
+
120
+ * Restore default_options in #generate_unique_sid
121
+ Tom Scott
122
+
123
+ * Refactor connection_pool code
124
+
125
+ Adds a `Redis::Rack::Connection` object for handling the instantiation
126
+ of a `Redis::Store` or a `ConnectionPool` if pool configuration is
127
+ given. Restores the purpose of `Rack::Session::Redis` to only implement
128
+ the session ID abstract API provided by Rack.
129
+ Tom Scott
130
+
131
+ * Rename :use_global_lock option to :threadsafe to match Rails
132
+ Garrett Thornburg
133
+
134
+ * Use mocha mocks to assert the mutex is never locked
135
+ Garrett Thornburg
136
+
137
+ * Allow redis-store v1.4
138
+ Shane O'Grady
139
+
140
+ * Create a :use_global_lock option that avoids the global lock
141
+ Garrett Thornburg
142
+
143
+ * Rake task for running all tests on all gem versions
144
+ Tom Scott
145
+
146
+ * Install Appraisal so we can test against multiple versions of Rack
147
+ Tom Scott
148
+
149
+ v2.0.2
150
+ --------------------------------------------------------------------------------
151
+
152
+ * v2.0.2: Resolve regression forcing Rack 2.x and above
153
+ Tom Scott
154
+
155
+ v2.0.1
156
+ --------------------------------------------------------------------------------
157
+
158
+ * v2.0.1: Relax gem dependencies
159
+ Tom Scott
160
+
161
+ * smoothen redis-store dependency
162
+ Mathieu Jobin
163
+
164
+ * Drop support for Rubinius 1.9 mode
165
+
166
+ 1.9.x is EOL in MRI Ruby Land, and Rubinius 1.9 mode isn't really used
167
+ much anymore. This should make the builds pass again.
168
+ Tom Scott
169
+
170
+ * Update README.md (#20)
171
+ Nicolas
172
+
173
+ * Remove jruby 1.9 mode from the build matrix
174
+ Tom Scott
175
+
176
+ * Remove test because why
177
+ Tom Scott
178
+
179
+ v2.0.0
180
+ --------------------------------------------------------------------------------
181
+
182
+ * v2.0: Drop support for Ruby below 2.2 (thanks @connorshea)
183
+
184
+ Fixes #17, major shoutouts to @connorshea for getting this off the
185
+ ground. This also edits the CI config to drop support for older Ruby
186
+ versions.
187
+ Tom Scott
188
+
189
+ * Fix gem dependency versions
190
+ Tom Scott
191
+
192
+ * v2.0.0.pre Add support for Rails 5 and Rack 2.
193
+ Tom Scott
194
+
195
+ * v2.0.0: Upgrade to Rack 2.0
196
+
197
+ This release includes some backwards-incompatible changes that pertain
198
+ to Rails' upgrade to Rack 2.x.
199
+ Tom Scott
200
+
201
+ * Update README
202
+ Tom Scott
203
+
204
+ * Fix readme
205
+ Tom Scott
206
+
207
+ * travis.yml add Ruby 2.3.0
208
+ shiro16
209
+
210
+ * add 2.1 and 2.2 rubies to travis
211
+ Marc Roberts
212
+
213
+ * Remove support for Ruby 1.9
214
+ Marc Roberts
215
+
216
+ * Loosen dependancy on Rack to allow 1.5 and 2.x
217
+
218
+ Rails 5 beta requires Rack 2.x and this gem is unusable unless can use Rack 2.x
219
+ Marc Roberts
220
+
221
+ * Update README.md
222
+ Ryan Bigg
223
+
224
+ * add support for ConnectionPool
225
+ Roman Usherenko
226
+
227
+ * Introduce redis_store option (closes #1)
228
+ Kurakin Alexander
229
+
230
+ * Atomically lock session id and implement skip support.
231
+ W. Andrew Loe III
232
+
233
+ v1.5.0
234
+ ------
235
+
236
+ * Enable CI
237
+ Luca Guidi
238
+
239
+ * Update README.md
240
+ Luca Guidi
241
+
242
+ * Moved back from jodosha/redis-store
243
+ Luca Guidi
244
+
245
+ * Moved
246
+ Luca Guidi
data/CODEOWNERS ADDED
@@ -0,0 +1 @@
1
+ * @tubbo
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'redis-store-testing', github: 'redis-store/testing'
6
+ gem 'appraisal', '~> 2.2'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 - 2013 Luca Guidi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Redis session store for Rack
2
+
3
+ __`redis-rack`__ provides a Redis-backed session store for __Rack__.
4
+
5
+ See the main [redis-store readme] for general guidelines.
6
+
7
+ **NOTE:** This is not [redis-rack-cache][], the library for using Redis
8
+ as a backend store for the `Rack::Cache` HTTP cache. All this gem does
9
+ is store the Rack session within Redis.
10
+
11
+ [![Build Status](https://secure.travis-ci.org/redis-store/redis-rack.png?branch=master)](http://travis-ci.org/redis-store/redis-rack?branch=master)
12
+ [![Code Climate](https://codeclimate.com/github/redis-store/redis-store.png)](https://codeclimate.com/github/redis-store/redis-rack)
13
+ [![Gem Version](https://badge.fury.io/rb/redis-rack.png)](http://badge.fury.io/rb/redis-rack)
14
+
15
+ ## Installation
16
+
17
+ Install with Bundler by adding the following to Gemfile:
18
+
19
+ ```ruby
20
+ gem 'redis-rack'
21
+ ```
22
+
23
+ Then, run:
24
+
25
+ ```shell
26
+ $ bundle install
27
+ ```
28
+
29
+ Or, you can install it manually using RubyGems:
30
+
31
+ ```shell
32
+ $ gem install redis-rack
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ If you are using redis-store with Rails, consider using the [redis-rails gem](https://github.com/redis-store/redis-rails) instead. For standalone usage:
38
+
39
+ ```ruby
40
+ # config.ru
41
+ require 'rack'
42
+ require 'rack/session/redis'
43
+
44
+ use Rack::Session::Redis
45
+
46
+ # Alternatively you can specify options to use:
47
+ use Rack::Session::Redis,
48
+ :redis_server => "redis://redis:6379/0",
49
+ :expires_in => 3600 # Seconds. If you are using ActiveSupport you can use 1.hour
50
+ ```
51
+
52
+ ## Development
53
+
54
+ To install this gem for development purposes:
55
+
56
+ ```shell
57
+ $ gem install bundler # note: you don't need to do this if you already have it installed
58
+ $ git clone git://github.com/redis-store/redis-rack.git
59
+ $ cd redis-rack
60
+ $ bundle install
61
+ ```
62
+
63
+ ## Running tests
64
+
65
+ To run tests:
66
+
67
+ ```shell
68
+ $ bundle exec rake
69
+ ```
70
+
71
+ If you are on **Snow Leopard** you have to run the following command to
72
+ build this software:
73
+
74
+ ```shell
75
+ $ env ARCHFLAGS="-arch x86_64" bundle exec rake
76
+ ```
77
+
78
+ ## Copyright
79
+
80
+ 2009 - 2013 Luca Guidi - [http://lucaguidi.com](http://lucaguidi.com), released under the MIT license
81
+
82
+ [redis-rack-cache]: https://github.com/redis-store/redis-rack-cache
83
+ [redis-store readme]: https://github.com/redis-store/redis-store
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'rake'
3
+ require 'bundler/gem_tasks'
4
+ require 'redis-store/testing/tasks'
5
+
6
+ task :all do
7
+ Dir["gemfiles/*.gemfile"].reject { |p| p =~ /\.lock\Z/ }.each do |gemfile|
8
+ sh "BUNDLE_GEMFILE=#{gemfile} bundle exec rake"
9
+ end
10
+ end
data/bin/appraisal ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'appraisal' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("appraisal", "appraisal")
data/bin/rake ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rake' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rake", "rake")
@@ -0,0 +1,92 @@
1
+ require 'rack/session/abstract/id'
2
+ require 'redis-store'
3
+ require 'thread'
4
+ require 'redis/rack/connection'
5
+
6
+ module Rack
7
+ module Session
8
+ class Redis < Abstract::PersistedSecure
9
+ attr_reader :mutex
10
+
11
+ DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge(
12
+ :redis_server => 'redis://127.0.0.1:6379/0/rack:session'
13
+ )
14
+
15
+ def initialize(app, options = {})
16
+ super
17
+
18
+ @mutex = Mutex.new
19
+ @conn = ::Redis::Rack::Connection.new(@default_options)
20
+ end
21
+
22
+ def generate_unique_sid(session)
23
+ return generate_sid if session.empty?
24
+ loop do
25
+ sid = generate_sid
26
+ first = with do |c|
27
+ [*c.setnx(sid.private_id, session, @default_options.to_hash)].first
28
+ end
29
+ break sid if [1, true].include?(first)
30
+ end
31
+ end
32
+
33
+ def find_session(req, sid)
34
+ if req.session.options[:skip]
35
+ [generate_sid, {}]
36
+ else
37
+ with_lock(req, [nil, {}]) do
38
+ unless sid and session = get_session_with_fallback(sid)
39
+ session = {}
40
+ sid = generate_unique_sid(session)
41
+ end
42
+ [sid, session]
43
+ end
44
+ end
45
+ end
46
+
47
+ def write_session(req, sid, new_session, options = {})
48
+ with_lock(req, false) do
49
+ with { |c| c.set(sid.private_id, new_session, options.to_hash) }
50
+ sid
51
+ end
52
+ end
53
+
54
+ def delete_session(req, sid, options)
55
+ with_lock(req) do
56
+ with do |c|
57
+ c.del(sid.public_id)
58
+ c.del(sid.private_id)
59
+ end
60
+ generate_sid unless options[:drop]
61
+ end
62
+ end
63
+
64
+ def threadsafe?
65
+ @default_options.fetch(:threadsafe, true)
66
+ end
67
+
68
+ def with_lock(req, default = nil)
69
+ @mutex.lock if req.multithread? && threadsafe?
70
+ yield
71
+ rescue Errno::ECONNREFUSED
72
+ if $VERBOSE
73
+ warn "#{self} is unable to find Redis server."
74
+ warn $!.inspect
75
+ end
76
+ default
77
+ ensure
78
+ @mutex.unlock if @mutex.locked?
79
+ end
80
+
81
+ def with(&block)
82
+ @conn.with(&block)
83
+ end
84
+
85
+ private
86
+
87
+ def get_session_with_fallback(sid)
88
+ with { |c| c.get(sid.private_id) || c.get(sid.public_id) }
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/redis-rack.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'redis-store'
2
+ require 'redis/rack/version'
3
+ require 'rack/session/redis'
@@ -0,0 +1,50 @@
1
+ class Redis
2
+ module Rack
3
+ class Connection
4
+ POOL_KEYS = %i[pool pool_size pool_timeout].freeze
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ @store = options[:redis_store]
9
+ @pool = options[:pool]
10
+
11
+ if @pool && !@pool.is_a?(ConnectionPool)
12
+ raise ArgumentError, "pool must be an instance of ConnectionPool"
13
+ end
14
+
15
+ if @store && !@store.is_a?(Redis::Store)
16
+ raise ArgumentError, "redis_store must be an instance of Redis::Store (currently #{@store.class.name})"
17
+ end
18
+ end
19
+
20
+ def with(&block)
21
+ if pooled?
22
+ pool.with(&block)
23
+ else
24
+ block.call(store)
25
+ end
26
+ end
27
+
28
+ def pooled?
29
+ return @pooled if defined?(@pooled)
30
+
31
+ @pooled = POOL_KEYS.any? { |key| @options.key?(key) }
32
+ end
33
+
34
+ def pool
35
+ @pool ||= ConnectionPool.new(pool_options) { store } if pooled?
36
+ end
37
+
38
+ def store
39
+ @store ||= Redis::Store::Factory.create(@options[:redis_server], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })
40
+ end
41
+
42
+ def pool_options
43
+ {
44
+ size: @options[:pool_size],
45
+ timeout: @options[:pool_timeout]
46
+ }.reject { |key, value| value.nil? }.to_h
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ class Redis
2
+ module Rack
3
+ VERSION = '2.1.3'
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'redis/rack/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'redis-rack-my-checksub'
7
+ s.version = Redis::Rack::VERSION
8
+ s.authors = ['Luca Guidi']
9
+ s.email = ['me@lucaguidi.com']
10
+ s.homepage = 'http://redis-store.org/redis-rack'
11
+ s.summary = %q{Redis Store for Rack}
12
+ s.description = %q{Redis Store for Rack applications}
13
+ s.license = 'MIT'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = []
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_runtime_dependency 'redis-store', ['< 2', '>= 1.2']
21
+ s.add_runtime_dependency 'rack', '>= 2.0.8', '< 3'
22
+
23
+ s.add_development_dependency 'rake', '>= 12.3.3'
24
+ s.add_development_dependency 'bundler', '> 1', '< 3'
25
+ s.add_development_dependency 'mocha', '~> 0.14.0'
26
+ s.add_development_dependency 'minitest', '~> 5'
27
+ s.add_development_dependency 'connection_pool', '~> 1.2.0'
28
+ end
29
+
@@ -0,0 +1,414 @@
1
+ require 'test_helper'
2
+ require 'rack/mock'
3
+ require 'thread'
4
+ require 'connection_pool'
5
+
6
+ describe Rack::Session::Redis do
7
+ session_key = Rack::Session::Redis::DEFAULT_OPTIONS[:key]
8
+ session_match = /#{session_key}=([0-9a-fA-F]+);/
9
+ incrementor = lambda do |env|
10
+ env["rack.session"]["counter"] ||= 0
11
+ env["rack.session"]["counter"] += 1
12
+ Rack::Response.new(env["rack.session"].inspect).to_a
13
+ end
14
+ drop_session = proc do |env|
15
+ env['rack.session.options'][:drop] = true
16
+ incrementor.call(env)
17
+ end
18
+ renew_session = proc do |env|
19
+ env['rack.session.options'][:renew] = true
20
+ incrementor.call(env)
21
+ end
22
+ defer_session = proc do |env|
23
+ env['rack.session.options'][:defer] = true
24
+ incrementor.call(env)
25
+ end
26
+ skip_session = proc do |env|
27
+ env['rack.session.options'][:skip] = true
28
+ incrementor.call(env)
29
+ end
30
+
31
+ # # test Redis connection
32
+ # Rack::Session::Redis.new(incrementor)
33
+ #
34
+ # it "faults on no connection" do
35
+ # lambda{
36
+ # Rack::Session::Redis.new(incrementor, :redis_server => 'nosuchserver')
37
+ # }.must_raise(Exception)
38
+ # end
39
+
40
+ it "can create it's own pool" do
41
+ session_store = Rack::Session::Redis.new(incrementor, pool_size: 5, pool_timeout: 10)
42
+ conn = session_store.instance_variable_get(:@conn)
43
+ conn.pool.class.must_equal ::ConnectionPool
44
+ conn.pool.instance_variable_get(:@size).must_equal 5
45
+ end
46
+
47
+ it "can create it's own pool using default Redis server" do
48
+ session_store = Rack::Session::Redis.new(incrementor, pool_size: 5, pool_timeout: 10)
49
+ session_store.with { |connection| connection.to_s.must_match(/127\.0\.0\.1:6379 against DB 0 with namespace rack:session$/) }
50
+ end
51
+
52
+ it "can create it's own pool using provided Redis server" do
53
+ session_store = Rack::Session::Redis.new(incrementor, redis_server: 'redis://127.0.0.1:6380/1', pool_size: 5, pool_timeout: 10)
54
+ session_store.with { |connection| connection.to_s.must_match(/127\.0\.0\.1:6380 against DB 1$/) }
55
+ end
56
+
57
+ it "can use a supplied pool" do
58
+ session_store = Rack::Session::Redis.new(incrementor, pool: ::ConnectionPool.new(size: 1, timeout: 1) { ::Redis::Store::Factory.create("redis://127.0.0.1:6380/1")})
59
+ conn = session_store.instance_variable_get(:@conn)
60
+ conn.pool.class.must_equal ::ConnectionPool
61
+ conn.pool.instance_variable_get(:@size).must_equal 1
62
+ end
63
+
64
+ it "uses the specified Redis store when provided" do
65
+ store = ::Redis::Store::Factory.create('redis://127.0.0.1:6380/1')
66
+ pool = Rack::Session::Redis.new(incrementor, :redis_store => store)
67
+ pool.with do |p|
68
+ p.to_s.must_match(/127\.0\.0\.1:6380 against DB 1$/)
69
+ p.must_equal(store)
70
+ end
71
+ end
72
+
73
+ it "uses the default Redis server and namespace when not provided" do
74
+ pool = Rack::Session::Redis.new(incrementor)
75
+ pool.with { |p| p.to_s.must_match(/127\.0\.0\.1:6379 against DB 0 with namespace rack:session$/) }
76
+ end
77
+
78
+ it "uses the specified namespace when provided" do
79
+ pool = Rack::Session::Redis.new(incrementor, :redis_server => {:namespace => 'test:rack:session'})
80
+ pool.with { |p| p.to_s.must_match(/namespace test:rack:session$/) }
81
+ end
82
+
83
+ it "uses the specified Redis server when provided" do
84
+ pool = Rack::Session::Redis.new(incrementor, :redis_server => 'redis://127.0.0.1:6380/1')
85
+ pool.with { |p| p.to_s.must_match(/127\.0\.0\.1:6380 against DB 1$/) }
86
+ end
87
+
88
+ it "is threadsafe by default" do
89
+ sesion_store = Rack::Session::Redis.new(incrementor)
90
+ sesion_store.threadsafe?.must_equal(true)
91
+ end
92
+
93
+ it "does not store a blank session" do
94
+ session_store = Rack::Session::Redis.new(incrementor)
95
+ sid = session_store.generate_unique_sid({})
96
+ session_store.with { |c| c.get(sid.private_id).must_be_nil }
97
+ end
98
+
99
+ it "locks the store mutex" do
100
+ mutex = Mutex.new
101
+ mutex.expects(:lock).once
102
+ sesion_store = Rack::Session::Redis.new(incrementor)
103
+ sesion_store.instance_variable_set(:@mutex, mutex)
104
+ was_yielded = false
105
+ request = Minitest::Mock.new
106
+ request.expect(:multithread?, true)
107
+ sesion_store.with_lock(request) { was_yielded = true}
108
+ was_yielded.must_equal(true)
109
+ end
110
+
111
+ describe "threadsafe disabled" do
112
+ it "can have the global lock disabled" do
113
+ sesion_store = Rack::Session::Redis.new(incrementor, :threadsafe => false)
114
+ sesion_store.threadsafe?.must_equal(false)
115
+ end
116
+
117
+ it "does not lock the store mutex" do
118
+ mutex = Mutex.new
119
+ mutex.expects(:lock).never
120
+ sesion_store = Rack::Session::Redis.new(incrementor, :threadsafe => false)
121
+ sesion_store.instance_variable_set(:@mutex, mutex)
122
+ was_yielded = false
123
+ request = Minitest::Mock.new
124
+ request.expect(:multithread?, true)
125
+ sesion_store.with_lock(request) { was_yielded = true}
126
+ was_yielded.must_equal(true)
127
+ end
128
+ end
129
+
130
+ it "creates a new cookie" do
131
+ with_pool_management(incrementor) do |pool|
132
+ res = Rack::MockRequest.new(pool).get("/")
133
+ res["Set-Cookie"].must_include("#{session_key}=")
134
+ res.body.must_equal('{"counter"=>1}')
135
+ end
136
+ end
137
+
138
+ it "determines session from a cookie" do
139
+ with_pool_management(incrementor) do |pool|
140
+ req = Rack::MockRequest.new(pool)
141
+ res = req.get("/")
142
+ cookie = res["Set-Cookie"]
143
+ req.get("/", "HTTP_COOKIE" => cookie).
144
+ body.must_equal('{"counter"=>2}')
145
+ req.get("/", "HTTP_COOKIE" => cookie).
146
+ body.must_equal('{"counter"=>3}')
147
+ end
148
+ end
149
+
150
+ it "determines session only from a cookie by default" do
151
+ with_pool_management(incrementor) do |pool|
152
+ req = Rack::MockRequest.new(pool)
153
+ res = req.get("/")
154
+ sid = res["Set-Cookie"][session_match, 1]
155
+ req.get("/?rack.session=#{sid}").
156
+ body.must_equal('{"counter"=>1}')
157
+ req.get("/?rack.session=#{sid}").
158
+ body.must_equal('{"counter"=>1}')
159
+ end
160
+ end
161
+
162
+ it "determines session from params" do
163
+ with_pool_management(incrementor, :cookie_only => false) do |pool|
164
+ req = Rack::MockRequest.new(pool)
165
+ res = req.get("/")
166
+ sid = res["Set-Cookie"][session_match, 1]
167
+ req.get("/?rack.session=#{sid}").
168
+ body.must_equal('{"counter"=>2}')
169
+ req.get("/?rack.session=#{sid}").
170
+ body.must_equal('{"counter"=>3}')
171
+ end
172
+ end
173
+
174
+ it "survives nonexistant cookies" do
175
+ bad_cookie = "rack.session=blarghfasel"
176
+ with_pool_management(incrementor) do |pool|
177
+ res = Rack::MockRequest.new(pool).
178
+ get("/", "HTTP_COOKIE" => bad_cookie)
179
+ res.body.must_equal('{"counter"=>1}')
180
+ cookie = res["Set-Cookie"][session_match]
181
+ cookie.wont_match(/#{bad_cookie}/)
182
+ end
183
+ end
184
+
185
+ it "maintains freshness" do
186
+ with_pool_management(incrementor, :expire_after => 3) do |pool|
187
+ res = Rack::MockRequest.new(pool).get('/')
188
+ res.body.must_include('"counter"=>1')
189
+ cookie = res["Set-Cookie"]
190
+ sid = cookie[session_match, 1]
191
+ res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
192
+ res["Set-Cookie"][session_match, 1].must_equal(sid)
193
+ res.body.must_include('"counter"=>2')
194
+ puts 'Sleeping to expire session' if $DEBUG
195
+ sleep 4
196
+ res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
197
+ res["Set-Cookie"][session_match, 1].wont_equal(sid)
198
+ res.body.must_include('"counter"=>1')
199
+ end
200
+ end
201
+
202
+ it "does not send the same session id if it did not change" do
203
+ with_pool_management(incrementor) do |pool|
204
+ req = Rack::MockRequest.new(pool)
205
+
206
+ res0 = req.get("/")
207
+ cookie = res0["Set-Cookie"]
208
+ res0.body.must_equal('{"counter"=>1}')
209
+
210
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
211
+ res1["Set-Cookie"].must_be_nil
212
+ res1.body.must_equal('{"counter"=>2}')
213
+
214
+ res2 = req.get("/", "HTTP_COOKIE" => cookie)
215
+ res2["Set-Cookie"].must_be_nil
216
+ res2.body.must_equal('{"counter"=>3}')
217
+ end
218
+ end
219
+
220
+ it "deletes cookies with :drop option" do
221
+ with_pool_management(incrementor) do |pool|
222
+ req = Rack::MockRequest.new(pool)
223
+ drop = Rack::Utils::Context.new(pool, drop_session)
224
+ dreq = Rack::MockRequest.new(drop)
225
+
226
+ res1 = req.get("/")
227
+ session = (cookie = res1["Set-Cookie"])[session_match]
228
+ res1.body.must_equal('{"counter"=>1}')
229
+
230
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
231
+ res2["Set-Cookie"].must_be_nil
232
+ res2.body.must_equal('{"counter"=>2}')
233
+
234
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
235
+ res3["Set-Cookie"][session_match].wont_equal(session)
236
+ res3.body.must_equal('{"counter"=>1}')
237
+ end
238
+ end
239
+
240
+ it "provides new session id with :renew option" do
241
+ with_pool_management(incrementor) do |pool|
242
+ req = Rack::MockRequest.new(pool)
243
+ renew = Rack::Utils::Context.new(pool, renew_session)
244
+ rreq = Rack::MockRequest.new(renew)
245
+
246
+ res1 = req.get("/")
247
+ session = (cookie = res1["Set-Cookie"])[session_match]
248
+ res1.body.must_equal('{"counter"=>1}')
249
+
250
+ res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
251
+ new_cookie = res2["Set-Cookie"]
252
+ new_session = new_cookie[session_match]
253
+ new_session.wont_equal(session)
254
+ res2.body.must_equal('{"counter"=>2}')
255
+
256
+ res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
257
+ res3.body.must_equal('{"counter"=>3}')
258
+
259
+ # Old cookie was deleted
260
+ res4 = req.get("/", "HTTP_COOKIE" => cookie)
261
+ res4.body.must_equal('{"counter"=>1}')
262
+ end
263
+ end
264
+
265
+ it "omits cookie with :defer option" do
266
+ with_pool_management(incrementor) do |pool|
267
+ defer = Rack::Utils::Context.new(pool, defer_session)
268
+ dreq = Rack::MockRequest.new(defer)
269
+
270
+ res0 = dreq.get("/")
271
+ res0["Set-Cookie"].must_be_nil
272
+ res0.body.must_equal('{"counter"=>1}')
273
+ end
274
+ end
275
+
276
+ it "does not hit with :skip option" do
277
+ with_pool_management(incrementor) do |session_store|
278
+ skip = Rack::Utils::Context.new(session_store, skip_session)
279
+ sreq = Rack::MockRequest.new(skip)
280
+
281
+ res0 = sreq.get("/")
282
+ res0.body.must_equal('{"counter"=>1}')
283
+ end
284
+ end
285
+
286
+ it "updates deep hashes correctly" do
287
+ hash_check = proc do |env|
288
+ session = env['rack.session']
289
+ unless session.include? 'test'
290
+ session.update :a => :b, :c => { :d => :e },
291
+ :f => { :g => { :h => :i} }, 'test' => true
292
+ else
293
+ session[:f][:g][:h] = :j
294
+ end
295
+ [200, {}, [session.inspect]]
296
+ end
297
+ with_pool_management(hash_check) do |pool|
298
+ req = Rack::MockRequest.new(pool)
299
+
300
+ res0 = req.get("/")
301
+ session_id = (cookie = res0["Set-Cookie"])[session_match, 1]
302
+ sid = Rack::Session::SessionId.new(session_id)
303
+ ses0 = pool.with { |c| c.get(sid.private_id) }
304
+
305
+ req.get("/", "HTTP_COOKIE" => cookie)
306
+ ses1 = pool.with { |c| c.get(sid.private_id) }
307
+
308
+ ses1.wont_equal(ses0)
309
+ end
310
+ end
311
+
312
+ # anyone know how to do this better?
313
+ it "cleanly merges sessions when multithreaded" do
314
+ unless $DEBUG
315
+ 1.must_equal(1) # fake assertion to appease the mighty bacon
316
+ next
317
+ end
318
+ warn 'Running multithread test for Session::Redis'
319
+ with_pool_management(incrementor) do |pool|
320
+ req = Rack::MockRequest.new(pool)
321
+
322
+ res = req.get('/')
323
+ res.body.must_equal('{"counter"=>1}')
324
+ cookie = res["Set-Cookie"]
325
+ session_id = cookie[session_match, 1]
326
+ sid = Rack::Session::SessionId.new(session_id)
327
+
328
+ delta_incrementor = lambda do |env|
329
+ # emulate disconjoinment of threading
330
+ env['rack.session'] = env['rack.session'].dup
331
+ Thread.stop
332
+ env['rack.session'][(Time.now.usec*rand).to_i] = true
333
+ incrementor.call(env)
334
+ end
335
+ tses = Rack::Utils::Context.new pool, delta_incrementor
336
+ treq = Rack::MockRequest.new(tses)
337
+ tnum = rand(7).to_i+5
338
+ r = Array.new(tnum) do
339
+ Thread.new(treq) do |run|
340
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
341
+ end
342
+ end.reverse.map{|t| t.run.join.value }
343
+ r.each do |request|
344
+ request['Set-Cookie'].must_equal(cookie)
345
+ request.body.must_include('"counter"=>2')
346
+ end
347
+
348
+ session = pool.with { |c| c.get(sid.private_id) }
349
+ session.size.must_equal(tnum+1) # counter
350
+ session['counter'].must_equal(2) # meeeh
351
+
352
+ tnum = rand(7).to_i+5
353
+ r = Array.new(tnum) do |i|
354
+ app = Rack::Utils::Context.new pool, time_delta
355
+ req = Rack::MockRequest.new app
356
+ Thread.new(req) do |run|
357
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
358
+ end
359
+ end.reverse.map{|t| t.run.join.value }
360
+ r.each do |request|
361
+ request['Set-Cookie'].must_equal(cookie)
362
+ request.body.must_include('"counter"=>3')
363
+ end
364
+
365
+ session = pool.with { |c| c.get(sid.private_id) }
366
+ session.size.must_equal(tnum+1)
367
+ session['counter'].must_equal(3)
368
+
369
+ drop_counter = proc do |env|
370
+ env['rack.session'].delete 'counter'
371
+ env['rack.session']['foo'] = 'bar'
372
+ [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
373
+ end
374
+ tses = Rack::Utils::Context.new pool, drop_counter
375
+ treq = Rack::MockRequest.new(tses)
376
+ tnum = rand(7).to_i+5
377
+ r = Array.new(tnum) do
378
+ Thread.new(treq) do |run|
379
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
380
+ end
381
+ end.reverse.map{|t| t.run.join.value }
382
+ r.each do |request|
383
+ request['Set-Cookie'].must_equal(cookie)
384
+ request.body.must_include('"foo"=>"bar"')
385
+ end
386
+
387
+ session = pool.with { |c| c.get(sid.private_id) }
388
+ session.size.must_equal(r.size+1)
389
+ session['counter'].must_be_nil
390
+ session['foo'].must_equal('bar')
391
+ end
392
+ end
393
+
394
+ private
395
+ def with_pool_management(*args)
396
+ yield simple(*args)
397
+ yield pooled(*args)
398
+ yield external_pooled(*args)
399
+ end
400
+
401
+ def simple(app, options = {})
402
+ Rack::Session::Redis.new(app, options)
403
+ end
404
+
405
+ def pooled(app, options = {})
406
+ Rack::Session::Redis.new(app, options)
407
+ Rack::Session::Redis.new(app, options.merge(pool_size: 5, pool_timeout: 10))
408
+ end
409
+
410
+ def external_pooled(app, options = {})
411
+ Rack::Session::Redis.new(app, options.merge(pool: ::ConnectionPool.new(size: 1, timeout: 1) { ::Redis::Store::Factory.create("redis://127.0.0.1:6380/1") }))
412
+ end
413
+
414
+ end
@@ -0,0 +1,84 @@
1
+ require 'test_helper'
2
+ require 'connection_pool'
3
+ require 'redis/rack/connection'
4
+
5
+ class Redis
6
+ module Rack
7
+ describe Connection do
8
+ def setup
9
+ @defaults = {
10
+ host: 'localhost'
11
+ }
12
+ end
13
+
14
+ it "can create it's own pool" do
15
+ conn = Connection.new @defaults.merge(pool_size: 5, pool_timeout: 10)
16
+
17
+ conn.pooled?.must_equal true
18
+ conn.pool.class.must_equal ConnectionPool
19
+ conn.pool.instance_variable_get(:@size).must_equal 5
20
+ end
21
+
22
+ it "can create it's own pool using default Redis server" do
23
+ conn = Connection.new @defaults.merge(pool_size: 5, pool_timeout: 10)
24
+
25
+ conn.pooled?.must_equal true
26
+
27
+ conn.with do |connection|
28
+ connection.to_s.must_match(/127\.0\.0\.1:6379 against DB 0$/)
29
+ end
30
+ end
31
+
32
+ it "can create it's own pool using provided Redis server" do
33
+ conn = Connection.new(redis_server: 'redis://127.0.0.1:6380/1', pool_size: 5, pool_timeout: 10)
34
+ conn.pooled?.must_equal true
35
+ conn.with do |connection|
36
+ connection.to_s.must_match(/127\.0\.0\.1:6380 against DB 1$/)
37
+ end
38
+ end
39
+
40
+ it "can use a supplied pool" do
41
+ pool = ConnectionPool.new size: 1, timeout: 1 do
42
+ ::Redis::Store::Factory.create('redis://127.0.0.1:6380/1')
43
+ end
44
+ conn = Connection.new pool: pool
45
+ conn.pooled?.must_equal true
46
+ conn.pool.class.must_equal ConnectionPool
47
+ conn.pool.instance_variable_get(:@size).must_equal 1
48
+ end
49
+
50
+ it "uses the specified Redis store when provided" do
51
+ store = ::Redis::Store::Factory.create('redis://127.0.0.1:6380/1')
52
+ conn = Connection.new(redis_store: store)
53
+
54
+ conn.pooled?.must_equal false
55
+ conn.store.to_s.must_match(/127\.0\.0\.1:6380 against DB 1$/)
56
+ conn.store.must_equal(store)
57
+ end
58
+
59
+ it "throws an error when provided Redis store is not the expected type" do
60
+ assert_raises ArgumentError do
61
+ Connection.new(redis_store: ::Redis.new)
62
+ end
63
+ end
64
+
65
+ it "uses the specified Redis server when provided" do
66
+ conn = Connection.new(redis_server: 'redis://127.0.0.1:6380/1')
67
+
68
+ conn.pooled?.must_equal false
69
+ conn.store.to_s.must_match(/127\.0\.0\.1:6380 against DB 1$/)
70
+ end
71
+
72
+ it "does not include nil options for the connection pool" do
73
+ conn = Connection.new
74
+ conn.pool_options.must_be_empty
75
+
76
+ conn = Connection.new(pool_size: nil)
77
+ conn.pool_options.must_be_empty
78
+
79
+ conn = Connection.new(pool_timeout: nil)
80
+ conn.pool_options.must_be_empty
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,5 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/autorun'
3
+ require 'mocha/setup'
4
+ require 'rack'
5
+ require 'rack/session/redis'
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis-rack-my-checksub
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Luca Guidi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis-store
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '1.2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "<"
28
+ - !ruby/object:Gem::Version
29
+ version: '2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '1.2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rack
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 2.0.8
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '3'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 2.0.8
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '3'
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 12.3.3
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 12.3.3
67
+ - !ruby/object:Gem::Dependency
68
+ name: bundler
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">"
72
+ - !ruby/object:Gem::Version
73
+ version: '1'
74
+ - - "<"
75
+ - !ruby/object:Gem::Version
76
+ version: '3'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">"
82
+ - !ruby/object:Gem::Version
83
+ version: '1'
84
+ - - "<"
85
+ - !ruby/object:Gem::Version
86
+ version: '3'
87
+ - !ruby/object:Gem::Dependency
88
+ name: mocha
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: 0.14.0
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: 0.14.0
101
+ - !ruby/object:Gem::Dependency
102
+ name: minitest
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '5'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '5'
115
+ - !ruby/object:Gem::Dependency
116
+ name: connection_pool
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: 1.2.0
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: 1.2.0
129
+ description: Redis Store for Rack applications
130
+ email:
131
+ - me@lucaguidi.com
132
+ executables: []
133
+ extensions: []
134
+ extra_rdoc_files: []
135
+ files:
136
+ - ".github/auto-assign-issues.yml"
137
+ - ".gitignore"
138
+ - ".ruby-version"
139
+ - ".travis.yml"
140
+ - CHANGELOG.md
141
+ - CODEOWNERS
142
+ - Gemfile
143
+ - MIT-LICENSE
144
+ - README.md
145
+ - Rakefile
146
+ - bin/appraisal
147
+ - bin/rake
148
+ - lib/rack/session/redis.rb
149
+ - lib/redis-rack.rb
150
+ - lib/redis/rack/connection.rb
151
+ - lib/redis/rack/version.rb
152
+ - redis-rack.gemspec
153
+ - test/rack/session/redis_test.rb
154
+ - test/redis/rack/connection_test.rb
155
+ - test/test_helper.rb
156
+ homepage: http://redis-store.org/redis-rack
157
+ licenses:
158
+ - MIT
159
+ metadata: {}
160
+ post_install_message:
161
+ rdoc_options: []
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ requirements: []
175
+ rubygems_version: 3.1.2
176
+ signing_key:
177
+ specification_version: 4
178
+ summary: Redis Store for Rack
179
+ test_files:
180
+ - test/rack/session/redis_test.rb
181
+ - test/redis/rack/connection_test.rb
182
+ - test/test_helper.rb