actionpack 2.2.3 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +433 -375
- data/MIT-LICENSE +1 -1
- data/README +21 -75
- data/Rakefile +1 -1
- data/lib/action_controller.rb +80 -43
- data/lib/action_controller/assertions/model_assertions.rb +1 -0
- data/lib/action_controller/assertions/response_assertions.rb +43 -16
- data/lib/action_controller/assertions/routing_assertions.rb +1 -1
- data/lib/action_controller/assertions/selector_assertions.rb +17 -12
- data/lib/action_controller/assertions/tag_assertions.rb +1 -4
- data/lib/action_controller/base.rb +153 -82
- data/lib/action_controller/benchmarking.rb +9 -9
- data/lib/action_controller/caching.rb +9 -11
- data/lib/action_controller/caching/actions.rb +11 -18
- data/lib/action_controller/caching/fragments.rb +28 -20
- data/lib/action_controller/caching/pages.rb +13 -15
- data/lib/action_controller/caching/sweeping.rb +2 -2
- data/lib/action_controller/cgi_ext.rb +0 -1
- data/lib/action_controller/cgi_ext/cookie.rb +2 -0
- data/lib/action_controller/cgi_process.rb +54 -162
- data/lib/action_controller/cookies.rb +13 -25
- data/lib/action_controller/dispatcher.rb +43 -122
- data/lib/action_controller/failsafe.rb +52 -0
- data/lib/action_controller/flash.rb +38 -47
- data/lib/action_controller/helpers.rb +13 -9
- data/lib/action_controller/http_authentication.rb +203 -23
- data/lib/action_controller/integration.rb +126 -70
- data/lib/action_controller/layout.rb +36 -39
- data/lib/action_controller/middleware_stack.rb +119 -0
- data/lib/action_controller/middlewares.rb +13 -0
- data/lib/action_controller/mime_responds.rb +19 -4
- data/lib/action_controller/mime_type.rb +8 -0
- data/lib/action_controller/params_parser.rb +71 -0
- data/lib/action_controller/performance_test.rb +0 -1
- data/lib/action_controller/polymorphic_routes.rb +36 -30
- data/lib/action_controller/reloader.rb +14 -0
- data/lib/action_controller/request.rb +107 -499
- data/lib/action_controller/request_forgery_protection.rb +7 -39
- data/lib/action_controller/rescue.rb +55 -35
- data/lib/action_controller/resources.rb +34 -31
- data/lib/action_controller/response.rb +99 -57
- data/lib/action_controller/rewindable_input.rb +28 -0
- data/lib/action_controller/routing.rb +7 -7
- data/lib/action_controller/routing/builder.rb +4 -1
- data/lib/action_controller/routing/optimisations.rb +1 -1
- data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
- data/lib/action_controller/routing/route.rb +15 -5
- data/lib/action_controller/routing/route_set.rb +82 -35
- data/lib/action_controller/routing/segments.rb +35 -0
- data/lib/action_controller/session/abstract_store.rb +181 -0
- data/lib/action_controller/session/cookie_store.rb +197 -175
- data/lib/action_controller/session/mem_cache_store.rb +36 -83
- data/lib/action_controller/session_management.rb +26 -134
- data/lib/action_controller/streaming.rb +24 -7
- data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
- data/lib/action_controller/templates/rescues/template_error.erb +2 -2
- data/lib/action_controller/test_case.rb +87 -30
- data/lib/action_controller/test_process.rb +145 -104
- data/lib/action_controller/uploaded_file.rb +44 -0
- data/lib/action_controller/url_rewriter.rb +3 -6
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
- data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
- data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
- data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
- data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
- data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
- data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
- data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
- data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
- data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
- data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
- data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
- data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
- data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
- data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
- data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
- data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
- data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
- data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
- data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
- data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
- data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
- data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
- data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
- data/lib/action_controller/verification.rb +1 -1
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +22 -17
- data/lib/action_view/base.rb +53 -79
- data/lib/action_view/erb/util.rb +38 -0
- data/lib/action_view/helpers.rb +24 -5
- data/lib/action_view/helpers/active_record_helper.rb +2 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
- data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
- data/lib/action_view/helpers/benchmark_helper.rb +26 -5
- data/lib/action_view/helpers/date_helper.rb +82 -7
- data/lib/action_view/helpers/form_helper.rb +295 -64
- data/lib/action_view/helpers/form_options_helper.rb +160 -18
- data/lib/action_view/helpers/form_tag_helper.rb +2 -2
- data/lib/action_view/helpers/number_helper.rb +31 -18
- data/lib/action_view/helpers/prototype_helper.rb +2 -12
- data/lib/action_view/helpers/sanitize_helper.rb +0 -10
- data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
- data/lib/action_view/helpers/tag_helper.rb +3 -4
- data/lib/action_view/helpers/text_helper.rb +99 -122
- data/lib/action_view/helpers/translation_helper.rb +19 -1
- data/lib/action_view/helpers/url_helper.rb +25 -2
- data/lib/action_view/inline_template.rb +1 -1
- data/lib/action_view/locale/en.yml +19 -1
- data/lib/action_view/partials.rb +46 -9
- data/lib/action_view/paths.rb +28 -84
- data/lib/action_view/reloadable_template.rb +117 -0
- data/lib/action_view/renderable.rb +28 -35
- data/lib/action_view/renderable_partial.rb +3 -4
- data/lib/action_view/template.rb +172 -31
- data/lib/action_view/template_error.rb +8 -9
- data/lib/action_view/template_handler.rb +1 -1
- data/lib/action_view/template_handlers.rb +9 -6
- data/lib/action_view/template_handlers/erb.rb +2 -39
- data/lib/action_view/template_handlers/rjs.rb +1 -0
- data/lib/action_view/test_case.rb +27 -1
- data/test/abstract_unit.rb +23 -17
- data/test/active_record_unit.rb +5 -4
- data/test/activerecord/active_record_store_test.rb +139 -106
- data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
- data/test/controller/action_pack_assertions_test.rb +25 -23
- data/test/controller/addresses_render_test.rb +3 -6
- data/test/controller/assert_select_test.rb +83 -70
- data/test/controller/base_test.rb +11 -13
- data/test/controller/benchmark_test.rb +3 -3
- data/test/controller/caching_test.rb +34 -24
- data/test/controller/capture_test.rb +3 -6
- data/test/controller/content_type_test.rb +3 -6
- data/test/controller/cookie_test.rb +31 -66
- data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
- data/test/controller/dispatcher_test.rb +23 -28
- data/test/controller/fake_models.rb +8 -0
- data/test/controller/filters_test.rb +6 -2
- data/test/controller/flash_test.rb +2 -6
- data/test/controller/helper_test.rb +15 -1
- data/test/controller/html-scanner/document_test.rb +1 -1
- data/test/controller/html-scanner/sanitizer_test.rb +1 -1
- data/test/controller/http_basic_authentication_test.rb +88 -0
- data/test/controller/http_digest_authentication_test.rb +178 -0
- data/test/controller/integration_test.rb +56 -52
- data/test/controller/layout_test.rb +46 -44
- data/test/controller/middleware_stack_test.rb +90 -0
- data/test/controller/mime_responds_test.rb +7 -11
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/polymorphic_routes_test.rb +235 -151
- data/test/controller/rack_test.rb +52 -81
- data/test/controller/redirect_test.rb +6 -14
- data/test/controller/render_test.rb +273 -60
- data/test/controller/request/json_params_parsing_test.rb +45 -0
- data/test/controller/request/multipart_params_parsing_test.rb +223 -0
- data/test/controller/request/query_string_parsing_test.rb +120 -0
- data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
- data/test/controller/request/xml_params_parsing_test.rb +88 -0
- data/test/controller/request_forgery_protection_test.rb +17 -98
- data/test/controller/request_test.rb +45 -530
- data/test/controller/rescue_test.rb +45 -22
- data/test/controller/resources_test.rb +112 -37
- data/test/controller/routing_test.rb +1442 -1384
- data/test/controller/selector_test.rb +3 -3
- data/test/controller/send_file_test.rb +30 -3
- data/test/controller/session/cookie_store_test.rb +169 -240
- data/test/controller/session/mem_cache_store_test.rb +94 -148
- data/test/controller/session/test_session_test.rb +58 -0
- data/test/controller/test_test.rb +32 -13
- data/test/controller/url_rewriter_test.rb +54 -4
- data/test/controller/verification_test.rb +1 -1
- data/test/controller/view_paths_test.rb +15 -15
- data/test/controller/webservice_test.rb +178 -147
- data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
- data/test/fixtures/layouts/default_html.html.erb +1 -0
- data/test/fixtures/layouts/xhr.html.erb +2 -0
- data/test/fixtures/multipart/empty +10 -0
- data/test/fixtures/multipart/hello.txt +1 -0
- data/test/fixtures/multipart/none +9 -0
- data/test/fixtures/public/500.da.html +1 -0
- data/test/fixtures/quiz/questions/_question.html.erb +1 -0
- data/test/fixtures/replies.yml +1 -1
- data/test/fixtures/test/_one.html.erb +1 -0
- data/test/fixtures/test/_two.html.erb +1 -0
- data/test/fixtures/test/dont_pick_me +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hello_world.da.html.erb +1 -0
- data/test/fixtures/test/hello_world.erb~ +1 -0
- data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
- data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
- data/test/fixtures/test/malformed/malformed.erb~ +1 -0
- data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
- data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
- data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
- data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
- data/test/fixtures/test/utf8.html.erb +2 -0
- data/test/template/active_record_helper_i18n_test.rb +31 -33
- data/test/template/active_record_helper_test.rb +34 -0
- data/test/template/asset_tag_helper_test.rb +52 -14
- data/test/template/atom_feed_helper_test.rb +3 -5
- data/test/template/benchmark_helper_test.rb +50 -24
- data/test/template/compiled_templates_test.rb +177 -33
- data/test/template/date_helper_i18n_test.rb +88 -81
- data/test/template/date_helper_test.rb +427 -43
- data/test/template/form_helper_test.rb +243 -44
- data/test/template/form_options_helper_test.rb +631 -565
- data/test/template/form_tag_helper_test.rb +9 -2
- data/test/template/javascript_helper_test.rb +0 -5
- data/test/template/number_helper_i18n_test.rb +60 -48
- data/test/template/number_helper_test.rb +1 -0
- data/test/template/render_test.rb +117 -35
- data/test/template/test_test.rb +4 -6
- data/test/template/text_helper_test.rb +129 -50
- data/test/template/translation_helper_test.rb +23 -19
- data/test/template/url_helper_test.rb +35 -2
- data/test/view/test_case_test.rb +8 -0
- metadata +197 -23
- data/lib/action_controller/assertions.rb +0 -69
- data/lib/action_controller/caching/sql_cache.rb +0 -18
- data/lib/action_controller/cgi_ext/session.rb +0 -53
- data/lib/action_controller/components.rb +0 -169
- data/lib/action_controller/rack_process.rb +0 -297
- data/lib/action_controller/request_profiler.rb +0 -169
- data/lib/action_controller/session/active_record_store.rb +0 -340
- data/lib/action_controller/session/drb_server.rb +0 -32
- data/lib/action_controller/session/drb_store.rb +0 -35
- data/test/controller/cgi_test.rb +0 -269
- data/test/controller/components_test.rb +0 -156
- data/test/controller/http_authentication_test.rb +0 -54
- data/test/controller/integration_upload_test.rb +0 -43
- data/test/controller/session_fixation_test.rb +0 -89
- data/test/controller/session_management_test.rb +0 -178
- data/test/fixtures/test/hello_world.js +0 -1
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
|
3
|
+
class XmlParamsParsingTest < ActionController::IntegrationTest
|
4
|
+
class TestController < ActionController::Base
|
5
|
+
class << self
|
6
|
+
attr_accessor :last_request_parameters
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse
|
10
|
+
self.class.last_request_parameters = request.request_parameters
|
11
|
+
head :ok
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
TestController.last_request_parameters = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
test "parses hash params" do
|
20
|
+
with_test_routing do
|
21
|
+
xml = "<person><name>David</name></person>"
|
22
|
+
post "/parse", xml, default_headers
|
23
|
+
assert_response :ok
|
24
|
+
assert_equal({"person" => {"name" => "David"}}, TestController.last_request_parameters)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
test "parses single file" do
|
29
|
+
with_test_routing do
|
30
|
+
xml = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></person>"
|
31
|
+
post "/parse", xml, default_headers
|
32
|
+
assert_response :ok
|
33
|
+
|
34
|
+
person = TestController.last_request_parameters
|
35
|
+
assert_equal "image/jpg", person['person']['avatar'].content_type
|
36
|
+
assert_equal "me.jpg", person['person']['avatar'].original_filename
|
37
|
+
assert_equal "ABC", person['person']['avatar'].read
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test "parses multiple files" do
|
42
|
+
xml = <<-end_body
|
43
|
+
<person>
|
44
|
+
<name>David</name>
|
45
|
+
<avatars>
|
46
|
+
<avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar>
|
47
|
+
<avatar type='file' name='you.gif' content_type='image/gif'>#{ActiveSupport::Base64.encode64('DEF')}</avatar>
|
48
|
+
</avatars>
|
49
|
+
</person>
|
50
|
+
end_body
|
51
|
+
|
52
|
+
with_test_routing do
|
53
|
+
post "/parse", xml, default_headers
|
54
|
+
assert_response :ok
|
55
|
+
end
|
56
|
+
|
57
|
+
person = TestController.last_request_parameters
|
58
|
+
|
59
|
+
assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
|
60
|
+
assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
|
61
|
+
assert_equal "ABC", person['person']['avatars']['avatar'].first.read
|
62
|
+
|
63
|
+
assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
|
64
|
+
assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
|
65
|
+
assert_equal "DEF", person['person']['avatars']['avatar'].last.read
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def with_test_routing
|
70
|
+
with_routing do |set|
|
71
|
+
set.draw do |map|
|
72
|
+
map.connect ':action', :controller => "xml_params_parsing_test/test"
|
73
|
+
end
|
74
|
+
yield
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_headers
|
79
|
+
{'CONTENT_TYPE' => 'application/xml'}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class LegacyXmlParamsParsingTest < XmlParamsParsingTest
|
84
|
+
private
|
85
|
+
def default_headers
|
86
|
+
{'HTTP_X_POST_DATA_FORMAT' => 'xml'}
|
87
|
+
end
|
88
|
+
end
|
@@ -5,13 +5,6 @@ ActionController::Routing::Routes.draw do |map|
|
|
5
5
|
map.connect ':controller/:action/:id'
|
6
6
|
end
|
7
7
|
|
8
|
-
# simulates cookie session store
|
9
|
-
class FakeSessionDbMan
|
10
|
-
def self.generate_digest(data)
|
11
|
-
Digest::SHA1.hexdigest("secure")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
8
|
# common controller actions
|
16
9
|
module RequestForgeryProtectionActions
|
17
10
|
def index
|
@@ -35,30 +28,11 @@ end
|
|
35
28
|
|
36
29
|
# sample controllers
|
37
30
|
class RequestForgeryProtectionController < ActionController::Base
|
38
|
-
include RequestForgeryProtectionActions
|
39
|
-
protect_from_forgery :only => :index, :secret => 'abc'
|
40
|
-
end
|
41
|
-
|
42
|
-
class RequestForgeryProtectionWithoutSecretController < ActionController::Base
|
43
|
-
include RequestForgeryProtectionActions
|
44
|
-
protect_from_forgery
|
45
|
-
end
|
46
|
-
|
47
|
-
# no token is given, assume the cookie store is used
|
48
|
-
class CsrfCookieMonsterController < ActionController::Base
|
49
31
|
include RequestForgeryProtectionActions
|
50
32
|
protect_from_forgery :only => :index
|
51
33
|
end
|
52
34
|
|
53
|
-
|
54
|
-
class SessionOffController < ActionController::Base
|
55
|
-
protect_from_forgery :secret => 'foobar'
|
56
|
-
session :off
|
57
|
-
def rescue_action(e) raise e end
|
58
|
-
include RequestForgeryProtectionActions
|
59
|
-
end
|
60
|
-
|
61
|
-
class FreeCookieController < CsrfCookieMonsterController
|
35
|
+
class FreeCookieController < RequestForgeryProtectionController
|
62
36
|
self.allow_forgery_protection = false
|
63
37
|
|
64
38
|
def index
|
@@ -105,17 +79,17 @@ module RequestForgeryProtectionTests
|
|
105
79
|
|
106
80
|
def test_should_not_allow_html_post_without_token
|
107
81
|
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
|
108
|
-
|
82
|
+
assert_raise(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
|
109
83
|
end
|
110
84
|
|
111
85
|
def test_should_not_allow_html_put_without_token
|
112
86
|
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
|
113
|
-
|
87
|
+
assert_raise(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
|
114
88
|
end
|
115
89
|
|
116
90
|
def test_should_not_allow_html_delete_without_token
|
117
91
|
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
|
118
|
-
|
92
|
+
assert_raise(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
|
119
93
|
end
|
120
94
|
|
121
95
|
def test_should_allow_api_formatted_post_without_token
|
@@ -137,42 +111,42 @@ module RequestForgeryProtectionTests
|
|
137
111
|
end
|
138
112
|
|
139
113
|
def test_should_not_allow_api_formatted_post_sent_as_url_encoded_form_without_token
|
140
|
-
|
114
|
+
assert_raise(ActionController::InvalidAuthenticityToken) do
|
141
115
|
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
|
142
116
|
post :index, :format => 'xml'
|
143
117
|
end
|
144
118
|
end
|
145
119
|
|
146
120
|
def test_should_not_allow_api_formatted_put_sent_as_url_encoded_form_without_token
|
147
|
-
|
121
|
+
assert_raise(ActionController::InvalidAuthenticityToken) do
|
148
122
|
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
|
149
123
|
put :index, :format => 'xml'
|
150
124
|
end
|
151
125
|
end
|
152
126
|
|
153
127
|
def test_should_not_allow_api_formatted_delete_sent_as_url_encoded_form_without_token
|
154
|
-
|
128
|
+
assert_raise(ActionController::InvalidAuthenticityToken) do
|
155
129
|
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
|
156
130
|
delete :index, :format => 'xml'
|
157
131
|
end
|
158
132
|
end
|
159
133
|
|
160
134
|
def test_should_not_allow_api_formatted_post_sent_as_multipart_form_without_token
|
161
|
-
|
135
|
+
assert_raise(ActionController::InvalidAuthenticityToken) do
|
162
136
|
@request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
|
163
137
|
post :index, :format => 'xml'
|
164
138
|
end
|
165
139
|
end
|
166
140
|
|
167
141
|
def test_should_not_allow_api_formatted_put_sent_as_multipart_form_without_token
|
168
|
-
|
142
|
+
assert_raise(ActionController::InvalidAuthenticityToken) do
|
169
143
|
@request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
|
170
144
|
put :index, :format => 'xml'
|
171
145
|
end
|
172
146
|
end
|
173
147
|
|
174
148
|
def test_should_not_allow_api_formatted_delete_sent_as_multipart_form_without_token
|
175
|
-
|
149
|
+
assert_raise(ActionController::InvalidAuthenticityToken) do
|
176
150
|
@request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
|
177
151
|
delete :index, :format => 'xml'
|
178
152
|
end
|
@@ -230,62 +204,28 @@ end
|
|
230
204
|
|
231
205
|
# OK let's get our test on
|
232
206
|
|
233
|
-
class RequestForgeryProtectionControllerTest <
|
207
|
+
class RequestForgeryProtectionControllerTest < ActionController::TestCase
|
234
208
|
include RequestForgeryProtectionTests
|
235
209
|
def setup
|
236
210
|
@controller = RequestForgeryProtectionController.new
|
237
211
|
@request = ActionController::TestRequest.new
|
238
212
|
@request.format = :html
|
239
213
|
@response = ActionController::TestResponse.new
|
240
|
-
|
241
|
-
def session_id() '123' end
|
242
|
-
end
|
243
|
-
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
|
244
|
-
ActionController::Base.request_forgery_protection_token = :authenticity_token
|
245
|
-
end
|
246
|
-
end
|
214
|
+
@token = "cf50faa3fe97702ca1ae"
|
247
215
|
|
248
|
-
|
249
|
-
def setup
|
250
|
-
@controller = RequestForgeryProtectionWithoutSecretController.new
|
251
|
-
@request = ActionController::TestRequest.new
|
252
|
-
@response = ActionController::TestResponse.new
|
253
|
-
class << @request.session
|
254
|
-
def session_id() '123' end
|
255
|
-
end
|
256
|
-
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
|
216
|
+
ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
|
257
217
|
ActionController::Base.request_forgery_protection_token = :authenticity_token
|
258
218
|
end
|
259
|
-
|
260
|
-
# def test_should_raise_error_without_secret
|
261
|
-
# assert_raises ActionController::InvalidAuthenticityToken do
|
262
|
-
# get :index
|
263
|
-
# end
|
264
|
-
# end
|
265
219
|
end
|
266
220
|
|
267
|
-
class
|
268
|
-
include RequestForgeryProtectionTests
|
269
|
-
def setup
|
270
|
-
@controller = CsrfCookieMonsterController.new
|
271
|
-
@request = ActionController::TestRequest.new
|
272
|
-
@response = ActionController::TestResponse.new
|
273
|
-
class << @request.session
|
274
|
-
attr_accessor :dbman
|
275
|
-
end
|
276
|
-
# simulate a cookie session store
|
277
|
-
@request.session.dbman = FakeSessionDbMan
|
278
|
-
@token = Digest::SHA1.hexdigest("secure")
|
279
|
-
ActionController::Base.request_forgery_protection_token = :authenticity_token
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
class FreeCookieControllerTest < Test::Unit::TestCase
|
221
|
+
class FreeCookieControllerTest < ActionController::TestCase
|
284
222
|
def setup
|
285
223
|
@controller = FreeCookieController.new
|
286
224
|
@request = ActionController::TestRequest.new
|
287
225
|
@response = ActionController::TestResponse.new
|
288
|
-
@token =
|
226
|
+
@token = "cf50faa3fe97702ca1ae"
|
227
|
+
|
228
|
+
ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
|
289
229
|
end
|
290
230
|
|
291
231
|
def test_should_not_render_form_with_token_tag
|
@@ -304,24 +244,3 @@ class FreeCookieControllerTest < Test::Unit::TestCase
|
|
304
244
|
end
|
305
245
|
end
|
306
246
|
end
|
307
|
-
|
308
|
-
class SessionOffControllerTest < Test::Unit::TestCase
|
309
|
-
def setup
|
310
|
-
@controller = SessionOffController.new
|
311
|
-
@request = ActionController::TestRequest.new
|
312
|
-
@response = ActionController::TestResponse.new
|
313
|
-
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
|
314
|
-
end
|
315
|
-
|
316
|
-
# TODO: Rewrite this test.
|
317
|
-
# This test was passing but for the wrong reason.
|
318
|
-
# Sessions aren't really being turned off, so an exception was raised
|
319
|
-
# because sessions weren't on - not because the token didn't match.
|
320
|
-
#
|
321
|
-
# def test_should_raise_correct_exception
|
322
|
-
# @request.session = {} # session(:off) doesn't appear to work with controller tests
|
323
|
-
# assert_raises(ActionController::InvalidAuthenticityToken) do
|
324
|
-
# post :index, :authenticity_token => @token, :format => :html
|
325
|
-
# end
|
326
|
-
# end
|
327
|
-
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'abstract_unit'
|
2
|
-
require 'action_controller/integration'
|
3
2
|
|
4
|
-
class RequestTest <
|
3
|
+
class RequestTest < ActiveSupport::TestCase
|
5
4
|
def setup
|
6
5
|
ActionController::Base.relative_url_root = nil
|
7
6
|
@request = ActionController::TestRequest.new
|
@@ -15,60 +14,69 @@ class RequestTest < Test::Unit::TestCase
|
|
15
14
|
assert_equal '0.0.0.0', @request.remote_ip
|
16
15
|
|
17
16
|
@request.remote_addr = '1.2.3.4'
|
18
|
-
assert_equal '1.2.3.4', @request.remote_ip
|
17
|
+
assert_equal '1.2.3.4', @request.remote_ip
|
19
18
|
|
20
19
|
@request.remote_addr = '1.2.3.4,3.4.5.6'
|
21
|
-
assert_equal '1.2.3.4', @request.remote_ip
|
20
|
+
assert_equal '1.2.3.4', @request.remote_ip
|
22
21
|
|
23
22
|
@request.env['HTTP_CLIENT_IP'] = '2.3.4.5'
|
24
|
-
assert_equal '1.2.3.4', @request.remote_ip
|
23
|
+
assert_equal '1.2.3.4', @request.remote_ip
|
25
24
|
|
26
25
|
@request.remote_addr = '192.168.0.1'
|
27
|
-
assert_equal '2.3.4.5', @request.remote_ip
|
26
|
+
assert_equal '2.3.4.5', @request.remote_ip
|
28
27
|
@request.env.delete 'HTTP_CLIENT_IP'
|
29
28
|
|
30
29
|
@request.remote_addr = '1.2.3.4'
|
31
30
|
@request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
|
32
|
-
assert_equal '1.2.3.4', @request.remote_ip
|
31
|
+
assert_equal '1.2.3.4', @request.remote_ip
|
33
32
|
|
34
33
|
@request.remote_addr = '127.0.0.1'
|
35
34
|
@request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
|
36
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
35
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
37
36
|
|
38
37
|
@request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,3.4.5.6'
|
39
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
38
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
40
39
|
|
41
40
|
@request.env['HTTP_X_FORWARDED_FOR'] = '172.16.0.1,3.4.5.6'
|
42
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
41
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
43
42
|
|
44
43
|
@request.env['HTTP_X_FORWARDED_FOR'] = '192.168.0.1,3.4.5.6'
|
45
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
44
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
46
45
|
|
47
46
|
@request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1,3.4.5.6'
|
48
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
47
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
49
48
|
|
50
49
|
@request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1, 10.0.0.1, 3.4.5.6'
|
51
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
50
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
52
51
|
|
53
52
|
@request.env['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,3.4.5.6'
|
54
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
53
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
55
54
|
|
56
55
|
@request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,192.168.0.1'
|
57
|
-
assert_equal 'unknown', @request.remote_ip
|
56
|
+
assert_equal 'unknown', @request.remote_ip
|
58
57
|
|
59
58
|
@request.env['HTTP_X_FORWARDED_FOR'] = '9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4'
|
60
|
-
assert_equal '3.4.5.6', @request.remote_ip
|
59
|
+
assert_equal '3.4.5.6', @request.remote_ip
|
61
60
|
|
62
61
|
@request.env['HTTP_CLIENT_IP'] = '8.8.8.8'
|
63
|
-
e =
|
64
|
-
@request.remote_ip
|
62
|
+
e = assert_raise(ActionController::ActionControllerError) {
|
63
|
+
@request.remote_ip
|
65
64
|
}
|
66
65
|
assert_match /IP spoofing attack/, e.message
|
67
66
|
assert_match /HTTP_X_FORWARDED_FOR="9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4"/, e.message
|
68
67
|
assert_match /HTTP_CLIENT_IP="8.8.8.8"/, e.message
|
69
68
|
|
69
|
+
# turn IP Spoofing detection off.
|
70
|
+
# This is useful for sites that are aimed at non-IP clients. The typical
|
71
|
+
# example is WAP. Since the cellular network is not IP based, it's a
|
72
|
+
# leap of faith to assume that their proxies are ever going to set the
|
73
|
+
# HTTP_CLIENT_IP/HTTP_X_FORWARDED_FOR headers properly.
|
74
|
+
ActionController::Base.ip_spoofing_check = false
|
75
|
+
assert_equal('8.8.8.8', @request.remote_ip)
|
76
|
+
ActionController::Base.ip_spoofing_check = true
|
77
|
+
|
70
78
|
@request.env['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 9.9.9.9'
|
71
|
-
assert_equal '8.8.8.8', @request.remote_ip
|
79
|
+
assert_equal '8.8.8.8', @request.remote_ip
|
72
80
|
|
73
81
|
@request.env.delete 'HTTP_CLIENT_IP'
|
74
82
|
@request.env.delete 'HTTP_X_FORWARDED_FOR'
|
@@ -181,8 +189,8 @@ class RequestTest < Test::Unit::TestCase
|
|
181
189
|
@request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1"
|
182
190
|
@request.env['SCRIPT_NAME'] = "/path/dispatch.rb"
|
183
191
|
@request.set_REQUEST_URI nil
|
184
|
-
assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
|
185
|
-
assert_equal "/of/some/uri", @request.path
|
192
|
+
assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
|
193
|
+
assert_equal "/of/some/uri", @request.path
|
186
194
|
ActionController::Base.relative_url_root = nil
|
187
195
|
|
188
196
|
@request.env['PATH_INFO'] = "/path/of/some/uri"
|
@@ -217,12 +225,12 @@ class RequestTest < Test::Unit::TestCase
|
|
217
225
|
|
218
226
|
@request.set_REQUEST_URI '/hieraki/dispatch.cgi'
|
219
227
|
ActionController::Base.relative_url_root = '/hieraki'
|
220
|
-
assert_equal "/dispatch.cgi", @request.path
|
228
|
+
assert_equal "/dispatch.cgi", @request.path
|
221
229
|
ActionController::Base.relative_url_root = nil
|
222
230
|
|
223
231
|
@request.set_REQUEST_URI '/hieraki/dispatch.cgi'
|
224
232
|
ActionController::Base.relative_url_root = '/foo'
|
225
|
-
assert_equal "/hieraki/dispatch.cgi", @request.path
|
233
|
+
assert_equal "/hieraki/dispatch.cgi", @request.path
|
226
234
|
ActionController::Base.relative_url_root = nil
|
227
235
|
|
228
236
|
# This test ensures that Rails uses REQUEST_URI over PATH_INFO
|
@@ -230,8 +238,8 @@ class RequestTest < Test::Unit::TestCase
|
|
230
238
|
@request.env['REQUEST_URI'] = "/some/path"
|
231
239
|
@request.env['PATH_INFO'] = "/another/path"
|
232
240
|
@request.env['SCRIPT_NAME'] = "/dispatch.cgi"
|
233
|
-
assert_equal "/some/path", @request.request_uri
|
234
|
-
assert_equal "/some/path", @request.path
|
241
|
+
assert_equal "/some/path", @request.request_uri
|
242
|
+
assert_equal "/some/path", @request.path
|
235
243
|
end
|
236
244
|
|
237
245
|
def test_host_with_default_port
|
@@ -247,13 +255,13 @@ class RequestTest < Test::Unit::TestCase
|
|
247
255
|
end
|
248
256
|
|
249
257
|
def test_server_software
|
250
|
-
assert_equal nil, @request.server_software
|
258
|
+
assert_equal nil, @request.server_software
|
251
259
|
|
252
260
|
@request.env['SERVER_SOFTWARE'] = 'Apache3.422'
|
253
|
-
assert_equal 'apache', @request.server_software
|
261
|
+
assert_equal 'apache', @request.server_software
|
254
262
|
|
255
263
|
@request.env['SERVER_SOFTWARE'] = 'lighttpd(1.1.4)'
|
256
|
-
assert_equal 'lighttpd', @request.server_software
|
264
|
+
assert_equal 'lighttpd', @request.server_software
|
257
265
|
end
|
258
266
|
|
259
267
|
def test_xml_http_request
|
@@ -289,25 +297,23 @@ class RequestTest < Test::Unit::TestCase
|
|
289
297
|
end
|
290
298
|
|
291
299
|
def test_invalid_http_method_raises_exception
|
292
|
-
|
300
|
+
assert_raise(ActionController::UnknownHttpMethod) do
|
293
301
|
self.request_method = :random_method
|
302
|
+
@request.request_method
|
294
303
|
end
|
295
304
|
end
|
296
305
|
|
297
306
|
def test_allow_method_hacking_on_post
|
298
|
-
self.request_method = :post
|
299
307
|
[:get, :head, :options, :put, :post, :delete].each do |method|
|
300
|
-
|
301
|
-
@request.request_method(true)
|
308
|
+
self.request_method = method
|
302
309
|
assert_equal(method == :head ? :get : method, @request.method)
|
303
310
|
end
|
304
311
|
end
|
305
312
|
|
306
313
|
def test_invalid_method_hacking_on_post_raises_exception
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
@request.request_method(true)
|
314
|
+
assert_raise(ActionController::UnknownHttpMethod) do
|
315
|
+
self.request_method = :_random_method
|
316
|
+
@request.request_method
|
311
317
|
end
|
312
318
|
end
|
313
319
|
|
@@ -385,8 +391,8 @@ class RequestTest < Test::Unit::TestCase
|
|
385
391
|
end
|
386
392
|
|
387
393
|
def test_parameters
|
388
|
-
@request.
|
389
|
-
@request.
|
394
|
+
@request.stubs(:request_parameters).returns({ "foo" => 1 })
|
395
|
+
@request.stubs(:query_parameters).returns({ "bar" => 2 })
|
390
396
|
|
391
397
|
assert_equal({"foo" => 1, "bar" => 2}, @request.parameters)
|
392
398
|
assert_equal({"foo" => 1}, @request.request_parameters)
|
@@ -396,497 +402,6 @@ class RequestTest < Test::Unit::TestCase
|
|
396
402
|
protected
|
397
403
|
def request_method=(method)
|
398
404
|
@request.env['REQUEST_METHOD'] = method.to_s.upcase
|
399
|
-
@request.request_method
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase
|
404
|
-
def setup
|
405
|
-
@query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
|
406
|
-
@query_string_with_empty = "action=create_customer&full_name="
|
407
|
-
@query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3"
|
408
|
-
@query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does"
|
409
|
-
@query_string_with_multiple_of_same_name =
|
410
|
-
"action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
|
411
|
-
@query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
|
412
|
-
@query_string_without_equal = "action"
|
413
|
-
@query_string_with_many_ampersands =
|
414
|
-
"&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
|
415
|
-
@query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
|
416
|
-
end
|
417
|
-
|
418
|
-
def test_query_string
|
419
|
-
assert_equal(
|
420
|
-
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
|
421
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string)
|
422
|
-
)
|
423
|
-
end
|
424
|
-
|
425
|
-
def test_deep_query_string
|
426
|
-
expected = {'x' => {'y' => {'z' => '10'}}}
|
427
|
-
assert_equal(expected, ActionController::AbstractRequest.parse_query_parameters('x[y][z]=10'))
|
428
|
-
end
|
429
|
-
|
430
|
-
def test_deep_query_string_with_array
|
431
|
-
assert_equal({'x' => {'y' => {'z' => ['10']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10'))
|
432
|
-
assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
|
433
|
-
end
|
434
|
-
|
435
|
-
def test_deep_query_string_with_array_of_hash
|
436
|
-
assert_equal({'x' => {'y' => [{'z' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10'))
|
437
|
-
assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=10'))
|
438
|
-
end
|
439
|
-
|
440
|
-
def test_deep_query_string_with_array_of_hashes_with_one_pair
|
441
|
-
assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20'))
|
442
|
-
assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"])
|
443
|
-
assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z])
|
444
|
-
end
|
445
|
-
|
446
|
-
def test_deep_query_string_with_array_of_hashes_with_multiple_pairs
|
447
|
-
assert_equal(
|
448
|
-
{'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
|
449
|
-
ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b')
|
450
|
-
)
|
451
|
-
end
|
452
|
-
|
453
|
-
def test_query_string_with_nil
|
454
|
-
assert_equal(
|
455
|
-
{ "action" => "create_customer", "full_name" => ''},
|
456
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty)
|
457
|
-
)
|
458
|
-
end
|
459
|
-
|
460
|
-
def test_query_string_with_array
|
461
|
-
assert_equal(
|
462
|
-
{ "action" => "create_customer", "selected" => ["1", "2", "3"]},
|
463
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_array)
|
464
|
-
)
|
465
|
-
end
|
466
|
-
|
467
|
-
def test_query_string_with_amps
|
468
|
-
assert_equal(
|
469
|
-
{ "action" => "create_customer", "name" => "Don't & Does"},
|
470
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_amps)
|
471
|
-
)
|
472
|
-
end
|
473
|
-
|
474
|
-
def test_query_string_with_multiple_of_same_name
|
475
|
-
assert_equal(
|
476
|
-
{ "action" => "update_order", "full_name" => "Lau Taarnskov", "products" => "4" },
|
477
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_multiple_of_same_name)
|
478
|
-
)
|
479
|
-
end
|
480
|
-
|
481
|
-
def test_query_string_with_many_equal
|
482
|
-
assert_equal(
|
483
|
-
{ "action" => "create_customer", "full_name" => "abc=def=ghi"},
|
484
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_equal)
|
485
|
-
)
|
486
|
-
end
|
487
|
-
|
488
|
-
def test_query_string_without_equal
|
489
|
-
assert_equal(
|
490
|
-
{ "action" => nil },
|
491
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_without_equal)
|
492
|
-
)
|
493
|
-
end
|
494
|
-
|
495
|
-
def test_query_string_with_empty_key
|
496
|
-
assert_equal(
|
497
|
-
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
|
498
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty_key)
|
499
|
-
)
|
500
|
-
end
|
501
|
-
|
502
|
-
def test_query_string_with_many_ampersands
|
503
|
-
assert_equal(
|
504
|
-
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
|
505
|
-
ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_ampersands)
|
506
|
-
)
|
507
|
-
end
|
508
|
-
|
509
|
-
def test_unbalanced_query_string_with_array
|
510
|
-
assert_equal(
|
511
|
-
{'location' => ["1", "2"], 'age_group' => ["2"]},
|
512
|
-
ActionController::AbstractRequest.parse_query_parameters("location[]=1&location[]=2&age_group[]=2")
|
513
|
-
)
|
514
|
-
assert_equal(
|
515
|
-
{'location' => ["1", "2"], 'age_group' => ["2"]},
|
516
|
-
ActionController::AbstractRequest.parse_request_parameters({'location[]' => ["1", "2"],
|
517
|
-
'age_group[]' => ["2"]})
|
518
|
-
)
|
519
|
-
end
|
520
|
-
|
521
|
-
def test_request_hash_parsing
|
522
|
-
query = {
|
523
|
-
"note[viewers][viewer][][type]" => ["User", "Group"],
|
524
|
-
"note[viewers][viewer][][id]" => ["1", "2"]
|
525
|
-
}
|
526
|
-
|
527
|
-
expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
|
528
|
-
|
529
|
-
assert_equal(expected, ActionController::AbstractRequest.parse_request_parameters(query))
|
530
|
-
end
|
531
|
-
|
532
|
-
def test_parse_params
|
533
|
-
input = {
|
534
|
-
"customers[boston][first][name]" => [ "David" ],
|
535
|
-
"customers[boston][first][url]" => [ "http://David" ],
|
536
|
-
"customers[boston][second][name]" => [ "Allan" ],
|
537
|
-
"customers[boston][second][url]" => [ "http://Allan" ],
|
538
|
-
"something_else" => [ "blah" ],
|
539
|
-
"something_nil" => [ nil ],
|
540
|
-
"something_empty" => [ "" ],
|
541
|
-
"products[first]" => [ "Apple Computer" ],
|
542
|
-
"products[second]" => [ "Pc" ],
|
543
|
-
"" => [ 'Save' ]
|
544
|
-
}
|
545
|
-
|
546
|
-
expected_output = {
|
547
|
-
"customers" => {
|
548
|
-
"boston" => {
|
549
|
-
"first" => {
|
550
|
-
"name" => "David",
|
551
|
-
"url" => "http://David"
|
552
|
-
},
|
553
|
-
"second" => {
|
554
|
-
"name" => "Allan",
|
555
|
-
"url" => "http://Allan"
|
556
|
-
}
|
557
|
-
}
|
558
|
-
},
|
559
|
-
"something_else" => "blah",
|
560
|
-
"something_empty" => "",
|
561
|
-
"something_nil" => "",
|
562
|
-
"products" => {
|
563
|
-
"first" => "Apple Computer",
|
564
|
-
"second" => "Pc"
|
565
|
-
}
|
566
|
-
}
|
567
|
-
|
568
|
-
assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
|
569
|
-
end
|
570
|
-
|
571
|
-
UploadedStringIO = ActionController::UploadedStringIO
|
572
|
-
class MockUpload < UploadedStringIO
|
573
|
-
def initialize(content_type, original_path, *args)
|
574
|
-
self.content_type = content_type
|
575
|
-
self.original_path = original_path
|
576
|
-
super *args
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
def test_parse_params_from_multipart_upload
|
581
|
-
file = MockUpload.new('img/jpeg', 'foo.jpg')
|
582
|
-
ie_file = MockUpload.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
|
583
|
-
non_file_text_part = MockUpload.new('text/plain', '', 'abc')
|
584
|
-
|
585
|
-
input = {
|
586
|
-
"something" => [ UploadedStringIO.new("") ],
|
587
|
-
"array_of_stringios" => [[ UploadedStringIO.new("One"), UploadedStringIO.new("Two") ]],
|
588
|
-
"mixed_types_array" => [[ UploadedStringIO.new("Three"), "NotStringIO" ]],
|
589
|
-
"mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", UploadedStringIO.new("StringIO")]],
|
590
|
-
"ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", UploadedStringIO.new("StringIO")]],
|
591
|
-
"products[string]" => [ UploadedStringIO.new("Apple Computer") ],
|
592
|
-
"products[file]" => [ file ],
|
593
|
-
"ie_products[string]" => [ UploadedStringIO.new("Microsoft") ],
|
594
|
-
"ie_products[file]" => [ ie_file ],
|
595
|
-
"text_part" => [non_file_text_part]
|
596
|
-
}
|
597
|
-
|
598
|
-
expected_output = {
|
599
|
-
"something" => "",
|
600
|
-
"array_of_stringios" => ["One", "Two"],
|
601
|
-
"mixed_types_array" => [ "Three", "NotStringIO" ],
|
602
|
-
"mixed_types_as_checkboxes" => {
|
603
|
-
"strings" => {
|
604
|
-
"nested" => [ file, "String", "StringIO" ]
|
605
|
-
},
|
606
|
-
},
|
607
|
-
"ie_mixed_types_as_checkboxes" => {
|
608
|
-
"strings" => {
|
609
|
-
"nested" => [ ie_file, "String", "StringIO" ]
|
610
|
-
},
|
611
|
-
},
|
612
|
-
"products" => {
|
613
|
-
"string" => "Apple Computer",
|
614
|
-
"file" => file
|
615
|
-
},
|
616
|
-
"ie_products" => {
|
617
|
-
"string" => "Microsoft",
|
618
|
-
"file" => ie_file
|
619
|
-
},
|
620
|
-
"text_part" => "abc"
|
621
|
-
}
|
622
|
-
|
623
|
-
params = ActionController::AbstractRequest.parse_request_parameters(input)
|
624
|
-
assert_equal expected_output, params
|
625
|
-
|
626
|
-
# Lone filenames are preserved.
|
627
|
-
assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
628
|
-
assert_equal 'foo.jpg', params['products']['file'].original_filename
|
629
|
-
|
630
|
-
# But full Windows paths are reduced to their basename.
|
631
|
-
assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
632
|
-
assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
|
633
|
-
end
|
634
|
-
|
635
|
-
def test_parse_params_with_file
|
636
|
-
input = {
|
637
|
-
"customers[boston][first][name]" => [ "David" ],
|
638
|
-
"something_else" => [ "blah" ],
|
639
|
-
"logo" => [ File.new(File.dirname(__FILE__) + "/cgi_test.rb").path ]
|
640
|
-
}
|
641
|
-
|
642
|
-
expected_output = {
|
643
|
-
"customers" => {
|
644
|
-
"boston" => {
|
645
|
-
"first" => {
|
646
|
-
"name" => "David"
|
647
|
-
}
|
648
|
-
}
|
649
|
-
},
|
650
|
-
"something_else" => "blah",
|
651
|
-
"logo" => File.new(File.dirname(__FILE__) + "/cgi_test.rb").path,
|
652
|
-
}
|
653
|
-
|
654
|
-
assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
|
655
|
-
end
|
656
|
-
|
657
|
-
def test_parse_params_with_array
|
658
|
-
input = { "selected[]" => [ "1", "2", "3" ] }
|
659
|
-
|
660
|
-
expected_output = { "selected" => [ "1", "2", "3" ] }
|
661
|
-
|
662
|
-
assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
|
663
|
-
end
|
664
|
-
|
665
|
-
def test_parse_params_with_non_alphanumeric_name
|
666
|
-
input = { "a/b[c]" => %w(d) }
|
667
|
-
expected = { "a/b" => { "c" => "d" }}
|
668
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
669
|
-
end
|
670
|
-
|
671
|
-
def test_parse_params_with_single_brackets_in_middle
|
672
|
-
input = { "a/b[c]d" => %w(e) }
|
673
|
-
expected = { "a/b" => {} }
|
674
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
675
|
-
end
|
676
|
-
|
677
|
-
def test_parse_params_with_separated_brackets
|
678
|
-
input = { "a/b@[c]d[e]" => %w(f) }
|
679
|
-
expected = { "a/b@" => { }}
|
680
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
681
|
-
end
|
682
|
-
|
683
|
-
def test_parse_params_with_separated_brackets_and_array
|
684
|
-
input = { "a/b@[c]d[e][]" => %w(f) }
|
685
|
-
expected = { "a/b@" => { }}
|
686
|
-
assert_equal expected , ActionController::AbstractRequest.parse_request_parameters(input)
|
687
|
-
end
|
688
|
-
|
689
|
-
def test_parse_params_with_unmatched_brackets_and_array
|
690
|
-
input = { "a/b@[c][d[e][]" => %w(f) }
|
691
|
-
expected = { "a/b@" => { "c" => { }}}
|
692
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
693
|
-
end
|
694
|
-
|
695
|
-
def test_parse_params_with_nil_key
|
696
|
-
input = { nil => nil, "test2" => %w(value1) }
|
697
|
-
expected = { "test2" => "value1" }
|
698
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
699
|
-
end
|
700
|
-
|
701
|
-
def test_parse_params_with_array_prefix_and_hashes
|
702
|
-
input = { "a[][b][c]" => %w(d) }
|
703
|
-
expected = {"a" => [{"b" => {"c" => "d"}}]}
|
704
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
705
|
-
end
|
706
|
-
|
707
|
-
def test_parse_params_with_complex_nesting
|
708
|
-
input = { "a[][b][c][][d][]" => %w(e) }
|
709
|
-
expected = {"a" => [{"b" => {"c" => [{"d" => ["e"]}]}}]}
|
710
|
-
assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
|
711
|
-
end
|
712
|
-
end
|
713
|
-
|
714
|
-
class MultipartRequestParameterParsingTest < Test::Unit::TestCase
|
715
|
-
FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
|
716
|
-
|
717
|
-
def test_single_parameter
|
718
|
-
params = process('single_parameter')
|
719
|
-
assert_equal({ 'foo' => 'bar' }, params)
|
720
|
-
end
|
721
|
-
|
722
|
-
def test_bracketed_param
|
723
|
-
assert_equal({ 'foo' => { 'baz' => 'bar'}}, process('bracketed_param'))
|
724
|
-
end
|
725
|
-
|
726
|
-
def test_text_file
|
727
|
-
params = process('text_file')
|
728
|
-
assert_equal %w(file foo), params.keys.sort
|
729
|
-
assert_equal 'bar', params['foo']
|
730
|
-
|
731
|
-
file = params['file']
|
732
|
-
assert_kind_of StringIO, file
|
733
|
-
assert_equal 'file.txt', file.original_filename
|
734
|
-
assert_equal "text/plain", file.content_type
|
735
|
-
assert_equal 'contents', file.read
|
736
|
-
end
|
737
|
-
|
738
|
-
def test_boundary_problem_file
|
739
|
-
params = process('boundary_problem_file')
|
740
|
-
assert_equal %w(file foo), params.keys.sort
|
741
|
-
|
742
|
-
file = params['file']
|
743
|
-
foo = params['foo']
|
744
|
-
|
745
|
-
assert_kind_of Tempfile, file
|
746
|
-
|
747
|
-
assert_equal 'file.txt', file.original_filename
|
748
|
-
assert_equal "text/plain", file.content_type
|
749
|
-
|
750
|
-
assert_equal 'bar', foo
|
751
|
-
end
|
752
|
-
|
753
|
-
def test_large_text_file
|
754
|
-
params = process('large_text_file')
|
755
|
-
assert_equal %w(file foo), params.keys.sort
|
756
|
-
assert_equal 'bar', params['foo']
|
757
|
-
|
758
|
-
file = params['file']
|
759
|
-
|
760
|
-
assert_kind_of Tempfile, file
|
761
|
-
|
762
|
-
assert_equal 'file.txt', file.original_filename
|
763
|
-
assert_equal "text/plain", file.content_type
|
764
|
-
assert ('a' * 20480) == file.read
|
765
|
-
end
|
766
|
-
|
767
|
-
uses_mocha "test_no_rewind_stream" do
|
768
|
-
def test_no_rewind_stream
|
769
|
-
# Ensures that parse_multipart_form_parameters works with streams that cannot be rewound
|
770
|
-
file = File.open(File.join(FIXTURE_PATH, 'large_text_file'), 'rb')
|
771
|
-
file.expects(:rewind).raises(Errno::ESPIPE)
|
772
|
-
params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
|
773
|
-
assert_not_equal 0, file.pos # file was not rewound after reading
|
774
|
-
end
|
775
|
-
end
|
776
|
-
|
777
|
-
def test_binary_file
|
778
|
-
params = process('binary_file')
|
779
|
-
assert_equal %w(file flowers foo), params.keys.sort
|
780
|
-
assert_equal 'bar', params['foo']
|
781
|
-
|
782
|
-
file = params['file']
|
783
|
-
assert_kind_of StringIO, file
|
784
|
-
assert_equal 'file.csv', file.original_filename
|
785
|
-
assert_nil file.content_type
|
786
|
-
assert_equal 'contents', file.read
|
787
|
-
|
788
|
-
file = params['flowers']
|
789
|
-
assert_kind_of StringIO, file
|
790
|
-
assert_equal 'flowers.jpg', file.original_filename
|
791
|
-
assert_equal "image/jpeg", file.content_type
|
792
|
-
assert_equal 19512, file.size
|
793
|
-
#assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
|
794
|
-
end
|
795
|
-
|
796
|
-
def test_mixed_files
|
797
|
-
params = process('mixed_files')
|
798
|
-
assert_equal %w(files foo), params.keys.sort
|
799
|
-
assert_equal 'bar', params['foo']
|
800
|
-
|
801
|
-
# Ruby CGI doesn't handle multipart/mixed for us.
|
802
|
-
files = params['files']
|
803
|
-
assert_kind_of String, files
|
804
|
-
files.force_encoding('ASCII-8BIT') if files.respond_to?(:force_encoding)
|
805
|
-
assert_equal 19756, files.size
|
806
|
-
end
|
807
|
-
|
808
|
-
private
|
809
|
-
def process(name)
|
810
|
-
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
|
811
|
-
params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
|
812
|
-
assert_equal 0, file.pos # file was rewound after reading
|
813
|
-
params
|
814
|
-
end
|
815
|
-
end
|
816
|
-
end
|
817
|
-
|
818
|
-
class XmlParamsParsingTest < Test::Unit::TestCase
|
819
|
-
def test_hash_params
|
820
|
-
person = parse_body("<person><name>David</name></person>")[:person]
|
821
|
-
assert_kind_of Hash, person
|
822
|
-
assert_equal 'David', person['name']
|
823
|
-
end
|
824
|
-
|
825
|
-
def test_single_file
|
826
|
-
person = parse_body("<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></person>")
|
827
|
-
|
828
|
-
assert_equal "image/jpg", person['person']['avatar'].content_type
|
829
|
-
assert_equal "me.jpg", person['person']['avatar'].original_filename
|
830
|
-
assert_equal "ABC", person['person']['avatar'].read
|
831
|
-
end
|
832
|
-
|
833
|
-
def test_multiple_files
|
834
|
-
person = parse_body(<<-end_body)
|
835
|
-
<person>
|
836
|
-
<name>David</name>
|
837
|
-
<avatars>
|
838
|
-
<avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar>
|
839
|
-
<avatar type='file' name='you.gif' content_type='image/gif'>#{ActiveSupport::Base64.encode64('DEF')}</avatar>
|
840
|
-
</avatars>
|
841
|
-
</person>
|
842
|
-
end_body
|
843
|
-
|
844
|
-
assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
|
845
|
-
assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
|
846
|
-
assert_equal "ABC", person['person']['avatars']['avatar'].first.read
|
847
|
-
|
848
|
-
assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
|
849
|
-
assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
|
850
|
-
assert_equal "DEF", person['person']['avatars']['avatar'].last.read
|
851
|
-
end
|
852
|
-
|
853
|
-
private
|
854
|
-
def parse_body(body)
|
855
|
-
env = { 'rack.input' => StringIO.new(body),
|
856
|
-
'CONTENT_TYPE' => 'application/xml',
|
857
|
-
'CONTENT_LENGTH' => body.size.to_s }
|
858
|
-
ActionController::RackRequest.new(env).request_parameters
|
859
|
-
end
|
860
|
-
end
|
861
|
-
|
862
|
-
class LegacyXmlParamsParsingTest < XmlParamsParsingTest
|
863
|
-
private
|
864
|
-
def parse_body(body)
|
865
|
-
env = { 'rack.input' => StringIO.new(body),
|
866
|
-
'HTTP_X_POST_DATA_FORMAT' => 'xml',
|
867
|
-
'CONTENT_LENGTH' => body.size.to_s }
|
868
|
-
ActionController::RackRequest.new(env).request_parameters
|
869
|
-
end
|
870
|
-
end
|
871
|
-
|
872
|
-
class JsonParamsParsingTest < Test::Unit::TestCase
|
873
|
-
def test_hash_params_for_application_json
|
874
|
-
person = parse_body({:person => {:name => "David"}}.to_json,'application/json')[:person]
|
875
|
-
assert_kind_of Hash, person
|
876
|
-
assert_equal 'David', person['name']
|
877
|
-
end
|
878
|
-
|
879
|
-
def test_hash_params_for_application_jsonrequest
|
880
|
-
person = parse_body({:person => {:name => "David"}}.to_json,'application/jsonrequest')[:person]
|
881
|
-
assert_kind_of Hash, person
|
882
|
-
assert_equal 'David', person['name']
|
883
|
-
end
|
884
|
-
|
885
|
-
private
|
886
|
-
def parse_body(body,content_type)
|
887
|
-
env = { 'rack.input' => StringIO.new(body),
|
888
|
-
'CONTENT_TYPE' => content_type,
|
889
|
-
'CONTENT_LENGTH' => body.size.to_s }
|
890
|
-
ActionController::RackRequest.new(env).request_parameters
|
405
|
+
@request.request_method = nil # Reset the ivar cache
|
891
406
|
end
|
892
407
|
end
|