merb-core 0.9.10 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +6 -0
- data/lib/merb-core.rb +11 -4
- data/lib/merb-core/autoload.rb +1 -0
- data/lib/merb-core/bootloader.rb +44 -11
- data/lib/merb-core/config.rb +7 -0
- data/lib/merb-core/controller/abstract_controller.rb +1 -1
- data/lib/merb-core/controller/merb_controller.rb +0 -1
- data/lib/merb-core/controller/mixins/controller.rb +1 -1
- data/lib/merb-core/core_ext/kernel.rb +30 -24
- data/lib/merb-core/dispatch/cookies.rb +2 -2
- data/lib/merb-core/dispatch/request.rb +8 -229
- data/lib/merb-core/dispatch/request_parsers.rb +236 -0
- data/lib/merb-core/dispatch/router/route.rb +1 -1
- data/lib/merb-core/dispatch/session/cookie.rb +2 -2
- data/lib/merb-core/rack.rb +0 -1
- data/lib/merb-core/rack/adapter/abstract.rb +3 -1
- data/lib/merb-core/rack/middleware/static.rb +2 -2
- data/lib/merb-core/server.rb +1 -1
- data/lib/merb-core/tasks/gem_management.rb +2 -1
- data/lib/merb-core/test/helpers.rb +2 -1
- data/lib/merb-core/test/helpers/cookie_jar.rb +106 -0
- data/lib/merb-core/test/helpers/mock_request_helper.rb +2 -2
- data/lib/merb-core/test/helpers/request_helper.rb +48 -32
- data/lib/merb-core/test/matchers/request_matchers.rb +20 -0
- data/lib/merb-core/test/matchers/route_matchers.rb +1 -1
- data/lib/merb-core/test/test_ext/rspec.rb +5 -2
- data/lib/merb-core/version.rb +1 -1
- metadata +4 -3
- data/lib/merb-core/rack/middleware/csrf.rb +0 -73
@@ -52,7 +52,7 @@ module Merb
|
|
52
52
|
if value.blank?
|
53
53
|
self.delete(key)
|
54
54
|
else
|
55
|
-
self[key] = Merb::
|
55
|
+
self[key] = Merb::Parse.unescape(value)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -210,7 +210,7 @@ module Merb
|
|
210
210
|
# @api public
|
211
211
|
# @deprecated
|
212
212
|
def build_request(params = {}, env = {})
|
213
|
-
params = Merb::
|
213
|
+
params = Merb::Parse.params_to_query_string(params)
|
214
214
|
|
215
215
|
query_string = env[:query_string] || env['QUERY_STRING']
|
216
216
|
env[:query_string] = query_string ? "#{query_string}&#{params}" : params
|
@@ -2,54 +2,48 @@ require "rack"
|
|
2
2
|
|
3
3
|
module Merb
|
4
4
|
module Test
|
5
|
-
module
|
6
|
-
|
7
|
-
def describe_request(rack)
|
8
|
-
"a #{rack.original_env[:method] || rack.original_env["REQUEST_METHOD"] || "GET"} to '#{rack.url}'"
|
9
|
-
end
|
10
|
-
|
11
|
-
def describe_input(input)
|
12
|
-
if input.respond_to?(:controller_name)
|
13
|
-
"#{input.controller_name}##{input.action_name}"
|
14
|
-
elsif input.respond_to?(:original_env)
|
15
|
-
describe_request(input)
|
16
|
-
else
|
17
|
-
input
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def status_code(input)
|
22
|
-
input.respond_to?(:status) ? input.status : input
|
23
|
-
end
|
5
|
+
module MakeRequest
|
24
6
|
|
25
7
|
def request(uri, env = {})
|
26
|
-
uri = url(uri) if uri.is_a?(Symbol)
|
8
|
+
uri = url(uri) if uri.is_a?(Symbol)
|
9
|
+
uri = URI(uri)
|
10
|
+
uri.scheme ||= "http"
|
11
|
+
uri.host ||= "example.org"
|
27
12
|
|
28
13
|
if (env[:method] == "POST" || env["REQUEST_METHOD"] == "POST")
|
29
14
|
params = env.delete(:body_params) if env.key?(:body_params)
|
30
15
|
params = env.delete(:params) if env.key?(:params) && !env.key?(:input)
|
31
|
-
|
16
|
+
|
32
17
|
unless env.key?(:input)
|
33
|
-
env[:input] = Merb::
|
18
|
+
env[:input] = Merb::Parse.params_to_query_string(params)
|
34
19
|
env["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
|
35
20
|
end
|
36
21
|
end
|
37
22
|
|
38
23
|
if env[:params]
|
39
|
-
uri
|
24
|
+
uri.query = [
|
25
|
+
uri.query, Merb::Parse.params_to_query_string(env.delete(:params))
|
26
|
+
].compact.join("&")
|
40
27
|
end
|
28
|
+
|
29
|
+
ignore_cookies = env.has_key?(:jar) && env[:jar].nil?
|
41
30
|
|
42
|
-
|
43
|
-
|
31
|
+
unless ignore_cookies
|
32
|
+
# Setup a default cookie jar container
|
33
|
+
@__cookie_jar__ ||= Merb::Test::CookieJar.new
|
34
|
+
# Grab the cookie group name
|
35
|
+
jar = env.delete(:jar) || :default
|
36
|
+
# Set the cookie header with the cookies
|
37
|
+
env["HTTP_COOKIE"] = @__cookie_jar__.for(jar, uri)
|
44
38
|
end
|
45
|
-
|
39
|
+
|
46
40
|
app = Merb::Rack::Application.new
|
47
|
-
rack = app.call(::Rack::MockRequest.env_for(uri, env))
|
41
|
+
rack = app.call(::Rack::MockRequest.env_for(uri.to_s, env))
|
48
42
|
|
49
43
|
rack = Struct.new(:status, :headers, :body, :url, :original_env).
|
50
|
-
new(rack[0], rack[1], rack[2], uri, env)
|
51
|
-
|
52
|
-
@
|
44
|
+
new(rack[0], rack[1], rack[2], uri.to_s, env)
|
45
|
+
|
46
|
+
@__cookie_jar__.update(jar, uri, rack.headers["Set-Cookie"]) unless ignore_cookies
|
53
47
|
|
54
48
|
Merb::Dispatcher.work_queue.size.times do
|
55
49
|
Merb::Dispatcher.work_queue.pop.call
|
@@ -57,9 +51,31 @@ module Merb
|
|
57
51
|
|
58
52
|
rack
|
59
53
|
end
|
60
|
-
|
61
|
-
|
54
|
+
end
|
55
|
+
|
56
|
+
module RequestHelper
|
57
|
+
include MakeRequest
|
58
|
+
|
59
|
+
def describe_request(rack)
|
60
|
+
"a #{rack.original_env[:method] || rack.original_env["REQUEST_METHOD"] || "GET"} to '#{rack.url}'"
|
61
|
+
end
|
62
|
+
|
63
|
+
def describe_input(input)
|
64
|
+
if input.respond_to?(:controller_name)
|
65
|
+
"#{input.controller_name}##{input.action_name}"
|
66
|
+
elsif input.respond_to?(:original_env)
|
67
|
+
describe_request(input)
|
68
|
+
else
|
69
|
+
input
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def status_code(input)
|
74
|
+
input.respond_to?(:status) ? input.status : input
|
75
|
+
end
|
62
76
|
|
77
|
+
def requesting(*args) request(*args) end
|
78
|
+
def response_for(*args) request(*args) end
|
63
79
|
end
|
64
80
|
end
|
65
81
|
end
|
@@ -36,6 +36,26 @@ Spec::Matchers.create(:be_missing, :be_client_error) do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
Spec::Matchers.create(:have_body) do
|
40
|
+
matches do |rack, body|
|
41
|
+
@actual = if rack.respond_to?(:body)
|
42
|
+
rack.body.to_s
|
43
|
+
else
|
44
|
+
rack.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
@actual == body
|
48
|
+
end
|
49
|
+
|
50
|
+
negative_failure_message do |rack, body|
|
51
|
+
"Expected the response not to match:\n #{body}\nActual response was:\n #{@actual}"
|
52
|
+
end
|
53
|
+
|
54
|
+
failure_message do |rack, body|
|
55
|
+
"Expected the response to match:\n #{body}\nActual response was:\n #{@actual}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
39
59
|
Spec::Matchers.create(:have_content_type) do
|
40
60
|
matches do |rack, mime_symbol|
|
41
61
|
content_type = rack.headers["Content-Type"].split("; ").first
|
@@ -56,7 +56,7 @@ module Merb::Test::Rspec::RouteMatchers
|
|
56
56
|
# ==== Returns
|
57
57
|
# String:: The failure message.
|
58
58
|
def failure_message
|
59
|
-
"expected the request to route to #{@expected_controller.
|
59
|
+
"expected the request to route to #{@expected_controller.to_const_string}##{@expected_action}#{expected_parameters_message}, but was #{@target_controller.to_const_string}##{@target_action}#{actual_parameters_message}"
|
60
60
|
end
|
61
61
|
|
62
62
|
# ==== Returns
|
@@ -36,8 +36,12 @@ module Merb
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
module Matchers
|
40
|
+
end
|
41
|
+
|
39
42
|
class ExampleGroup < Spec::Example::ExampleGroup
|
40
43
|
|
44
|
+
include ::Merb::Test::Matchers
|
41
45
|
include ::Merb::Test::ViewHelper
|
42
46
|
include ::Merb::Test::RouteHelper
|
43
47
|
include ::Merb::Test::ControllerHelper
|
@@ -76,7 +80,7 @@ module Spec
|
|
76
80
|
|
77
81
|
def self.create(*names, &block)
|
78
82
|
@guid ||= 0
|
79
|
-
|
83
|
+
Merb::Test::Matchers.module_eval do
|
80
84
|
klass = Class.new(MatcherDSL) do
|
81
85
|
def initialize(expected_value)
|
82
86
|
@expected_value = expected_value
|
@@ -91,7 +95,6 @@ module Spec
|
|
91
95
|
end
|
92
96
|
end
|
93
97
|
end
|
94
|
-
Merb::Test::ExampleGroup.send(:include, mod)
|
95
98
|
end
|
96
99
|
|
97
100
|
class MatcherDSL
|
data/lib/merb-core/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: merb-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ezra Zygmuntowicz
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-10-
|
12
|
+
date: 2008-10-29 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- lib/merb-core/dispatch/default_exception/views/index.html.erb
|
154
154
|
- lib/merb-core/dispatch/dispatcher.rb
|
155
155
|
- lib/merb-core/dispatch/request.rb
|
156
|
+
- lib/merb-core/dispatch/request_parsers.rb
|
156
157
|
- lib/merb-core/dispatch/router
|
157
158
|
- lib/merb-core/dispatch/router/behavior.rb
|
158
159
|
- lib/merb-core/dispatch/router/cached_proc.rb
|
@@ -192,7 +193,6 @@ files:
|
|
192
193
|
- lib/merb-core/rack/middleware
|
193
194
|
- lib/merb-core/rack/middleware/conditional_get.rb
|
194
195
|
- lib/merb-core/rack/middleware/content_length.rb
|
195
|
-
- lib/merb-core/rack/middleware/csrf.rb
|
196
196
|
- lib/merb-core/rack/middleware/path_prefix.rb
|
197
197
|
- lib/merb-core/rack/middleware/profiler.rb
|
198
198
|
- lib/merb-core/rack/middleware/static.rb
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- lib/merb-core/test
|
211
211
|
- lib/merb-core/test/helpers
|
212
212
|
- lib/merb-core/test/helpers/controller_helper.rb
|
213
|
+
- lib/merb-core/test/helpers/cookie_jar.rb
|
213
214
|
- lib/merb-core/test/helpers/mock_request_helper.rb
|
214
215
|
- lib/merb-core/test/helpers/multipart_request_helper.rb
|
215
216
|
- lib/merb-core/test/helpers/request_helper.rb
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'digest/md5'
|
2
|
-
|
3
|
-
module Merb
|
4
|
-
module Rack
|
5
|
-
|
6
|
-
class Csrf < Merb::Rack::Middleware
|
7
|
-
HTML_TYPES = %w(text/html application/xhtml+xml)
|
8
|
-
POST_FORM_RE = Regexp.compile('(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', Regexp::IGNORECASE)
|
9
|
-
ERROR_MSG = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>'.freeze
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
status, header, body = @app.call(env)
|
13
|
-
body = body.to_s
|
14
|
-
if env[Merb::Const::REQUEST_METHOD] == Merb::Const::GET
|
15
|
-
body = process_response(body) if valid_content_type?(header[Merb::Const::CONTENT_TYPE])
|
16
|
-
elsif env[Merb::Const::REQUEST_METHOD] == Merb::Const::POST
|
17
|
-
status, body = process_request(env, status, body)
|
18
|
-
end
|
19
|
-
|
20
|
-
[status, header, body]
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def process_request(env, status, body)
|
25
|
-
session_id = Merb::Config[:session_id_key]
|
26
|
-
csrf_token = _make_token(session_id)
|
27
|
-
|
28
|
-
request_csrf_token = env['csrf_authentication_token']
|
29
|
-
|
30
|
-
unless csrf_token == request_csrf_token
|
31
|
-
exception = Merb::ControllerExceptions::Forbidden.new(ERROR_MSG)
|
32
|
-
status = exception.status
|
33
|
-
body = exception.message
|
34
|
-
|
35
|
-
return [status, body]
|
36
|
-
end
|
37
|
-
|
38
|
-
return [status, body]
|
39
|
-
end
|
40
|
-
|
41
|
-
def process_response(body)
|
42
|
-
session_id = Merb::Config[:session_id_key]
|
43
|
-
csrf_token = _make_token(session_id)
|
44
|
-
|
45
|
-
if csrf_token
|
46
|
-
modified_body = ''
|
47
|
-
body.scan(POST_FORM_RE) do |match|
|
48
|
-
modified_body << add_csrf_field($~, csrf_token)
|
49
|
-
end
|
50
|
-
|
51
|
-
body = modified_body
|
52
|
-
end
|
53
|
-
|
54
|
-
body
|
55
|
-
end
|
56
|
-
|
57
|
-
def add_csrf_field(match, csrf_token)
|
58
|
-
modified_body = match.pre_match
|
59
|
-
modified_body << match.to_s
|
60
|
-
modified_body << "<div style='display: none;'><input type='hidden' id='csrf_authentication_token' name='csrf_authentication_token' value='#{csrf_token}' /></div>"
|
61
|
-
modified_body << match.post_match
|
62
|
-
end
|
63
|
-
|
64
|
-
def valid_content_type?(content_type)
|
65
|
-
HTML_TYPES.include?(content_type.split(';').first)
|
66
|
-
end
|
67
|
-
|
68
|
-
def _make_token(session_id)
|
69
|
-
Digest::MD5.hexdigest(Merb::Config[:session_secret_key] + session_id)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|