diff options
author | Joshua Peek <josh@joshpeek.com> | 2011-03-30 21:04:33 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2011-03-30 21:04:33 -0500 |
commit | 56a5da89dbcdd6d73f26f5c1be6221b684574b2b (patch) | |
tree | 577fbc16d37ed54bbda1a2a7477894caa6a7bfff /actionpack/lib | |
parent | 5df076ad0965dc684afff8a019fd9f92a53ada76 (diff) | |
parent | 58c3ec1b7b7ee073edf9c245de5d06426be60a25 (diff) | |
download | rails-56a5da89dbcdd6d73f26f5c1be6221b684574b2b.tar.gz rails-56a5da89dbcdd6d73f26f5c1be6221b684574b2b.tar.bz2 rails-56a5da89dbcdd6d73f26f5c1be6221b684574b2b.zip |
Merge branch 'master' into sprockets
Conflicts:
railties/lib/rails/application/configuration.rb
Diffstat (limited to 'actionpack/lib')
14 files changed, 117 insertions, 56 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index c384fd0978..07ff5ad9f3 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -128,20 +128,23 @@ module AbstractController self.class.action_methods end - private + # Returns true if the name can be considered an action. This can + # be overridden in subclasses to modify the semantics of what + # can be considered an action. + # + # For instance, this is overriden by ActionController to add + # the implicit rendering feature. + # + # ==== Parameters + # * <tt>name</tt> - The name of an action to be tested + # + # ==== Returns + # * <tt>TrueClass</tt>, <tt>FalseClass</tt> + def action_method?(name) + self.class.action_methods.include?(name) + end - # Returns true if the name can be considered an action. This can - # be overridden in subclasses to modify the semantics of what - # can be considered an action. - # - # ==== Parameters - # * <tt>name</tt> - The name of an action to be tested - # - # ==== Returns - # * <tt>TrueClass</tt>, <tt>FalseClass</tt> - def action_method?(name) - self.class.action_methods.include?(name) - end + private # Call the action. Override this in a subclass to modify the # behavior around processing an action. This, and not #process, @@ -160,8 +163,8 @@ module AbstractController # If the action name was not found, but a method called "action_missing" # was found, #method_for_action will return "_handle_action_missing". # This method calls #action_missing with the current action name. - def _handle_action_missing - action_missing(@_action_name) + def _handle_action_missing(*args) + action_missing(@_action_name, *args) end # Takes an action name and returns the name of the method that will diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb index 1943ca4436..95992c2698 100644 --- a/actionpack/lib/abstract_controller/callbacks.rb +++ b/actionpack/lib/abstract_controller/callbacks.rb @@ -14,7 +14,7 @@ module AbstractController # Override AbstractController::Base's process_action to run the # process_action callbacks around the normal behavior. def process_action(method_name, *args) - run_callbacks(:process_action, action_name) do + run_callbacks(:process_action, method_name) do super end end diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 5b81cd39f4..62cc18b253 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -14,6 +14,7 @@ module ActionController autoload :ConditionalGet autoload :Cookies autoload :Flash + autoload :ForceSSL autoload :Head autoload :Helpers autoload :HideActions diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 81c0698fb8..e6523e56d2 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -198,6 +198,7 @@ module ActionController Cookies, Flash, RequestForgeryProtection, + ForceSSL, Streaming, RecordIdentifier, HttpAuthentication::Basic::ControllerMethods, diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 2c8a6e4d4d..5fc6956266 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -56,19 +56,18 @@ module ActionController #:nodoc: # # caches_page :public # - # caches_action :index, :if => proc do |c| - # !c.request.format.json? # cache if is not a JSON request + # caches_action :index, :if => proc do + # !request.format.json? # cache if is not a JSON request # end # # caches_action :show, :cache_path => { :project => 1 }, # :expires_in => 1.hour # - # caches_action :feed, :cache_path => proc do |c| - # if c.params[:user_id] - # c.send(:user_list_url, - # c.params[:user_id], c.params[:id]) + # caches_action :feed, :cache_path => proc do + # if params[:user_id] + # user_list_url(params[:user_id, params[:id]) # else - # c.send(:list_url, c.params[:id]) + # list_url(params[:id]) # end # end # end diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb new file mode 100644 index 0000000000..eb8ed7dfbd --- /dev/null +++ b/actionpack/lib/action_controller/metal/force_ssl.rb @@ -0,0 +1,35 @@ +module ActionController + # This module provides a method which will redirects browser to use HTTPS + # protocol. This will ensure that user's sensitive information will be + # transferred safely over the internet. You _should_ always force browser + # to use HTTPS when you're transferring sensitive information such as + # user authentication, account information, or credit card information. + # + # Note that if you really concern about your application safety, you might + # consider using +config.force_ssl+ in your configuration config file instead. + # That will ensure all the data transferred via HTTPS protocol and prevent + # user from getting session hijacked when accessing the site under unsecured + # HTTP protocol. + module ForceSSL + extend ActiveSupport::Concern + include AbstractController::Callbacks + + module ClassMethods + # Force the request to this particular controller or specified actions to be + # under HTTPS protocol. + # + # Note that this method will not be effective on development environment. + # + # ==== Options + # * <tt>only</tt> - The callback should be run only for this action + # * <tt>except<tt> - The callback should be run for all actions except this action + def force_ssl(options = {}) + before_filter(options) do + if !request.ssl? && !Rails.env.development? + redirect_to :protocol => 'https://', :status => :moved_permanently + end + end + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 39c804d707..b98429792d 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -8,9 +8,7 @@ module ActionController # === Simple \Basic example # # class PostsController < ApplicationController - # USER_NAME, PASSWORD = "dhh", "secret" - # - # before_filter :authenticate, :except => [ :index ] + # http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index # # def index # render :text => "Everyone can see me!" @@ -19,15 +17,7 @@ module ActionController # def edit # render :text => "I'm only accessible if you know the password" # end - # - # private - # def authenticate - # authenticate_or_request_with_http_basic do |user_name, password| - # user_name == USER_NAME && password == PASSWORD - # end - # end - # end - # + # end # # === Advanced \Basic example # @@ -115,6 +105,18 @@ module ActionController extend self module ControllerMethods + extend ActiveSupport::Concern + + module ClassMethods + def http_basic_authenticate_with(options = {}) + before_filter(options.except(:name, :password, :realm)) do + authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password| + name == options[:name] && password == options[:password] + end + end + end + end + def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure) authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm) end @@ -378,7 +380,6 @@ module ActionController # # RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L] module Token - extend self module ControllerMethods @@ -458,6 +459,5 @@ module ActionController controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized end end - end end diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index cfa7004048..678f4ca763 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -1,21 +1,21 @@ module ActionController module ImplicitRender - def send_action(*) - ret = super - default_render unless response_body - ret + def send_action(method, *args) + if respond_to?(method, true) + ret = super + default_render unless response_body + ret + else + default_render + end end def default_render render end - def method_for_action(action_name) - super || begin - if template_exists?(action_name.to_s, _prefixes) - "default_render" - end - end + def action_method?(action_name) + super || template_exists?(action_name.to_s, _prefixes) end end end diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb index 50d8ca9484..2099fd069a 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb @@ -1,7 +1,7 @@ <h1> <%=h @exception.class.to_s %> <% if @request.parameters['controller'] %> - in <%=h @request.parameters['controller'].humanize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %> + in <%=h @request.parameters['controller'].classify.pluralize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %> <% end %> </h1> <pre><%=h @exception.message %></pre> diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 14c424f24b..35be0b3a27 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -104,10 +104,16 @@ module ActionDispatch @options.reverse_merge!(:controller => /.+?/) end + # Add a constraint for wildcard route to make it non-greedy and match the + # optional format part of the route by default + if path.match(/\*([^\/]+)$/) && @options[:format] != false + @options.reverse_merge!(:"#{$1}" => /.+?/) + end + if @options[:format] == false @options.delete(:format) path - elsif path.include?(":format") || path.end_with?('/') || path.match(/^\/?\*/) + elsif path.include?(":format") || path.end_with?('/') path else "#{path}(.:format)" diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 11e8c63fa0..b760db42e2 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -46,7 +46,7 @@ module ActionDispatch expected_options.stringify_keys! msg = build_message(message, "The recognized options <?> did not match <?>, difference: <?>", request.path_parameters, expected_options, expected_options.diff(request.path_parameters)) - assert_block(msg) { request.path_parameters == expected_options } + assert_equal(expected_options, request.path_parameters, msg) end # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+. @@ -84,11 +84,11 @@ module ActionDispatch found_extras = options.reject {|k, v| ! extra_keys.include? k} msg = build_message(message, "found extras <?>, not <?>", found_extras, extras) - assert_block(msg) { found_extras == extras } + assert_equal(extras, found_extras, msg) msg = build_message(message, "The generated path <?> did not match <?>", generated_path, expected_path) - assert_block(msg) { expected_path == generated_path } + assert_equal(expected_path, generated_path, msg) end # Asserts that path and options match both ways; in other words, it verifies that <tt>path</tt> generates diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 48abf119f1..9025d9e24c 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -185,7 +185,7 @@ module ActionView # # is equivalent to something like: # - # <%= form_for @post, :as => :post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %> + # <%= form_for @post, :as => :post, :url => post_path(@post), :method => :put, :html => { :class => "edit_post", :id => "edit_post_45" } do |f| %> # ... # <% end %> # @@ -236,6 +236,16 @@ module ActionView # Where <tt>@document = Document.find(params[:id])</tt> and # <tt>@comment = Comment.new</tt>. # + # === Setting the method + # + # You can force the form to use the full array of HTTP verbs by setting + # + # :method => (:get|:post|:put|:delete) + # + # in the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the + # form will be set to POST and a hidden input called _method will carry the intended verb for the server + # to interpret. + # # === Unobtrusive JavaScript # # Specifying: @@ -298,7 +308,7 @@ module ActionView # # In this case, if you use this: # - # <%= render :partial => f %> + # <%= render f %> # # The rendered template is <tt>people/_labelling_form</tt> and the local # variable referencing the form builder is called @@ -350,6 +360,7 @@ module ActionView end options[:html][:remote] = options.delete(:remote) + options[:html][:method] = options.delete(:method) if options.has_key?(:method) options[:html][:authenticity_token] = options.delete(:authenticity_token) builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index cd3a3eac80..a19ba7a968 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -47,6 +47,9 @@ module ActionView "'" => "\\'" } # Escape carrier returns and single and double quotes for JavaScript segments. + # Also available through the alias j(). This is particularly helpful in JavaScript responses, like: + # + # $('some_element').replaceWith('<%=j render 'some/element_template' %>'); def escape_javascript(javascript) if javascript javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] } @@ -55,6 +58,8 @@ module ActionView end end + alias_method :j, :escape_javascript + # Returns a JavaScript tag with the +content+ inside. Example: # javascript_tag "alert('All is good')" # diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 6c1063592f..41c6310ae2 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -157,8 +157,8 @@ module ActionView query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}") } - query.gsub!(/\.{html,/, ".{html,text.html,") - query.gsub!(/\.{text,/, ".{text,text.plain,") + query.gsub!('.{html,', '.{html,text.html,') + query.gsub!('.{text,', '.{text,text.plain,') File.expand_path(query, @path) end |