riak-sessions 0.8.0.beta2

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 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