redis-rack 1.6.0 → 2.0.6
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 +5 -5
- data/.github/auto-assign-issues.yml +2 -0
- data/.gitignore +2 -0
- data/.travis.yml +18 -10
- data/Appraisals +7 -0
- data/CODEOWNERS +1 -0
- data/Gemfile +0 -4
- data/README.md +53 -12
- data/Rakefile +6 -0
- data/bin/appraisal +17 -0
- data/bin/rake +17 -0
- data/gemfiles/rack_1.gemfile +7 -0
- data/gemfiles/rack_2.gemfile +7 -0
- data/lib/rack/session/redis.rb +30 -16
- data/lib/redis/rack/connection.rb +46 -0
- data/lib/redis/rack/version.rb +1 -1
- data/redis-rack.gemspec +5 -3
- data/test/rack/session/redis_test.rb +293 -174
- data/test/redis/rack/connection_test.rb +84 -0
- metadata +73 -26
- data/test/redis/rack/version_test.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 68b8d92fa59d3d7167cf87bd16e1e62ca34ba905a901964a6d386b47155f8da0
|
4
|
+
data.tar.gz: 3c8b27ef07b66c2050d053287c03eb3aee64860fda3e4ff806200d9cc663f7ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 351e468a771f67ed2e05c3620735636f23f7ad40e338d420c3662a2f7bfc1abdf82e3cf30c1e9a8268452ed1451e87740cc7fabb110b5c60251717a84b2c70f4
|
7
|
+
data.tar.gz: b93772d79076558bf42e60effd452a47699e215538e73435ec70f500ee8e2902b65b7c1f2eb40d4019884c12fbf81ab57b940702657b4295581abe820483631d
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
language: ruby
|
2
|
-
script:
|
2
|
+
script: bundle exec rake
|
3
3
|
rvm:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
- jruby-19mode
|
9
|
-
- jruby-head
|
10
|
-
|
4
|
+
- 2.2.3
|
5
|
+
- 2.3.1
|
6
|
+
- ruby-head
|
7
|
+
- jruby-head
|
11
8
|
matrix:
|
12
9
|
allow_failures:
|
13
|
-
|
14
|
-
|
10
|
+
- rvm: jruby-head
|
11
|
+
- rvm: ruby-head
|
12
|
+
gemfile:
|
13
|
+
- gemfiles/rack_2.gemfile
|
14
|
+
- gemfiles/rack_1.gemfile
|
15
|
+
deploy:
|
16
|
+
provider: rubygems
|
17
|
+
api_key:
|
18
|
+
secure: VTosVmCdLWUGK8KyzovYri7ySfd7fACtfL8MClEBBHnI+m2cLCpmtCJ7Z1X7z9BXlj974EDaF8V9iRKzfksXIf8aaPfVQw9AW94fLJZbfSB8YGOGyNbPu9YECoZQB1aZ2lw9s/aEdfwCbmqizO/fYpG3YoPKJdm1ZJpNOFR37Xk=
|
19
|
+
gem: redis-rack
|
20
|
+
on:
|
21
|
+
tags: true
|
22
|
+
repo: redis-store/redis-rack
|
data/Appraisals
ADDED
data/CODEOWNERS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* @tubbo
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,37 @@
|
|
1
|
-
# Redis
|
1
|
+
# Redis session store for Rack
|
2
2
|
|
3
|
-
__`redis-rack`__ provides a Redis
|
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
|
+
[](http://travis-ci.org/redis-store/redis-rack?branch=master)
|
12
|
+
[](https://codeclimate.com/github/redis-store/redis-rack)
|
13
|
+
[](http://badge.fury.io/rb/redis-rack)
|
4
14
|
|
5
15
|
## Installation
|
6
16
|
|
17
|
+
Install with Bundler by adding the following to Gemfile:
|
18
|
+
|
7
19
|
```ruby
|
8
|
-
# Gemfile
|
9
20
|
gem 'redis-rack'
|
10
21
|
```
|
11
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
|
+
|
12
35
|
## Usage
|
13
36
|
|
14
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:
|
@@ -19,24 +42,42 @@ require 'rack'
|
|
19
42
|
require 'rack/session/redis'
|
20
43
|
|
21
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
|
22
50
|
```
|
23
51
|
|
24
|
-
##
|
52
|
+
## Development
|
53
|
+
|
54
|
+
To install this gem for development purposes:
|
25
55
|
|
26
56
|
```shell
|
27
|
-
gem install bundler
|
28
|
-
git clone git://github.com/redis-store/redis-rack.git
|
29
|
-
cd redis-rack
|
30
|
-
bundle install
|
31
|
-
bundle exec rake
|
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
|
32
61
|
```
|
33
62
|
|
34
|
-
|
63
|
+
## Running tests
|
35
64
|
|
36
|
-
|
65
|
+
To run tests:
|
37
66
|
|
38
|
-
|
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
|
+
```
|
39
77
|
|
40
78
|
## Copyright
|
41
79
|
|
42
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
CHANGED
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")
|
data/lib/rack/session/redis.rb
CHANGED
@@ -1,57 +1,69 @@
|
|
1
1
|
require 'rack/session/abstract/id'
|
2
2
|
require 'redis-store'
|
3
3
|
require 'thread'
|
4
|
+
require 'redis/rack/connection'
|
4
5
|
|
5
6
|
module Rack
|
6
7
|
module Session
|
7
8
|
class Redis < Abstract::ID
|
8
|
-
attr_reader :mutex
|
9
|
+
attr_reader :mutex
|
9
10
|
|
10
|
-
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge
|
11
|
+
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge(
|
11
12
|
:redis_server => 'redis://127.0.0.1:6379/0/rack:session'
|
13
|
+
)
|
12
14
|
|
13
15
|
def initialize(app, options = {})
|
14
16
|
super
|
15
17
|
|
16
18
|
@mutex = Mutex.new
|
17
|
-
@
|
19
|
+
@conn = ::Redis::Rack::Connection.new(@default_options)
|
18
20
|
end
|
19
21
|
|
20
|
-
def
|
22
|
+
def generate_unique_sid(session)
|
23
|
+
return generate_sid if session.empty?
|
21
24
|
loop do
|
22
|
-
sid =
|
23
|
-
|
25
|
+
sid = generate_sid
|
26
|
+
first = with do |c|
|
27
|
+
[*c.setnx(sid, session, @default_options)].first
|
28
|
+
end
|
29
|
+
break sid if [1, true].include?(first)
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
27
33
|
def get_session(env, sid)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
if env['rack.session.options'][:skip]
|
35
|
+
[generate_sid, {}]
|
36
|
+
else
|
37
|
+
with_lock(env, [nil, {}]) do
|
38
|
+
unless sid and session = with { |c| c.get(sid) }
|
39
|
+
session = {}
|
40
|
+
sid = generate_unique_sid(session)
|
33
41
|
end
|
42
|
+
[sid, session]
|
34
43
|
end
|
35
|
-
[sid, session]
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
39
47
|
def set_session(env, session_id, new_session, options)
|
40
48
|
with_lock(env, false) do
|
41
|
-
|
49
|
+
with { |c| c.set session_id, new_session, options }
|
42
50
|
session_id
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
54
|
def destroy_session(env, session_id, options)
|
47
55
|
with_lock(env) do
|
48
|
-
|
56
|
+
with { |c| c.del(session_id) }
|
49
57
|
generate_sid unless options[:drop]
|
50
58
|
end
|
51
59
|
end
|
52
60
|
|
61
|
+
def threadsafe?
|
62
|
+
@default_options.fetch(:threadsafe, true)
|
63
|
+
end
|
64
|
+
|
53
65
|
def with_lock(env, default=nil)
|
54
|
-
@mutex.lock if env['rack.multithread']
|
66
|
+
@mutex.lock if env['rack.multithread'] && threadsafe?
|
55
67
|
yield
|
56
68
|
rescue Errno::ECONNREFUSED
|
57
69
|
if $VERBOSE
|
@@ -63,7 +75,9 @@ module Rack
|
|
63
75
|
@mutex.unlock if @mutex.locked?
|
64
76
|
end
|
65
77
|
|
78
|
+
def with(&block)
|
79
|
+
@conn.with(&block)
|
80
|
+
end
|
66
81
|
end
|
67
82
|
end
|
68
83
|
end
|
69
|
-
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class Redis
|
2
|
+
module Rack
|
3
|
+
class Connection
|
4
|
+
def initialize(options = {})
|
5
|
+
@options = options
|
6
|
+
@store = options[:redis_store]
|
7
|
+
@pool = options[:pool]
|
8
|
+
|
9
|
+
if @pool && !@pool.is_a?(ConnectionPool)
|
10
|
+
raise ArgumentError, "pool must be an instance of ConnectionPool"
|
11
|
+
end
|
12
|
+
|
13
|
+
if @store && !@store.is_a?(Redis::Store)
|
14
|
+
raise ArgumentError, "redis_store must be an instance of Redis::Store (currently #{@store.class.name})"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def with(&block)
|
19
|
+
if pooled?
|
20
|
+
pool.with(&block)
|
21
|
+
else
|
22
|
+
block.call(store)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def pooled?
|
27
|
+
[:pool, :pool_size, :pool_timeout].any? { |key| @options.key?(key) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def pool
|
31
|
+
@pool ||= ConnectionPool.new(pool_options) { store } if pooled?
|
32
|
+
end
|
33
|
+
|
34
|
+
def store
|
35
|
+
@store ||= Redis::Store::Factory.create(@options[:redis_server])
|
36
|
+
end
|
37
|
+
|
38
|
+
def pool_options
|
39
|
+
{
|
40
|
+
size: @options[:pool_size],
|
41
|
+
timeout: @options[:pool_timeout]
|
42
|
+
}.reject { |key, value| value.nil? }.to_h
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/redis/rack/version.rb
CHANGED
data/redis-rack.gemspec
CHANGED
@@ -16,16 +16,18 @@ Gem::Specification.new do |s|
|
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
-
s.executables =
|
19
|
+
s.executables = []
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_runtime_dependency 'redis-store', '
|
23
|
-
s.add_runtime_dependency 'rack', '
|
22
|
+
s.add_runtime_dependency 'redis-store', ['< 2', '>= 1.2']
|
23
|
+
s.add_runtime_dependency 'rack', '>= 1.5', '< 3'
|
24
24
|
|
25
25
|
s.add_development_dependency 'rake', '~> 10'
|
26
26
|
s.add_development_dependency 'bundler', '~> 1.3'
|
27
27
|
s.add_development_dependency 'mocha', '~> 0.14.0'
|
28
28
|
s.add_development_dependency 'minitest', '~> 5'
|
29
29
|
s.add_development_dependency 'redis-store-testing'
|
30
|
+
s.add_development_dependency 'connection_pool', '~> 1.2.0'
|
31
|
+
s.add_development_dependency 'appraisal'
|
30
32
|
end
|
31
33
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'rack/mock'
|
3
3
|
require 'thread'
|
4
|
+
require 'connection_pool'
|
4
5
|
|
5
6
|
describe Rack::Session::Redis do
|
6
7
|
session_key = Rack::Session::Redis::DEFAULT_OPTIONS[:key]
|
@@ -22,6 +23,10 @@ describe Rack::Session::Redis do
|
|
22
23
|
env['rack.session.options'][:defer] = true
|
23
24
|
incrementor.call(env)
|
24
25
|
end
|
26
|
+
skip_session = proc do |env|
|
27
|
+
env['rack.session.options'][:skip] = true
|
28
|
+
incrementor.call(env)
|
29
|
+
end
|
25
30
|
|
26
31
|
# # test Redis connection
|
27
32
|
# Rack::Session::Redis.new(incrementor)
|
@@ -32,155 +37,246 @@ describe Rack::Session::Redis do
|
|
32
37
|
# }.must_raise(Exception)
|
33
38
|
# end
|
34
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
|
+
|
35
73
|
it "uses the default Redis server and namespace when not provided" do
|
36
74
|
pool = Rack::Session::Redis.new(incrementor)
|
37
|
-
pool.
|
75
|
+
pool.with { |p| p.to_s.must_match(/127\.0\.0\.1:6379 against DB 0 with namespace rack:session$/) }
|
38
76
|
end
|
39
77
|
|
40
78
|
it "uses the specified namespace when provided" do
|
41
79
|
pool = Rack::Session::Redis.new(incrementor, :redis_server => {:namespace => 'test:rack:session'})
|
42
|
-
pool.
|
80
|
+
pool.with { |p| p.to_s.must_match(/namespace test:rack:session$/) }
|
43
81
|
end
|
44
82
|
|
45
83
|
it "uses the specified Redis server when provided" do
|
46
84
|
pool = Rack::Session::Redis.new(incrementor, :redis_server => 'redis://127.0.0.1:6380/1')
|
47
|
-
pool.
|
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).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
|
+
sesion_store.with_lock({'rack.multithread' => true}) { was_yielded = true}
|
106
|
+
was_yielded.must_equal(true)
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "threadsafe disabled" do
|
110
|
+
it "can have the global lock disabled" do
|
111
|
+
sesion_store = Rack::Session::Redis.new(incrementor, :threadsafe => false)
|
112
|
+
sesion_store.threadsafe?.must_equal(false)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "does not lock the store mutex" do
|
116
|
+
mutex = Mutex.new
|
117
|
+
mutex.expects(:lock).never
|
118
|
+
sesion_store = Rack::Session::Redis.new(incrementor, :threadsafe => false)
|
119
|
+
sesion_store.instance_variable_set(:@mutex, mutex)
|
120
|
+
was_yielded = false
|
121
|
+
sesion_store.with_lock({'rack.multithread' => true}) { was_yielded = true}
|
122
|
+
was_yielded.must_equal(true)
|
123
|
+
end
|
48
124
|
end
|
49
125
|
|
50
126
|
it "creates a new cookie" do
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
127
|
+
with_pool_management(incrementor) do |pool|
|
128
|
+
res = Rack::MockRequest.new(pool).get("/")
|
129
|
+
res["Set-Cookie"].must_include("#{session_key}=")
|
130
|
+
res.body.must_equal('{"counter"=>1}')
|
131
|
+
end
|
55
132
|
end
|
56
133
|
|
57
134
|
it "determines session from a cookie" do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
135
|
+
with_pool_management(incrementor) do |pool|
|
136
|
+
req = Rack::MockRequest.new(pool)
|
137
|
+
res = req.get("/")
|
138
|
+
cookie = res["Set-Cookie"]
|
139
|
+
req.get("/", "HTTP_COOKIE" => cookie).
|
140
|
+
body.must_equal('{"counter"=>2}')
|
141
|
+
req.get("/", "HTTP_COOKIE" => cookie).
|
142
|
+
body.must_equal('{"counter"=>3}')
|
143
|
+
end
|
66
144
|
end
|
67
145
|
|
68
146
|
it "determines session only from a cookie by default" do
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
147
|
+
with_pool_management(incrementor) do |pool|
|
148
|
+
req = Rack::MockRequest.new(pool)
|
149
|
+
res = req.get("/")
|
150
|
+
sid = res["Set-Cookie"][session_match, 1]
|
151
|
+
req.get("/?rack.session=#{sid}").
|
152
|
+
body.must_equal('{"counter"=>1}')
|
153
|
+
req.get("/?rack.session=#{sid}").
|
154
|
+
body.must_equal('{"counter"=>1}')
|
155
|
+
end
|
77
156
|
end
|
78
157
|
|
79
158
|
it "determines session from params" do
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
159
|
+
with_pool_management(incrementor, :cookie_only => false) do |pool|
|
160
|
+
req = Rack::MockRequest.new(pool)
|
161
|
+
res = req.get("/")
|
162
|
+
sid = res["Set-Cookie"][session_match, 1]
|
163
|
+
req.get("/?rack.session=#{sid}").
|
164
|
+
body.must_equal('{"counter"=>2}')
|
165
|
+
req.get("/?rack.session=#{sid}").
|
166
|
+
body.must_equal('{"counter"=>3}')
|
167
|
+
end
|
88
168
|
end
|
89
169
|
|
90
170
|
it "survives nonexistant cookies" do
|
91
171
|
bad_cookie = "rack.session=blarghfasel"
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
172
|
+
with_pool_management(incrementor) do |pool|
|
173
|
+
res = Rack::MockRequest.new(pool).
|
174
|
+
get("/", "HTTP_COOKIE" => bad_cookie)
|
175
|
+
res.body.must_equal('{"counter"=>1}')
|
176
|
+
cookie = res["Set-Cookie"][session_match]
|
177
|
+
cookie.wont_match(/#{bad_cookie}/)
|
178
|
+
end
|
98
179
|
end
|
99
180
|
|
100
181
|
it "maintains freshness" do
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
182
|
+
with_pool_management(incrementor, :expire_after => 3) do |pool|
|
183
|
+
res = Rack::MockRequest.new(pool).get('/')
|
184
|
+
res.body.must_include('"counter"=>1')
|
185
|
+
cookie = res["Set-Cookie"]
|
186
|
+
sid = cookie[session_match, 1]
|
187
|
+
res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
188
|
+
res["Set-Cookie"][session_match, 1].must_equal(sid)
|
189
|
+
res.body.must_include('"counter"=>2')
|
190
|
+
puts 'Sleeping to expire session' if $DEBUG
|
191
|
+
sleep 4
|
192
|
+
res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
193
|
+
res["Set-Cookie"][session_match, 1].wont_equal(sid)
|
194
|
+
res.body.must_include('"counter"=>1')
|
195
|
+
end
|
114
196
|
end
|
115
197
|
|
116
198
|
it "does not send the same session id if it did not change" do
|
117
|
-
|
118
|
-
|
199
|
+
with_pool_management(incrementor) do |pool|
|
200
|
+
req = Rack::MockRequest.new(pool)
|
119
201
|
|
120
|
-
|
121
|
-
|
122
|
-
|
202
|
+
res0 = req.get("/")
|
203
|
+
cookie = res0["Set-Cookie"]
|
204
|
+
res0.body.must_equal('{"counter"=>1}')
|
123
205
|
|
124
|
-
|
125
|
-
|
126
|
-
|
206
|
+
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
207
|
+
res1["Set-Cookie"].must_be_nil
|
208
|
+
res1.body.must_equal('{"counter"=>2}')
|
127
209
|
|
128
|
-
|
129
|
-
|
130
|
-
|
210
|
+
res2 = req.get("/", "HTTP_COOKIE" => cookie)
|
211
|
+
res2["Set-Cookie"].must_be_nil
|
212
|
+
res2.body.must_equal('{"counter"=>3}')
|
213
|
+
end
|
131
214
|
end
|
132
215
|
|
133
216
|
it "deletes cookies with :drop option" do
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
217
|
+
with_pool_management(incrementor) do |pool|
|
218
|
+
req = Rack::MockRequest.new(pool)
|
219
|
+
drop = Rack::Utils::Context.new(pool, drop_session)
|
220
|
+
dreq = Rack::MockRequest.new(drop)
|
221
|
+
|
222
|
+
res1 = req.get("/")
|
223
|
+
session = (cookie = res1["Set-Cookie"])[session_match]
|
224
|
+
res1.body.must_equal('{"counter"=>1}')
|
225
|
+
|
226
|
+
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
227
|
+
res2["Set-Cookie"].must_be_nil
|
228
|
+
res2.body.must_equal('{"counter"=>2}')
|
229
|
+
|
230
|
+
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
231
|
+
res3["Set-Cookie"][session_match].wont_equal(session)
|
232
|
+
res3.body.must_equal('{"counter"=>1}')
|
233
|
+
end
|
150
234
|
end
|
151
235
|
|
152
236
|
it "provides new session id with :renew option" do
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
237
|
+
with_pool_management(incrementor) do |pool|
|
238
|
+
req = Rack::MockRequest.new(pool)
|
239
|
+
renew = Rack::Utils::Context.new(pool, renew_session)
|
240
|
+
rreq = Rack::MockRequest.new(renew)
|
241
|
+
|
242
|
+
res1 = req.get("/")
|
243
|
+
session = (cookie = res1["Set-Cookie"])[session_match]
|
244
|
+
res1.body.must_equal('{"counter"=>1}')
|
245
|
+
|
246
|
+
res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
|
247
|
+
new_cookie = res2["Set-Cookie"]
|
248
|
+
new_session = new_cookie[session_match]
|
249
|
+
new_session.wont_equal(session)
|
250
|
+
res2.body.must_equal('{"counter"=>2}')
|
251
|
+
|
252
|
+
res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
|
253
|
+
res3.body.must_equal('{"counter"=>3}')
|
254
|
+
|
255
|
+
# Old cookie was deleted
|
256
|
+
res4 = req.get("/", "HTTP_COOKIE" => cookie)
|
257
|
+
res4.body.must_equal('{"counter"=>1}')
|
258
|
+
end
|
174
259
|
end
|
175
260
|
|
176
261
|
it "omits cookie with :defer option" do
|
177
|
-
|
178
|
-
|
179
|
-
|
262
|
+
with_pool_management(incrementor) do |pool|
|
263
|
+
defer = Rack::Utils::Context.new(pool, defer_session)
|
264
|
+
dreq = Rack::MockRequest.new(defer)
|
265
|
+
|
266
|
+
res0 = dreq.get("/")
|
267
|
+
res0["Set-Cookie"].must_be_nil
|
268
|
+
res0.body.must_equal('{"counter"=>1}')
|
269
|
+
end
|
270
|
+
end
|
180
271
|
|
181
|
-
|
182
|
-
|
183
|
-
|
272
|
+
it "does not hit with :skip option" do
|
273
|
+
with_pool_management(incrementor) do |session_store|
|
274
|
+
skip = Rack::Utils::Context.new(session_store, skip_session)
|
275
|
+
sreq = Rack::MockRequest.new(skip)
|
276
|
+
|
277
|
+
res0 = sreq.get("/")
|
278
|
+
res0.body.must_equal('{"counter"=>1}')
|
279
|
+
end
|
184
280
|
end
|
185
281
|
|
186
282
|
it "updates deep hashes correctly" do
|
@@ -194,17 +290,18 @@ describe Rack::Session::Redis do
|
|
194
290
|
end
|
195
291
|
[200, {}, [session.inspect]]
|
196
292
|
end
|
197
|
-
|
198
|
-
|
293
|
+
with_pool_management(hash_check) do |pool|
|
294
|
+
req = Rack::MockRequest.new(pool)
|
199
295
|
|
200
|
-
|
201
|
-
|
202
|
-
|
296
|
+
res0 = req.get("/")
|
297
|
+
session_id = (cookie = res0["Set-Cookie"])[session_match, 1]
|
298
|
+
ses0 = pool.with { |c| c.get(session_id) }
|
203
299
|
|
204
|
-
|
205
|
-
|
300
|
+
req.get("/", "HTTP_COOKIE" => cookie)
|
301
|
+
ses1 = pool.with { |c| c.get(session_id) }
|
206
302
|
|
207
|
-
|
303
|
+
ses1.wont_equal(ses0)
|
304
|
+
end
|
208
305
|
end
|
209
306
|
|
210
307
|
# anyone know how to do this better?
|
@@ -214,76 +311,98 @@ describe Rack::Session::Redis do
|
|
214
311
|
next
|
215
312
|
end
|
216
313
|
warn 'Running multithread test for Session::Redis'
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
314
|
+
with_pool_management(incrementor) do |pool|
|
315
|
+
req = Rack::MockRequest.new(pool)
|
316
|
+
|
317
|
+
res = req.get('/')
|
318
|
+
res.body.must_equal('{"counter"=>1}')
|
319
|
+
cookie = res["Set-Cookie"]
|
320
|
+
session_id = cookie[session_match, 1]
|
321
|
+
|
322
|
+
delta_incrementor = lambda do |env|
|
323
|
+
# emulate disconjoinment of threading
|
324
|
+
env['rack.session'] = env['rack.session'].dup
|
325
|
+
Thread.stop
|
326
|
+
env['rack.session'][(Time.now.usec*rand).to_i] = true
|
327
|
+
incrementor.call(env)
|
328
|
+
end
|
329
|
+
tses = Rack::Utils::Context.new pool, delta_incrementor
|
330
|
+
treq = Rack::MockRequest.new(tses)
|
331
|
+
tnum = rand(7).to_i+5
|
332
|
+
r = Array.new(tnum) do
|
333
|
+
Thread.new(treq) do |run|
|
334
|
+
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
335
|
+
end
|
336
|
+
end.reverse.map{|t| t.run.join.value }
|
337
|
+
r.each do |request|
|
338
|
+
request['Set-Cookie'].must_equal(cookie)
|
339
|
+
request.body.must_include('"counter"=>2')
|
340
|
+
end
|
341
|
+
|
342
|
+
session = pool.with { |c| c.get(session_id) }
|
343
|
+
session.size.must_equal(tnum+1) # counter
|
344
|
+
session['counter'].must_equal(2) # meeeh
|
345
|
+
|
346
|
+
tnum = rand(7).to_i+5
|
347
|
+
r = Array.new(tnum) do |i|
|
348
|
+
app = Rack::Utils::Context.new pool, time_delta
|
349
|
+
req = Rack::MockRequest.new app
|
350
|
+
Thread.new(req) do |run|
|
351
|
+
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
352
|
+
end
|
353
|
+
end.reverse.map{|t| t.run.join.value }
|
354
|
+
r.each do |request|
|
355
|
+
request['Set-Cookie'].must_equal(cookie)
|
356
|
+
request.body.must_include('"counter"=>3')
|
238
357
|
end
|
239
|
-
end.reverse.map{|t| t.run.join.value }
|
240
|
-
r.each do |request|
|
241
|
-
request['Set-Cookie'].must_equal(cookie)
|
242
|
-
request.body.must_include('"counter"=>2')
|
243
|
-
end
|
244
358
|
|
245
|
-
|
246
|
-
|
247
|
-
|
359
|
+
session = pool.with { |c| c.get(session_id) }
|
360
|
+
session.size.must_equal(tnum+1)
|
361
|
+
session['counter'].must_equal(3)
|
248
362
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
363
|
+
drop_counter = proc do |env|
|
364
|
+
env['rack.session'].delete 'counter'
|
365
|
+
env['rack.session']['foo'] = 'bar'
|
366
|
+
[200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
|
367
|
+
end
|
368
|
+
tses = Rack::Utils::Context.new pool, drop_counter
|
369
|
+
treq = Rack::MockRequest.new(tses)
|
370
|
+
tnum = rand(7).to_i+5
|
371
|
+
r = Array.new(tnum) do
|
372
|
+
Thread.new(treq) do |run|
|
373
|
+
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
374
|
+
end
|
375
|
+
end.reverse.map{|t| t.run.join.value }
|
376
|
+
r.each do |request|
|
377
|
+
request['Set-Cookie'].must_equal(cookie)
|
378
|
+
request.body.must_include('"foo"=>"bar"')
|
255
379
|
end
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
380
|
+
|
381
|
+
session = pool.with { |c| c.get(session_id) }
|
382
|
+
session.size.must_equal(r.size+1)
|
383
|
+
session['counter'].must_be_nil
|
384
|
+
session['foo'].must_equal('bar')
|
260
385
|
end
|
386
|
+
end
|
261
387
|
|
262
|
-
|
263
|
-
|
264
|
-
|
388
|
+
private
|
389
|
+
def with_pool_management(*args)
|
390
|
+
yield simple(*args)
|
391
|
+
yield pooled(*args)
|
392
|
+
yield external_pooled(*args)
|
393
|
+
end
|
265
394
|
|
266
|
-
|
267
|
-
|
268
|
-
env['rack.session']['foo'] = 'bar'
|
269
|
-
[200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
|
395
|
+
def simple(app, options = {})
|
396
|
+
Rack::Session::Redis.new(app, options)
|
270
397
|
end
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
r.each do |request|
|
280
|
-
request['Set-Cookie'].must_equal(cookie)
|
281
|
-
request.body.must_include('"foo"=>"bar"')
|
398
|
+
|
399
|
+
def pooled(app, options = {})
|
400
|
+
Rack::Session::Redis.new(app, options)
|
401
|
+
Rack::Session::Redis.new(app, options.merge(pool_size: 5, pool_timeout: 10))
|
402
|
+
end
|
403
|
+
|
404
|
+
def external_pooled(app, options = {})
|
405
|
+
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") }))
|
282
406
|
end
|
283
407
|
|
284
|
-
session = pool.pool.get(session_id)
|
285
|
-
session.size.must_equal(r.size+1)
|
286
|
-
session['counter'].must_be_nil
|
287
|
-
session['foo'].must_equal('bar')
|
288
|
-
end
|
289
408
|
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
|
metadata
CHANGED
@@ -1,111 +1,151 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-store
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.2
|
19
|
+
version: '1.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.2
|
29
|
+
version: '1.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rack
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- -
|
37
|
+
- - ">="
|
32
38
|
- !ruby/object:Gem::Version
|
33
39
|
version: '1.5'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '3'
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- -
|
47
|
+
- - ">="
|
39
48
|
- !ruby/object:Gem::Version
|
40
49
|
version: '1.5'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '3'
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: rake
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
44
56
|
requirements:
|
45
|
-
- - ~>
|
57
|
+
- - "~>"
|
46
58
|
- !ruby/object:Gem::Version
|
47
59
|
version: '10'
|
48
60
|
type: :development
|
49
61
|
prerelease: false
|
50
62
|
version_requirements: !ruby/object:Gem::Requirement
|
51
63
|
requirements:
|
52
|
-
- - ~>
|
64
|
+
- - "~>"
|
53
65
|
- !ruby/object:Gem::Version
|
54
66
|
version: '10'
|
55
67
|
- !ruby/object:Gem::Dependency
|
56
68
|
name: bundler
|
57
69
|
requirement: !ruby/object:Gem::Requirement
|
58
70
|
requirements:
|
59
|
-
- - ~>
|
71
|
+
- - "~>"
|
60
72
|
- !ruby/object:Gem::Version
|
61
73
|
version: '1.3'
|
62
74
|
type: :development
|
63
75
|
prerelease: false
|
64
76
|
version_requirements: !ruby/object:Gem::Requirement
|
65
77
|
requirements:
|
66
|
-
- - ~>
|
78
|
+
- - "~>"
|
67
79
|
- !ruby/object:Gem::Version
|
68
80
|
version: '1.3'
|
69
81
|
- !ruby/object:Gem::Dependency
|
70
82
|
name: mocha
|
71
83
|
requirement: !ruby/object:Gem::Requirement
|
72
84
|
requirements:
|
73
|
-
- - ~>
|
85
|
+
- - "~>"
|
74
86
|
- !ruby/object:Gem::Version
|
75
87
|
version: 0.14.0
|
76
88
|
type: :development
|
77
89
|
prerelease: false
|
78
90
|
version_requirements: !ruby/object:Gem::Requirement
|
79
91
|
requirements:
|
80
|
-
- - ~>
|
92
|
+
- - "~>"
|
81
93
|
- !ruby/object:Gem::Version
|
82
94
|
version: 0.14.0
|
83
95
|
- !ruby/object:Gem::Dependency
|
84
96
|
name: minitest
|
85
97
|
requirement: !ruby/object:Gem::Requirement
|
86
98
|
requirements:
|
87
|
-
- - ~>
|
99
|
+
- - "~>"
|
88
100
|
- !ruby/object:Gem::Version
|
89
101
|
version: '5'
|
90
102
|
type: :development
|
91
103
|
prerelease: false
|
92
104
|
version_requirements: !ruby/object:Gem::Requirement
|
93
105
|
requirements:
|
94
|
-
- - ~>
|
106
|
+
- - "~>"
|
95
107
|
- !ruby/object:Gem::Version
|
96
108
|
version: '5'
|
97
109
|
- !ruby/object:Gem::Dependency
|
98
110
|
name: redis-store-testing
|
99
111
|
requirement: !ruby/object:Gem::Requirement
|
100
112
|
requirements:
|
101
|
-
- -
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: connection_pool
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.2.0
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "~>"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: 1.2.0
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: appraisal
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
102
142
|
- !ruby/object:Gem::Version
|
103
143
|
version: '0'
|
104
144
|
type: :development
|
105
145
|
prerelease: false
|
106
146
|
version_requirements: !ruby/object:Gem::Requirement
|
107
147
|
requirements:
|
108
|
-
- -
|
148
|
+
- - ">="
|
109
149
|
- !ruby/object:Gem::Version
|
110
150
|
version: '0'
|
111
151
|
description: Redis Store for Rack applications
|
@@ -115,18 +155,26 @@ executables: []
|
|
115
155
|
extensions: []
|
116
156
|
extra_rdoc_files: []
|
117
157
|
files:
|
118
|
-
- .
|
119
|
-
- .
|
158
|
+
- ".github/auto-assign-issues.yml"
|
159
|
+
- ".gitignore"
|
160
|
+
- ".travis.yml"
|
161
|
+
- Appraisals
|
162
|
+
- CODEOWNERS
|
120
163
|
- Gemfile
|
121
164
|
- MIT-LICENSE
|
122
165
|
- README.md
|
123
166
|
- Rakefile
|
167
|
+
- bin/appraisal
|
168
|
+
- bin/rake
|
169
|
+
- gemfiles/rack_1.gemfile
|
170
|
+
- gemfiles/rack_2.gemfile
|
124
171
|
- lib/rack/session/redis.rb
|
125
172
|
- lib/redis-rack.rb
|
173
|
+
- lib/redis/rack/connection.rb
|
126
174
|
- lib/redis/rack/version.rb
|
127
175
|
- redis-rack.gemspec
|
128
176
|
- test/rack/session/redis_test.rb
|
129
|
-
- test/redis/rack/
|
177
|
+
- test/redis/rack/connection_test.rb
|
130
178
|
- test/test_helper.rb
|
131
179
|
homepage: http://redis-store.org/redis-rack
|
132
180
|
licenses:
|
@@ -138,21 +186,20 @@ require_paths:
|
|
138
186
|
- lib
|
139
187
|
required_ruby_version: !ruby/object:Gem::Requirement
|
140
188
|
requirements:
|
141
|
-
- -
|
189
|
+
- - ">="
|
142
190
|
- !ruby/object:Gem::Version
|
143
191
|
version: '0'
|
144
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
193
|
requirements:
|
146
|
-
- -
|
194
|
+
- - ">="
|
147
195
|
- !ruby/object:Gem::Version
|
148
196
|
version: '0'
|
149
197
|
requirements: []
|
150
|
-
|
151
|
-
rubygems_version: 2.5.2
|
198
|
+
rubygems_version: 3.0.3
|
152
199
|
signing_key:
|
153
200
|
specification_version: 4
|
154
201
|
summary: Redis Store for Rack
|
155
202
|
test_files:
|
156
203
|
- test/rack/session/redis_test.rb
|
157
|
-
- test/redis/rack/
|
204
|
+
- test/redis/rack/connection_test.rb
|
158
205
|
- test/test_helper.rb
|