mongo-store 0.1.2 → 0.2.0
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.
- data/Rakefile +0 -1
- data/VERSION +2 -1
- data/lib/rack/session/mongo.rb +47 -8
- data/mongo-store.gemspec +33 -21
- data/spec/rack-mongo-store_spec.rb +17 -5
- data/spec/spec_helper.rb +0 -0
- metadata +73 -50
- data/.gitignore +0 -23
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
2
|
+
|
data/lib/rack/session/mongo.rb
CHANGED
@@ -11,10 +11,10 @@ module Rack
|
|
11
11
|
#
|
12
12
|
# == Usage Example
|
13
13
|
#
|
14
|
-
# use Rack::Session::Mongo, :connection => @existing_mongodb_connection
|
14
|
+
# use Rack::Session::Mongo, :connection => @existing_mongodb_connection;,
|
15
15
|
# :expire_after => 1800
|
16
16
|
class Mongo < Abstract::ID
|
17
|
-
attr_reader :mutex, :pool, :connection
|
17
|
+
attr_reader :mutex, :pool, :connection, :marshal_data
|
18
18
|
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :db => 'rack', :collection => 'sessions', :drop => false
|
19
19
|
|
20
20
|
# Creates a new Mongo session store pool. You probably won't initialize
|
@@ -35,10 +35,27 @@ module Rack
|
|
35
35
|
# instance global</i>
|
36
36
|
# @option options [String] :collection ('sessions') the Mongo collection
|
37
37
|
# to use. — <i>pool instance global</i>
|
38
|
+
# @option options [boolean] :marshal_data (true) Marshal data into string
|
39
|
+
# otherwise store as hash in db. — <i>pool instance global</i>
|
40
|
+
# Note: if you use this then the keys used to lookup values must be strings
|
41
|
+
# even if you put in symbols. *Example:*
|
42
|
+
# request1: session[:test] = true
|
43
|
+
# request2: session[:test]
|
44
|
+
# > nil
|
45
|
+
# session['test']
|
46
|
+
# > true
|
47
|
+
#
|
48
|
+
# The advantage is that you can query the contents of the sessions and
|
49
|
+
# potentially make changes on the fly
|
38
50
|
# @option options [Integer] :expire_after (nil) the time in seconds for
|
39
51
|
# the session to last for. *Example:* If this is set to +1800+, the
|
40
52
|
# session will be deleted if the client doesn't make a request within 30
|
41
53
|
# minutes of its last request.
|
54
|
+
# @option options [Integer] :clear_expired_after (1800) the time in seconds
|
55
|
+
# before we clear out old sessions. *Example:* If this is set to +1800+, the
|
56
|
+
# the session will be cleared from mongodb when a session is requested, if
|
57
|
+
# it has been 1800 seconds since it was last cleared. setting to -1 will
|
58
|
+
# disable this.
|
42
59
|
# @option options [true, false] :defer (false) don't set the session
|
43
60
|
# cookie for this request.
|
44
61
|
# @option options [true, false] :renew (false) causes the generation of
|
@@ -58,7 +75,11 @@ module Rack
|
|
58
75
|
@mutex = Mutex.new
|
59
76
|
@connection = @default_options[:connection] || ::Mongo::Connection.new
|
60
77
|
@pool = @connection.db(@default_options[:db]).collection(@default_options[:collection])
|
78
|
+
@pool.create_index([['expires', -1]])
|
61
79
|
@pool.create_index('sid', :unique => true)
|
80
|
+
@marshal_data = @default_options[:marshal_data].nil? ? true : @default_options[:marshal_data] == true
|
81
|
+
@next_expire_period = nil
|
82
|
+
@recheck_expire_period = @default_options[:clear_expired_after].nil? ? 1800 : @default_options[:clear_expired_after].to_i
|
62
83
|
end
|
63
84
|
|
64
85
|
def get_session(env, sid)
|
@@ -71,6 +92,7 @@ module Rack
|
|
71
92
|
save_session(sid)
|
72
93
|
end
|
73
94
|
session.instance_variable_set('@old', {}.merge(session))
|
95
|
+
session.instance_variable_set('@sid', sid)
|
74
96
|
return [sid, session]
|
75
97
|
ensure
|
76
98
|
@mutex.unlock if env['rack.multithread']
|
@@ -95,16 +117,25 @@ module Rack
|
|
95
117
|
end
|
96
118
|
|
97
119
|
private
|
120
|
+
|
98
121
|
def generate_sid
|
99
122
|
loop do
|
100
123
|
sid = super
|
101
124
|
break sid unless find_session(sid)
|
102
125
|
end
|
103
126
|
end
|
104
|
-
|
127
|
+
|
105
128
|
def find_session(sid)
|
106
|
-
|
129
|
+
time = Time.now
|
130
|
+
if @recheck_expire_period != -1 && (@next_expire_period.nil? || @next_expire_period < time)
|
131
|
+
@next_expire_period = time + @recheck_expire_period
|
132
|
+
@pool.remove :expires => {'$lte' => time} # clean out expired sessions
|
133
|
+
end
|
107
134
|
session = @pool.find_one :sid => sid
|
135
|
+
#if session is expired but hasn't been cleared yet. don't return it.
|
136
|
+
if session && session['expires'] != nil && session['expires'] < time
|
137
|
+
session = nil
|
138
|
+
end
|
108
139
|
session ? unpack(session['data']) : false
|
109
140
|
end
|
110
141
|
|
@@ -113,7 +144,7 @@ module Rack
|
|
113
144
|
end
|
114
145
|
|
115
146
|
def save_session(sid, session={}, expires=nil)
|
116
|
-
@pool.update({:sid => sid}, {
|
147
|
+
@pool.update({:sid => sid}, {"$set" => {:data => pack(session), :expires => expires}}, :upsert => true)
|
117
148
|
end
|
118
149
|
|
119
150
|
def merge_sessions(sid, old, new, current=nil)
|
@@ -127,7 +158,7 @@ module Rack
|
|
127
158
|
warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
|
128
159
|
delete.each{|k| current.delete k }
|
129
160
|
|
130
|
-
update = new.keys.select{|k| new[k] != old[k] }
|
161
|
+
update = new.keys.select{|k| new[k] != old[k] || new[k].kind_of?(Hash) || new[k].kind_of?(Array) }
|
131
162
|
warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
|
132
163
|
update.each{|k| current[k] = new[k] }
|
133
164
|
|
@@ -135,12 +166,20 @@ module Rack
|
|
135
166
|
end
|
136
167
|
|
137
168
|
def pack(data)
|
138
|
-
|
169
|
+
if(@marshal_data)
|
170
|
+
[Marshal.dump(data)].pack("m*")
|
171
|
+
else
|
172
|
+
data
|
173
|
+
end
|
139
174
|
end
|
140
175
|
|
141
176
|
def unpack(packed)
|
142
177
|
return nil unless packed
|
143
|
-
|
178
|
+
if(@marshal_data)
|
179
|
+
Marshal.load(packed.unpack("m*").first)
|
180
|
+
else
|
181
|
+
packed
|
182
|
+
end
|
144
183
|
end
|
145
184
|
end
|
146
185
|
end
|
data/mongo-store.gemspec
CHANGED
@@ -1,62 +1,74 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongo-store}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jonathan Rudenberg"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-04-26}
|
13
13
|
s.email = %q{jonathan@titanous.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
16
|
-
|
16
|
+
"README.rdoc"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
".document",
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
"spec/spec_helper.rb"
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/mongo-store.rb",
|
27
|
+
"lib/rack/session/mongo.rb",
|
28
|
+
"mongo-store.gemspec",
|
29
|
+
"spec/rack-mongo-store_spec.rb",
|
30
|
+
"spec/spec.opts",
|
31
|
+
"spec/spec_helper.rb"
|
33
32
|
]
|
34
33
|
s.homepage = %q{http://github.com/titanous/mongo-store}
|
35
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
36
34
|
s.require_paths = ["lib"]
|
37
|
-
s.rubygems_version = %q{1.
|
35
|
+
s.rubygems_version = %q{1.7.2}
|
38
36
|
s.summary = %q{Rack session store for MongoDB}
|
39
37
|
s.test_files = [
|
40
38
|
"spec/rack-mongo-store_spec.rb",
|
41
|
-
|
39
|
+
"spec/spec_helper.rb"
|
42
40
|
]
|
43
41
|
|
44
42
|
if s.respond_to? :specification_version then
|
45
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
43
|
s.specification_version = 3
|
47
44
|
|
48
45
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_runtime_dependency(%q<mongo-store>, [">= 0"])
|
47
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
48
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
50
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
49
51
|
s.add_runtime_dependency(%q<mongo>, [">= 1.0.1"])
|
50
52
|
s.add_runtime_dependency(%q<rack>, [">= 1.1.0"])
|
51
53
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
52
54
|
s.add_development_dependency(%q<yard>, [">= 0"])
|
53
55
|
else
|
56
|
+
s.add_dependency(%q<mongo-store>, [">= 0"])
|
57
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
58
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
59
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
60
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
54
61
|
s.add_dependency(%q<mongo>, [">= 1.0.1"])
|
55
62
|
s.add_dependency(%q<rack>, [">= 1.1.0"])
|
56
63
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
57
64
|
s.add_dependency(%q<yard>, [">= 0"])
|
58
65
|
end
|
59
66
|
else
|
67
|
+
s.add_dependency(%q<mongo-store>, [">= 0"])
|
68
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
69
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
70
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
71
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
60
72
|
s.add_dependency(%q<mongo>, [">= 1.0.1"])
|
61
73
|
s.add_dependency(%q<rack>, [">= 1.1.0"])
|
62
74
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
@@ -27,15 +27,14 @@ describe 'Rack::Session::Mongo' do
|
|
27
27
|
it 'should specify connection params' do
|
28
28
|
mongo = Rack::Session::Mongo.new(@incrementor,
|
29
29
|
:connection => Mongo::Connection.new('localhost'), :db => 'rack-test',
|
30
|
-
:collection => '
|
30
|
+
:collection => 'mongo_test')
|
31
31
|
pool = mongo.pool
|
32
32
|
connection = mongo.connection
|
33
|
-
|
34
|
-
connection.host.should == 'localhost'
|
33
|
+
connection.primary[0].should == 'localhost'
|
35
34
|
|
36
35
|
pool.should be_kind_of(Mongo::Collection)
|
37
36
|
pool.db.name.should == 'rack-test'
|
38
|
-
pool.name.should == '
|
37
|
+
pool.name.should == 'mongo_test'
|
39
38
|
end
|
40
39
|
|
41
40
|
it 'creates a new cookie' do
|
@@ -128,7 +127,20 @@ describe 'Rack::Session::Mongo' do
|
|
128
127
|
res3['Set-Cookie'][@session_match].should == new_session
|
129
128
|
res3.body.should == '{"counter"=>4}'
|
130
129
|
end
|
131
|
-
|
130
|
+
it 'should default marshal_data to true' do
|
131
|
+
pool = Rack::Session::Mongo.new(@incrementor)
|
132
|
+
pool.marshal_data.should == true
|
133
|
+
data = {'test' => true}
|
134
|
+
pool.send(:pack, data).should == [Marshal.dump(data)].pack("m*")
|
135
|
+
pool.send(:unpack, [Marshal.dump(data)].pack("m*"))['test'] == true
|
136
|
+
end
|
137
|
+
it 'should be able to set marshal_data to false' do
|
138
|
+
pool = Rack::Session::Mongo.new(@incrementor, :marshal_data => false)
|
139
|
+
pool.marshal_data.should == false
|
140
|
+
data = {'test' => true}
|
141
|
+
pool.send(:pack, data).should === data
|
142
|
+
pool.send(:unpack, data).should === data
|
143
|
+
end
|
132
144
|
specify 'omits cookie with :defer option' do
|
133
145
|
pool = Rack::Session::Mongo.new(@incrementor)
|
134
146
|
req = Rack::MockRequest.new(pool)
|
data/spec/spec_helper.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo-store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 2
|
10
|
-
version: 0.1.2
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Jonathan Rudenberg
|
@@ -15,71 +10,107 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
13
|
+
date: 2011-04-26 00:00:00 Z
|
20
14
|
dependencies:
|
21
15
|
- !ruby/object:Gem::Dependency
|
22
|
-
name: mongo
|
23
|
-
prerelease: false
|
16
|
+
name: mongo-store
|
24
17
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
19
|
requirements:
|
27
20
|
- - ">="
|
28
21
|
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 0
|
33
|
-
- 1
|
34
|
-
version: 1.0.1
|
22
|
+
version: "0"
|
35
23
|
type: :runtime
|
24
|
+
prerelease: false
|
36
25
|
version_requirements: *id001
|
37
26
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
39
|
-
prerelease: false
|
27
|
+
name: rspec
|
40
28
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
29
|
none: false
|
42
30
|
requirements:
|
43
31
|
- - ">="
|
44
32
|
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
- 1
|
49
|
-
- 0
|
50
|
-
version: 1.1.0
|
51
|
-
type: :runtime
|
33
|
+
version: 1.2.9
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
52
36
|
version_requirements: *id002
|
53
37
|
- !ruby/object:Gem::Dependency
|
54
|
-
name:
|
55
|
-
prerelease: false
|
38
|
+
name: yard
|
56
39
|
requirement: &id003 !ruby/object:Gem::Requirement
|
57
40
|
none: false
|
58
41
|
requirements:
|
59
42
|
- - ">="
|
60
43
|
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
segments:
|
63
|
-
- 1
|
64
|
-
- 2
|
65
|
-
- 9
|
66
|
-
version: 1.2.9
|
44
|
+
version: "0"
|
67
45
|
type: :development
|
46
|
+
prerelease: false
|
68
47
|
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.2.9
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *id004
|
69
59
|
- !ruby/object:Gem::Dependency
|
70
60
|
name: yard
|
61
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
type: :development
|
71
68
|
prerelease: false
|
72
|
-
|
69
|
+
version_requirements: *id005
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: mongo
|
72
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.0.1
|
78
|
+
type: :runtime
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *id006
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rack
|
83
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.1.0
|
89
|
+
type: :runtime
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: *id007
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: rspec
|
94
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.2.9
|
100
|
+
type: :development
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: *id008
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: yard
|
105
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
73
106
|
none: false
|
74
107
|
requirements:
|
75
108
|
- - ">="
|
76
109
|
- !ruby/object:Gem::Version
|
77
|
-
hash: 3
|
78
|
-
segments:
|
79
|
-
- 0
|
80
110
|
version: "0"
|
81
111
|
type: :development
|
82
|
-
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: *id009
|
83
114
|
description:
|
84
115
|
email: jonathan@titanous.com
|
85
116
|
executables: []
|
@@ -91,7 +122,6 @@ extra_rdoc_files:
|
|
91
122
|
- README.rdoc
|
92
123
|
files:
|
93
124
|
- .document
|
94
|
-
- .gitignore
|
95
125
|
- Gemfile
|
96
126
|
- Gemfile.lock
|
97
127
|
- LICENSE
|
@@ -104,13 +134,12 @@ files:
|
|
104
134
|
- spec/rack-mongo-store_spec.rb
|
105
135
|
- spec/spec.opts
|
106
136
|
- spec/spec_helper.rb
|
107
|
-
has_rdoc: true
|
108
137
|
homepage: http://github.com/titanous/mongo-store
|
109
138
|
licenses: []
|
110
139
|
|
111
140
|
post_install_message:
|
112
|
-
rdoc_options:
|
113
|
-
|
141
|
+
rdoc_options: []
|
142
|
+
|
114
143
|
require_paths:
|
115
144
|
- lib
|
116
145
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -118,23 +147,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
147
|
requirements:
|
119
148
|
- - ">="
|
120
149
|
- !ruby/object:Gem::Version
|
121
|
-
hash: 3
|
122
|
-
segments:
|
123
|
-
- 0
|
124
150
|
version: "0"
|
125
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
152
|
none: false
|
127
153
|
requirements:
|
128
154
|
- - ">="
|
129
155
|
- !ruby/object:Gem::Version
|
130
|
-
hash: 3
|
131
|
-
segments:
|
132
|
-
- 0
|
133
156
|
version: "0"
|
134
157
|
requirements: []
|
135
158
|
|
136
159
|
rubyforge_project:
|
137
|
-
rubygems_version: 1.
|
160
|
+
rubygems_version: 1.7.2
|
138
161
|
signing_key:
|
139
162
|
specification_version: 3
|
140
163
|
summary: Rack session store for MongoDB
|
data/.gitignore
DELETED