diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware')
6 files changed, 114 insertions, 51 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb index 0bb950d1cc..4d038c29f2 100644 --- a/actionpack/lib/action_dispatch/middleware/callbacks.rb +++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb @@ -1,32 +1,14 @@ +require 'active_support/core_ext/module/delegation' + module ActionDispatch # Provide callbacks to be executed before and after the request dispatch. - # - # It also provides a to_prepare callback, which is performed in all requests - # in development by only once in production and notification callback for async - # operations. - # class Callbacks include ActiveSupport::Callbacks define_callbacks :call, :rescuable => true - define_callbacks :prepare, :scope => :name - # Add a preparation callback. Preparation callbacks are run before every - # request in development mode, and before the first request in production mode. - # - # If a symbol with a block is given, the symbol is used as an identifier. - # That allows to_prepare to be called again with the same identifier to - # replace the existing callback. Passing an identifier is a suggested - # practice if the code adding a preparation block may be reloaded. - def self.to_prepare(*args, &block) - first_arg = args.first - if first_arg.is_a?(Symbol) && block_given? - remove_method :"__#{first_arg}" if method_defined?(:"__#{first_arg}") - define_method :"__#{first_arg}", &block - set_callback(:prepare, :"__#{first_arg}") - else - set_callback(:prepare, *args, &block) - end + class << self + delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader" end def self.before(*args, &block) @@ -37,14 +19,13 @@ module ActionDispatch set_callback(:call, :after, *args, &block) end - def initialize(app, prepare_each_request = false) - @app, @prepare_each_request = app, prepare_each_request - _run_prepare_callbacks + def initialize(app, unused = nil) + ActiveSupport::Deprecation.warn "Passing a second argument to ActionDispatch::Callbacks.new is deprecated." unless unused.nil? + @app = app end def call(env) _run_call_callbacks do - _run_prepare_callbacks if @prepare_each_request @app.call(env) end end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index c4c2e1acd7..f369d2d3c2 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -16,17 +16,23 @@ module ActionDispatch # Examples for writing: # # # Sets a simple session cookie. + # # This cookie will be deleted when the user's browser is closed. # cookies[:user_name] = "david" # + # # Assign an array of values to a cookie. + # cookies[:lat_lon] = [47.68, -122.37] + # # # Sets a cookie that expires in 1 hour. # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now } # # # Sets a signed cookie, which prevents a user from tampering with its value. - # # You must specify a value in ActionController::Base.cookie_verifier_secret. - # cookies.signed[:remember_me] = [current_user.id, current_user.salt] + # # The cookie is signed by your app's <tt>config.secret_token</tt> value. + # # Rails generates this value by default when you create a new Rails app. + # cookies.signed[:user_id] = current_user.id # # # Sets a "permanent" cookie (which expires in 20 years from now). # cookies.permanent[:login] = "XJ-122" + # # # You can also chain these methods: # cookies.permanent.signed[:login] = "XJ-122" # @@ -34,6 +40,7 @@ module ActionDispatch # # cookies[:user_name] # => "david" # cookies.size # => 2 + # cookies[:lat_lon] # => [47.68, -122.37] # # Example for deleting: # @@ -124,8 +131,11 @@ module ActionDispatch options[:path] ||= "/" if options[:domain] == :all - @host =~ DOMAIN_REGEXP - options[:domain] = ".#{$1}.#{$2}" + # if host is not ip and matches domain regexp + # (ip confirms to domain regexp so we explicitly check for ip) + options[:domain] = if (@host !~ /^[\d.]+$/) && (@host =~ DOMAIN_REGEXP) + ".#{$1}.#{$2}" + end end end @@ -275,7 +285,7 @@ module ActionDispatch "integrity hash for cookie session data. Use " + "config.secret_token = \"some secret phrase of at " + "least #{SECRET_MIN_LENGTH} characters\"" + - "in config/application.rb" + "in config/initializers/secret_token.rb" end if secret.length < SECRET_MIN_LENGTH diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb new file mode 100644 index 0000000000..f6ab368ad8 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/reloader.rb @@ -0,0 +1,76 @@ +module ActionDispatch + # ActionDispatch::Reloader provides prepare and cleanup callbacks, + # intended to assist with code reloading during development. + # + # Prepare callbacks are run before each request, and cleanup callbacks + # after each request. In this respect they are analogs of ActionDispatch::Callback's + # before and after callbacks. However, cleanup callbacks are not called until the + # request is fully complete -- that is, after #close has been called on + # the response body. This is important for streaming responses such as the + # following: + # + # self.response_body = lambda { |response, output| + # # code here which refers to application models + # } + # + # Cleanup callbacks will not be called until after the response_body lambda + # is evaluated, ensuring that it can refer to application models and other + # classes before they are unloaded. + # + # By default, ActionDispatch::Reloader is included in the middleware stack + # only in the development environment; specifically, when config.cache_classes + # is false. Callbacks may be registered even when it is not included in the + # middleware stack, but are executed only when +ActionDispatch::Reloader.prepare!+ + # or +ActionDispatch::Reloader.cleanup!+ are called manually. + # + class Reloader + include ActiveSupport::Callbacks + + define_callbacks :prepare, :scope => :name + define_callbacks :cleanup, :scope => :name + + # Add a prepare callback. Prepare callbacks are run before each request, prior + # to ActionDispatch::Callback's before callbacks. + def self.to_prepare(*args, &block) + set_callback(:prepare, *args, &block) + end + + # Add a cleanup callback. Cleanup callbacks are run after each request is + # complete (after #close is called on the response body). + def self.to_cleanup(*args, &block) + set_callback(:cleanup, *args, &block) + end + + # Execute all prepare callbacks. + def self.prepare! + new(nil).send(:_run_prepare_callbacks) + end + + # Execute all cleanup callbacks. + def self.cleanup! + new(nil).send(:_run_cleanup_callbacks) + end + + def initialize(app) + @app = app + end + + module CleanupOnClose + def close + super if defined?(super) + ensure + ActionDispatch::Reloader.cleanup! + end + end + + def call(env) + _run_prepare_callbacks + response = @app.call(env) + response[2].extend(CleanupOnClose) + response + rescue Exception + _run_cleanup_callbacks + raise + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 71e736ce9f..dbe3206808 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -43,20 +43,20 @@ module ActionDispatch end def call(env) - status, headers, body = @app.call(env) - - # Only this middleware cares about RoutingError. So, let's just raise - # it here. - # TODO: refactor this middleware to handle the X-Cascade scenario without - # having to raise an exception. - if headers['X-Cascade'] == 'pass' - raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}" + begin + status, headers, body = @app.call(env) + exception = nil + + # Only this middleware cares about RoutingError. So, let's just raise + # it here. + if headers['X-Cascade'] == 'pass' + raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}" + end + rescue Exception => exception + raise exception if env['action_dispatch.show_exceptions'] == false end - [status, headers, body] - rescue Exception => exception - raise exception if env['action_dispatch.show_exceptions'] == false - render_exception(env, exception) + exception ? render_exception(env, exception) : [status, headers, body] end private diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb index bd6ffbab5d..50d8ca9484 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb @@ -6,5 +6,5 @@ </h1> <pre><%=h @exception.message %></pre> -<%= render :file => "rescues/_trace.erb" %> -<%= render :file => "rescues/_request_and_response.erb" %> +<%= render :template => "rescues/_trace" %> +<%= render :template => "rescues/_request_and_response" %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb index 02fa18211d..c658559be9 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb @@ -13,9 +13,5 @@ <p><%=h @exception.sub_template_message %></p> -<% @real_exception = @exception - @exception = @exception.original_exception || @exception %> -<%= render :file => "rescues/_trace.erb" %> -<% @exception = @real_exception %> - -<%= render :file => "rescues/_request_and_response.erb" %> +<%= render :template => "rescues/_trace" %> +<%= render :template => "rescues/_request_and_response" %> |