merb-core 0.9.5 → 0.9.6
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/CHANGELOG +925 -0
- data/CONTRIBUTORS +93 -0
- data/PUBLIC_CHANGELOG +85 -0
- data/Rakefile +18 -28
- data/bin/merb +34 -5
- data/lib/merb-core/autoload.rb +2 -3
- data/lib/merb-core/bootloader.rb +60 -66
- data/lib/merb-core/config.rb +7 -1
- data/lib/merb-core/controller/abstract_controller.rb +35 -21
- data/lib/merb-core/controller/merb_controller.rb +15 -42
- data/lib/merb-core/controller/mixins/authentication.rb +42 -6
- data/lib/merb-core/controller/mixins/conditional_get.rb +83 -0
- data/lib/merb-core/controller/mixins/render.rb +3 -3
- data/lib/merb-core/core_ext/kernel.rb +6 -19
- data/lib/merb-core/dispatch/cookies.rb +96 -80
- data/lib/merb-core/dispatch/default_exception/views/index.html.erb +2 -0
- data/lib/merb-core/dispatch/request.rb +18 -16
- data/lib/merb-core/dispatch/router/route.rb +6 -0
- data/lib/merb-core/dispatch/router.rb +4 -1
- data/lib/merb-core/dispatch/session/container.rb +64 -0
- data/lib/merb-core/dispatch/session/cookie.rb +91 -101
- data/lib/merb-core/dispatch/session/memcached.rb +38 -174
- data/lib/merb-core/dispatch/session/memory.rb +62 -208
- data/lib/merb-core/dispatch/session/store_container.rb +145 -0
- data/lib/merb-core/dispatch/session.rb +174 -48
- data/lib/merb-core/rack/middleware/conditional_get.rb +14 -8
- data/lib/merb-core/rack/middleware/csrf.rb +73 -0
- data/lib/merb-core/rack.rb +1 -0
- data/lib/merb-core/script.rb +112 -0
- data/lib/merb-core/server.rb +2 -0
- data/lib/merb-core/tasks/merb_rake_helper.rb +25 -0
- data/lib/merb-core/test/helpers/request_helper.rb +40 -3
- data/lib/merb-core/test/run_specs.rb +4 -3
- data/lib/merb-core/vendor/facets/inflect.rb +7 -10
- data/lib/merb-core/version.rb +1 -1
- data/lib/merb-core.rb +11 -40
- data/spec/private/core_ext/kernel_spec.rb +0 -11
- data/spec/private/dispatch/fixture/log/merb_test.log +893 -0
- data/spec/private/router/fixture/log/merb_test.log +12 -1728
- data/spec/private/router/route_spec.rb +4 -0
- data/spec/private/router/router_spec.rb +8 -0
- data/spec/private/vendor/facets/plural_spec.rb +1 -1
- data/spec/private/vendor/facets/singular_spec.rb +1 -1
- data/spec/public/abstract_controller/controllers/display.rb +8 -2
- data/spec/public/abstract_controller/controllers/filters.rb +18 -0
- data/spec/public/abstract_controller/display_spec.rb +6 -2
- data/spec/public/abstract_controller/filter_spec.rb +4 -0
- data/spec/public/controller/authentication_spec.rb +114 -43
- data/spec/public/controller/base_spec.rb +8 -0
- data/spec/public/controller/conditional_get_spec.rb +100 -0
- data/spec/public/controller/config/init.rb +1 -1
- data/spec/public/controller/controllers/authentication.rb +29 -0
- data/spec/public/controller/controllers/base.rb +13 -0
- data/spec/public/controller/controllers/conditional_get.rb +35 -0
- data/spec/public/controller/controllers/cookies.rb +10 -1
- data/spec/public/controller/cookies_spec.rb +38 -9
- data/spec/public/controller/spec_helper.rb +1 -0
- data/spec/public/controller/url_spec.rb +70 -1
- data/spec/public/directory_structure/directory/log/merb_test.log +461 -0
- data/spec/public/rack/conditinal_get_middleware_spec.rb +77 -89
- data/spec/public/rack/csrf_middleware_spec.rb +70 -0
- data/spec/public/reloading/directory/log/merb_test.log +52 -0
- data/spec/public/request/request_spec.rb +19 -1
- data/spec/public/router/fixation_spec.rb +26 -4
- data/spec/public/router/fixture/log/merb_test.log +234 -30332
- data/spec/public/session/controllers/sessions.rb +52 -0
- data/spec/public/session/cookie_session_spec.rb +73 -0
- data/spec/public/session/memcached_session_spec.rb +31 -0
- data/spec/public/session/memory_session_spec.rb +28 -0
- data/spec/public/session/multiple_sessions_spec.rb +74 -0
- data/spec/public/session/no_session_spec.rb +12 -0
- data/spec/public/session/session_spec.rb +91 -0
- data/spec/public/test/controllers/spec_helper_controller.rb +2 -1
- data/spec/public/test/request_helper_spec.rb +15 -0
- data/spec/spec_helper.rb +2 -2
- metadata +23 -5
- data/spec/private/dispatch/cookies_spec.rb +0 -219
- data/spec/private/dispatch/session_mixin_spec.rb +0 -47
@@ -1,139 +1,127 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
|
2
|
-
require File.join(File.dirname(__FILE__), "shared_example_groups")
|
3
2
|
|
4
3
|
require "sha1"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def non_matching_etag
|
10
|
-
response = "Ruby world needs a Paste port. Or... CherryPy?"
|
5
|
+
class ConditionalGetTestController < Merb::Controller
|
6
|
+
def with_etag
|
7
|
+
response = "original message-body"
|
11
8
|
headers['ETag'] = Digest::SHA1.hexdigest(response)
|
12
9
|
|
13
10
|
response
|
14
11
|
end
|
15
12
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
response
|
21
|
-
end
|
22
|
-
|
23
|
-
def no_etag
|
24
|
-
# sanity check
|
25
|
-
headers.delete('ETag')
|
26
|
-
|
27
|
-
"Everyone loves Rack"
|
13
|
+
def with_last_modified
|
14
|
+
headers[Merb::Const::LAST_MODIFIED] = :documents_last_modified_time
|
15
|
+
"original message-body"
|
28
16
|
end
|
29
|
-
end
|
30
17
|
|
31
|
-
|
32
|
-
def non_matching_last_modified
|
33
|
-
response = "Who cares about efficiency? Just throw more hardware at the problem."
|
34
|
-
headers[Merb::Const::LAST_MODIFIED] = :non_matching
|
35
|
-
|
36
|
-
response
|
37
|
-
end
|
38
|
-
|
39
|
-
def matching_last_modified
|
40
|
-
response = "Who cares about efficiency? Just throw more hardware at the problem."
|
41
|
-
headers[Merb::Const::LAST_MODIFIED] = :matching
|
42
|
-
|
43
|
-
response
|
44
|
-
end
|
45
|
-
|
46
|
-
def no_last_modified
|
18
|
+
def without
|
47
19
|
# sanity check
|
48
|
-
headers.delete('
|
20
|
+
headers.delete('ETag')
|
21
|
+
headers.delete(Merb::Const::LAST_MODIFIED)
|
49
22
|
|
50
|
-
"
|
23
|
+
"original message-body"
|
51
24
|
end
|
52
25
|
end
|
53
26
|
|
54
27
|
|
55
28
|
Merb::Router.prepare do |r|
|
56
|
-
r.match("/
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
r.match("/
|
29
|
+
r.match("/with_etag").to(
|
30
|
+
:controller => "conditional_get_test_controller", :action => "with_etag"
|
31
|
+
)
|
32
|
+
r.match("/with_last_modified").to(
|
33
|
+
:controller => "conditional_get_test_controller", :action => "with_last_modified"
|
34
|
+
)
|
35
|
+
r.match("/without").to(
|
36
|
+
:controller => "conditional_get_test_controller", :action => "without"
|
37
|
+
)
|
63
38
|
end
|
64
39
|
|
40
|
+
describe Merb::Rack::ConditionalGet do
|
65
41
|
|
42
|
+
describe(
|
43
|
+
"when the client already has an up-to-date document",
|
44
|
+
:shared => true
|
45
|
+
) do
|
46
|
+
it 'sets status to "304"' do
|
47
|
+
@status.should == 304
|
48
|
+
end
|
66
49
|
|
67
|
-
|
50
|
+
it 'returns no message-body' do
|
51
|
+
@body.should == ""
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe(
|
56
|
+
"when the client does NOT have an up-to-date document",
|
57
|
+
:shared => true
|
58
|
+
) do
|
59
|
+
it 'does not modify status' do
|
60
|
+
@status.should == 200
|
61
|
+
end
|
68
62
|
|
63
|
+
it 'does not modify message-body' do
|
64
|
+
@body.should == "original message-body"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
69
68
|
before(:each) do
|
70
69
|
@app = Merb::Rack::Application.new
|
71
70
|
@middleware = Merb::Rack::ConditionalGet.new(@app)
|
72
71
|
end
|
73
72
|
|
74
|
-
describe "when response has no ETag header" do
|
75
|
-
|
76
|
-
env = Rack::MockRequest.env_for('/
|
77
|
-
status, headers, body = @middleware.call(env)
|
78
|
-
|
79
|
-
status.should == 200
|
73
|
+
describe "when response has no ETag header and no Last-Modified header" do
|
74
|
+
before(:each) do
|
75
|
+
env = Rack::MockRequest.env_for('/without')
|
76
|
+
@status, @headers, @body = @middleware.call(env)
|
80
77
|
end
|
78
|
+
|
79
|
+
it_should_behave_like "when the client does NOT have an up-to-date document"
|
81
80
|
end
|
82
81
|
|
83
82
|
describe "when response has ETag header" do
|
84
83
|
describe "and it == to HTTP_IF_NONE_MATCH of the request" do
|
85
|
-
|
86
|
-
env = Rack::MockRequest.env_for('/
|
84
|
+
before(:each) do
|
85
|
+
env = Rack::MockRequest.env_for('/with_etag')
|
87
86
|
env['HTTP_IF_NONE_MATCH'] =
|
88
|
-
Digest::SHA1.hexdigest("
|
89
|
-
|
90
|
-
status, headers, body = @middleware.call(env)
|
91
|
-
status.should == 304
|
87
|
+
Digest::SHA1.hexdigest("original message-body")
|
88
|
+
@status, @headers, @body = @middleware.call(env)
|
92
89
|
end
|
90
|
+
|
91
|
+
it_should_behave_like "when the client already has an up-to-date document"
|
93
92
|
end
|
94
93
|
|
95
94
|
describe "and it IS NOT == to HTTP_IF_NONE_MATCH of the request" do
|
96
|
-
|
97
|
-
env = Rack::MockRequest.env_for('/
|
95
|
+
before(:each) do
|
96
|
+
env = Rack::MockRequest.env_for('/with_etag')
|
98
97
|
env['HTTP_IF_NONE_MATCH'] =
|
99
|
-
Digest::SHA1.hexdigest("
|
100
|
-
|
101
|
-
status, headers, body = @middleware.call(env)
|
102
|
-
status.should == 200
|
98
|
+
Digest::SHA1.hexdigest("a different message-body")
|
99
|
+
@status, @headers, @body = @middleware.call(env)
|
103
100
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
describe "when response has no Last-Modified header" do
|
108
|
-
it 'does not modify status' do
|
109
|
-
env = Rack::MockRequest.env_for('/last_modified/stomach')
|
110
|
-
status, headers, body = @middleware.call(env)
|
111
|
-
|
112
|
-
status.should == 200
|
101
|
+
|
102
|
+
it_should_behave_like "when the client does NOT have an up-to-date document"
|
113
103
|
end
|
114
104
|
end
|
115
105
|
|
116
106
|
describe "when response has Last-Modified header" do
|
117
|
-
describe "
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
status, headers, body = @middleware.call(env)
|
124
|
-
status.should == 304
|
125
|
-
end
|
107
|
+
describe "and it == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
|
108
|
+
before(:each) do
|
109
|
+
env = Rack::MockRequest.env_for('/with_last_modified')
|
110
|
+
env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :documents_last_modified_time
|
111
|
+
@status, @headers, @body = @middleware.call(env)
|
126
112
|
end
|
113
|
+
|
114
|
+
it_should_behave_like "when the client already has an up-to-date document"
|
115
|
+
end
|
127
116
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
status, headers, body = @middleware.call(env)
|
134
|
-
status.should == 200
|
135
|
-
end
|
117
|
+
describe "and it IS NOT == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
|
118
|
+
before(:each) do
|
119
|
+
env = Rack::MockRequest.env_for('/with_last_modified')
|
120
|
+
env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :some_other_time
|
121
|
+
@status, @headers, @body = @middleware.call(env)
|
136
122
|
end
|
123
|
+
|
124
|
+
it_should_behave_like "when the client does NOT have an up-to-date document"
|
137
125
|
end
|
138
126
|
end
|
139
127
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
|
2
|
+
require File.join(File.dirname(__FILE__), "shared_example_groups")
|
3
|
+
|
4
|
+
|
5
|
+
Merb::Router.prepare do |r|
|
6
|
+
r.resources :users
|
7
|
+
end
|
8
|
+
|
9
|
+
class Users < Merb::Controller
|
10
|
+
def new
|
11
|
+
body = "<div><form action='/users' method='POST'></form></div>"
|
12
|
+
body
|
13
|
+
end
|
14
|
+
|
15
|
+
def index
|
16
|
+
body = "<div>This is my index action</div>"
|
17
|
+
body
|
18
|
+
end
|
19
|
+
|
20
|
+
def edit
|
21
|
+
body = "<div><form action='/users' method='POST'></form><form action='/sessions' method='POST'></form></div>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def create
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe Merb::Rack::Csrf do
|
31
|
+
before(:each) do
|
32
|
+
@app = Merb::Rack::Application.new
|
33
|
+
@middleware = Merb::Rack::Csrf.new(@app)
|
34
|
+
@env = Rack::MockRequest.env_for('/users/new')
|
35
|
+
|
36
|
+
Merb::Config[:session_secret_key] = "ABC"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be successful" do
|
40
|
+
env = Rack::MockRequest.env_for('/users', :method => 'POST', 'csrf_authentication_token' => "b072aa15485e028dc8973d48089efe0e")
|
41
|
+
status, header, body = @middleware.call(env)
|
42
|
+
status.should == 200
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return a Merb::ExceptionsController::Forbidden (403)" do
|
46
|
+
env = Rack::MockRequest.env_for('/users', :method => 'POST', 'csrf_authentication_token' => "INCORRECT_AUTH_TOKEN")
|
47
|
+
status, header, body = @middleware.call(env)
|
48
|
+
status.should == 403
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should insert a hidden field in to any form with a POST method" do
|
52
|
+
env = Rack::MockRequest.env_for('/users/new')
|
53
|
+
status, header, body = @middleware.call(env)
|
54
|
+
body.should have_tag(:form, :action => '/users')
|
55
|
+
body.should have_tag(:input, :type => 'hidden', :id => 'csrf_authentication_token')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not do anything if there is no form found in the response" do
|
59
|
+
env = Rack::MockRequest.env_for('/users')
|
60
|
+
status, header, body = @middleware.call(env)
|
61
|
+
body.should not_match_tag('form')
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should insert hidden fields in to both forms" do
|
65
|
+
env = Rack::MockRequest.env_for('/users/1/edit')
|
66
|
+
status, header, body = @middleware.call(env)
|
67
|
+
body.should have_tag(:form, :action => '/users')
|
68
|
+
body.should have_tag(:form, :action => '/sessions')
|
69
|
+
end
|
70
|
+
end
|
@@ -288161,3 +288161,55 @@ Restarting Worker Thread
|
|
288161
288161
|
~ Not Using Sessions
|
288162
288162
|
~ Not Using Sessions
|
288163
288163
|
~ Not Using Sessions
|
288164
|
+
~ Not Using Sessions
|
288165
|
+
~ Not Using Sessions
|
288166
|
+
~ Not Using Sessions
|
288167
|
+
~ Not Using Sessions
|
288168
|
+
~ Not Using Sessions
|
288169
|
+
~ Not Using Sessions
|
288170
|
+
~ Not Using Sessions
|
288171
|
+
~ Not Using Sessions
|
288172
|
+
~ Not Using Sessions
|
288173
|
+
~ Not Using Sessions
|
288174
|
+
~ Not Using Sessions
|
288175
|
+
~ Not Using Sessions
|
288176
|
+
~ Not Using Sessions
|
288177
|
+
~ Not Using Sessions
|
288178
|
+
~ Not Using Sessions
|
288179
|
+
~ Not Using Sessions
|
288180
|
+
~ Not Using Sessions
|
288181
|
+
~ Not Using Sessions
|
288182
|
+
~ Not Using Sessions
|
288183
|
+
~ Not Using Sessions
|
288184
|
+
~ Not Using Sessions
|
288185
|
+
~ Not Using Sessions
|
288186
|
+
~ Not Using Sessions
|
288187
|
+
~ Not Using Sessions
|
288188
|
+
~ Not Using Sessions
|
288189
|
+
~ Not Using Sessions
|
288190
|
+
~ Not Using Sessions
|
288191
|
+
~ Not Using Sessions
|
288192
|
+
~ Not Using Sessions
|
288193
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288194
|
+
~ Not Using Sessions
|
288195
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288196
|
+
~ Not Using Sessions
|
288197
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288198
|
+
~ Not Using Sessions
|
288199
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288200
|
+
~ Not Using Sessions
|
288201
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288202
|
+
~ Not Using Sessions
|
288203
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288204
|
+
~ Not Using Sessions
|
288205
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288206
|
+
~ Not Using Sessions
|
288207
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288208
|
+
~ Not Using Sessions
|
288209
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288210
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288211
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288212
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288213
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288214
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
288215
|
+
~ Starting Merb server listening at 0.0.0.0:4000
|
@@ -56,6 +56,7 @@ describe Merb::Request, " query and body params" do
|
|
56
56
|
before(:all) { Merb::BootLoader::Dependencies.enable_json_gem }
|
57
57
|
|
58
58
|
{"foo=bar&baz=bat" => {"foo" => "bar", "baz" => "bat"},
|
59
|
+
"foo=bar&foo=baz" => {"foo" => "baz"},
|
59
60
|
"foo[]=bar&foo[]=baz" => {"foo" => ["bar", "baz"]},
|
60
61
|
"foo[][bar]=1&foo[][bar]=2" => {"foo" => [{"bar" => "1"},{"bar" => "2"}]},
|
61
62
|
"foo[bar][][baz]=1&foo[bar][][baz]=2" => {"foo" => {"bar" => [{"baz" => "1"},{"baz" => "2"}]}},
|
@@ -220,4 +221,21 @@ describe Merb::Request, " misc" do
|
|
220
221
|
|
221
222
|
end
|
222
223
|
|
223
|
-
end
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
describe Merb::Request, "#if_none_match" do
|
229
|
+
it 'returns value of If-None-Match request header' do
|
230
|
+
fake_request(Merb::Const::HTTP_IF_NONE_MATCH => "dc1562a133").if_none_match.should == "dc1562a133"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
describe Merb::Request, "#if_modified_since" do
|
237
|
+
it 'returns value of If-Modified-Since request header' do
|
238
|
+
t = '05 Sep 2008 22:00:27 GMT'
|
239
|
+
fake_request(Merb::Const::HTTP_IF_MODIFIED_SINCE => t).if_modified_since.should == Time.rfc2822(t)
|
240
|
+
end
|
241
|
+
end
|
@@ -1,19 +1,41 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
2
|
|
3
|
+
module Merb::Test::Fixtures
|
4
|
+
module Controllers
|
5
|
+
class FixatableRoutes < Merb::Controller
|
6
|
+
|
7
|
+
def fixoid
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
3
14
|
describe "A route marked as fixatable" do
|
4
15
|
predicate_matchers[:allow_fixation] = :allow_fixation?
|
5
16
|
|
6
|
-
|
17
|
+
before do
|
7
18
|
Merb::Router.prepare do |r|
|
8
|
-
r.match("/hello/:action/:id").to(
|
19
|
+
r.match("/hello/:action/:id").to(
|
20
|
+
:controller => "merb/test/fixtures/controllers/fixatable_routes",
|
21
|
+
:action => "fixoid").fixatable
|
9
22
|
end
|
23
|
+
end
|
10
24
|
|
25
|
+
it "allows fixation" do
|
11
26
|
matched_route_for("/hello/goodbye/tagging").should allow_fixation
|
12
27
|
end
|
28
|
+
|
29
|
+
it "should store a cookie with the session_id" do
|
30
|
+
session_id = Merb::SessionMixin.rand_uuid
|
31
|
+
request = fake_request(:request_uri => "/hello/goodbye/tagging",
|
32
|
+
:query_string => "_session_id=#{session_id}")
|
33
|
+
controller = ::Merb::Dispatcher.handle(request)
|
34
|
+
controller.params["_session_id"].should == session_id
|
35
|
+
controller.request.session_cookie_value.should == session_id
|
36
|
+
end
|
13
37
|
end
|
14
38
|
|
15
|
-
|
16
|
-
|
17
39
|
describe "A route NOT marked as fixatable" do
|
18
40
|
predicate_matchers[:allow_fixation] = :allow_fixation?
|
19
41
|
|