actionpack 1.13.6 → 2.0.0
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 +1400 -20
- data/MIT-LICENSE +1 -1
- data/README +5 -5
- data/RUNNING_UNIT_TESTS +4 -5
- data/Rakefile +5 -6
- data/install.rb +2 -2
- data/lib/action_controller.rb +11 -15
- data/lib/action_controller/assertions.rb +12 -25
- data/lib/action_controller/assertions/dom_assertions.rb +18 -4
- data/lib/action_controller/assertions/model_assertions.rb +8 -1
- data/lib/action_controller/assertions/response_assertions.rb +35 -12
- data/lib/action_controller/assertions/routing_assertions.rb +56 -12
- data/lib/action_controller/assertions/selector_assertions.rb +105 -38
- data/lib/action_controller/assertions/tag_assertions.rb +28 -15
- data/lib/action_controller/base.rb +318 -250
- data/lib/action_controller/benchmarking.rb +33 -29
- data/lib/action_controller/caching.rb +130 -64
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
- data/lib/action_controller/cgi_process.rb +34 -57
- data/lib/action_controller/components.rb +19 -36
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/dispatcher.rb +195 -0
- data/lib/action_controller/filters.rb +35 -34
- data/lib/action_controller/flash.rb +30 -35
- data/lib/action_controller/helpers.rb +121 -47
- data/lib/action_controller/http_authentication.rb +126 -0
- data/lib/action_controller/integration.rb +105 -101
- data/lib/action_controller/layout.rb +59 -47
- data/lib/action_controller/mime_responds.rb +57 -68
- data/lib/action_controller/mime_type.rb +43 -80
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +88 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/request.rb +553 -88
- data/lib/action_controller/request_forgery_protection.rb +126 -0
- data/lib/action_controller/request_profiler.rb +138 -0
- data/lib/action_controller/rescue.rb +185 -69
- data/lib/action_controller/resources.rb +211 -172
- data/lib/action_controller/response.rb +49 -8
- data/lib/action_controller/routing.rb +359 -236
- data/lib/action_controller/routing_optimisation.rb +119 -0
- data/lib/action_controller/session/active_record_store.rb +3 -2
- data/lib/action_controller/session/cookie_store.rb +161 -0
- data/lib/action_controller/session/mem_cache_store.rb +9 -16
- data/lib/action_controller/session_management.rb +17 -8
- data/lib/action_controller/streaming.rb +6 -3
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
- data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
- data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
- data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
- data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
- data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
- data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
- data/lib/action_controller/test_case.rb +53 -0
- data/lib/action_controller/test_process.rb +59 -46
- data/lib/action_controller/url_rewriter.rb +48 -24
- data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
- data/lib/action_controller/verification.rb +27 -21
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +2 -3
- data/lib/action_view/base.rb +218 -63
- data/lib/action_view/compiled_templates.rb +1 -2
- data/lib/action_view/helpers/active_record_helper.rb +35 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
- data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
- data/lib/action_view/helpers/benchmark_helper.rb +12 -5
- data/lib/action_view/helpers/cache_helper.rb +29 -0
- data/lib/action_view/helpers/capture_helper.rb +97 -63
- data/lib/action_view/helpers/date_helper.rb +295 -35
- data/lib/action_view/helpers/debug_helper.rb +6 -2
- data/lib/action_view/helpers/form_helper.rb +354 -111
- data/lib/action_view/helpers/form_options_helper.rb +171 -109
- data/lib/action_view/helpers/form_tag_helper.rb +332 -76
- data/lib/action_view/helpers/javascript_helper.rb +35 -11
- data/lib/action_view/helpers/javascripts/controls.js +484 -354
- data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
- data/lib/action_view/helpers/javascripts/effects.js +396 -364
- data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
- data/lib/action_view/helpers/number_helper.rb +84 -60
- data/lib/action_view/helpers/prototype_helper.rb +419 -43
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +223 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
- data/lib/action_view/helpers/tag_helper.rb +69 -39
- data/lib/action_view/helpers/text_helper.rb +221 -148
- data/lib/action_view/helpers/url_helper.rb +283 -165
- data/lib/action_view/partials.rb +134 -62
- data/lib/action_view/template_error.rb +4 -12
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +21 -1
- data/test/action_view_test.rb +26 -0
- data/test/active_record_unit.rb +12 -20
- data/test/activerecord/active_record_store_test.rb +2 -2
- data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
- data/test/controller/action_pack_assertions_test.rb +21 -152
- data/test/controller/addresses_render_test.rb +2 -7
- data/test/controller/assert_select_test.rb +120 -14
- data/test/controller/base_test.rb +11 -13
- data/test/controller/caching_test.rb +125 -5
- data/test/controller/capture_test.rb +23 -16
- data/test/controller/cgi_test.rb +66 -391
- data/test/controller/components_test.rb +31 -42
- data/test/controller/content_type_test.rb +1 -1
- data/test/controller/cookie_test.rb +42 -14
- data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
- data/test/controller/dispatcher_test.rb +123 -0
- data/test/controller/fake_models.rb +5 -0
- data/test/controller/filters_test.rb +44 -7
- data/test/controller/flash_test.rb +46 -2
- data/test/controller/fragment_store_setting_test.rb +10 -8
- data/test/controller/helper_test.rb +19 -2
- data/test/controller/html-scanner/document_test.rb +124 -0
- data/test/controller/html-scanner/node_test.rb +69 -0
- data/test/controller/html-scanner/sanitizer_test.rb +250 -0
- data/test/controller/html-scanner/tag_node_test.rb +239 -0
- data/test/controller/html-scanner/text_node_test.rb +51 -0
- data/test/controller/html-scanner/tokenizer_test.rb +125 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +12 -26
- data/test/controller/layout_test.rb +64 -12
- data/test/controller/mime_responds_test.rb +193 -38
- data/test/controller/mime_type_test.rb +30 -8
- data/test/controller/new_render_test.rb +104 -22
- data/test/controller/polymorphic_routes_test.rb +98 -0
- data/test/controller/record_identifier_test.rb +103 -0
- data/test/controller/redirect_test.rb +120 -18
- data/test/controller/render_test.rb +195 -45
- data/test/controller/request_forgery_protection_test.rb +217 -0
- data/test/controller/request_test.rb +545 -27
- data/test/controller/rescue_test.rb +501 -0
- data/test/controller/resources_test.rb +258 -132
- data/test/controller/routing_test.rb +502 -106
- data/test/controller/selector_test.rb +5 -5
- data/test/controller/send_file_test.rb +17 -7
- data/test/controller/session/cookie_store_test.rb +246 -0
- data/test/controller/session/mem_cache_store_test.rb +182 -0
- data/test/controller/session_fixation_test.rb +8 -11
- data/test/controller/session_management_test.rb +7 -7
- data/test/controller/test_test.rb +150 -38
- data/test/controller/url_rewriter_test.rb +87 -12
- data/test/controller/verification_test.rb +11 -0
- data/test/controller/view_paths_test.rb +137 -0
- data/test/controller/webservice_test.rb +11 -75
- data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/developer.rb +2 -0
- data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
- data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
- data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
- data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/replies.yml +2 -0
- data/test/fixtures/reply.rb +2 -1
- data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
- data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
- data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
- data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
- data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
- data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
- data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
- data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
- data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
- data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
- data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
- data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
- data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
- data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
- data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
- data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
- data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
- data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +1 -1
- data/test/template/active_record_helper_test.rb +67 -20
- data/test/template/asset_tag_helper_test.rb +222 -54
- data/test/template/atom_feed_helper_test.rb +101 -0
- data/test/template/benchmark_helper_test.rb +2 -2
- data/test/template/compiled_templates_test.rb +76 -32
- data/test/template/date_helper_test.rb +125 -9
- data/test/template/form_helper_test.rb +326 -33
- data/test/template/form_options_helper_test.rb +822 -15
- data/test/template/form_tag_helper_test.rb +96 -30
- data/test/template/javascript_helper_test.rb +61 -13
- data/test/template/number_helper_test.rb +12 -11
- data/test/template/prototype_helper_test.rb +185 -24
- data/test/template/sanitize_helper_test.rb +49 -0
- data/test/template/scriptaculous_helper_test.rb +9 -3
- data/test/template/tag_helper_test.rb +13 -2
- data/test/template/text_helper_test.rb +38 -52
- data/test/template/url_helper_test.rb +216 -46
- metadata +144 -116
- data/examples/.htaccess +0 -24
- data/examples/address_book/index.rhtml +0 -33
- data/examples/address_book/layout.rhtml +0 -8
- data/examples/address_book_controller.cgi +0 -9
- data/examples/address_book_controller.fcgi +0 -6
- data/examples/address_book_controller.rb +0 -52
- data/examples/address_book_controller.rbx +0 -4
- data/examples/benchmark.rb +0 -52
- data/examples/benchmark_with_ar.fcgi +0 -89
- data/examples/blog_controller.cgi +0 -53
- data/examples/debate/index.rhtml +0 -14
- data/examples/debate/new_topic.rhtml +0 -22
- data/examples/debate/topic.rhtml +0 -32
- data/examples/debate_controller.cgi +0 -57
- data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
- data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
- data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
- data/lib/action_controller/deprecated_dependencies.rb +0 -65
- data/lib/action_controller/deprecated_redirects.rb +0 -17
- data/lib/action_controller/deprecated_request_methods.rb +0 -34
- data/lib/action_controller/macros/auto_complete.rb +0 -53
- data/lib/action_controller/macros/in_place_editing.rb +0 -33
- data/lib/action_controller/pagination.rb +0 -408
- data/lib/action_controller/scaffolding.rb +0 -189
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
- data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
- data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
- data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
- data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
- data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
- data/lib/action_controller/vendor/xml_node.rb +0 -97
- data/lib/action_view/helpers/deprecated_helper.rb +0 -37
- data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
- data/lib/action_view/helpers/pagination_helper.rb +0 -86
- data/test/activerecord/active_record_assertions_test.rb +0 -92
- data/test/activerecord/pagination_test.rb +0 -165
- data/test/controller/deprecated_instance_variables_test.rb +0 -48
- data/test/controller/raw_post_test.rb +0 -68
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
- data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
- data/test/fixtures/test/_hash_object.rhtml +0 -1
- data/test/fixtures/test/list.rhtml +0 -1
- data/test/template/deprecated_helper_test.rb +0 -36
- data/test/template/deprecated_instance_variables_test.rb +0 -43
- data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'action_controller/cgi_ext/stdinput'
|
2
|
+
require 'action_controller/cgi_ext/query_extension'
|
3
|
+
require 'action_controller/cgi_ext/cookie'
|
4
|
+
require 'action_controller/cgi_ext/session'
|
5
|
+
|
6
|
+
class CGI #:nodoc:
|
7
|
+
include ActionController::CgiExt::Stdinput
|
8
|
+
|
9
|
+
class << self
|
10
|
+
alias :escapeHTML_fail_on_nil :escapeHTML
|
11
|
+
|
12
|
+
def escapeHTML(string)
|
13
|
+
escapeHTML_fail_on_nil(string) unless string.nil?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
CGI.module_eval { remove_const "Cookie" }
|
2
2
|
|
3
|
+
# TODO: document how this differs from stdlib CGI::Cookie
|
3
4
|
class CGI #:nodoc:
|
4
|
-
# This is a cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below.
|
5
|
-
# It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on
|
6
|
-
# http://groups.google.com/groups?th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14
|
7
5
|
class Cookie < DelegateClass(Array)
|
6
|
+
attr_accessor :name, :value, :path, :domain, :expires
|
7
|
+
attr_reader :secure, :http_only
|
8
|
+
|
8
9
|
# Create a new CGI::Cookie object.
|
9
10
|
#
|
10
11
|
# The contents of the cookie can be specified as a +name+ and one
|
@@ -19,9 +20,11 @@ class CGI #:nodoc:
|
|
19
20
|
# domain:: the domain for which this cookie applies.
|
20
21
|
# expires:: the time at which this cookie expires, as a +Time+ object.
|
21
22
|
# secure:: whether this cookie is a secure cookie or not (default to
|
22
|
-
# false). Secure cookies are only transmitted to HTTPS
|
23
|
+
# false). Secure cookies are only transmitted to HTTPS
|
23
24
|
# servers.
|
24
|
-
#
|
25
|
+
# http_only:: whether this cookie can be accessed by client side scripts (e.g. document.cookie) or only over HTTP
|
26
|
+
# More details: http://msdn2.microsoft.com/en-us/library/system.web.httpcookie.httponly.aspx
|
27
|
+
# Defaults to false.
|
25
28
|
# These keywords correspond to attributes of the cookie object.
|
26
29
|
def initialize(name = '', *value)
|
27
30
|
if name.kind_of?(String)
|
@@ -30,6 +33,7 @@ class CGI #:nodoc:
|
|
30
33
|
@domain = nil
|
31
34
|
@expires = nil
|
32
35
|
@secure = false
|
36
|
+
@http_only = false
|
33
37
|
@path = nil
|
34
38
|
else
|
35
39
|
@name = name['name']
|
@@ -37,12 +41,11 @@ class CGI #:nodoc:
|
|
37
41
|
@domain = name['domain']
|
38
42
|
@expires = name['expires']
|
39
43
|
@secure = name['secure'] || false
|
44
|
+
@http_only = name['http_only'] || false
|
40
45
|
@path = name['path']
|
41
46
|
end
|
42
|
-
|
43
|
-
unless @name
|
44
|
-
raise ArgumentError, "`name' required"
|
45
|
-
end
|
47
|
+
|
48
|
+
raise ArgumentError, "`name' required" unless @name
|
46
49
|
|
47
50
|
# simple support for IE
|
48
51
|
unless @path
|
@@ -57,44 +60,26 @@ class CGI #:nodoc:
|
|
57
60
|
@_dc_obj = obj
|
58
61
|
end
|
59
62
|
|
60
|
-
attr_accessor("name", "value", "path", "domain", "expires")
|
61
|
-
attr_reader("secure")
|
62
|
-
|
63
63
|
# Set whether the Cookie is a secure cookie or not.
|
64
|
-
#
|
65
|
-
# +val+ must be a boolean.
|
66
64
|
def secure=(val)
|
67
|
-
@secure = val
|
68
|
-
|
65
|
+
@secure = val == true
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set whether the Cookie is an HTTP only cookie or not.
|
69
|
+
def http_only=(val)
|
70
|
+
@http_only = val == true
|
69
71
|
end
|
70
72
|
|
71
73
|
# Convert the Cookie to its string representation.
|
72
74
|
def to_s
|
73
|
-
buf =
|
75
|
+
buf = ''
|
74
76
|
buf << @name << '='
|
75
|
-
|
76
|
-
if @
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if @domain
|
83
|
-
buf << '; domain=' << @domain
|
84
|
-
end
|
85
|
-
|
86
|
-
if @path
|
87
|
-
buf << '; path=' << @path
|
88
|
-
end
|
89
|
-
|
90
|
-
if @expires
|
91
|
-
buf << '; expires=' << CGI::rfc1123_date(@expires)
|
92
|
-
end
|
93
|
-
|
94
|
-
if @secure == true
|
95
|
-
buf << '; secure'
|
96
|
-
end
|
97
|
-
|
77
|
+
buf << (@value.kind_of?(String) ? CGI::escape(@value) : @value.collect{|v| CGI::escape(v) }.join("&"))
|
78
|
+
buf << '; domain=' << @domain if @domain
|
79
|
+
buf << '; path=' << @path if @path
|
80
|
+
buf << '; expires=' << CGI::rfc1123_date(@expires) if @expires
|
81
|
+
buf << '; secure' if @secure
|
82
|
+
buf << '; HttpOnly' if @http_only
|
98
83
|
buf
|
99
84
|
end
|
100
85
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
class CGI #:nodoc:
|
4
|
+
module QueryExtension
|
5
|
+
# Remove the old initialize_query method before redefining it.
|
6
|
+
remove_method :initialize_query
|
7
|
+
|
8
|
+
# Neuter CGI parameter parsing.
|
9
|
+
def initialize_query
|
10
|
+
# Fix some strange request environments.
|
11
|
+
env_table['REQUEST_METHOD'] ||= 'GET'
|
12
|
+
|
13
|
+
# POST assumes missing Content-Type is application/x-www-form-urlencoded.
|
14
|
+
if env_table['CONTENT_TYPE'].blank? && env_table['REQUEST_METHOD'] == 'POST'
|
15
|
+
env_table['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
|
16
|
+
end
|
17
|
+
|
18
|
+
@cookies = CGI::Cookie::parse(env_table['HTTP_COOKIE'] || env_table['COOKIE'])
|
19
|
+
@params = {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'cgi/session'
|
3
|
+
require 'cgi/session/pstore'
|
4
|
+
|
5
|
+
class CGI #:nodoc:
|
6
|
+
# * Expose the CGI instance to session stores.
|
7
|
+
# * Don't require 'digest/md5' whenever a new session id is generated.
|
8
|
+
class Session #:nodoc:
|
9
|
+
begin
|
10
|
+
require 'securerandom'
|
11
|
+
|
12
|
+
# Generate a 32-character unique id using SecureRandom.
|
13
|
+
# This is used to generate session ids but may be reused elsewhere.
|
14
|
+
def self.generate_unique_id(constant = nil)
|
15
|
+
SecureRandom.hex(16)
|
16
|
+
end
|
17
|
+
rescue LoadError
|
18
|
+
# Generate an 32-character unique id based on a hash of the current time,
|
19
|
+
# a random number, the process id, and a constant string. This is used
|
20
|
+
# to generate session ids but may be reused elsewhere.
|
21
|
+
def self.generate_unique_id(constant = 'foobar')
|
22
|
+
md5 = Digest::MD5.new
|
23
|
+
now = Time.now
|
24
|
+
md5 << now.to_s
|
25
|
+
md5 << String(now.usec)
|
26
|
+
md5 << String(rand(0))
|
27
|
+
md5 << String($$)
|
28
|
+
md5 << constant
|
29
|
+
md5.hexdigest
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Make the CGI instance available to session stores.
|
34
|
+
attr_reader :cgi
|
35
|
+
attr_reader :dbman
|
36
|
+
alias_method :initialize_without_cgi_reader, :initialize
|
37
|
+
def initialize(cgi, options = {})
|
38
|
+
@cgi = cgi
|
39
|
+
initialize_without_cgi_reader(cgi, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
# Create a new session id.
|
44
|
+
def create_new_id
|
45
|
+
@new_session = true
|
46
|
+
self.class.generate_unique_id
|
47
|
+
end
|
48
|
+
|
49
|
+
# * Don't require 'digest/md5' whenever a new session is started.
|
50
|
+
class PStore #:nodoc:
|
51
|
+
def initialize(session, option={})
|
52
|
+
dir = option['tmpdir'] || Dir::tmpdir
|
53
|
+
prefix = option['prefix'] || ''
|
54
|
+
id = session.session_id
|
55
|
+
md5 = Digest::MD5.hexdigest(id)[0,16]
|
56
|
+
path = dir+"/"+prefix+md5
|
57
|
+
path.untaint
|
58
|
+
if File::exist?(path)
|
59
|
+
@hash = nil
|
60
|
+
else
|
61
|
+
unless session.new_session
|
62
|
+
raise CGI::Session::NoSession, "uninitialized session"
|
63
|
+
end
|
64
|
+
@hash = {}
|
65
|
+
end
|
66
|
+
@p = ::PStore.new(path)
|
67
|
+
@p.transaction do |p|
|
68
|
+
File.chmod(0600, p.path)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module CgiExt
|
5
|
+
# Publicize the CGI's internal input stream so we can lazy-read
|
6
|
+
# request.body. Make it writable so we don't have to play $stdin games.
|
7
|
+
module Stdinput
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
remove_method :stdinput
|
11
|
+
attr_accessor :stdinput
|
12
|
+
end
|
13
|
+
|
14
|
+
base.alias_method_chain :initialize, :stdinput
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize_with_stdinput(type = nil, stdinput = $stdin)
|
18
|
+
@stdinput = stdinput
|
19
|
+
initialize_without_stdinput(type || 'query')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,8 +1,5 @@
|
|
1
|
-
require 'action_controller/cgi_ext
|
2
|
-
require 'action_controller/
|
3
|
-
require 'action_controller/cgi_ext/raw_post_data_fix'
|
4
|
-
require 'action_controller/cgi_ext/session_performance_fix'
|
5
|
-
require 'action_controller/cgi_ext/pstore_performance_fix'
|
1
|
+
require 'action_controller/cgi_ext'
|
2
|
+
require 'action_controller/session/cookie_store'
|
6
3
|
|
7
4
|
module ActionController #:nodoc:
|
8
5
|
class Base
|
@@ -40,9 +37,9 @@ module ActionController #:nodoc:
|
|
40
37
|
class SessionFixationAttempt < StandardError; end #:nodoc:
|
41
38
|
|
42
39
|
DEFAULT_SESSION_OPTIONS = {
|
43
|
-
:database_manager => CGI::Session::
|
44
|
-
:prefix => "ruby_sess.",
|
45
|
-
:session_path => "/",
|
40
|
+
:database_manager => CGI::Session::CookieStore, # store data in cookie
|
41
|
+
:prefix => "ruby_sess.", # prefix session file names
|
42
|
+
:session_path => "/", # available to all paths in app
|
46
43
|
:session_key => "_session_id",
|
47
44
|
:cookie_only => true
|
48
45
|
} unless const_defined?(:DEFAULT_SESSION_OPTIONS)
|
@@ -50,45 +47,42 @@ module ActionController #:nodoc:
|
|
50
47
|
def initialize(cgi, session_options = {})
|
51
48
|
@cgi = cgi
|
52
49
|
@session_options = session_options
|
53
|
-
@env = @cgi.send(:env_table)
|
50
|
+
@env = @cgi.send!(:env_table)
|
54
51
|
super()
|
55
52
|
end
|
56
53
|
|
57
|
-
def cookie_only?
|
58
|
-
session_options_with_string_keys['cookie_only']
|
59
|
-
end
|
60
|
-
|
61
54
|
def query_string
|
62
|
-
|
55
|
+
qs = @cgi.query_string if @cgi.respond_to?(:query_string)
|
56
|
+
if !qs.blank?
|
63
57
|
qs
|
64
|
-
elsif uri = @env['REQUEST_URI']
|
65
|
-
parts = uri.split('?')
|
66
|
-
parts.shift
|
67
|
-
parts.join('?')
|
68
58
|
else
|
69
|
-
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# The request body is an IO input stream. If the RAW_POST_DATA environment
|
64
|
+
# variable is already set, wrap it in a StringIO.
|
65
|
+
def body
|
66
|
+
if raw_post = env['RAW_POST_DATA']
|
67
|
+
StringIO.new(raw_post)
|
68
|
+
else
|
69
|
+
@cgi.stdinput
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
def query_parameters
|
74
|
-
@query_parameters ||=
|
75
|
-
(qs = self.query_string).empty? ? {} : CGIMethods.parse_query_parameters(qs)
|
74
|
+
@query_parameters ||= self.class.parse_query_parameters(query_string)
|
76
75
|
end
|
77
76
|
|
78
77
|
def request_parameters
|
79
|
-
@request_parameters ||=
|
80
|
-
if ActionController::Base.param_parsers.has_key?(content_type)
|
81
|
-
CGIMethods.parse_formatted_request_parameters(content_type, @env['RAW_POST_DATA'])
|
82
|
-
else
|
83
|
-
CGIMethods.parse_request_parameters(@cgi.params)
|
84
|
-
end
|
78
|
+
@request_parameters ||= parse_formatted_request_parameters
|
85
79
|
end
|
86
80
|
|
87
81
|
def cookies
|
88
82
|
@cgi.cookies.freeze
|
89
83
|
end
|
90
84
|
|
91
|
-
def
|
85
|
+
def host_with_port_without_standard_port_handling
|
92
86
|
if forwarded = env["HTTP_X_FORWARDED_HOST"]
|
93
87
|
forwarded.split(/,\s?/).last
|
94
88
|
elsif http_host = env['HTTP_HOST']
|
@@ -101,11 +95,11 @@ module ActionController #:nodoc:
|
|
101
95
|
end
|
102
96
|
|
103
97
|
def host
|
104
|
-
|
98
|
+
host_with_port_without_standard_port_handling.sub(/:\d+$/, '')
|
105
99
|
end
|
106
100
|
|
107
101
|
def port
|
108
|
-
if
|
102
|
+
if host_with_port_without_standard_port_handling =~ /:(\d+)$/
|
109
103
|
$1.to_i
|
110
104
|
else
|
111
105
|
standard_port
|
@@ -118,7 +112,7 @@ module ActionController #:nodoc:
|
|
118
112
|
@session = Hash.new
|
119
113
|
else
|
120
114
|
stale_session_check! do
|
121
|
-
if cookie_only? &&
|
115
|
+
if cookie_only? && query_parameters[session_options_with_string_keys['session_key']]
|
122
116
|
raise SessionFixationAttempt
|
123
117
|
end
|
124
118
|
case value = session_options_with_string_keys['new_session']
|
@@ -150,7 +144,7 @@ module ActionController #:nodoc:
|
|
150
144
|
end
|
151
145
|
|
152
146
|
def method_missing(method_id, *arguments)
|
153
|
-
@cgi.send(method_id, *arguments) rescue super
|
147
|
+
@cgi.send!(method_id, *arguments) rescue super
|
154
148
|
end
|
155
149
|
|
156
150
|
private
|
@@ -164,12 +158,17 @@ module ActionController #:nodoc:
|
|
164
158
|
end
|
165
159
|
end
|
166
160
|
|
161
|
+
def cookie_only?
|
162
|
+
session_options_with_string_keys['cookie_only']
|
163
|
+
end
|
164
|
+
|
167
165
|
def stale_session_check!
|
168
166
|
yield
|
169
167
|
rescue ArgumentError => argument_error
|
170
|
-
if argument_error.message =~ %r{undefined class/module ([\w:]
|
168
|
+
if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
|
171
169
|
begin
|
172
|
-
|
170
|
+
# Note that the regexp does not allow $1 to end with a ':'
|
171
|
+
$1.constantize
|
173
172
|
rescue LoadError, NameError => const_error
|
174
173
|
raise ActionController::SessionRestoreError, <<-end_msg
|
175
174
|
Session contains objects whose class definition isn\'t available.
|
@@ -196,16 +195,13 @@ end_msg
|
|
196
195
|
end
|
197
196
|
|
198
197
|
def out(output = $stdout)
|
199
|
-
convert_content_type!
|
200
|
-
set_content_length!
|
201
|
-
|
202
198
|
output.binmode if output.respond_to?(:binmode)
|
203
199
|
output.sync = false if output.respond_to?(:sync=)
|
204
200
|
|
205
201
|
begin
|
206
202
|
output.write(@cgi.header(@headers))
|
207
203
|
|
208
|
-
if @cgi.send(:env_table)['REQUEST_METHOD'] == 'HEAD'
|
204
|
+
if @cgi.send!(:env_table)['REQUEST_METHOD'] == 'HEAD'
|
209
205
|
return
|
210
206
|
elsif @body.respond_to?(:call)
|
211
207
|
# Flush the output now in case the @body Proc uses
|
@@ -221,24 +217,5 @@ end_msg
|
|
221
217
|
# lost connection to parent process, ignore output
|
222
218
|
end
|
223
219
|
end
|
224
|
-
|
225
|
-
private
|
226
|
-
def convert_content_type!
|
227
|
-
if content_type = @headers.delete("Content-Type")
|
228
|
-
@headers["type"] = content_type
|
229
|
-
end
|
230
|
-
if content_type = @headers.delete("Content-type")
|
231
|
-
@headers["type"] = content_type
|
232
|
-
end
|
233
|
-
if content_type = @headers.delete("content-type")
|
234
|
-
@headers["type"] = content_type
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# Don't set the Content-Length for block-based bodies as that would mean reading it all into memory. Not nice
|
239
|
-
# for, say, a 2GB streaming file.
|
240
|
-
def set_content_length!
|
241
|
-
@headers["Content-Length"] = @body.size unless @body.respond_to?(:call)
|
242
|
-
end
|
243
220
|
end
|
244
221
|
end
|
@@ -17,44 +17,44 @@ module ActionController #:nodoc:
|
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# The same can be done in a view to do a partial rendering:
|
20
|
-
#
|
21
|
-
# Let's see a greeting:
|
20
|
+
#
|
21
|
+
# Let's see a greeting:
|
22
22
|
# <%= render_component :controller => "greeter", :action => "hello_world" %>
|
23
23
|
#
|
24
24
|
# It is also possible to specify the controller as a class constant, bypassing the inflector
|
25
25
|
# code to compute the controller class at runtime:
|
26
|
-
#
|
26
|
+
#
|
27
27
|
# <%= render_component :controller => GreeterController, :action => "hello_world" %>
|
28
28
|
#
|
29
29
|
# == When to use components
|
30
30
|
#
|
31
31
|
# Components should be used with care. They're significantly slower than simply splitting reusable parts into partials and
|
32
32
|
# conceptually more complicated. Don't use components as a way of separating concerns inside a single application. Instead,
|
33
|
-
# reserve components to those rare cases where you truly have reusable view and controller elements that can be employed
|
33
|
+
# reserve components to those rare cases where you truly have reusable view and controller elements that can be employed
|
34
34
|
# across many applications at once.
|
35
35
|
#
|
36
36
|
# So to repeat: Components are a special-purpose approach that can often be replaced with better use of partials and filters.
|
37
37
|
module Components
|
38
38
|
def self.included(base) #:nodoc:
|
39
|
-
base.
|
40
|
-
|
39
|
+
base.class_eval do
|
40
|
+
include InstanceMethods
|
41
|
+
extend ClassMethods
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
helper do
|
44
|
+
def render_component(options)
|
45
|
+
@controller.send!(:render_component_as_string, options)
|
46
|
+
end
|
45
47
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
base.class_eval do
|
48
|
+
|
49
|
+
# If this controller was instantiated to process a component request,
|
50
|
+
# +parent_controller+ points to the instantiator of this controller.
|
51
|
+
attr_accessor :parent_controller
|
52
|
+
|
53
53
|
alias_method_chain :process_cleanup, :components
|
54
54
|
alias_method_chain :set_session_options, :components
|
55
55
|
alias_method_chain :flash, :components
|
56
56
|
|
57
|
-
alias_method :component_request?, :parent_controller
|
57
|
+
alias_method :component_request?, :parent_controller
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -65,23 +65,6 @@ module ActionController #:nodoc:
|
|
65
65
|
controller.parent_controller = parent_controller
|
66
66
|
controller.process(request, response)
|
67
67
|
end
|
68
|
-
|
69
|
-
# Set the template root to be one directory behind the root dir of the controller. Examples:
|
70
|
-
# /code/weblog/components/admin/users_controller.rb with Admin::UsersController
|
71
|
-
# will use /code/weblog/components as template root
|
72
|
-
# and find templates in /code/weblog/components/admin/users/
|
73
|
-
#
|
74
|
-
# /code/weblog/components/admin/parties/users_controller.rb with Admin::Parties::UsersController
|
75
|
-
# will also use /code/weblog/components as template root
|
76
|
-
# and find templates in /code/weblog/components/admin/parties/users/
|
77
|
-
def uses_component_template_root
|
78
|
-
path_of_calling_controller = File.dirname(caller[1].split(/:\d+:/, 2).first)
|
79
|
-
path_of_controller_root = path_of_calling_controller.sub(/#{Regexp.escape(File.dirname(controller_path))}$/, "")
|
80
|
-
|
81
|
-
self.template_root = path_of_controller_root
|
82
|
-
end
|
83
|
-
|
84
|
-
deprecate :uses_component_template_root => 'Components are deprecated and will be removed in Rails 2.0.'
|
85
68
|
end
|
86
69
|
|
87
70
|
module InstanceMethods
|
@@ -90,12 +73,12 @@ module ActionController #:nodoc:
|
|
90
73
|
flash.discard if component_request?
|
91
74
|
process_without_components(request, response, method, *arguments)
|
92
75
|
end
|
93
|
-
|
76
|
+
|
94
77
|
protected
|
95
78
|
# Renders the component specified as the response for the current method
|
96
79
|
def render_component(options) #:doc:
|
97
80
|
component_logging(options) do
|
98
|
-
|
81
|
+
render_for_text(component_response(options, true).body, response.headers["Status"])
|
99
82
|
end
|
100
83
|
end
|
101
84
|
|