riak-sessions 0.8.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ version = File.read('../VERSION').strip
5
+
6
+ gemspec = Gem::Specification.new do |gem|
7
+ gem.name = "riak-sessions"
8
+ gem.summary = %Q{riak-sessions is a session store backed by Riak, the distributed database by Basho.}
9
+ gem.description = %Q{riak-sessions is a session store backed by Riak, the distributed database by Basho. It includes session implementations for both Rack and Rails 3.}
10
+ gem.version = version
11
+ gem.email = "seancribbs@gmail.com"
12
+ gem.homepage = "http://seancribbs.github.com/ripple"
13
+ gem.authors = ["Sean Cribbs"]
14
+ gem.add_development_dependency "rspec", "~>2.0.0.beta.18"
15
+ gem.add_development_dependency "rspec-rails", "~>2.0.0.beta.18"
16
+ gem.add_development_dependency "yajl-ruby"
17
+ gem.add_development_dependency "rails", "~>3.0.0"
18
+ gem.add_development_dependency "curb", ">0.6"
19
+ gem.add_development_dependency "rake"
20
+ gem.add_dependency "riak-client", "~>#{version}"
21
+ gem.add_dependency "rack", ">=1.0"
22
+
23
+ files = FileList["**/*"]
24
+ files.exclude /\.DS_Store/
25
+ files.exclude /\#/
26
+ files.exclude /~/
27
+ files.exclude /\.swp/
28
+ files.exclude '**/._*'
29
+ files.exclude '**/*.orig'
30
+ files.exclude '**/*.rej'
31
+ files.exclude /^pkg/
32
+ files.exclude 'riak-sessions.gemspec'
33
+ files.exclude 'Gemfile'
34
+ files.exclude 'Gemfile.lock'
35
+
36
+ gem.files = files.to_a
37
+
38
+ gem.test_files = FileList["spec/**/*.rb"].to_a
39
+ end
40
+
41
+ # Gem packaging tasks
42
+ Rake::GemPackageTask.new(gemspec) do |pkg|
43
+ pkg.need_zip = false
44
+ pkg.need_tar = false
45
+ end
46
+
47
+ task :gem => :gemspec
48
+
49
+ desc %{Build the gemspec file.}
50
+ task :gemspec do
51
+ gemspec.validate
52
+ File.open("#{gemspec.name}.gemspec", 'w'){|f| f.write gemspec.to_ruby }
53
+ end
54
+
55
+ desc %{Release the gem to RubyGems.org}
56
+ task :release => :gem do
57
+ system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
58
+ end
59
+
60
+ require 'rspec/core'
61
+ require 'rspec/core/rake_task'
62
+
63
+ desc "Run Specs"
64
+ Rspec::Core::RakeTask.new(:spec) do |spec|
65
+ spec.pattern = "spec/**/*_spec.rb"
66
+ end
67
+
68
+ task :default => :spec
@@ -0,0 +1,96 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'riak'
15
+ require 'rack/session/abstract/id'
16
+
17
+ module Riak
18
+ # Lets you store web application session data in Riak.
19
+ # Useful for those cases where you need more than the 4K that
20
+ # cookies provide.
21
+ #
22
+ # Usage (Rack builder):
23
+ # use Riak::SessionStore
24
+ #
25
+ # Usage (Rails):
26
+ # config.middleware.use Riak::SessionStore
27
+ #
28
+ # For configuration options, see #initialize.
29
+ class SessionStore < Rack::Session::Abstract::ID
30
+ DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS.merge \
31
+ :host => "127.0.0.1",
32
+ :port => 8098,
33
+ :bucket => "_sessions",
34
+ :r => 1,
35
+ :w => 1,
36
+ :dw => 0,
37
+ :rw => 1,
38
+ :n_val => 2,
39
+ :last_write_wins => false
40
+
41
+
42
+ attr_reader :bucket
43
+
44
+ # Creates a new Riak::SessionStore middleware
45
+ # @param app the Rack application
46
+ # @param [Hash] options configuration options
47
+ # @option
48
+ # @see Rack::Session::Abstract::ID#initialize
49
+ def initialize(app, options={})
50
+ super
51
+ @client = Riak::Client.new(default_options.slice(:host,:port))
52
+ # @client.http.send(:curl).verbose = true
53
+ @bucket = @client.bucket(default_options[:bucket]).tap do |b|
54
+ new_props = {}
55
+ [:r,:w,:dw,:rw,:n_val].each do |q|
56
+ new_props[q.to_s] = default_options[q] unless b.send(q) == default_options[q]
57
+ end
58
+ b.props = new_props unless new_props.blank?
59
+ end
60
+ self
61
+ end
62
+
63
+ def generate_sid
64
+ loop do
65
+ sid = super
66
+ break sid unless @bucket.exists?(sid)
67
+ end
68
+ end
69
+
70
+ private
71
+ def get_session(env, session_id)
72
+ unless session_id && robject = (bucket.get(session_id) rescue nil)
73
+ session_id, robject = generate_sid, bucket.new
74
+ robject.key = session_id
75
+ robject.data = {}
76
+ robject.store
77
+ end
78
+ [session_id, robject.data]
79
+ end
80
+
81
+ def set_session(env, session_id, session, options)
82
+ if options[:renew] or options[:drop]
83
+ bucket.delete(session_id)
84
+ return false if options[:drop]
85
+ session_id = generate_sid
86
+ end
87
+ robject = bucket.get_or_new(session_id)
88
+ robject.data = session
89
+ robject.store
90
+ session_id
91
+ rescue Riak::FailedRequest
92
+ env['rack.errors'].puts $!.inspect
93
+ false
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'riak'
15
+ require 'rack'
16
+
17
+ module Riak
18
+ autoload :SessionStore, "riak/session_store"
19
+ end
20
+
21
+ if defined?(ActionDispatch)
22
+ module Ripple
23
+ autoload :SessionStore, "ripple/session_store"
24
+ end
25
+
26
+ module ActionDispatch
27
+ module Session
28
+ autoload :RiakStore, "ripple/session_store"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,81 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ begin
15
+ require 'action_dispatch/middleware/session/abstract_store'
16
+ rescue LoadError, NameError
17
+ # TODO i18n this message
18
+ $stderr.puts "Ripple::SessionStore requires ActionPack >= 3.0.0"
19
+ exit 1
20
+ end
21
+
22
+ module Ripple
23
+ class SessionStore < ActionDispatch::Session::AbstractStore
24
+ def initialize(app, options={})
25
+ super
26
+ @default_options = {
27
+ :bucket => "_sessions",
28
+ :r => 1,
29
+ :w => 1,
30
+ :dw => 0,
31
+ :rw => 1,
32
+ :n_val => 2,
33
+ :last_write_wins => false,
34
+ :host => "127.0.0.1",
35
+ :port => 8098
36
+ }.merge(@default_options)
37
+ @client = Riak::Client.new(@default_options.slice(:host,:port,:client_id))
38
+ @bucket = @client.bucket(@default_options[:bucket])
39
+ set_bucket_defaults
40
+ end
41
+
42
+ private
43
+ def get_session(env, sid)
44
+ sid ||= generate_sid
45
+ session = {}
46
+ begin
47
+ session = @bucket.get(sid).data
48
+ rescue Riak::FailedRequest => fr
49
+ raise fr unless fr.code.to_i == 404
50
+ end
51
+ [sid, session]
52
+ end
53
+
54
+ def set_session(env, sid, session_data)
55
+ robject = @bucket.get_or_new(sid)
56
+ robject.content_type = "application/x-ruby-marshal"
57
+ robject.data = session_data
58
+ robject.store
59
+ sid
60
+ rescue Riak::FailedRequest
61
+ false
62
+ end
63
+
64
+ def destroy(env)
65
+ if sid = current_session_id(env)
66
+ @bucket.delete(sid)
67
+ end
68
+ rescue Riak::FailedRequest
69
+ false
70
+ end
71
+
72
+ def set_bucket_defaults
73
+ bucket_opts = @default_options.slice(:r,:w,:dw,:rw,:n_val,:last_write_wins).stringify_keys
74
+ new_props = bucket_opts.inject({}) do |hash,(k,v)|
75
+ hash[k] = v unless @bucket.props[k] == v
76
+ hash
77
+ end
78
+ @bucket.props = new_props unless new_props.empty?
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,10 @@
1
+ module SessionAutoloadTest
2
+ class Foo
3
+ def initialize(bar='baz')
4
+ @bar = bar
5
+ end
6
+ def inspect
7
+ "#<#{self.class} bar:#{@bar.inspect}>"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,150 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require File.expand_path("../spec_helper", __FILE__)
15
+ require 'rack/mock'
16
+
17
+ describe Riak::SessionStore do
18
+ session_key = Riak::SessionStore::DEFAULT_OPTIONS[:key]
19
+ session_match = /#{session_key}=([0-9a-fA-F]+);/
20
+ incrementor = lambda do |env|
21
+ env["rack.session"]["counter"] ||= 0
22
+ env["rack.session"]["counter"] += 1
23
+ Rack::Response.new(env["rack.session"].inspect).to_a
24
+ end
25
+ drop_session = proc do |env|
26
+ env['rack.session.options'][:drop] = true
27
+ incrementor.call(env)
28
+ end
29
+ renew_session = proc do |env|
30
+ env['rack.session.options'][:renew] = true
31
+ incrementor.call(env)
32
+ end
33
+ defer_session = proc do |env|
34
+ env['rack.session.options'][:defer] = true
35
+ incrementor.call(env)
36
+ end
37
+
38
+ it "creates a new cookie" do
39
+ pool = Riak::SessionStore.new(incrementor)
40
+ res = Rack::MockRequest.new(pool).get("/")
41
+ res["Set-Cookie"].should include("#{session_key}=")
42
+ res.body.should == '{"counter"=>1}'
43
+ end
44
+
45
+ it "determines session from a cookie" do
46
+ pool = Riak::SessionStore.new(incrementor)
47
+ req = Rack::MockRequest.new(pool)
48
+ res = req.get("/")
49
+ cookie = res["Set-Cookie"]
50
+ req.get("/", "HTTP_COOKIE" => cookie).
51
+ body.should == '{"counter"=>2}'
52
+ req.get("/", "HTTP_COOKIE" => cookie).
53
+ body.should == '{"counter"=>3}'
54
+ end
55
+
56
+ it "survives nonexistant cookies" do
57
+ bad_cookie = "rack.session=blarghfasel"
58
+ pool = Riak::SessionStore.new(incrementor)
59
+ res = Rack::MockRequest.new(pool).
60
+ get("/", "HTTP_COOKIE" => bad_cookie)
61
+ res.body.should == '{"counter"=>1}'
62
+ cookie = res["Set-Cookie"][session_match]
63
+ cookie.should_not match(/#{bad_cookie}/)
64
+ end
65
+
66
+ # it "maintains freshness" do
67
+ # pool = Riak::SessionStore.new(incrementor, :expire_after => 3)
68
+ # res = Rack::MockRequest.new(pool).get('/')
69
+ # res.body.should include '"counter"=>1'
70
+ # cookie = res["Set-Cookie"]
71
+ # res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
72
+ # res["Set-Cookie"].should == cookie
73
+ # res.body.should include '"counter"=>2'
74
+ # puts 'Sleeping to expire session' if $DEBUG
75
+ # sleep 4
76
+ # res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
77
+ # res["Set-Cookie"].should_not == cookie
78
+ # res.body.should include '"counter"=>1'
79
+ # end
80
+
81
+ it "deletes cookies with :drop option" do
82
+ pool = Riak::SessionStore.new(incrementor)
83
+ req = Rack::MockRequest.new(pool)
84
+ drop = Rack::Utils::Context.new(pool, drop_session)
85
+ dreq = Rack::MockRequest.new(drop)
86
+
87
+ res0 = req.get("/")
88
+ session = (cookie = res0["Set-Cookie"])[session_match]
89
+ res0.body.should == '{"counter"=>1}'
90
+
91
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
92
+ res1["Set-Cookie"][session_match].should == session
93
+ res1.body.should == '{"counter"=>2}'
94
+
95
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
96
+ res2["Set-Cookie"].should == nil
97
+ res2.body.should == '{"counter"=>3}'
98
+
99
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
100
+ res3["Set-Cookie"][session_match].should_not == session
101
+ res3.body.should == '{"counter"=>1}'
102
+ end
103
+ it "provides new session id with :renew option" do
104
+ pool = Riak::SessionStore.new(incrementor)
105
+ req = Rack::MockRequest.new(pool)
106
+ renew = Rack::Utils::Context.new(pool, renew_session)
107
+ rreq = Rack::MockRequest.new(renew)
108
+
109
+ res0 = req.get("/")
110
+ session = (cookie = res0["Set-Cookie"])[session_match]
111
+ res0.body.should == '{"counter"=>1}'
112
+
113
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
114
+ res1["Set-Cookie"][session_match].should == session
115
+ res1.body.should == '{"counter"=>2}'
116
+
117
+ res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
118
+ new_cookie = res2["Set-Cookie"]
119
+ new_session = new_cookie[session_match]
120
+ new_session.should_not == session
121
+ res2.body.should == '{"counter"=>3}'
122
+
123
+ res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
124
+ res3["Set-Cookie"][session_match].should == new_session
125
+ res3.body.should == '{"counter"=>4}'
126
+ end
127
+
128
+ it "omits cookie with :defer option" do
129
+ pool = Riak::SessionStore.new(incrementor)
130
+ req = Rack::MockRequest.new(pool)
131
+ defer = Rack::Utils::Context.new(pool, defer_session)
132
+ dreq = Rack::MockRequest.new(defer)
133
+
134
+ res0 = req.get("/")
135
+ session = (cookie = res0["Set-Cookie"])[session_match]
136
+ res0.body.should == '{"counter"=>1}'
137
+
138
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
139
+ res1["Set-Cookie"][session_match].should == session
140
+ res1.body.should == '{"counter"=>2}'
141
+
142
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
143
+ res2["Set-Cookie"].should == nil
144
+ res2.body.should == '{"counter"=>3}'
145
+
146
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
147
+ res3["Set-Cookie"][session_match].should == session
148
+ res3.body.should == '{"counter"=>4}'
149
+ end
150
+ end
@@ -0,0 +1,140 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require File.expand_path("../spec_helper", __FILE__)
15
+ require 'ripple/session_store'
16
+
17
+ describe "Ripple::SessionStore" do
18
+ include RSpec::Rails::RequestExampleGroup
19
+ include Ripple::SessionStoreTest
20
+ hooks[:before][:each].pop # Remove the router junk
21
+
22
+ before :each do
23
+ @app = build_app do |middleware|
24
+ middleware.use Ripple::SessionStore, :key => '_session_id'
25
+ middleware.delete "ActionDispatch::ShowExceptions"
26
+ end
27
+ @app.routes.draw do
28
+ match ':action', :to => ::Ripple::SessionStoreTest::TestController
29
+ end
30
+ ::Ripple::SessionStoreTest::TestController.send(:include, @app.routes.url_helpers)
31
+ end
32
+
33
+ it "should set and get a session value" do
34
+ get '/set_session_value'
35
+ response.should be_success
36
+ cookies['_session_id'].should be
37
+
38
+ get '/get_session_value'
39
+ response.should be_success
40
+ 'foo: "bar"'.should == response.body
41
+ end
42
+
43
+ it "should get nothing from a new session" do
44
+ get '/get_session_value'
45
+ response.should be_success
46
+ 'foo: nil'.should == response.body
47
+ end
48
+
49
+ it "should get an empty session after reset" do
50
+ get '/set_session_value'
51
+ response.should be_success
52
+ cookies['_session_id'].should be
53
+ session_cookie = cookies.send(:hash_for)['_session_id']
54
+
55
+ get '/call_reset_session'
56
+ response.should be_success
57
+ [].should_not == headers['Set-Cookie']
58
+
59
+ cookies << session_cookie # replace our new session_id with our old, pre-reset session_id
60
+
61
+ get '/get_session_value'
62
+ response.should be_success
63
+ 'foo: nil'.should == response.body
64
+ end
65
+
66
+ it "should not create a session unless writing to it" do
67
+ get '/get_session_value'
68
+ response.should be_success
69
+ 'foo: nil'.should == response.body
70
+ cookies['_session_id'].should be_nil
71
+ end
72
+
73
+ it "should set a value in the new session after reset" do
74
+ get '/set_session_value'
75
+ response.should be_success
76
+ cookies['_session_id'].should be
77
+ session_id = cookies['_session_id']
78
+
79
+ get '/call_reset_session'
80
+ response.should be_success
81
+ [].should_not == headers['Set-Cookie']
82
+
83
+ get '/get_session_value'
84
+ response.should be_success
85
+ 'foo: nil'.should == response.body
86
+
87
+ get '/get_session_id'
88
+ response.should be_success
89
+ session_id.should_not == response.body
90
+ end
91
+
92
+ it "should get the session id when the session exists" do
93
+ get '/set_session_value'
94
+ response.should be_success
95
+ cookies['_session_id'].should be
96
+ session_id = cookies['_session_id']
97
+
98
+ get '/get_session_id'
99
+ response.should be_success
100
+ session_id.should == response.body
101
+ end
102
+
103
+ it "should deserialize an unloaded class" do
104
+ with_autoload_path "session_autoload_test" do
105
+ get '/set_serialized_session_value'
106
+ response.should be_success
107
+ cookies['_session_id'].should be
108
+ end
109
+ with_autoload_path "session_autoload_test" do
110
+ get '/get_session_id'
111
+ response.should be_success
112
+ end
113
+ with_autoload_path "session_autoload_test" do
114
+ get '/get_session_value'
115
+ response.should be_success
116
+ 'foo: #<SessionAutoloadTest::Foo bar:"baz">'.should == response.body
117
+ end
118
+ end
119
+
120
+ it "should not send the session cookie again if the ID already exists" do
121
+ get '/set_session_value'
122
+ response.should be_success
123
+ cookies['_session_id'].should be
124
+
125
+ get '/get_session_value'
126
+ response.should be_success
127
+ headers['Set-Cookie'].should be_nil
128
+ end
129
+
130
+ it "should prevent session fixation" do
131
+ get '/set_session_value'
132
+ response.should be_success
133
+ cookies['_session_id'].should be
134
+
135
+ get '/get_session_value'
136
+ response.should be_success
137
+ headers['Set-Cookie'].should be_nil
138
+ end
139
+ end
140
+
@@ -0,0 +1,29 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'riak-client','lib'))
17
+
18
+ require 'rubygems' # Use the gems path only for the spec suite
19
+ require 'riak'
20
+ %w{rails action_pack action_dispatch action_controller action_view}.each {|f| require f }
21
+ require 'riak-sessions'
22
+ require 'rspec/rails'
23
+ require 'rspec/autorun'
24
+
25
+ Dir[File.join(File.dirname(__FILE__), "support", "*.rb")].each {|f| require f }
26
+
27
+ Rspec.configure do |config|
28
+ config.mock_with :rspec
29
+ end
@@ -0,0 +1,82 @@
1
+ require 'rspec/rails/example/request_example_group'
2
+
3
+ class RoutedRackApp
4
+ attr_reader :routes
5
+
6
+ def initialize(routes, &blk)
7
+ @routes = routes
8
+ @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
9
+ end
10
+
11
+ def call(env)
12
+ @stack.call(env)
13
+ end
14
+ end
15
+
16
+ module Ripple
17
+ module SessionStoreTest
18
+ class TestController < ActionController::Base
19
+ def no_session_access
20
+ head :ok
21
+ end
22
+
23
+ def set_session_value
24
+ session[:foo] = "bar"
25
+ head :ok
26
+ end
27
+
28
+ def set_serialized_session_value
29
+ session[:foo] = SessionAutoloadTest::Foo.new
30
+ head :ok
31
+ end
32
+
33
+ def get_session_value
34
+ render :text => "foo: #{session[:foo].inspect}"
35
+ end
36
+
37
+ def get_session_id
38
+ render :text => "#{request.session_options[:id]}"
39
+ end
40
+
41
+ def call_reset_session
42
+ session[:bar]
43
+ reset_session
44
+ session[:bar] = "baz"
45
+ head :ok
46
+ end
47
+
48
+ def rescue_action(e) raise end
49
+ end
50
+
51
+ def build_app(routes = nil)
52
+ RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
53
+ middleware.use "ActionDispatch::ShowExceptions"
54
+ middleware.use "ActionDispatch::Callbacks"
55
+ middleware.use "ActionDispatch::ParamsParser"
56
+ middleware.use "ActionDispatch::Cookies"
57
+ middleware.use "ActionDispatch::Flash"
58
+ middleware.use "ActionDispatch::Head"
59
+ yield(middleware) if block_given?
60
+ end
61
+ end
62
+
63
+ def app
64
+ @app || super
65
+ end
66
+
67
+ def with_autoload_path(path)
68
+ path = File.join(File.dirname(__FILE__),"..","fixtures", path)
69
+ if ActiveSupport::Dependencies.autoload_paths.include?(path)
70
+ yield
71
+ else
72
+ begin
73
+ ActiveSupport::Dependencies.autoload_paths << path
74
+ yield
75
+ ensure
76
+ ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
77
+ ActiveSupport::Dependencies.clear
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: riak-sessions
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 0
7
+ - 8
8
+ - 0
9
+ - beta2
10
+ version: 0.8.0.beta2
11
+ platform: ruby
12
+ authors:
13
+ - Sean Cribbs
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-30 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 2
31
+ - 0
32
+ - 0
33
+ - beta
34
+ - 18
35
+ version: 2.0.0.beta.18
36
+ type: :development
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec-rails
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 2
48
+ - 0
49
+ - 0
50
+ - beta
51
+ - 18
52
+ version: 2.0.0.beta.18
53
+ type: :development
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: yajl-ruby
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ type: :development
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: rails
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 3
78
+ - 0
79
+ - 0
80
+ version: 3.0.0
81
+ type: :development
82
+ version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ name: curb
85
+ prerelease: false
86
+ requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">"
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ - 6
94
+ version: "0.6"
95
+ type: :development
96
+ version_requirements: *id005
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ prerelease: false
100
+ requirement: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ type: :development
109
+ version_requirements: *id006
110
+ - !ruby/object:Gem::Dependency
111
+ name: riak-client
112
+ prerelease: false
113
+ requirement: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ segments:
119
+ - 0
120
+ - 8
121
+ - 0
122
+ - beta2
123
+ version: 0.8.0.beta2
124
+ type: :runtime
125
+ version_requirements: *id007
126
+ - !ruby/object:Gem::Dependency
127
+ name: rack
128
+ prerelease: false
129
+ requirement: &id008 !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ segments:
135
+ - 1
136
+ - 0
137
+ version: "1.0"
138
+ type: :runtime
139
+ version_requirements: *id008
140
+ description: riak-sessions is a session store backed by Riak, the distributed database by Basho. It includes session implementations for both Rack and Rails 3.
141
+ email: seancribbs@gmail.com
142
+ executables: []
143
+
144
+ extensions: []
145
+
146
+ extra_rdoc_files: []
147
+
148
+ files:
149
+ - lib/riak/session_store.rb
150
+ - lib/riak-sessions.rb
151
+ - lib/ripple/session_store.rb
152
+ - Rakefile
153
+ - spec/fixtures/session_autoload_test/session_autoload_test/foo.rb
154
+ - spec/riak_session_store_spec.rb
155
+ - spec/ripple_session_store_spec.rb
156
+ - spec/spec_helper.rb
157
+ - spec/support/ripple_session_support.rb
158
+ has_rdoc: true
159
+ homepage: http://seancribbs.github.com/ripple
160
+ licenses: []
161
+
162
+ post_install_message:
163
+ rdoc_options: []
164
+
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ segments:
173
+ - 0
174
+ version: "0"
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ">"
179
+ - !ruby/object:Gem::Version
180
+ segments:
181
+ - 1
182
+ - 3
183
+ - 1
184
+ version: 1.3.1
185
+ requirements: []
186
+
187
+ rubyforge_project:
188
+ rubygems_version: 1.3.7
189
+ signing_key:
190
+ specification_version: 3
191
+ summary: riak-sessions is a session store backed by Riak, the distributed database by Basho.
192
+ test_files:
193
+ - spec/fixtures/session_autoload_test/session_autoload_test/foo.rb
194
+ - spec/riak_session_store_spec.rb
195
+ - spec/ripple_session_store_spec.rb
196
+ - spec/spec_helper.rb
197
+ - spec/support/ripple_session_support.rb