mongo-store 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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