rack-session-file 0.4.0 → 0.5.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/README.md +6 -0
- data/Rakefile +5 -0
- data/lib/rack/session/file.rb +1 -1
- data/lib/rack/session/file/abstract.rb +10 -0
- data/lib/rack/session/file/marshal.rb +9 -3
- data/lib/rack/session/file/pstore.rb +9 -3
- data/lib/rack/session/file/yaml.rb +11 -4
- data/rack-session-file.gemspec +1 -1
- data/spec/common.rb +17 -7
- metadata +4 -4
data/README.md
CHANGED
@@ -17,6 +17,12 @@ use Rack::Session::File, :storage => ENV['TEMP'],
|
|
17
17
|
:expire_after => 1800
|
18
18
|
```
|
19
19
|
|
20
|
+
**NOTICE**: Never use this module in conjunction with other session middlewares (especially `Rack::Session::Cookie`). That would brake session handling.
|
21
|
+
|
22
|
+
### For Sinatra and Padrino
|
23
|
+
|
24
|
+
Do not enable session mechanism by `enable :session`. Built-in session of Sinatra (and Padrino) utilizes `Rack::Session::Cookie`, so it will interfere this module's behavior. Using this middleware makes `session[]` available in your application without `enable :session`.
|
25
|
+
|
20
26
|
## Usage in Rails 3 Applications
|
21
27
|
|
22
28
|
On Gemfile:
|
data/Rakefile
CHANGED
data/lib/rack/session/file.rb
CHANGED
@@ -5,6 +5,8 @@ require 'rack/session/abstract/id'
|
|
5
5
|
module Rack
|
6
6
|
module Session
|
7
7
|
module File
|
8
|
+
class InvalidSessionIDError < SecurityError; end
|
9
|
+
|
8
10
|
class Abstract < Rack::Session::Abstract::ID
|
9
11
|
DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS.merge({
|
10
12
|
:storage => Dir.tmpdir,
|
@@ -161,6 +163,14 @@ module Rack
|
|
161
163
|
def want_thread_safe?
|
162
164
|
@env['rack.multithread']
|
163
165
|
end
|
166
|
+
|
167
|
+
def ensure_sid_is_valid(sid)
|
168
|
+
unless /^[0-9A-Fa-f]+$/ =~ sid
|
169
|
+
raise InvalidSessionIDError.new("'#{sid}' is not suitable for session ID")
|
170
|
+
end
|
171
|
+
|
172
|
+
true
|
173
|
+
end
|
164
174
|
end
|
165
175
|
end
|
166
176
|
end
|
@@ -23,6 +23,8 @@ module Rack
|
|
23
23
|
open_session_file(sid, 'r') do |file|
|
24
24
|
return ::Marshal.load(file)
|
25
25
|
end
|
26
|
+
rescue InvalidSessionIDError
|
27
|
+
return nil
|
26
28
|
rescue Errno::ENOENT
|
27
29
|
return nil
|
28
30
|
rescue TypeError
|
@@ -31,9 +33,12 @@ module Rack
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def delete_session(sid)
|
34
|
-
|
35
|
-
|
36
|
-
::File.
|
36
|
+
begin
|
37
|
+
filename = session_file_name(sid)
|
38
|
+
if ::File.exists?(filename)
|
39
|
+
::File.unlink(filename)
|
40
|
+
end
|
41
|
+
rescue InvalidSessionIDError
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
@@ -55,6 +60,7 @@ module Rack
|
|
55
60
|
end
|
56
61
|
|
57
62
|
def session_file_name(sid)
|
63
|
+
ensure_sid_is_valid(sid)
|
58
64
|
return ::File.join(@storage, sid)
|
59
65
|
end
|
60
66
|
|
@@ -33,6 +33,8 @@ module Rack
|
|
33
33
|
data[key] = db[key]
|
34
34
|
end
|
35
35
|
end
|
36
|
+
rescue InvalidSessionIDError
|
37
|
+
return nil
|
36
38
|
rescue TypeError
|
37
39
|
return nil
|
38
40
|
end
|
@@ -40,9 +42,12 @@ module Rack
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def delete_session(sid)
|
43
|
-
|
44
|
-
|
45
|
-
::File.
|
45
|
+
begin
|
46
|
+
filename = store_for_sid(sid).path
|
47
|
+
if ::File.exists?(filename)
|
48
|
+
::File.unlink(filename)
|
49
|
+
end
|
50
|
+
rescue InvalidSessionIDError
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
@@ -61,6 +66,7 @@ module Rack
|
|
61
66
|
end
|
62
67
|
|
63
68
|
def session_file_name(sid)
|
69
|
+
ensure_sid_is_valid(sid)
|
64
70
|
return ::File.join(@storage, sid)
|
65
71
|
end
|
66
72
|
|
@@ -8,6 +8,7 @@ module Rack
|
|
8
8
|
module Session
|
9
9
|
module File
|
10
10
|
class YAML < Abstract
|
11
|
+
|
11
12
|
def initialize(app, options = {})
|
12
13
|
super
|
13
14
|
@transaction_options['yaml'] = @default_options.delete(:yaml) || {}
|
@@ -43,16 +44,21 @@ module Rack
|
|
43
44
|
data[key] = db[key]
|
44
45
|
end
|
45
46
|
end
|
46
|
-
rescue
|
47
|
+
rescue InvalidSessionIDError
|
48
|
+
return nil
|
49
|
+
rescue (::Psych::SyntaxError rescue nil), (::Syck::Error rescue nil), (::Syck::TypeError rescue nil)
|
47
50
|
return nil
|
48
51
|
end
|
49
52
|
return data
|
50
53
|
end
|
51
54
|
|
52
55
|
def delete_session(sid)
|
53
|
-
|
54
|
-
|
55
|
-
::File.
|
56
|
+
begin
|
57
|
+
filename = store_for_sid(sid).path
|
58
|
+
if ::File.exists?(filename)
|
59
|
+
::File.unlink(filename)
|
60
|
+
end
|
61
|
+
rescue InvalidSessionIDError
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
@@ -67,6 +73,7 @@ module Rack
|
|
67
73
|
end
|
68
74
|
|
69
75
|
def session_file_name(sid)
|
76
|
+
ensure_sid_is_valid(sid)
|
70
77
|
return ::File.join(@storage, sid)
|
71
78
|
end
|
72
79
|
|
data/rack-session-file.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |gem|
|
|
32
32
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
33
33
|
gem.name = "rack-session-file"
|
34
34
|
gem.require_paths = ["lib"]
|
35
|
-
gem.version = '0.
|
35
|
+
gem.version = '0.5.0'
|
36
36
|
|
37
37
|
if gem.respond_to? :specification_version then
|
38
38
|
gem.specification_version = 3
|
data/spec/common.rb
CHANGED
@@ -65,26 +65,26 @@ shared_examples_for Rack::Session::File do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'survives nonexistent cookies' do
|
68
|
-
bad_cookie = 'rack.session=
|
68
|
+
bad_cookie = 'rack.session=00000001'
|
69
69
|
res = Rack::MockRequest.new(pool) \
|
70
70
|
.get('/', 'HTTP_COOKIE' => bad_cookie)
|
71
71
|
|
72
72
|
res.body.should == '{"counter"=>1}'
|
73
73
|
cookie = res['Set-Cookie'][@session_match]
|
74
|
-
cookie.should_not match(/#{bad_cookie}/)
|
74
|
+
cookie.should_not match(/#{bad_cookie}(?:;|$)/)
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'survives broken session data' do
|
78
|
-
open(::File.join(@storage, '
|
79
|
-
f.write "\x1\x1o" # broken data for Marshal
|
78
|
+
open(::File.join(@storage, '00000002'), 'w') do |f|
|
79
|
+
f.write "\x1\x1o" # broken data for Marshal and YAML
|
80
80
|
end
|
81
|
-
|
81
|
+
bad_cookie = 'rack.session=00000002'
|
82
82
|
res = Rack::MockRequest.new(pool) \
|
83
|
-
.get('/', 'HTTP_COOKIE' =>
|
83
|
+
.get('/', 'HTTP_COOKIE' => bad_cookie)
|
84
84
|
|
85
85
|
res.body.should == '{"counter"=>1}'
|
86
86
|
cookie = res['Set-Cookie'][@session_match]
|
87
|
-
cookie.should_not match(/
|
87
|
+
cookie.should_not match(/#{bad_cookie}(?:;|$)/)
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'should maintain freshness' do
|
@@ -173,5 +173,15 @@ shared_examples_for Rack::Session::File do
|
|
173
173
|
# res3['Set-Cookie'][@session_match].should == session
|
174
174
|
res3.body.should == '{"counter"=>4}'
|
175
175
|
end
|
176
|
+
|
177
|
+
it 'omit cookie with bad session id' do
|
178
|
+
bad_cookie = 'rack.session=/etc/passwd'
|
179
|
+
res = Rack::MockRequest.new(pool) \
|
180
|
+
.get('/', 'HTTP_COOKIE' => bad_cookie)
|
181
|
+
|
182
|
+
res.body.should == '{"counter"=>1}'
|
183
|
+
cookie = res['Set-Cookie'][@session_match]
|
184
|
+
cookie.should_not match(/#{bad_cookie}(?:;|$)/)
|
185
|
+
end
|
176
186
|
end
|
177
187
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-session-file
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -82,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
82
|
version: '0'
|
83
83
|
segments:
|
84
84
|
- 0
|
85
|
-
hash:
|
85
|
+
hash: 3379845102946176394
|
86
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
87
|
none: false
|
88
88
|
requirements:
|
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
91
|
version: '0'
|
92
92
|
segments:
|
93
93
|
- 0
|
94
|
-
hash:
|
94
|
+
hash: 3379845102946176394
|
95
95
|
requirements: []
|
96
96
|
rubyforge_project:
|
97
97
|
rubygems_version: 1.8.23
|